* starttls.c (do_tls_negotiate): New signal handler.
authorueno <ueno>
Wed, 9 Jun 2004 02:53:45 +0000 (02:53 +0000)
committerueno <ueno>
Wed, 9 Jun 2004 02:53:45 +0000 (02:53 +0000)
* openssl.c: New file; split functions which use OpenSSL API from
starttls.c.
* Makefile.am (starttls_SOURCES): Add openssl.c.

ChangeLog
Makefile.am
openssl.c [new file with mode: 0644]
starttls.c

index 9278e1f..cca24c5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-06-09  Daiki Ueno  <ueno@unixuser.org>
+
+       * starttls.c (do_tls_negotiate): New signal handler.
+       * openssl.c: New file; split functions which use OpenSSL API from
+       starttls.c.
+       * Makefile.am (starttls_SOURCES): Add openssl.c.
+
 2004-03-21  Kenichi Okada  <okada@opaopa.org>
 
        * configure.in (VERSION): Bump up to 0.10.
index c9eb5f7..468edb6 100644 (file)
@@ -6,5 +6,5 @@ EXTRA_DIST = starttls.el basename.c getopt.c getopt.h getopt1.c
 bin_PROGRAMS= starttls
 lisp_LISP = starttls.el
 
-starttls_SOURCES = starttls.c
+starttls_SOURCES = starttls.c openssl.c
 starttls_LDADD = $(LIBOBJS)
diff --git a/openssl.c b/openssl.c
new file mode 100644 (file)
index 0000000..1eeff0a
--- /dev/null
+++ b/openssl.c
@@ -0,0 +1,177 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+
+static SSL_CTX *tls_ctx = NULL;
+static SSL *tls_conn = NULL;
+
+static int
+tls_ssl_ctx_new (cert_file, key_file)
+  const char *cert_file, *key_file;
+{
+  SSL_load_error_strings ();
+  SSLeay_add_ssl_algorithms ();
+
+  tls_ctx = SSL_CTX_new (TLSv1_client_method());
+  if (!tls_ctx)
+    return -1;
+
+  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, cert_file, 
+                                       SSL_FILETYPE_PEM) <= 0)
+       return -1;
+      if (!key_file)
+       key_file = cert_file;
+      if (SSL_CTX_use_PrivateKey_file (tls_ctx, key_file, 
+                                      SSL_FILETYPE_PEM) <= 0)
+       return -1;
+      if (!SSL_CTX_check_private_key (tls_ctx))
+       return -1;
+    }
+
+  SSL_CTX_set_verify (tls_ctx, SSL_VERIFY_NONE, NULL);
+
+  return 0;
+}
+
+static int
+tls_ssl_new(ctx, s)
+  SSL_CTX *ctx;
+  int s;
+{
+  SSL_SESSION *session;
+  SSL_CIPHER *cipher;
+  X509   *peer;
+
+  tls_conn = (SSL *) SSL_new (ctx);
+  if (!tls_conn)
+    return -1;
+  SSL_clear(tls_conn);
+
+  if (!SSL_set_fd (tls_conn, s))
+    return -1;
+
+  SSL_set_connect_state (tls_conn);
+
+  if (SSL_connect (tls_conn) <= 0)
+    {
+      session = SSL_get_session (tls_conn);
+      if (session)
+       SSL_CTX_remove_session (ctx, session);
+      if (tls_conn!=NULL)
+       SSL_free (tls_conn);
+      return -1;
+    }
+
+  return 0;
+}
+
+int
+tls_connect (hostname, service)
+     const char *hostname, *service;
+{
+  int server, false = 0;
+#ifdef HAVE_ADDRINFO
+  struct addrinfo *in, *in0, hints;
+#else
+  struct hostent *host;
+  struct servent *serv;
+  struct sockaddr_in sin;
+#endif
+
+#ifdef HAVE_ADDRINFO
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_STREAM;
+  if (getaddrinfo (hostname, service, &hints, &in0))
+    return -1;
+
+  for (in = in0; in; in = in->ai_next)
+    {
+      server = socket (in->ai_family, in->ai_socktype, in->ai_protocol);
+      if (server < 0)
+       continue;
+      if (connect (server, in->ai_addr, in->ai_addrlen) < 0)
+       {
+         server = -1;
+         continue;
+       }
+      break;
+  }
+
+  if (server < 0)
+    return -1;
+#else
+  memset (&sin, 0, sizeof (sin));
+  host = gethostbyname (hostname);
+  if (!host)
+    return -1;
+  memcpy (&sin.sin_addr, host->h_addr, host->h_length);
+  serv = getservbyname (service, "tcp");
+  if (serv)
+    sin.sin_port = serv->s_port;
+  else if (isdigit (service[0]))
+    sin.sin_port = htons (atoi (service));
+  sin.sin_family = AF_INET;
+  server = socket (sin.sin_family, SOCK_STREAM, 0);
+  if (server == -1)
+    return -1;
+
+  if (connect (server, (struct sockaddr *)&sin, sizeof (sin)) < 0)
+    {
+      close (server);
+      return -1;
+    }
+#endif
+
+  setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, (const char *) &false,
+             sizeof (false));
+
+  return server;
+}
+
+void
+tls_negotiate (fd, cert_file, key_file)
+     int fd;
+{
+  if (tls_ssl_ctx_new (cert_file, key_file) == -1)
+    return;
+
+  (void) tls_ssl_new (tls_ctx, fd); /* Negotiation has done. */
+}
+
+int
+tls_write(fd, buf, num)
+     const char *buf;
+     int fd, num;
+{
+  if (tls_conn) 
+    return SSL_write (tls_conn, buf, num);
+  return write (fd, buf, num);
+}
+
+int
+tls_read(fd, buf, num)
+     char *buf;
+     int fd, num;
+{
+  if (tls_conn)
+    return SSL_read (tls_conn, buf, num);
+  return read (fd, buf, num);
+}
+
+int
+tls_pending()
+{
+  return tls_conn && SSL_pending(tls_conn);
+}
index f0d61ce..ba867f7 100644 (file)
 
 #include <unistd.h>
 
-#include <openssl/lhash.h>
-#include <openssl/bn.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/x509.h>
-#include <openssl/ssl.h>
-
+#include <errno.h>
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/file.h>
 #define _GNU_SOURCE
 #include "getopt.h"
 
-static SSL_CTX *tls_ctx = NULL;
-static SSL *tls_conn = NULL;
-static int tls_fd;
+extern int tls_connect (const char *, const char *);
+extern void tls_negotiate (int, const char *, const char *);
+extern int tls_write(int, const char *, int);
+extern int tls_read(int, char *, int);
+extern int tls_pending();
 
 static char *opt_cert_file = NULL, *opt_key_file = NULL;
-static int  opt_verify = 0;
-
-static int
-tls_ssl_ctx_new (cert_file, key_file)
-  const char *cert_file, *key_file;
-{
-  SSL_load_error_strings ();
-  SSLeay_add_ssl_algorithms ();
-
-  tls_ctx = SSL_CTX_new (TLSv1_client_method());
-  if (!tls_ctx)
-    return -1;
-
-  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, cert_file, 
-                                       SSL_FILETYPE_PEM) <= 0)
-       return -1;
-      if (!key_file)
-       key_file = cert_file;
-      if (SSL_CTX_use_PrivateKey_file (tls_ctx, key_file, 
-                                      SSL_FILETYPE_PEM) <= 0)
-       return -1;
-      if (!SSL_CTX_check_private_key (tls_ctx))
-       return -1;
-    }
-
-  SSL_CTX_set_verify (tls_ctx, SSL_VERIFY_NONE, NULL);
-
-  return 0;
-}
-
-static int
-tls_ssl_new(ctx, s)
-  SSL_CTX *ctx;
-  int s;
-{
-  SSL_SESSION *session;
-  SSL_CIPHER *cipher;
-  X509   *peer;
-
-  tls_conn = (SSL *) SSL_new (ctx);
-  if (!tls_conn)
-    return -1;
-  SSL_clear(tls_conn);
-
-  if (!SSL_set_fd (tls_conn, s))
-    return -1;
-
-  SSL_set_connect_state (tls_conn);
-
-  if (SSL_connect (tls_conn) <= 0)
-    {
-      session = SSL_get_session (tls_conn);
-      if (session)
-       SSL_CTX_remove_session (ctx, session);
-      if (tls_conn!=NULL)
-       SSL_free (tls_conn);
-      return -1;
-    }
-
-  return 0;
-}
-
-static int
-tls_connect (hostname, service)
-     const char *hostname, *service;
-{
-  int server, false = 0;
-#ifdef HAVE_ADDRINFO
-  struct addrinfo *in, *in0, hints;
-#else
-  struct hostent *host;
-  struct servent *serv;
-  struct sockaddr_in sin;
-#endif
-
-#ifdef HAVE_ADDRINFO
-  memset (&hints, 0, sizeof (hints));
-  hints.ai_family = AF_UNSPEC;
-  hints.ai_socktype = SOCK_STREAM;
-  if (getaddrinfo (hostname, service, &hints, &in0))
-    return -1;
-
-  for (in = in0; in; in = in->ai_next)
-    {
-      server = socket (in->ai_family, in->ai_socktype, in->ai_protocol);
-      if (server < 0)
-       continue;
-      if (connect (server, in->ai_addr, in->ai_addrlen) < 0)
-       {
-         server = -1;
-         continue;
-       }
-      break;
-  }
-
-  if (server < 0)
-    return -1;
-#else
-  memset (&sin, 0, sizeof (sin));
-  host = gethostbyname (hostname);
-  if (!host)
-    return -1;
-  memcpy (&sin.sin_addr, host->h_addr, host->h_length);
-  serv = getservbyname (service, "tcp");
-  if (serv)
-    sin.sin_port = serv->s_port;
-  else if (isdigit (service[0]))
-    sin.sin_port = htons (atoi (service));
-  sin.sin_family = AF_INET;
-  server = socket (sin.sin_family, SOCK_STREAM, 0);
-  if (server == -1)
-    return -1;
-
-  if (connect (server, (struct sockaddr *)&sin, sizeof (sin)) < 0)
-    {
-      close (server);
-      return -1;
-    }
-#endif
-
-  setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, (const char *) &false,
-             sizeof (false));
-
-  return server;
-}
-
-static void
-tls_negotiate (sig)
-     int sig;
-{
-  if (tls_ssl_ctx_new (opt_cert_file, opt_key_file) == -1)
-    return;
-
-  (void) tls_ssl_new (tls_ctx, tls_fd); /* Negotiation has done. */
-}
+static int tls_fd;
 
 static void
 usage (progname)
@@ -212,11 +70,17 @@ usage (progname)
          "Usage: %s [options] host port\n\n"
          "Options:\n\n"
          " --cert-file [file]      specify certificate file\n"
-         " --key-file [file]       specify private key file\n"
-         " --verify [level]        set verification level\n",
+         " --key-file [file]       specify private key file\n",
          progname, PACKAGE, VERSION, progname);
 }
-     
+
+static void
+do_tls_negotiate(sig)
+  int sig;
+{
+  tls_negotiate(tls_fd, opt_cert_file, opt_key_file);
+}
+
 int
 main (argc, argv) 
   int argc;
@@ -238,13 +102,12 @@ main (argc, argv)
     {
       {"cert-file", 1, 0, 'c'},
       {"key-file", 1, 0, 'k'},
-      {"verify", 1, 0, 'v'},
       {0, 0, 0, 0}
     };
 
   while (1)
     {
-      c = getopt_long (argc, argv, "c:k:v:", long_options, &option_index);
+      c = getopt_long (argc, argv, "c:k:", long_options, &option_index);
       if (c == -1)
        break;
     
@@ -256,9 +119,6 @@ main (argc, argv)
        case 'k':
          opt_key_file = optarg;
          break;
-       case 'v':
-         opt_verify = atoi (optarg);
-         break;
        default:
          usage (basename (argv[0]));
          return 1;
@@ -279,7 +139,7 @@ main (argc, argv)
     }
 
   memset (&act, 0, sizeof (act));
-  act.sa_handler = tls_negotiate;
+  act.sa_handler = do_tls_negotiate;
   sigemptyset (&act.sa_mask);
   act.sa_flags = SA_RESTART|SA_RESETHAND;
   sigaction (SIGALRM, &act, NULL);
@@ -331,10 +191,7 @@ main (argc, argv)
                  perror ("poll");
                  return 1;
                }
-             if (tls_conn) 
-               wrote = SSL_write (tls_conn, retry, nbuffer);
-             else
-               wrote = write (tls_fd, retry, nbuffer);
+             wrote = tls_write(tls_fd, retry, nbuffer);
              if (wrote < 0) goto finish;
            }
        }
@@ -345,10 +202,7 @@ main (argc, argv)
 #endif
        {
 readtop:
-         if (tls_conn)
-           nbuffer = SSL_read (tls_conn, buffer, sizeof buffer -1);
-         else
-           nbuffer = read (tls_fd, buffer, sizeof buffer -1);
+         nbuffer = tls_read(tls_fd, buffer, sizeof buffer -1);
          if (nbuffer == 0)
            goto finish;
          for (retry = buffer; nbuffer > 0; nbuffer -= wrote, retry += wrote)
@@ -368,7 +222,7 @@ readtop:
              wrote = write (out, retry, nbuffer);
              if (wrote < 0) goto finish;
            }
-         if (tls_conn && SSL_pending(tls_conn))
+         if (tls_pending())
            goto readtop;
        }
     }