From 1d3e6377d2cc4ab4f3bad03f798f5debab7ae81b Mon Sep 17 00:00:00 2001 From: okada Date: Sat, 20 Nov 1999 22:22:19 +0000 Subject: [PATCH] * starttls.el: New file. * starttls.c: New file. --- ChangeLog | 37 +++++---- starttls.c | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ starttls.el | 79 +++++++++++++++++++ 3 files changed, 347 insertions(+), 16 deletions(-) create mode 100644 starttls.c create mode 100644 starttls.el diff --git a/ChangeLog b/ChangeLog index 448817b..070a181 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +1999-10-21 Daiki Ueno + + * starttls.el: New file. + * starttls.c: New file. + 1999-10-20 Kenichi OKADA * smtp.el (smtp-via-smtp): Update to delete @@ -433,7 +438,7 @@ 1999-05-31 MORIOKA Tomohiko - * FLIM: Version 1.12.7 (Y-D~zaki) released. + * FLIM: Version 1.12.7 (Y~zaki) released. 1999-05-31 MORIOKA Tomohiko @@ -608,7 +613,7 @@ 1999-05-11 MORIOKA Tomohiko - * FLIM: Version 1.12.6 (Family-K-Drenmae) released. + * FLIM: Version 1.12.6 (Family-Krenmae) released. 1999-04-27 Shuhei KOBAYASHI @@ -725,7 +730,7 @@ 1999-01-23 MORIOKA Tomohiko - * FLIM: Version 1.12.3 (Kintetsu-K-Drriyama) released. + * FLIM: Version 1.12.3 (Kintetsu-Krriyama) released. 1999-01-23 MORIOKA Tomohiko @@ -768,7 +773,7 @@ 1999-01-21 MORIOKA Tomohiko - * FLIM: Version 1.12.2 (Kuj-Dr) released. + * FLIM: Version 1.12.2 (Kujr) released. 1999-01-16 MORIOKA Tomohiko @@ -954,7 +959,7 @@ 1998-12-02 MORIOKA Tomohiko - * FLIM: Version 1.12.1 (Nishinoky-Dr) released. + * FLIM: Version 1.12.1 (Nishinokyr) released. 1998-11-30 MORIOKA Tomohiko @@ -1172,7 +1177,7 @@ 1998-10-26 MORIOKA Tomohiko - * FLIM: Version 1.11.2 (Heij-Dr) was released. + * FLIM: Version 1.11.2 (Heijr) was released. * NEWS (Abolish variable `mime-temp-directory'): New subsection. @@ -1452,7 +1457,7 @@ 1998-10-12 MORIOKA Tomohiko - * FLIM: Version 1.10.4 (Shin-H-Drsono) was released. + * FLIM: Version 1.10.4 (Shin-Hrsono) was released. 1998-10-12 Katsumi Yamaoka @@ -1637,7 +1642,7 @@ 1998-09-29 MORIOKA Tomohiko - * FLIM: Version 1.10.0 (K-Drdo) was released. + * FLIM: Version 1.10.0 (Krdo) was released. * README.en (What's FLIM): Add mel-ccl.el. @@ -1924,7 +1929,7 @@ 1998-08-31 MORIOKA Tomohiko - * FLIM: Version 1.9.1 (Tonosh-Dr) was released. + * FLIM: Version 1.9.1 (Tonoshr) was released. * mime-en.sgml (mm-backend): Translate a little. @@ -2067,7 +2072,7 @@ 1998-07-07 MORIOKA Tomohiko - * FLIM-Chao: Version 1.8.0 (Shij-Dr) was released. + * FLIM-Chao: Version 1.8.0 (Shijr) was released. 1998-07-07 MORIOKA Tomohiko @@ -2179,7 +2184,7 @@ 1998-07-01 MORIOKA Tomohiko - * FLIM: Version 1.8.0 (-DRkubo) was released. + * FLIM: Version 1.8.0 (Rkubo) was released. * README.en: Delete `How to use'. @@ -2304,7 +2309,7 @@ 1998-06-28 MORIOKA Tomohiko - * FLIM-Chao: Version 1.7.0 (Goj-Dr) was released. + * FLIM-Chao: Version 1.7.0 (Gojr) was released. 1998-06-26 MORIOKA Tomohiko @@ -2563,7 +2568,7 @@ 1998-06-19 MORIOKA Tomohiko - * FLIM: Version 1.4.1 (Momoyama-Gory-Drmae) was released. + * FLIM: Version 1.4.1 (Momoyama-Goryrmae) was released. 1998-06-18 MORIOKA Tomohiko @@ -2683,7 +2688,7 @@ 1998-05-06 MORIOKA Tomohiko - * FLIM: Version 1.2.0 (J-D~jr) was released. + * FLIM: Version 1.2.0 (J~jr) was released. * README.en (What's FLIM): Delete description about std11-parse.el; add description about mailcap.el. @@ -2734,7 +2739,7 @@ 1998-05-05 MORIOKA Tomohiko - * FLIM: Version 1.1.0 (T-Drji) was released. + * FLIM: Version 1.1.0 (Trji) was released. 1998-05-04 MORIOKA Tomohiko @@ -2770,7 +2775,7 @@ 1998-04-17 MORIOKA Tomohiko - * FLIM: Version 1.0.1 (Ky-Drto) was released. + * FLIM: Version 1.0.1 (Kyrto) was released. * mime-def.el (mime-spadework-module-version-string): New constant. diff --git a/starttls.c b/starttls.c new file mode 100644 index 0000000..bc7b525 --- /dev/null +++ b/starttls.c @@ -0,0 +1,247 @@ +/* TLSv1 filter for STARTTLS extension. + + Copyright (C) 1999 Daiki Ueno + + Author: Daiki Ueno + Created: 1999-11-19 + Keywords: TLS, OpenSSL + + This file is part of FLIM (Faithful Library about Internet Message). + + 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +/* + How to compile: (OpenSSL is required) + + gcc -I/usr/local/ssl/include -o starttls starttls.c \ + -L/usr/local/ssl/lib -lssl -lcrypto + +*/ + +#include +#include +#include +#include + +#include + +/* OpenSSL library. */ + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SOCKS_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static SSL *tls_conn = NULL; +static int tls_fd; + +static SSL_CTX * +tls_ssl_ctx_new (cert_file, key_file) + const char *cert_file, key_file; +{ + SSL_CTX *tls_ctx; + + SSL_load_error_strings (); + SSLeay_add_ssl_algorithms (); + + if ((tls_ctx = SSL_CTX_new (TLSv1_client_method())) == NULL) + return NULL; + + SSL_CTX_set_options (tls_ctx, SSL_OP_ALL /* Work around all known bugs */); + + if (cert_file) { + if (SSL_CTX_use_certificate_file (tls_ctx, NULL, SSL_FILETYPE_PEM) <= 0) + return NULL; + if (SSL_CTX_use_PrivateKey_file (tls_ctx, NULL, SSL_FILETYPE_PEM) <= 0) + return NULL; + if (!SSL_CTX_check_private_key (tls_ctx)) + return NULL; + } + + SSL_CTX_set_verify (tls_ctx, SSL_VERIFY_NONE, NULL); + + return tls_ctx; +} + +static SSL * +tls_ssl_new(tls_ctx, s) + SSL_CTX *tls_ctx; + int s; +{ + SSL_SESSION *session; + SSL_CIPHER *cipher; + X509 *peer; + + if ((tls_conn = (SSL *) SSL_new (tls_ctx)) == NULL) + return NULL; + SSL_clear(tls_conn); + + if (!SSL_set_fd (tls_conn, s)) + return NULL; + + SSL_set_connect_state (tls_conn); + + if (SSL_connect (tls_conn) <= 0) { + session = SSL_get_session (tls_conn); + if (session) { + SSL_CTX_remove_session (tls_ctx, session); + } + if (tls_conn!=NULL) + SSL_free (tls_conn); + return NULL; + } + + return tls_conn; +} + +static int +tls_connect (hostname, service) + const char *hostname, *service; +{ + struct protoent *proto; + struct addrinfo *in, hints; + int server, false = 0; + + if ((proto = getprotobyname ("tcp")) == NULL) + return -1; + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = proto->p_proto; + if (getaddrinfo (hostname, service, &hints, &in) < 0) + return -1; + + if ((server = socket (in->ai_family, in->ai_socktype, 0)) < 0) + return -1; + + if (setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, + (const char *) &false, sizeof (false))) + return -1; + + if (connect (server, in->ai_addr, in->ai_addrlen) < 0) { + close (server); + return -1; + } + + return server; +} + +static void +tls_negotiate (sig) + int sig; +{ + SSL_CTX *tls_ctx; + + if ((tls_ctx = tls_ssl_ctx_new (NULL, NULL)) == NULL) + return; + + tls_conn = tls_ssl_new (tls_ctx, tls_fd); /* Negotiation has done. */ +} + +int +main (argc, argv) + int argc; + char **argv; +{ + int in = fileno (stdin), out = fileno (stdout), nbuffer, wrote; + fd_set readfds, writefds; + char buffer[BUFSIZ], *retry; + struct sigaction act; + + if ((tls_fd = tls_connect (argv[1], argv[2])) < 0) { + perror ("tls_connect"); + return 1; + } + + memset (&act, 0, sizeof (act)); + act.sa_handler = tls_negotiate; + sigemptyset (&act.sa_mask); + act.sa_flags = SA_RESTART|SA_RESETHAND; + sigaction (SIGALRM, &act, NULL); + + while (1) { + FD_SET (tls_fd, &readfds); + FD_SET (in, &readfds); + if (select (tls_fd+1, &readfds, NULL, NULL, NULL) == -1 && + errno != EINTR ) { + perror ("select"); + return 1; + } + if (FD_ISSET (in, &readfds)) { + nbuffer = read (in, buffer, sizeof buffer -1); + + if (nbuffer == 0) + goto finish; + for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote) { + FD_SET (tls_fd, &writefds); + if (select (tls_fd+1, NULL, &writefds, NULL, NULL) == -1) { + perror ("select"); + return 1; + } + if (tls_conn) + wrote = SSL_write (tls_conn, retry, nbuffer); + else + wrote = write (tls_fd, retry, nbuffer); + if (wrote < 0) goto finish; + } + } + if (FD_ISSET (tls_fd, &readfds)) { + if (tls_conn) + nbuffer = SSL_read (tls_conn, buffer, sizeof buffer -1); + else + nbuffer = read (tls_fd, buffer, sizeof buffer -1); + if (nbuffer == 0) + goto finish; + for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote) { + FD_SET (out, &writefds); + if (select (out+1, NULL, &writefds, NULL, NULL) == -1) { + perror ("select"); + return 1; + } + wrote = write (out, retry, nbuffer); + if (wrote < 0) goto finish; + } + } + } + + finish: + close (in); + close (out); + + return 0; +} diff --git a/starttls.el b/starttls.el new file mode 100644 index 0000000..2cc004f --- /dev/null +++ b/starttls.el @@ -0,0 +1,79 @@ +;;; starttls.el --- TLSv1 functions + +;; Copyright (C) 1999 Daiki Ueno + +;; Author: Daiki Ueno +;; Created: 1999/11/20 +;; Keywords: TLS, SSL, OpenSSL + +;; This file is part of FLIM (Faithful Library about Internet Message). + +;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This module defines some utility functions for TLSv1 functions. + +;; [RFC 2246] "The TLS Protocol Version 1.0" +;; by Christopher Allen and +;; Tim Dierks (1999/01) + +;; [RFC 2595] "Using TLS with IMAP, POP3 and ACAP" +;; by Chris Newman (1999/06) + +;;; Code: + +(defgroup starttls nil + "Support for `Transport Layer Security' protocol." + :group 'ssl) + +(defcustom starttls-program "starttls" + "The program to run in a subprocess to open an TLSv1 connection." + :group 'starttls) + +(defcustom starttls-extra-args nil + "Extra arguments to `starttls-program'" + :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. +Returns a subprocess-object to represent the connection. +Input and output work as for subprocesses; `delete-process' closes it. +Args are NAME BUFFER HOST SERVICE. +NAME is name for process. It is modified if necessary to make it unique. +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 +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) + +;;; starttls.el ends here -- 1.7.10.4