[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/lisp/gnus/starttls.el
From: |
Simon Josefsson |
Subject: |
[Emacs-diffs] Changes to emacs/lisp/gnus/starttls.el |
Date: |
Fri, 28 May 2004 01:33:57 -0400 |
Index: emacs/lisp/gnus/starttls.el
diff -c emacs/lisp/gnus/starttls.el:1.3 emacs/lisp/gnus/starttls.el:1.4
*** emacs/lisp/gnus/starttls.el:1.3 Mon Sep 1 15:45:28 2003
--- emacs/lisp/gnus/starttls.el Fri May 28 05:27:52 2004
***************
*** 1,10 ****
;;; starttls.el --- STARTTLS functions
! ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
;; Author: Daiki Ueno <address@hidden>
;; Created: 1999/11/20
! ;; Keywords: TLS, SSL, OpenSSL, mail, news
;; This file is part of GNU Emacs.
--- 1,11 ----
;;; starttls.el --- STARTTLS functions
! ;; Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
;; Author: Daiki Ueno <address@hidden>
+ ;; Author: Simon Josefsson <address@hidden>
;; Created: 1999/11/20
! ;; Keywords: TLS, SSL, OpenSSL, GNUTLS, mail, news
;; This file is part of GNU Emacs.
***************
*** 30,35 ****
--- 31,120 ----
;; [RFC 2595] "Using TLS with IMAP, POP3 and ACAP"
;; by Chris Newman <address@hidden> (1999/06)
+ ;; This file now contain a combination of the two previous
+ ;; implementations both called "starttls.el". The first one is Daiki
+ ;; Ueno's starttls.el which uses his own "starttls" command line tool,
+ ;; and the second one is Simon Josefsson's starttls.el which uses
+ ;; "gnutls-cli" from GNUTLS.
+ ;;
+ ;; If "starttls" is available, it is prefered by the code over
+ ;; "gnutls-cli", for backwards compatibility. Use
+ ;; `starttls-use-gnutls' to toggle between implementations if you have
+ ;; both tools installed. It is recommended to use GNUTLS, though, as
+ ;; it performs more verification of the certificates.
+
+ ;; The GNUTLS support require GNUTLS 0.9.90 (released 2003-10-08) or
+ ;; later, from <http://www.gnu.org/software/gnutls/>, or "starttls"
+ ;; from <ftp://ftp.opaopa.org/pub/elisp/>.
+
+ ;; Usage is similar to `open-network-stream'. For example:
+ ;;
+ ;; (when (setq tmp (starttls-open-stream
+ ;; "test" (current-buffer) "yxa.extundo.com" 25))
+ ;; (accept-process-output tmp 15)
+ ;; (process-send-string tmp "STARTTLS\n")
+ ;; (accept-process-output tmp 15)
+ ;; (message "STARTTLS output:\n%s" (starttls-negotiate tmp))
+ ;; (process-send-string tmp "EHLO foo\n"))
+
+ ;; An example run yield the following output:
+ ;;
+ ;; 220 yxa.extundo.com ESMTP Sendmail 8.12.11/8.12.11/Debian-3; Wed, 26 May
2004 19:12:29 +0200; (No UCE/UBE) logging access from:
c494102a.s-bi.bostream.se(OK)-c494102a.s-bi.bostream.se [217.215.27.65]
+ ;; 220 2.0.0 Ready to start TLS
+ ;; 250-yxa.extundo.com Hello c494102a.s-bi.bostream.se [217.215.27.65],
pleased to meet you
+ ;; 250-ENHANCEDSTATUSCODES
+ ;; 250-PIPELINING
+ ;; 250-EXPN
+ ;; 250-VERB
+ ;; 250-8BITMIME
+ ;; 250-SIZE
+ ;; 250-DSN
+ ;; 250-ETRN
+ ;; 250-AUTH DIGEST-MD5 CRAM-MD5 PLAIN LOGIN
+ ;; 250-DELIVERBY
+ ;; 250 HELP
+ ;; nil
+ ;;
+ ;; With the message buffer containing:
+ ;;
+ ;; STARTTLS output:
+ ;; *** Starting TLS handshake
+ ;; - Server's trusted authorities:
+ ;; [0]:
C=SE,ST=Stockholm,L=Stockholm,O=YXA,OU=CA,CN=yxa.extundo.com,address@hidden
+ ;; - Certificate type: X.509
+ ;; - Got a certificate list of 2 certificates.
+ ;;
+ ;; - Certificate[0] info:
+ ;; # The hostname in the certificate matches 'yxa.extundo.com'.
+ ;; # valid since: Wed May 26 12:16:00 CEST 2004
+ ;; # expires at: Wed Jul 26 12:16:00 CEST 2023
+ ;; # serial number: 04
+ ;; # fingerprint: 7c 04 4b c1 fa 26 9b 5d 90 22 52 3c 65 3d 85 3a
+ ;; # version: #1
+ ;; # public key algorithm: RSA
+ ;; # Modulus: 1024 bits
+ ;; # Subject's DN: C=SE,ST=Stockholm,L=Stockholm,O=YXA,OU=Mail
server,CN=yxa.extundo.com,address@hidden
+ ;; # Issuer's DN:
C=SE,ST=Stockholm,L=Stockholm,O=YXA,OU=CA,CN=yxa.extundo.com,address@hidden
+ ;;
+ ;; - Certificate[1] info:
+ ;; # valid since: Sun May 23 11:35:00 CEST 2004
+ ;; # expires at: Sun Jul 23 11:35:00 CEST 2023
+ ;; # serial number: 00
+ ;; # fingerprint: fc 76 d8 63 1a c9 0b 3b fa 40 fe ed 47 7a 58 ae
+ ;; # version: #3
+ ;; # public key algorithm: RSA
+ ;; # Modulus: 1024 bits
+ ;; # Subject's DN:
C=SE,ST=Stockholm,L=Stockholm,O=YXA,OU=CA,CN=yxa.extundo.com,address@hidden
+ ;; # Issuer's DN:
C=SE,ST=Stockholm,L=Stockholm,O=YXA,OU=CA,CN=yxa.extundo.com,address@hidden
+ ;;
+ ;; - Peer's certificate issuer is unknown
+ ;; - Peer's certificate is NOT trusted
+ ;; - Version: TLS 1.0
+ ;; - Key Exchange: RSA
+ ;; - Cipher: ARCFOUR 128
+ ;; - MAC: SHA
+ ;; - Compression: NULL
+
;;; Code:
(defgroup starttls nil
***************
*** 37,54 ****
:version "21.1"
:group 'mail)
(defcustom starttls-program "starttls"
! "The program to run in a subprocess to open an TLSv1 connection."
:type 'string
:group 'starttls)
(defcustom starttls-extra-args nil
! "Extra arguments to `starttls-program'."
:type '(repeat string)
:group 'starttls)
(defun starttls-negotiate (process)
! (signal-process (process-id process) 'SIGALRM))
(defun starttls-open-stream (name buffer host service)
"Open a TLS connection for a service to a host.
--- 122,262 ----
:version "21.1"
:group 'mail)
+ (defcustom starttls-gnutls-program "gnutls-cli"
+ "Name of GNUTLS command line tool.
+ This program is used when GNUTLS is used, i.e. when
+ `starttls-use-gnutls' is non-nil."
+ :type 'string
+ :group 'starttls)
+
(defcustom starttls-program "starttls"
! "The program to run in a subprocess to open an TLSv1 connection.
! This program is used when the `starttls' command is used,
! i.e. when `starttls-use-gnutls' is nil."
:type 'string
:group 'starttls)
+ (defcustom starttls-use-gnutls (not (executable-find starttls-program))
+ "*Whether to use GNUTLS instead of the `starttls' command."
+ :type 'boolean
+ :group 'starttls)
+
(defcustom starttls-extra-args nil
! "Extra arguments to `starttls-program'.
! This program is used when the `starttls' command is used,
! i.e. when `starttls-use-gnutls' is nil."
:type '(repeat string)
:group 'starttls)
+ (defcustom starttls-extra-arguments nil
+ "Extra arguments to `starttls-program'.
+ This program is used when GNUTLS is used, i.e. when
+ `starttls-use-gnutls' is non-nil.
+
+ For example, non-TLS compliant servers may require
+ '(\"--protocols\" \"ssl3\"). Invoke \"gnutls-cli --help\" to
+ find out which parameters are available."
+ :type '(repeat string)
+ :group 'starttls)
+
+ (defcustom starttls-process-connection-type nil
+ "*Value for `process-connection-type' to use when starting STARTTLS
process."
+ :type 'boolean
+ :group 'starttls)
+
+ (defcustom starttls-connect "- Simple Client Mode:\n\n"
+ "*Regular expression indicating successful connection.
+ The default is what GNUTLS's \"gnutls-cli\" outputs."
+ ;; GNUTLS cli.c:main() print this string when it is starting to run
+ ;; in the application read/write phase. If the logic, or the string
+ ;; itself, is modified, this must be updated.
+ :type 'regexp
+ :group 'starttls)
+
+ (defcustom starttls-failure "\\*\\*\\* Handshake has failed"
+ "*Regular expression indicating failed TLS handshake.
+ The default is what GNUTLS's \"gnutls-cli\" outputs."
+ ;; GNUTLS cli.c:do_handshake() print this string on failure. If the
+ ;; logic, or the string itself, is modified, this must be updated.
+ :type 'regexp
+ :group 'starttls)
+
+ (defcustom starttls-success "- Compression: "
+ "*Regular expression indicating completed TLS handshakes.
+ The default is what GNUTLS's \"gnutls-cli\" outputs."
+ ;; GNUTLS cli.c:do_handshake() calls, on success,
+ ;; common.c:print_info(), that unconditionally print this string
+ ;; last. If that logic, or the string itself, is modified, this
+ ;; must be updated.
+ :type 'regexp
+ :group 'starttls)
+
+ (defun starttls-negotiate-gnutls (process)
+ "Negotiate TLS on process opened by `open-starttls-stream'.
+ This should typically only be done once. It typically return a
+ multi-line informational message with information about the
+ handshake, or NIL on failure."
+ (let (buffer info old-max done-ok done-bad)
+ (if (null (setq buffer (process-buffer process)))
+ ;; XXX How to remove/extract the TLS negotiation junk?
+ (signal-process (process-id process) 'SIGALRM)
+ (with-current-buffer buffer
+ (save-excursion
+ (setq old-max (goto-char (point-max)))
+ (signal-process (process-id process) 'SIGALRM)
+ (while (and (processp process)
+ (eq (process-status process) 'run)
+ (save-excursion
+ (goto-char old-max)
+ (not (or (setq done-ok (re-search-forward
+ starttls-success nil t))
+ (setq done-bad (re-search-forward
+ starttls-failure nil t))))))
+ (accept-process-output process 1 100)
+ (sit-for 0.1))
+ (setq info (buffer-substring-no-properties old-max (point-max)))
+ (delete-region old-max (point-max))
+ (if (or (and done-ok (not done-bad))
+ ;; Prevent mitm that fake success msg after failure msg.
+ (and done-ok done-bad (< done-ok done-bad)))
+ info
+ (message "STARTTLS negotiation failed: %s" info)
+ nil))))))
+
(defun starttls-negotiate (process)
! (if starttls-use-gnutls
! (starttls-negotiate-gnutls process)
! (signal-process (process-id process) 'SIGALRM)))
!
! (defun starttls-open-stream-gnutls (name buffer host service)
! (message "Opening STARTTLS connection to `%s'..." host)
! (let* (done
! (old-max (with-current-buffer buffer (point-max)))
! (process-connection-type starttls-process-connection-type)
! (process (apply #'start-process name buffer
! starttls-gnutls-program "-s" host
! "-p" (if (integerp service)
! (int-to-string service)
! service)
! starttls-extra-arguments)))
! (process-kill-without-query process)
! (while (and (processp process)
! (eq (process-status process) 'run)
! (save-excursion
! (set-buffer buffer)
! (goto-char old-max)
! (not (setq done (re-search-forward
! starttls-connect nil t)))))
! (accept-process-output process 0 100)
! (sit-for 0.1))
! (if done
! (with-current-buffer buffer
! (delete-region old-max done))
! (delete-process process)
! (setq process nil))
! (message "Opening STARTTLS connection to `%s'...%s"
! host (if done "done" "failed"))
! process))
(defun starttls-open-stream (name buffer host service)
"Open a TLS connection for a service to a host.
***************
*** 64,76 ****
Third arg is name of the host to connect to, or its IP address.
Fourth arg SERVICE is name of the service desired, or an integer
specifying a port number to connect to."
! (let* ((process-connection-type nil)
! (process (apply #'start-process
! name buffer starttls-program
! host (format "%s" service)
! starttls-extra-args)))
! (process-kill-without-query process)
! process))
(provide 'starttls)
--- 272,286 ----
Third arg is name of the host to connect to, or its IP address.
Fourth arg SERVICE is name of the service desired, or an integer
specifying a port number to connect to."
! (if starttls-use-gnutls
! (starttls-open-stream-gnutls name buffer host service)
! (let* ((process-connection-type starttls-process-connection-type)
! (process (apply #'start-process
! name buffer starttls-program
! host (format "%s" service)
! starttls-extra-args)))
! (process-kill-without-query process)
! process)))
(provide 'starttls)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] Changes to emacs/lisp/gnus/starttls.el,
Simon Josefsson <=