* Makefile.am (starttls_SOURCES): Add gnutls.c if USE_GNUTLS
authorueno <ueno>
Wed, 9 Jun 2004 06:56:12 +0000 (06:56 +0000)
committerueno <ueno>
Wed, 9 Jun 2004 06:56:12 +0000 (06:56 +0000)
conditional is asserted.
* starttls.c (socket_connect): Renamed from tls_connect.
* configure.in: Add --with-gnutls.
* gnutls.c: New file; support build with GnuTLS.

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

index cca24c5..bbbd974 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2004-06-09  Daiki Ueno  <ueno@unixuser.org>
 
+       * Makefile.am (starttls_SOURCES): Add gnutls.c if USE_GNUTLS
+       conditional is asserted.
+       * starttls.c (socket_connect): Renamed from tls_connect.
+       * configure.in: Add --with-gnutls.
+       * gnutls.c: New file; support build with GnuTLS.
+
+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.
index 468edb6..733ec97 100644 (file)
@@ -6,5 +6,9 @@ EXTRA_DIST = starttls.el basename.c getopt.c getopt.h getopt1.c
 bin_PROGRAMS= starttls
 lisp_LISP = starttls.el
 
+if USE_GNUTLS
+starttls_SOURCES = starttls.c gnutls.c
+else
 starttls_SOURCES = starttls.c openssl.c
+endif
 starttls_LDADD = $(LIBOBJS)
index 9b530a8..c3aa0c1 100644 (file)
@@ -23,15 +23,24 @@ AC_REPLACE_FUNCS(basename)
 AC_CHECK_FUNC(poll)
 
 AC_ARG_WITH(openssl,[  --with-openssl=PATH     use OpenSSL from PATH])
-
-if test -n "$with_openssl"; then
-       CPPFLAGS="$CPPFLAGS -I${with_openssl}/include"
-       LDFLAGS="$LDFLAGS -L${with_openssl}/lib"
+AC_ARG_WITH(gnutls,[  --with-gnutls     use GnuTLS instead of OpenSSL],
+       use_gnutls=true, use_gnutls=false)
+AM_CONDITIONAL(USE_GNUTLS, test x$use_gnutls = xtrue)
+
+if $use_gnutls; then
+       AC_CHECK_HEADER(gnutls/gnutls.h, [
+               AC_DEFINE(USE_GNUTLS)
+               AC_CHECK_LIB(gnutls, gnutls_global_init, LIBS="-lgnutls $LIBS")],
+               [GnuTLS is selected, but it is not installed])
+else
+       if test -n "$with_openssl"; then
+               CPPFLAGS="$CPPFLAGS -I${with_openssl}/include"
+               LDFLAGS="$LDFLAGS -L${with_openssl}/lib"
+       fi
+       AC_CHECK_HEADER(openssl/ssl.h, [
+               AC_CHECK_LIB(crypto, BIO_accept, LIBS="-lcrypto $LIBS")
+               AC_CHECK_LIB(ssl, SSL_CTX_new, LIBS="-lssl $LIBS")],
+               AC_MSG_ERROR([OpenSSL not installed - please install first]))
 fi
 
-AC_CHECK_HEADER(openssl/ssl.h, [
-       AC_CHECK_LIB(crypto, BIO_accept, LIBS="-lcrypto $LIBS")
-       AC_CHECK_LIB(ssl, SSL_CTX_new, LIBS="-lssl $LIBS")],
-       AC_MSG_ERROR([OpenSSL not installed - please install first]))
-
 AC_OUTPUT(Makefile)
diff --git a/gnutls.c b/gnutls.c
new file mode 100644 (file)
index 0000000..ba53a90
--- /dev/null
+++ b/gnutls.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <gnutls/gnutls.h>
+
+static gnutls_session tls_session = NULL;
+
+void
+tls_negotiate (fd, cert_file, key_file)
+     int fd;
+     const char *cert_file, *key_file;
+{
+  gnutls_certificate_credentials xcred;
+
+  gnutls_global_init ();
+
+  gnutls_certificate_allocate_credentials(&xcred);
+
+  if (cert_file)
+    {
+      if (!key_file)
+       key_file = cert_file;
+      gnutls_certificate_set_x509_key_file (xcred, cert_file, key_file,
+                                           GNUTLS_X509_FMT_PEM);
+    }
+
+  gnutls_init (&tls_session, GNUTLS_CLIENT);
+  gnutls_set_default_priority (tls_session);
+  gnutls_credentials_set (tls_session, GNUTLS_CRD_CERTIFICATE, xcred);
+
+  gnutls_transport_set_ptr (tls_session, (gnutls_transport_ptr)fd);
+
+  gnutls_handshake (tls_session);
+}
+
+int
+tls_write(fd, buf, num)
+     const char *buf;
+     int fd, num;
+{
+  if (tls_session) 
+    return gnutls_record_send (tls_session, buf, num);
+  return write (fd, buf, num);
+}
+
+int
+tls_read(fd, buf, num)
+     char *buf;
+     int fd, num;
+{
+  if (tls_session)
+    return gnutls_record_recv (tls_session, buf, num);
+  return read (fd, buf, num);
+}
+
+int
+tls_pending()
+{
+  return tls_session && gnutls_record_check_pending (tls_session);
+}
index 1eeff0a..89e5374 100644 (file)
--- a/openssl.c
+++ b/openssl.c
@@ -1,7 +1,5 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
+#include <stdio.h>
+#include <stdlib.h>
 #include <openssl/lhash.h>
 #include <openssl/bn.h>
 #include <openssl/err.h>
@@ -68,7 +66,7 @@ tls_ssl_new(ctx, s)
       session = SSL_get_session (tls_conn);
       if (session)
        SSL_CTX_remove_session (ctx, session);
-      if (tls_conn!=NULL)
+      if (tls_conn)
        SSL_free (tls_conn);
       return -1;
     }
@@ -76,73 +74,10 @@ tls_ssl_new(ctx, s)
   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;
+     const char *cert_file, *key_file;
 {
   if (tls_ssl_ctx_new (cert_file, key_file) == -1)
     return;
@@ -173,5 +108,5 @@ tls_read(fd, buf, num)
 int
 tls_pending()
 {
-  return tls_conn && SSL_pending(tls_conn);
+  return tls_conn && SSL_pending (tls_conn);
 }
index ba867f7..2cf7ced 100644 (file)
@@ -49,7 +49,6 @@
 #define _GNU_SOURCE
 #include "getopt.h"
 
-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);
@@ -82,6 +81,70 @@ do_tls_negotiate(sig)
 }
 
 int
+socket_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;
+}
+
+int
 main (argc, argv) 
   int argc;
   char **argv;
@@ -131,10 +194,10 @@ main (argc, argv)
       return 1;
     }
 
-  tls_fd = tls_connect (argv[optind], argv[optind+1]);
+  tls_fd = socket_connect (argv[optind], argv[optind+1]);
   if (tls_fd < 0)
     {
-      perror ("tls_connect");
+      perror ("socket_connect");
       return 1;
     }