* starttls.el: New file.
authorokada <okada>
Sat, 20 Nov 1999 22:22:19 +0000 (22:22 +0000)
committerokada <okada>
Sat, 20 Nov 1999 22:22:19 +0000 (22:22 +0000)
* starttls.c: New file.

ChangeLog
starttls.c [new file with mode: 0644]
starttls.el [new file with mode: 0644]

index 448817b..070a181 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+1999-10-21  Daiki Ueno <ueno@ueda.info.waseda.ac.jp>
+
+       * starttls.el: New file.
+       * starttls.c: New file.
+
 1999-10-20  Kenichi OKADA <okada@opaopa.org>
 
        * smtp.el (smtp-via-smtp): Update to delete
 \f
 1999-05-31  MORIOKA Tomohiko  <tomo@m17n.org>
 
-       * FLIM: Version 1.12.7 (Y\e-D\ e~\ fzaki) released.
+       * FLIM: Version 1.12.7 (Y\ e~\ fzaki) released.
 
 1999-05-31  MORIOKA Tomohiko  <tomo@m17n.org>
 
 \f
 1999-05-11  MORIOKA Tomohiko  <tomo@m17n.org>
 
-       * FLIM: Version 1.12.6 (Family-K\e-D\ er\ fenmae) released.
+       * FLIM: Version 1.12.6 (Family-K\ er\ fenmae) released.
 
 1999-04-27  Shuhei KOBAYASHI  <shuhei@aqua.ocn.ne.jp>
 
 \f
 1999-01-23  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.12.3 (Kintetsu-K\e-D\ er\ friyama) released.
+       * FLIM: Version 1.12.3 (Kintetsu-K\ er\ friyama) released.
 
 1999-01-23  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
 \f
 1999-01-21  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.12.2 (Kuj\e-D\ er\ f) released.
+       * FLIM: Version 1.12.2 (Kuj\ er\ f) released.
 
 1999-01-16  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
 \f
 1998-12-02  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.12.1 (Nishinoky\e-D\ er\ f) released.
+       * FLIM: Version 1.12.1 (Nishinoky\ er\ f) released.
 
 1998-11-30  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
 \f
 1998-10-26  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.11.2 (Heij\e-D\ er\ f) was released.
+       * FLIM: Version 1.11.2 (Heij\ er\ f) was released.
 
        * NEWS (Abolish variable `mime-temp-directory'): New subsection.
 
 \f
 1998-10-12  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.10.4 (Shin-H\e-D\ er\ fsono) was released.
+       * FLIM: Version 1.10.4 (Shin-H\ er\ fsono) was released.
 
 1998-10-12  Katsumi Yamaoka   <yamaoka@jpl.org>
 
 \f
 1998-09-29  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.10.0 (K\e-D\ er\ fdo) was released.
+       * FLIM: Version 1.10.0 (K\ er\ fdo) was released.
 
        * README.en (What's FLIM): Add mel-ccl.el.
 
 \f
 1998-08-31  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.9.1 (Tonosh\e-D\ er\ f) was released.
+       * FLIM: Version 1.9.1 (Tonosh\ er\ f) was released.
 
        * mime-en.sgml (mm-backend): Translate a little.
 
 \f
 1998-07-07  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM-Chao: Version 1.8.0 (Shij\e-D\ er\ f) was released.
+       * FLIM-Chao: Version 1.8.0 (Shij\ er\ f) was released.
 
 1998-07-07  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
 \f
 1998-07-01  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.8.0 (\e-D\ eR\ fkubo) was released.
+       * FLIM: Version 1.8.0 (\ eR\ fkubo) was released.
 
        * README.en: Delete `How to use'.
 
 \f
 1998-06-28  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM-Chao: Version 1.7.0 (Goj\e-D\ er\ f) was released.
+       * FLIM-Chao: Version 1.7.0 (Goj\ er\ f) was released.
 
 1998-06-26  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
 \f
 1998-06-19  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.4.1 (Momoyama-Gory\e-D\ er\ fmae) was released.
+       * FLIM: Version 1.4.1 (Momoyama-Gory\ er\ fmae) was released.
 
 1998-06-18  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
 \f
 1998-05-06  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.2.0 (J\e-D\ e~\ fj\ er\ f) was released.
+       * FLIM: Version 1.2.0 (J\ e~\ fj\ er\ f) was released.
 
        * README.en (What's FLIM): Delete description about
        std11-parse.el; add description about mailcap.el.
 \f
 1998-05-05  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.1.0 (T\e-D\ er\ fji) was released.
+       * FLIM: Version 1.1.0 (T\ er\ fji) was released.
 
 1998-05-04  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
 \f
 1998-04-17  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
-       * FLIM: Version 1.0.1 (Ky\e-D\ er\ fto) was released.
+       * FLIM: Version 1.0.1 (Ky\ er\ fto) was released.
 
        * mime-def.el (mime-spadework-module-version-string): New
        constant.
diff --git a/starttls.c b/starttls.c
new file mode 100644 (file)
index 0000000..bc7b525
--- /dev/null
@@ -0,0 +1,247 @@
+/* TLSv1 filter for STARTTLS extension.
+
+   Copyright (C) 1999 Daiki Ueno <ueno@ueda.info.waseda.ac.jp>
+
+   Author: Daiki Ueno <ueno@ueda.info.waseda.ac.jp>
+   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 <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+
+/* OpenSSL library. */
+
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+
+#ifdef HAVE_SOCKS_H
+#include <socks.h>
+#endif 
+
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <signal.h>
+
+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 (file)
index 0000000..2cc004f
--- /dev/null
@@ -0,0 +1,79 @@
+;;; starttls.el --- TLSv1 functions
+
+;; Copyright (C) 1999 Daiki Ueno
+
+;; Author: Daiki Ueno <ueno@ueda.info.waseda.ac.jp>
+;; 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 <callen@certicom.com> and 
+;;     Tim Dierks <tdierks@certicom.com> (1999/01)
+
+;; [RFC 2595] "Using TLS with IMAP, POP3 and ACAP"
+;;     by Chris Newman <chris.newman@innosoft.com> (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