Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > 0edc1ab5fa5058149211d8fea160d752 > files > 14

proftpd-1.3.2-0.4mdv2009.0.src.rpm

--- contrib/mod_tls.c	2009-01-26 12:35:01.000000000 -0500
+++ contrib/mod_tls.c.oden	2009-10-23 10:50:32.000000000 -0400
@@ -820,14 +820,33 @@ static unsigned char tls_check_client_ce
             const char *cert_dns_name = (const char *) name->d.ia5->data;
             have_dns_ext = TRUE;
 
-            if (strcmp(cert_dns_name, conn->remote_name) != 0) {
-              tls_log("client cert dNSName value '%s' != client FQDN '%s'",
-                cert_dns_name, conn->remote_name);
+            /* Check for subjectAltName values which contain embedded
+             * NULs.  This can cause verification problems (spoofing),
+             * e.g. if the string is "www.goodguy.com\0www.badguy.com"; the
+             * use of strcmp() only checks "www.goodguy.com".
+             */
+
+            if ((size_t) name->d.ia5->length != strlen(cert_dns_name)) {
+              tls_log("%s", "client cert dNSName contains embedded NULs, "
+                "rejecting as possible spoof attempt");
 
               GENERAL_NAME_free(name);
               sk_GENERAL_NAME_free(sk_alt_names);
               X509_free(cert);
+              ok = FALSE;
               return FALSE;
+
+            } else {
+              if (strcmp(cert_dns_name, conn->remote_name) != 0) {
+                tls_log("client cert dNSName value '%s' != client FQDN '%s'",
+                  cert_dns_name, conn->remote_name);
+
+                GENERAL_NAME_free(name);
+                sk_GENERAL_NAME_free(sk_alt_names);
+                X509_free(cert);
+                ok = FALSE;
+                return FALSE;
+              }
             }
 
             tls_log("%s", "client cert dNSName matches client FQDN");
@@ -2122,8 +2141,9 @@ static int tls_accept(conn_t *conn, unsi
       /* Now we can go on with our post-handshake, application level
        * requirement checks.
        */
-      if (!tls_check_client_cert(ssl, conn))
+      if (!tls_check_client_cert(ssl, conn)) {
         return -1;
+      }
     }
 
     /* Setup the TLS environment variables, if requested. */
@@ -4393,8 +4413,10 @@ MODRET tls_auth(cmd_rec *cmd) {
     if (tls_accept(session.c, FALSE) < 0) {
       tls_log("%s", "TLS/TLS-C negotiation failed on control channel");
 
-      if (tls_required_on_ctrl == 1)
+      if (tls_required_on_ctrl == 1) {
+        pr_response_send(R_550, _("TLS handshake failed"));
         end_login(1);
+      }
 
       /* If we reach this point, the debug logging may show gibberish
        * commands from the client.  In reality, this gibberish is probably
@@ -4421,8 +4443,10 @@ MODRET tls_auth(cmd_rec *cmd) {
     if (tls_accept(session.c, FALSE) < 0) {
       tls_log("%s", "SSL/TLS-P negotiation failed on control channel");
 
-      if (tls_required_on_ctrl == 1)
+      if (tls_required_on_ctrl == 1) {
+        pr_response_send(R_550, _("TLS handshake failed"));
         end_login(1);
+      }
 
       /* If we reach this point, the debug logging may show gibberish
        * commands from the client.  In reality, this gibberish is probably