shishi-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU shishi branch, master, updated. shishi-0-0-42-32-gdee002d


From: Simon Josefsson
Subject: [SCM] GNU shishi branch, master, updated. shishi-0-0-42-32-gdee002d
Date: Tue, 23 Mar 2010 10:07:12 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU shishi".

http://git.savannah.gnu.org/cgit/shishi.git/commit/?id=dee002d6f141f5c0ff2f73dc99ca6469543042d3

The branch, master has been updated
       via  dee002d6f141f5c0ff2f73dc99ca6469543042d3 (commit)
       via  1eba684ee45e4cf3e82a80f1a58472fc04906da0 (commit)
       via  91438e38b1db17a179ec92c55d61352f464d87e5 (commit)
       via  57f676e7f52a92b6ce343930f0ed86a87641df33 (commit)
      from  5a9fd040146caa05667081a7cdd450072b0d326d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit dee002d6f141f5c0ff2f73dc99ca6469543042d3
Author: Simon Josefsson <address@hidden>
Date:   Tue Mar 23 11:07:03 2010 +0100

    Upgrade TCP extension logic.

commit 1eba684ee45e4cf3e82a80f1a58472fc04906da0
Author: Simon Josefsson <address@hidden>
Date:   Tue Mar 23 11:05:23 2010 +0100

    Use RFC 5021 starttls negotiation.  Don't verify cert if we don't have a CA.

commit 91438e38b1db17a179ec92c55d61352f464d87e5
Author: Simon Josefsson <address@hidden>
Date:   Tue Mar 23 10:19:51 2010 +0100

    shishid: Add --no-tls parameter to disable TLS support.

commit 57f676e7f52a92b6ce343930f0ed86a87641df33
Author: Simon Josefsson <address@hidden>
Date:   Tue Mar 23 10:03:40 2010 +0100

    shishid: Improve server listening logic.

-----------------------------------------------------------------------

Summary of changes:
 NEWS            |    4 +
 doc/shishi.texi |   66 +++++------
 lib/starttls.c  |   34 ++++--
 src/kdc.h       |    5 +-
 src/server.c    |   64 +++++++++--
 src/shishid.c   |  339 +++++++++++++++++++++++++++----------------------------
 src/shishid.ggo |    5 +-
 src/starttls.c  |  161 ++++++++++++++-------------
 8 files changed, 366 insertions(+), 312 deletions(-)

diff --git a/NEWS b/NEWS
index 8269ac2..6775592 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,10 @@ See the end for copying conditions.
 
 ** shishid: Make server-side IPv6 support work.
 
+** shishid: Add --no-tls parameter to disable TLS support.
+
+** libshishi, shishid: STARTTLS extension negotiation now follows RFC 5021.
+
 ** doc: Fix spelling typos noticed by lintian.
 
 ** Update gnulib files.
diff --git a/doc/shishi.texi b/doc/shishi.texi
index 8279f9f..e8cc9ab 100644
--- a/doc/shishi.texi
+++ b/doc/shishi.texi
@@ -3269,45 +3269,39 @@ too.
 
 @example
 Usage: shishid [OPTIONS]...
- 
-  -h, --help                            Print help and exit
-  -V, --version                         Print version and exit
- 
+
+  -h, --help                    Print help and exit
+  -V, --version                 Print version and exit
+
 Commands:
-  -l, --listen=[FAMILY:]ADDR:PORT/TYPE  Sockets to listen for queries on.
-                                          Family is `IPv4' or `IPv6', if
-                                          absent the family is decided by
-                                          gethostbyname(ADDR). An address of
-                                          `*' indicates all addresses on the
-                                          local host. The default is
-                                          `IPv4:*:kerberos/udp,
-                                          IPv4:*:kerberos/tcp,
-                                          IPv6:*:kerberos/udp,
-                                          IPv6:*:kerberos/tcp'.
-  -u, --setuid=NAME                     After binding socket, set user
-                                          identity.
- 
+  -l, --listen=[FAMILY:]ADDR:PORT/TYPE
+                                Sockets to listen for queries on.  Family is
+                                  `IPv4' or `IPv6', if absent the family is
+                                  decided by gethostbyname(ADDR). An address of
+                                  `*' indicates all addresses on the local
+                                  host. The default is `*:kerberos/udp,
+                                  *:kerberos/tcp'.
+  -u, --setuid=NAME             After binding socket, set user identity.
+
 TLS settings:
-      --x509cafile=FILE                 X.509 certificate authorities used to
-                                          verify client certificates, in PEM
-                                          format.
-      --x509certfile=FILE               X.509 server certificate, in PEM
-                                          format.
-      --x509crlfile=FILE                X.509 certificate revocation list to
-                                          check for revoked client
-                                          certificates, in PEM format.
-      --x509keyfile=FILE                X.509 server certificate key, in PEM
-                                          format.
-       --resume-limit=SHORT             Keep track of up to this many TLS
-                                         sessions for resume purposes (0 to
-                                         disable TLS resume).  (default=`50')
- 
+      --no-tls                  Disable TLS support  (default=off)
+      --x509cafile=FILE         X.509 certificate authorities used to verify
+                                  client certificates, in PEM format.
+      --x509certfile=FILE       X.509 server certificate, in PEM format.
+      --x509crlfile=FILE        X.509 certificate revocation list to check for
+                                  revoked client certificates, in PEM format.
+      --x509keyfile=FILE        X.509 server certificate key, in PEM format.
+      --resume-limit=SHORT      Keep track of up to this many TLS sessions for
+                                  resume purposes (0 to disable TLS resume).
+                                  (default=`50')
+
 Other options:
-  -c, --configuration-file=FILE         Use specified configuration file.
-  -v, --verbose                         Produce verbose output.
-                                            (default=off)
-  -q, --quiet                           Don't produce any diagnostic output.
-                                            (default=off)
+  -c, --configuration-file=FILE Use specified configuration file.
+  -v, --verbose                 Produce verbose output.
+                                  Use multiple times to increase amount of
+                                  information.
+  -q, --quiet                   Don't produce any diagnostic output.
+                                    (default=off)
 @end example
 
 @node Parameters for shisa
diff --git a/lib/starttls.c b/lib/starttls.c
index 75a1c98..27025f3 100644
--- a/lib/starttls.c
+++ b/lib/starttls.c
@@ -68,12 +68,11 @@ _shishi_tls_done (Shishi * handle)
  *
  * Derive EncKDCRepPart key from TLS PRF?  Hm.
  *
- * The code currently implements
- * draft-josefsson-krb-tcp-expansion-02.txt and
+ * The code currently implements rfc5021.txt and
  * draft-josefsson-kerberos5-starttls-02.txt.
  */
 
-#define STARTTLS_CLIENT_REQUEST "\x70\x00\x00\x01"
+#define STARTTLS_CLIENT_REQUEST "\x80\x00\x00\x01"
 #define STARTTLS_SERVER_ACCEPT "\x00\x00\x00\x00"
 #define STARTTLS_LEN 4
 
@@ -88,7 +87,8 @@ _shishi_sendrecv_tls1 (Shishi * handle,
                       int sockfd,
                       gnutls_session session,
                       const char *indata, size_t inlen,
-                      char **outdata, size_t * outlen, size_t timeout)
+                      char **outdata, size_t * outlen,
+                      size_t timeout, bool have_cas)
 {
   int ret;
   ssize_t bytes_sent, bytes_read;
@@ -125,15 +125,18 @@ _shishi_sendrecv_tls1 (Shishi * handle,
   else
     shishi_error_printf (handle, "TLS handshake completed (not resumed)");
 
-  ret = gnutls_certificate_verify_peers2 (session, &status);
-  if (ret != 0 || status != 0)
+  if (have_cas)
     {
-      shishi_error_printf (handle, "TLS verification of CA failed (%d/%d)",
-                          ret, status);
-      return SHISHI_RECVFROM_ERROR;
-    }
+      ret = gnutls_certificate_verify_peers2 (session, &status);
+      if (ret != 0 || status != 0)
+       {
+         shishi_error_printf (handle, "TLS verification of CA failed (%d/%d)",
+                              ret, status);
+         return SHISHI_RECVFROM_ERROR;
+       }
 
-  /* XXX: We need to verify the CA cert further here. */
+      /* XXX: We need to verify the CA cert further here. */
+    }
 
   if (session_data_size == 0)
     {
@@ -239,6 +242,7 @@ _shishi_sendrecv_tls (Shishi * handle,
   const char *cafile = shishi_x509ca_default_file (handle);
   const char *certfile = shishi_x509cert_default_file (handle);
   const char *keyfile = shishi_x509key_default_file (handle);
+  bool have_cas = false;
 
   sockfd = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
   if (sockfd < 0)
@@ -303,7 +307,10 @@ _shishi_sendrecv_tls (Shishi * handle,
       return SHISHI_CRYPTO_ERROR;
     }
   else if (ret == GNUTLS_E_SUCCESS)
-    shishi_error_printf (handle, "Loaded CA certificate");
+    {
+      shishi_error_printf (handle, "Loaded CA certificate");
+      have_cas = true;
+    }
 
   ret = gnutls_certificate_set_x509_key_file (x509cred, certfile,
                                              keyfile, GNUTLS_X509_FMT_PEM);
@@ -334,7 +341,8 @@ _shishi_sendrecv_tls (Shishi * handle,
 
   /* Core part. */
   outerr = _shishi_sendrecv_tls1 (handle, sockfd, session, indata, inlen,
-                                 outdata, outlen, handle->kdctimeout);
+                                 outdata, outlen, handle->kdctimeout,
+                                 have_cas);
 
   ret = shutdown (sockfd, SHUT_RDWR);
   if (ret != 0)
diff --git a/src/kdc.h b/src/kdc.h
index 00685e0..c6611b0 100644
--- a/src/kdc.h
+++ b/src/kdc.h
@@ -105,14 +105,12 @@
 struct listenspec
 {
   char *str;
-  int family;
   int listening;
-  struct addrinfo *ai;
+  struct addrinfo ai;
   char addrname[NI_MAXHOST];
   struct sockaddr_storage udpclientaddr;
   socklen_t udpclientaddrlen;
   char clientaddrname[NI_MAXHOST];
-  int type;
   int sockfd;
   char buf[BUFSIZ];            /* XXX */
   size_t bufpos;
@@ -145,6 +143,7 @@ extern ssize_t process (const char *in, size_t inlen, char 
**out);
 
 /* Interface between server.c and starttls.c. */
 extern void kdc_send1 (struct listenspec *ls);
+extern int kdc_extension_reject (struct listenspec *ls);
 extern int kdc_extension (struct listenspec *ls);
 
 /* Interface between shishid.c, server.c and resume.c. */
diff --git a/src/server.c b/src/server.c
index bf91e7b..3add353 100644
--- a/src/server.c
+++ b/src/server.c
@@ -39,7 +39,7 @@ kdc_accept (struct listenspec *ls)
   ls->next = newls;
 
   newls->bufpos = 0;
-  newls->type = ls->type;
+  newls->ai.ai_socktype = ls->ai.ai_socktype;
   addrlen = sizeof (addr);
   newls->sockfd = accept (ls->sockfd, &addr, &addrlen);
 
@@ -112,7 +112,7 @@ kdc_send1 (struct listenspec *ls)
       sent_bytes = gnutls_record_send (ls->session, ls->buf, ls->bufpos);
     else
 #endif
-      if (ls->type == SOCK_DGRAM)
+      if (ls->ai.ai_socktype == SOCK_DGRAM)
        sent_bytes = sendto (ls->sockfd, ls->buf, ls->bufpos, 0,
                             (struct sockaddr *) &ls->udpclientaddr,
                             ls->udpclientaddrlen);
@@ -136,7 +136,7 @@ kdc_send1 (struct listenspec *ls)
 static void
 kdc_send (struct listenspec *ls)
 {
-  if (ls->type == SOCK_DGRAM)
+  if (ls->ai.ai_socktype == SOCK_DGRAM)
     syslog (LOG_DEBUG, "Sending %d bytes to %s socket %d via UDP",
            ls->bufpos, ls->clientaddrname, ls->sockfd);
   else
@@ -160,11 +160,55 @@ kdc_send (struct listenspec *ls)
   ls->bufpos = 0;
 }
 
+int
+kdc_extension_reject (struct listenspec *ls)
+{
+  Shishi_asn1 krberr;
+  char *der;
+  size_t derlen;
+  int rc;
+
+  syslog (LOG_INFO, "Reject extension from %s on socket %d",
+         ls->str, ls->sockfd);
+
+  krberr = shishi_krberror (handle);
+  if (!krberr)
+    return SHISHI_MALLOC_ERROR;
+
+  rc = shishi_krberror_errorcode_set (handle, krberr,
+                                     SHISHI_KRB_ERR_FIELD_TOOLONG);
+  if (rc != SHISHI_OK)
+    return rc;
+
+  rc = shishi_krberror_set_etext (handle, krberr, "Extension not support");
+  if (rc != SHISHI_OK)
+    return rc;
+
+  rc = shishi_krberror_der (handle, krberr, &der, &derlen);
+  if (rc != SHISHI_OK)
+    return rc;
+
+  if (derlen >= BUFSIZ)
+    return -1;
+
+  memcpy (ls->buf, der, derlen);
+  ls->bufpos = derlen;
+
+  free (der);
+
+  kdc_send1 (ls);
+
+  return -1;
+}
+
 #ifndef USE_STARTTLS
 /* Dummy function to replace starttls.c functionality. */
 int
 kdc_extension (struct listenspec *ls)
 {
+  if (ls->ai.ai_socktype == SOCK_STREAM
+      && ls->bufpos == 4 && ls->buf[0] & 0x80)
+    return kdc_extension_reject (ls);
   return 0;
 }
 #endif
@@ -182,7 +226,7 @@ kdc_read (struct listenspec *ls)
                                     sizeof (ls->buf) - ls->bufpos);
   else
 #endif
-    if (ls->type == SOCK_DGRAM)
+    if (ls->ai.ai_socktype == SOCK_DGRAM)
       {
        ls->udpclientaddrlen = sizeof (ls->udpclientaddr);
        read_bytes = recvfrom (ls->sockfd, ls->buf + ls->bufpos,
@@ -208,7 +252,7 @@ kdc_read (struct listenspec *ls)
       return -1;
     }
 
-  if (read_bytes == 0 && ls->type == SOCK_STREAM)
+  if (read_bytes == 0 && ls->ai.ai_socktype == SOCK_STREAM)
     {
       syslog (LOG_DEBUG, "Peer %s disconnected on socket %d\n",
              ls->str, ls->sockfd);
@@ -217,7 +261,7 @@ kdc_read (struct listenspec *ls)
 
   ls->bufpos += read_bytes;
 
-  if (ls->type == SOCK_DGRAM)
+  if (ls->ai.ai_socktype == SOCK_DGRAM)
     {
       int rc = getnameinfo ((struct sockaddr *) &ls->udpclientaddr,
                            ls->udpclientaddrlen,
@@ -247,12 +291,12 @@ kdc_ready (struct listenspec *ls)
 {
   size_t waitfor = ls->bufpos >= 4 ? C2I (ls->buf) : 4;
 
-  if (ls->type == SOCK_DGRAM && ls->bufpos > 0)
+  if (ls->ai.ai_socktype == SOCK_DGRAM && ls->bufpos > 0)
     return 1;
   else if (ls->bufpos > 4 && waitfor + 4 == ls->bufpos)
     return 1;
 
-  if (ls->type == SOCK_STREAM)
+  if (ls->ai.ai_socktype == SOCK_STREAM)
     syslog (LOG_DEBUG, "Got %d bytes of %d bytes from %s on socket %d\n",
            ls->bufpos, waitfor + 4, ls->str, ls->sockfd);
 
@@ -269,7 +313,7 @@ kdc_process (struct listenspec *ls)
   syslog (LOG_DEBUG, "Processing %d bytes on socket %d",
          ls->bufpos, ls->sockfd);
 
-  if (ls->type == SOCK_DGRAM)
+  if (ls->ai.ai_socktype == SOCK_DGRAM)
     plen = process (ls->buf, ls->bufpos, &p);
   else
     plen = process (ls->buf + 4, ls->bufpos - 4, &p);
@@ -352,7 +396,7 @@ kdc_loop (void)
       for (ls = listenspec; ls; ls = ls->next)
        if (ls->sockfd > 0 && FD_ISSET (ls->sockfd, &readfds))
          {
-           if (ls->type == SOCK_STREAM && ls->listening)
+           if (ls->ai.ai_socktype == SOCK_STREAM && ls->listening)
              kdc_accept (ls);
            else if (kdc_read (ls) < 0)
              ls = kdc_close (ls);
diff --git a/src/shishid.c b/src/shishid.c
index 09ce675..b84c094 100644
--- a/src/shishid.c
+++ b/src/shishid.c
@@ -51,42 +51,23 @@ kdc_listen (void)
 
   for (last = NULL, ls = listenspec; ls; last = ls, ls = ls->next)
     {
-      struct addrinfo *rp;
-
     restart:
-      for (rp = ls->ai; rp != NULL; rp = rp->ai_next)
+      ls->sockfd = socket (ls->ai.ai_family, ls->ai.ai_socktype,
+                          ls->ai.ai_protocol);
+      if (ls->sockfd == -1)
        {
-         ls->sockfd = socket (ls->family, rp->ai_socktype, rp->ai_protocol);
-         if (ls->sockfd == -1)
-           {
-             error (0, errno, "Cannot listen on %s because socket failed",
-                    ls->str);
-             continue;
-           }
-
-         if (bind (ls->sockfd, rp->ai_addr, rp->ai_addrlen) != 0)
-           {
-             error (0, errno, "Cannot listen on %s because bind failed",
-                    ls->str);
-             close (ls->sockfd);
-             ls->sockfd = -1;
-             continue;
-           }
-
-         break; /* Success */
+         error (0, errno,
+                "Cannot listen on %s because socket (%d,%d,%d) failed",
+                ls->str, ls->ai.ai_family, ls->ai.ai_socktype,
+                ls->ai.ai_protocol);
+         goto error;
        }
 
-      if (ls->sockfd < 0)
-       goto error;
-
-      if (!arg.quiet_flag)
+      if (bind (ls->sockfd, ls->ai.ai_addr, ls->ai.ai_addrlen) != 0)
        {
-         int rc = getnameinfo (rp->ai_addr, rp->ai_addrlen,
-                               ls->addrname, sizeof (ls->addrname),
-                               NULL, 0, NI_NUMERICHOST);
-         if (rc != 0)
-           strcpy (ls->addrname, "unknown address");
-         printf ("Listening on %s (%s)...\n", ls->str, ls->addrname);
+         error (0, errno, "Cannot listen on %s because bind %s failed",
+                ls->str, ls->addrname);
+         goto errorclose;
        }
 
       yes = 1;
@@ -98,13 +79,17 @@ kdc_listen (void)
          goto errorclose;
        }
 
-      if (ls->type == SOCK_STREAM && listen (ls->sockfd, SOMAXCONN) != 0)
+      if (ls->ai.ai_socktype == SOCK_STREAM
+         && listen (ls->sockfd, SOMAXCONN) != 0)
        {
          error (0, errno, "Cannot listen on %s because listen failed",
                 ls->str);
          goto errorclose;
        }
 
+      if (!arg.quiet_flag)
+       printf ("Listening on %s (%s)...\n", ls->str, ls->addrname);
+
       maxfd++;
       continue;
 
@@ -128,18 +113,20 @@ kdc_listen (void)
     error (EXIT_FAILURE, 0, "cannot bind any ports");
 
   if (!arg.quiet_flag)
-    printf ("Listening on %d ports...\n", maxfd);
+    printf ("Listening on %d sockets...\n", maxfd);
 }
 
 /* Close open sockets, reporting any errors. */
 static void
 kdc_unlisten (void)
 {
-  struct listenspec *ls;
+  struct listenspec *ls, *tmp;
   int rc;
 
-  for (ls = listenspec; ls; ls = ls->next)
+  for (ls = listenspec; ls; ls = tmp)
     {
+      tmp = ls->next;
+
       if (!ls->listening)
        syslog (LOG_NOTICE,
                "Closing outstanding connection to %s on socket %d",
@@ -155,7 +142,10 @@ kdc_unlisten (void)
                    ls->str, ls->sockfd, strerror (errno), errno);
        }
 
+
+      free (ls->ai.ai_addr);
       free (ls->str);
+      free (ls);
     }
 }
 
@@ -248,90 +238,95 @@ doit (void)
           shisa_strerror (rc), rc);
 
 #ifdef USE_STARTTLS
-  if (!arg.quiet_flag)
-    printf ("Initializing GNUTLS...\n");
+  if (!arg.no_tls_flag)
+    {
+      if (!arg.quiet_flag)
+       printf ("Initializing GNUTLS...\n");
 
-  rc = gnutls_global_init ();
-  if (rc)
-    error (EXIT_FAILURE, 0, "Cannot initialize GNUTLS: %s (%d)",
-          gnutls_strerror (rc), rc);
+      rc = gnutls_global_init ();
+      if (rc)
+       error (EXIT_FAILURE, 0, "Cannot initialize GNUTLS: %s (%d)",
+              gnutls_strerror (rc), rc);
 
-  rc = gnutls_anon_allocate_server_credentials (&anoncred);
-  if (rc)
-    error (EXIT_FAILURE, 0, "Cannot allocate GNUTLS credential: %s (%d)",
-          gnutls_strerror (rc), rc);
+      rc = gnutls_anon_allocate_server_credentials (&anoncred);
+      if (rc)
+       error (EXIT_FAILURE, 0, "Cannot allocate GNUTLS credential: %s (%d)",
+              gnutls_strerror (rc), rc);
 
-  rc = gnutls_certificate_allocate_credentials (&x509cred);
-  if (rc)
-    error (EXIT_FAILURE, 0,
-          "Cannot allocate GNUTLS X.509 credential: %s (%d)",
-          gnutls_strerror (rc), rc);
+      rc = gnutls_certificate_allocate_credentials (&x509cred);
+      if (rc)
+       error (EXIT_FAILURE, 0,
+              "Cannot allocate GNUTLS X.509 credential: %s (%d)",
+              gnutls_strerror (rc), rc);
 
-  if (arg.x509cafile_given)
-    {
-      int num;
-      num = gnutls_certificate_set_x509_trust_file (x509cred,
-                                                   arg.x509cafile_arg,
-                                                   GNUTLS_X509_FMT_PEM);
-      if (num <= 0)
-       error (EXIT_FAILURE, 0, "No X.509 CAs found in `%s' (%d): %s",
-              arg.x509cafile_arg, num, gnutls_strerror (num));
-      if (!arg.quiet_flag)
-       printf ("Parsed %d CAs...\n", num);
-    }
+      if (arg.x509cafile_given)
+       {
+         int num;
+         num = gnutls_certificate_set_x509_trust_file (x509cred,
+                                                       arg.x509cafile_arg,
+                                                       GNUTLS_X509_FMT_PEM);
+         if (num <= 0)
+           error (EXIT_FAILURE, 0, "No X.509 CAs found in `%s' (%d): %s",
+                  arg.x509cafile_arg, num, gnutls_strerror (num));
+         if (!arg.quiet_flag)
+           printf ("Parsed %d CAs...\n", num);
+       }
 
-  if (arg.x509crlfile_given)
-    {
-      int num;
-
-      num = gnutls_certificate_set_x509_crl_file (x509cred,
-                                                 arg.x509crlfile_arg,
-                                                 GNUTLS_X509_FMT_PEM);
-      if (num <= 0)
-       error (EXIT_FAILURE, 0, "No X.509 CRLs found in `%s' (%d): %s",
-              arg.x509crlfile_arg, num, gnutls_strerror (num));
-      if (!arg.quiet_flag)
-       printf ("Parsed %d CRLs...\n", num);
-    }
+      if (arg.x509crlfile_given)
+       {
+         int num;
+
+         num = gnutls_certificate_set_x509_crl_file (x509cred,
+                                                     arg.x509crlfile_arg,
+                                                     GNUTLS_X509_FMT_PEM);
+         if (num <= 0)
+           error (EXIT_FAILURE, 0, "No X.509 CRLs found in `%s' (%d): %s",
+                  arg.x509crlfile_arg, num, gnutls_strerror (num));
+         if (!arg.quiet_flag)
+           printf ("Parsed %d CRLs...\n", num);
+       }
 
-  if (arg.x509certfile_given && arg.x509keyfile_given)
-    {
-      rc = gnutls_certificate_set_x509_key_file (x509cred,
-                                                arg.x509certfile_arg,
-                                                arg.x509keyfile_arg,
-                                                GNUTLS_X509_FMT_PEM);
-      if (rc != GNUTLS_E_SUCCESS)
-       error (EXIT_FAILURE, 0,
-              "No X.509 server certificate/key found in `%s'/`%s' (%d): %s",
-              arg.x509certfile_arg, arg.x509keyfile_arg, rc,
-              gnutls_strerror (rc));
-      if (!arg.quiet_flag)
-       printf ("Loaded server certificate/key...\n");
-    }
-  else if (arg.x509certfile_given || arg.x509keyfile_given)
-    error (EXIT_FAILURE, 0, "Need both --x509certfile and --x509keyfile");
+      if (arg.x509certfile_given && arg.x509keyfile_given)
+       {
+         rc = gnutls_certificate_set_x509_key_file (x509cred,
+                                                    arg.x509certfile_arg,
+                                                    arg.x509keyfile_arg,
+                                                    GNUTLS_X509_FMT_PEM);
+         if (rc != GNUTLS_E_SUCCESS)
+           error (EXIT_FAILURE, 0,
+                  "No X.509 server certificate/key found in `%s'/`%s' (%d): 
%s",
+                  arg.x509certfile_arg, arg.x509keyfile_arg, rc,
+                  gnutls_strerror (rc));
+         if (!arg.quiet_flag)
+           printf ("Loaded server certificate/key...\n");
+       }
+      else if (arg.x509certfile_given || arg.x509keyfile_given)
+       error (EXIT_FAILURE, 0, "Need both --x509certfile and --x509keyfile");
 
-  rc = gnutls_dh_params_init (&dh_params);
-  if (rc)
-    error (EXIT_FAILURE, 0, "Cannot initialize GNUTLS DH parameters: %s (%d)",
-          gnutls_strerror (rc), rc);
+      rc = gnutls_dh_params_init (&dh_params);
+      if (rc)
+       error (EXIT_FAILURE, 0,
+              "Cannot initialize GNUTLS DH parameters: %s (%d)",
+              gnutls_strerror (rc), rc);
 
-  if (!arg.quiet_flag)
-    printf ("Generating Diffie-Hellman parameters...\n");
+      if (!arg.quiet_flag)
+       printf ("Generating Diffie-Hellman parameters...\n");
 
-  rc = gnutls_dh_params_generate2 (dh_params, DH_BITS);
-  if (rc)
-    error (EXIT_FAILURE, 0, "Cannot generate GNUTLS DH parameters: %s (%d)",
-          gnutls_strerror (rc), rc);
+      rc = gnutls_dh_params_generate2 (dh_params, DH_BITS);
+      if (rc)
+       error (EXIT_FAILURE, 0,
+              "Cannot generate GNUTLS DH parameters: %s (%d)",
+              gnutls_strerror (rc), rc);
 
-  gnutls_anon_set_server_dh_params (anoncred, dh_params);
+      gnutls_anon_set_server_dh_params (anoncred, dh_params);
 
-  gnutls_certificate_set_dh_params (x509cred, dh_params);
+      gnutls_certificate_set_dh_params (x509cred, dh_params);
 
-  resume_db_init (arg.resume_limit_arg);
+      resume_db_init (arg.resume_limit_arg);
 
-  if (!arg.quiet_flag)
-    printf ("Initializing GNUTLS...done\n");
+      if (!arg.quiet_flag)
+       printf ("Initializing GNUTLS...done\n");
+    }
 #endif
 
   kdc_listen ();
@@ -354,32 +349,28 @@ doit (void)
   kdc_unlisten ();
 
 #ifdef USE_STARTTLS
-  if (!arg.quiet_flag)
-    printf ("Deinitializing GNUTLS...\n");
+  if (!arg.no_tls_flag)
+    {
+      if (!arg.quiet_flag)
+       printf ("Deinitializing GNUTLS...\n");
 
-  resume_db_done ();
+      resume_db_done ();
 
-  gnutls_global_deinit ();
+      gnutls_global_deinit ();
 
-  if (!arg.quiet_flag)
-    printf ("Deinitializing GNUTLS...done\n");
+      if (!arg.quiet_flag)
+       printf ("Deinitializing GNUTLS...done\n");
+    }
 #endif
 
   shisa_done (dbh);
   shishi_done (handle);
 }
 
-#define FAMILY_IPV4 "IPv4"
-#define FAMILY_IPV6 "IPv6"
+#define FAMILY_IPV4 "IPv4:"
+#define FAMILY_IPV6 "IPv6:"
 
-#ifdef WITH_IPV6
-# define LISTEN_DEFAULT FAMILY_IPV4 ":*:kerberos/udp, " \
-  FAMILY_IPV4 ":*:kerberos/tcp, "                      \
-  FAMILY_IPV6 ":*:kerberos/udp, "                      \
-  FAMILY_IPV6 ":*:kerberos/tcp"
-#else
-# define LISTEN_DEFAULT "*:kerberos/udp, *:kerberos/tcp"
-#endif
+#define LISTEN_DEFAULT "*:kerberos/udp, *:kerberos/tcp"
 
 /* Parse the --listen parameter, creating listenspec elements. */
 static void
@@ -392,80 +383,88 @@ parse_listen (char *listenstr)
   for (i = 0; (val = strtok_r (i == 0 ? listenstr : NULL,
                               ", \t", &ptrptr)); i++)
     {
-      char *service, *proto;
+      char *name, *service, *proto;
       struct listenspec *ls;
+      struct addrinfo hints, *res, *p;
+      int rc;
 
-      ls = xzalloc (sizeof (*ls));
-      ls->next = listenspec;
-      listenspec = ls;
+      name = xstrdup (val);
 
-      ls->str = strdup (val);
-      ls->bufpos = 0;
-      ls->listening = 1;
+      memset (&hints, 0, sizeof (hints));
+
+      if (strncmp (val, FAMILY_IPV4, strlen (FAMILY_IPV4)) == 0)
+       {
+         hints.ai_family = AF_INET;
+         val += strlen (FAMILY_IPV4);
+       }
+#ifdef WITH_IPV6
+      else if (strncmp (val, FAMILY_IPV6, strlen (FAMILY_IPV6)) == 0)
+       {
+         hints.ai_family = AF_INET6;
+         val += strlen (FAMILY_IPV6);
+       }
+#endif
+      else
+       hints.ai_family = AF_UNSPEC;
 
       proto = strrchr (val, '/');
       if (proto == NULL)
-       error (EXIT_FAILURE, 0, "Could not find type in listen spec: `%s'",
-              ls->str);
+       error (EXIT_FAILURE, 0, "Could not find protocol type in: `%s'",
+              name);
       *proto = '\0';
       proto++;
 
       if (strcmp (proto, "tcp") == 0)
-       ls->type = SOCK_STREAM;
+       hints.ai_socktype = SOCK_STREAM;
+      else if (strcmp (proto, "udp") == 0)
+       hints.ai_socktype = SOCK_DGRAM;
       else
-       ls->type = SOCK_DGRAM;
+       error (EXIT_FAILURE, 0, "Unknown protocol type in `%s': %s",
+              name, proto);
 
       service = strrchr (val, ':');
       if (service == NULL)
        error (EXIT_FAILURE, 0, "Could not find service in listen spec: `%s'",
-              ls->str);
+              name);
       *service = '\0';
       service++;
 
-      if (strncmp (val, FAMILY_IPV4 ":", strlen (FAMILY_IPV4 ":")) == 0)
-       {
-         ls->family = AF_INET;
-         val += strlen (FAMILY_IPV4 ":");
-       }
-#ifdef WITH_IPV6
-      else if (strncmp (val, FAMILY_IPV6 ":", strlen (FAMILY_IPV6 ":")) == 0)
-       {
-         ls->family = AF_INET6;
-         val += strlen (FAMILY_IPV6 ":");
-       }
-#endif
-      else
-       ls->family = AF_INET;
+      hints.ai_flags = AI_ADDRCONFIG;
 
       if (strcmp (val, "*") == 0)
        {
-         struct addrinfo hints;
-         int rc;
-
-         memset (&hints, 0, sizeof (hints));
-         hints.ai_family = ls->family;
-         hints.ai_socktype = ls->type;
-         hints.ai_flags = AI_PASSIVE;
-         rc = getaddrinfo (NULL, "kerberos", &hints, &ls->ai);
-         if (rc != 0)
-           error (EXIT_FAILURE, errno, "Cannot get listen socket for %s",
-                  ls->str);
+         hints.ai_flags |= AI_PASSIVE;
+         rc = getaddrinfo (NULL, "kerberos", &hints, &res);
        }
       else
+       rc = getaddrinfo (val, "kerberos", &hints, &res);
+      if (rc != 0)
+       error (EXIT_FAILURE, errno,
+              "Cannot get listen socket for %s (host %s)",
+              name, val);
+
+      for (p = res; p; p = p->ai_next)
        {
-         struct addrinfo hints;
-         int rc;
-
-         memset (&hints, 0, sizeof (hints));
-         hints.ai_family = ls->family;
-         hints.ai_socktype = ls->type;
-         hints.ai_flags = AI_PASSIVE;
-         rc = getaddrinfo (val, "kerberos", &hints, &ls->ai);
+         ls = xzalloc (sizeof (*ls));
+         ls->next = listenspec;
+         listenspec = ls;
+
+         ls->str = xstrdup (name);
+         ls->bufpos = 0;
+         ls->listening = 1;
+
+         memcpy (&ls->ai, p, sizeof (*p));
+         ls->ai.ai_addr = xmemdup (p->ai_addr, p->ai_addrlen);
+         ls->ai.ai_next = NULL;
+
+         rc = getnameinfo (ls->ai.ai_addr, ls->ai.ai_addrlen,
+                           ls->addrname, sizeof (ls->addrname),
+                           NULL, 0, NI_NUMERICHOST);
          if (rc != 0)
-           error (EXIT_FAILURE, errno,
-                  "Cannot get host %s listen socket for %s",
-                  val, ls->str);
+           strncpy (ls->addrname, "unknown address", sizeof (ls->addrname));
        }
+      freeaddrinfo (res);
+      free (name);
     }
 }
 
diff --git a/src/shishid.ggo b/src/shishid.ggo
index 90d5a91..227103f 100644
--- a/src/shishid.ggo
+++ b/src/shishid.ggo
@@ -1,5 +1,5 @@
 ## Process this file with gengetopt to produce shishid_cmd.*
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Simon Josefsson.
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2010 Simon Josefsson.
 #
 # This file is part of Shishi.
 #
@@ -24,11 +24,12 @@ purpose "Shishi Key Distribution Center server."
 
 section "Commands"
 
-option "listen" l "Sockets to listen for queries on.  Family is `IPv4' or 
`IPv6', if absent the family is decided by gethostbyname(ADDR). An address of 
`*' indicates all addresses on the local host. The default is 
`IPv4:*:kerberos/udp, IPv4:*:kerberos/tcp, IPv6:*:kerberos/udp, 
IPv6:*:kerberos/tcp'." string typestr="[FAMILY:]ADDR:PORT/TYPE" no
+option "listen" l "Sockets to listen for queries on.  Family is `IPv4' or 
`IPv6', if absent the family is decided by gethostbyname(ADDR). An address of 
`*' indicates all addresses on the local host. The default is `*:kerberos/udp, 
*:kerberos/tcp'." string typestr="[FAMILY:]ADDR:PORT/TYPE" no
 option "setuid" u "After binding socket, set user identity." string 
typestr="NAME" no
 
 section "TLS settings"
 
+option "no-tls" - "Disable TLS support" flag off
 option "x509cafile" - "X.509 certificate authorities used to verify client 
certificates, in PEM format." string typestr="FILE" no
 option "x509certfile" - "X.509 server certificate, in PEM format." string 
typestr="FILE" no
 option "x509crlfile" - "X.509 certificate revocation list to check for revoked 
client certificates, in PEM format." string typestr="FILE" no
diff --git a/src/starttls.c b/src/starttls.c
index 1aacce1..18898d7 100644
--- a/src/starttls.c
+++ b/src/starttls.c
@@ -254,7 +254,7 @@ logtlsinfo (gnutls_session session)
     }
 }
 
-#define STARTTLS_CLIENT_REQUEST "\x70\x00\x00\x01"
+#define STARTTLS_CLIENT_REQUEST "\x80\x00\x00\x01"
 #define STARTTLS_SERVER_ACCEPT "\x00\x00\x00\x00"
 #define STARTTLS_LEN 4
 
@@ -262,87 +262,92 @@ logtlsinfo (gnutls_session session)
 int
 kdc_extension (struct listenspec *ls)
 {
+  const int kx_prio[] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS,
+                         GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, 0
+  };
   int rc;
 
-  if (!ls->usetls && ls->type == SOCK_STREAM && ls->bufpos == 4 &&
-      memcmp (ls->buf, STARTTLS_CLIENT_REQUEST, STARTTLS_LEN) == 0)
+  if (ls->usetls
+      || ls->ai.ai_socktype != SOCK_STREAM
+      || ls->bufpos < 4
+      || (ls->bufpos >= 4 && !(ls->buf[0] & 0x80)))
+    return 0;
+
+  if (x509cred == NULL || memcmp (ls->buf, STARTTLS_CLIENT_REQUEST,
+                                 STARTTLS_LEN) != 0)
+    return kdc_extension_reject (ls);
+
+  syslog (LOG_INFO, "Trying STARTTLS");
+
+  memcpy (ls->buf, STARTTLS_SERVER_ACCEPT, STARTTLS_LEN);
+  ls->bufpos = STARTTLS_LEN;
+
+  kdc_send1 (ls);
+
+  rc = gnutls_init (&ls->session, GNUTLS_SERVER);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      syslog (LOG_ERR, "TLS initialization failed (%d): %s", rc,
+             gnutls_strerror (rc));
+      return -1;
+    }
+
+  rc = gnutls_set_default_priority (ls->session);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      syslog (LOG_ERR, "TLS failed, gnutls_sdp %d: %s", rc,
+             gnutls_strerror (rc));
+      return -1;
+    }
+
+  rc = gnutls_kx_set_priority (ls->session, kx_prio);
+  if (rc != GNUTLS_E_SUCCESS)
     {
-      const int kx_prio[] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS,
-       GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, 0
-      };
-
-      syslog (LOG_INFO, "Trying STARTTLS");
-
-      memcpy (ls->buf, STARTTLS_SERVER_ACCEPT, STARTTLS_LEN);
-      ls->bufpos = STARTTLS_LEN;
-
-      kdc_send1 (ls);
-
-      rc = gnutls_init (&ls->session, GNUTLS_SERVER);
-      if (rc != GNUTLS_E_SUCCESS)
-       {
-         syslog (LOG_ERR, "TLS initialization failed (%d): %s", rc,
-                 gnutls_strerror (rc));
-         return -1;
-       }
-
-      rc = gnutls_set_default_priority (ls->session);
-      if (rc != GNUTLS_E_SUCCESS)
-       {
-         syslog (LOG_ERR, "TLS failed, gnutls_sdp %d: %s", rc,
-                 gnutls_strerror (rc));
-         return -1;
-       }
-
-      rc = gnutls_kx_set_priority (ls->session, kx_prio);
-      if (rc != GNUTLS_E_SUCCESS)
-       {
-         syslog (LOG_ERR, "TLS failed, gnutls_ksp %d: %s", rc,
-                 gnutls_strerror (rc));
-         return -1;
-       }
-
-      rc = gnutls_credentials_set (ls->session, GNUTLS_CRD_ANON, anoncred);
-      if (rc != GNUTLS_E_SUCCESS)
-       {
-         syslog (LOG_ERR, "TLS failed, gnutls_cs %d: %s", rc,
-                 gnutls_strerror (rc));
-         return -1;
-       }
-
-      rc = gnutls_credentials_set (ls->session, GNUTLS_CRD_CERTIFICATE,
-                                  x509cred);
-      if (rc != GNUTLS_E_SUCCESS)
-       {
-         syslog (LOG_ERR, "TLS failed, gnutls_cs X.509 %d: %s", rc,
-                 gnutls_strerror (rc));
-         return -1;
-       }
-
-      gnutls_certificate_server_set_request (ls->session,
-                                            GNUTLS_CERT_REQUEST);
-
-      gnutls_dh_set_prime_bits (ls->session, DH_BITS);
-      gnutls_transport_set_ptr (ls->session,
-                               (gnutls_transport_ptr) ls->sockfd);
-
-      gnutls_db_set_retrieve_function (ls->session, resume_db_fetch);
-      gnutls_db_set_store_function (ls->session, resume_db_store);
-      gnutls_db_set_remove_function (ls->session, resume_db_delete);
-
-      rc = gnutls_handshake (ls->session);
-      if (rc < 0)
-       {
-         syslog (LOG_ERR, "TLS handshake failed (%d): %s\n",
-                 rc, gnutls_strerror (rc));
-         return -1;
-       }
-
-      logtlsinfo (ls->session);
-
-      ls->bufpos = 0;
-      ls->usetls = 1;
+      syslog (LOG_ERR, "TLS failed, gnutls_ksp %d: %s", rc,
+             gnutls_strerror (rc));
+      return -1;
     }
 
+  rc = gnutls_credentials_set (ls->session, GNUTLS_CRD_ANON, anoncred);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      syslog (LOG_ERR, "TLS failed, gnutls_cs %d: %s", rc,
+             gnutls_strerror (rc));
+      return -1;
+    }
+
+  rc = gnutls_credentials_set (ls->session, GNUTLS_CRD_CERTIFICATE,
+                              x509cred);
+  if (rc != GNUTLS_E_SUCCESS)
+    {
+      syslog (LOG_ERR, "TLS failed, gnutls_cs X.509 %d: %s", rc,
+             gnutls_strerror (rc));
+      return -1;
+    }
+
+  gnutls_certificate_server_set_request (ls->session,
+                                        GNUTLS_CERT_REQUEST);
+
+  gnutls_dh_set_prime_bits (ls->session, DH_BITS);
+  gnutls_transport_set_ptr (ls->session,
+                           (gnutls_transport_ptr) ls->sockfd);
+
+  gnutls_db_set_retrieve_function (ls->session, resume_db_fetch);
+  gnutls_db_set_store_function (ls->session, resume_db_store);
+  gnutls_db_set_remove_function (ls->session, resume_db_delete);
+
+  rc = gnutls_handshake (ls->session);
+  if (rc < 0)
+    {
+      syslog (LOG_ERR, "TLS handshake failed (%d): %s\n",
+             rc, gnutls_strerror (rc));
+      return -1;
+    }
+
+  logtlsinfo (ls->session);
+
+  ls->bufpos = 0;
+  ls->usetls = 1;
+
   return 0;
 }


hooks/post-receive
-- 
GNU shishi




reply via email to

[Prev in Thread] Current Thread [Next in Thread]