diff options
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el')
-rw-r--r-- | configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el new file mode 100644 index 000000000000..aa7508568b96 --- /dev/null +++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el @@ -0,0 +1,194 @@ +;;; make-tls-process.el --- A non-blocking TLS connection function + +;; Copyright (C) 2015 Jorgen Schaefer <contact@jorgenschaefer.de> + +;; Author: Jorgen Schaefer <contact@jorgenschaefer.de> +;; URL: https://github.com/jorgenschaefer/circe + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 3 +;; of the License, or (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; A `make-tls-process' function like `make-network-process', in +;; particular supporting non-blocking connects. + +;;; Code: + +(require 'tls) + +(defcustom tls-connection-command + (if (executable-find "gnutls-cli") + "gnutls-cli --insecure -p %p %h" + "openssl s_client -connect %h:%p -ign_eof") + "The command to use to create a TLS connection. + +%h is replaced with server hostname, %p with port to connect to. +The program should read input on stdin and write output to +stdout. + +Also see `tls-success' for what the program should output after +successful negotiation." + :group 'tls + :type 'string) + +(defvar tls-debug-output nil + "Non-nil if you want to see lots of debug messages.") + +(defun tls--debug (format-string &rest args) + "Display a message if debug output is enabled. + +If `tls-debug-output' is non-nil, this acts like `message'. +Otherwise, it's a no-op." + (when tls-debug-output + (apply #'message format-string args))) + +(defun make-tls-process (&rest args) + "Create a TLS client process. + +A TLS network process is a command process that runs a command +line program like gnutls or openssl, not a full network process. +Network communication should work as usual, but the sentinel +might receive process-specific events. + +Different from a process sentinel, but like a network sentinel, +the sentinel is called with an event \"open\\n\" when the +connection is established. + +This function uses `tls-connection-command' to connect to a +server. + +Do NOT use `set-process-filter' or `set-process-sentinel' on the +return value of this function. The connection setup uses special +sentinels and filters to be deal with the program output used +here. Use the :sentinel and :filter keyword arguments to set them +once the connection is fully established. + +Arguments are specified as keyword/argument pairs, similar to +`make-network-process'. The following arguments are defined: + +:name NAME -- NAME is name for process. It is modified if necessary +to make it unique. + +:buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate +with the process. Process output goes at end of that buffer, unless +you specify an output stream or filter function to handle the output. +BUFFER may be also nil, meaning that this process is not associated +with any buffer. + +:host HOST -- HOST is name of the host to connect to, or its IP +address. The symbol `local' specifies the local host. If specified +for a server process, it must be a valid name or address for the local +host, and only clients connecting to that address will be accepted. + +:service SERVICE -- SERVICE is name of the service desired, or an +integer specifying a port number to connect to. If SERVICE is t, +a random port number is selected for the server. (If Emacs was +compiled with getaddrinfo, a port number can also be specified as +a string, e.g. \"80\", as well as an integer. This is not +portable.) + +:coding CODING -- If CODING is a symbol, it specifies the coding +system used for both reading and writing for this process. If CODING +is a cons (DECODING . ENCODING), DECODING is used for reading, and +ENCODING is used for writing. + +:noquery BOOL -- Query the user unless BOOL is non-nil, and process is +running when Emacs is exited. + +:filter FILTER -- Install FILTER as the process filter. + +:sentinel SENTINEL -- Install SENTINEL as the process sentinel. + +:plist PLIST -- Install PLIST as the new process's initial plist." + (let* ((name (plist-get args :name)) + (host (plist-get args :host)) + (service (plist-get args :service)) + (proc (tls--start-process name tls-connection-command host service))) + (process-put proc :tls-args args) + (set-process-sentinel proc #'tls--sentinel) + (set-process-filter proc #'tls--filter) + proc)) + +(defun tls--sentinel (proc event) + "The default sentinel for TLS connections. + +Try the next command in the list, or fail if there are none +left." + (tls--debug "tls--sentinel %S %S" + (process-status proc) + event) + (tls--debug "Failed TLS output: %s" + (process-get proc :tls-data)) + (if (eq (process-status proc) + 'exit) + (let ((sentinel (plist-get (process-get proc :tls-args) + :sentinel))) + (when sentinel + (funcall sentinel proc (format "failed with %s\n" event)))) + (error "Unexpected event in tls sentinel: %S" event))) + +(defun tls--filter (proc data) + "The default filter for TLS connections. + +We wait until both `tls-success' and `tls-end-of-info' have been +received. Once that happens, we are done and we can switch over +to the real connection." + (let ((data (concat (or (process-get proc :tls-data) + "") + data))) + (if (and (string-match tls-success data) + (string-match tls-end-of-info data)) + (let* ((remaining-data (substring data (match-end 0))) + (args (process-get proc :tls-args)) + (buffer (plist-get args :buffer)) + (coding (plist-get args :coding)) + (noquery (plist-get args :noquery)) + (filter (plist-get args :filter)) + (sentinel (plist-get args :sentinel)) + (plist (plist-get args :plist))) + (set-process-plist proc plist) + (set-process-sentinel proc sentinel) + (set-process-filter proc filter) + (set-process-buffer proc buffer) + (if (consp coding) + (set-process-coding-system proc (car coding) (cdr coding)) + (set-process-coding-system proc coding coding)) + (set-process-query-on-exit-flag proc (not noquery)) + (when sentinel + (funcall sentinel proc "open\n")) + (when (and (not (equal remaining-data "")) + filter) + (funcall filter proc remaining-data))) + (process-put proc :tls-data data)))) + +(defun tls--start-process (name cmd host port) + "Start a single process for network communication. + +This code is mostly taken from tls.el." + (let ((process-connection-type tls-process-connection-type) + (formatted-cmd + (format-spec + cmd + (format-spec-make + ?h host + ?p (if (integerp port) + (int-to-string port) + port))))) + (tls--debug "TLS starting process: %s" formatted-cmd) + (start-process name nil + shell-file-name shell-command-switch + formatted-cmd))) + +(provide 'make-tls-process) +;;; make-tls-process.el ends here |