Standards-Version: 3.9.6 (no changes)
[ckermit.git] / ck_ssl.c
index 7b53770..cc8a4ed 100644 (file)
--- a/ck_ssl.c
+++ b/ck_ssl.c
@@ -1,8 +1,8 @@
-char *cksslv = "SSL/TLS support, 8.0.221, 26 Feb 2004";
+char *cksslv = "SSL/TLS support, 9.0.232, 5 Feb 2015";
 /*
   C K _ S S L . C --  OpenSSL Interface for C-Kermit
 
-  Copyright (C) 1985, 2004,
+  Copyright (C) 1985, 2015,
     Trustees of Columbia University in the City of New York.
     All rights reserved.  See the C-Kermit COPYING.TXT file or the
     copyright text in the ckcmai.c module for disclaimer and permissions.
@@ -19,7 +19,7 @@ char *cksslv = "SSL/TLS support, 8.0.221, 26 Feb 2004";
   . Client certificate to user id routine
 
   Note: This code is written to be compatible with OpenSSL 0.9.6[abcdefgh]
-  and 0.9.7 beta 5.
+  and 0.9.7 beta 5 and later, and (since July 2012) 1.0.x.
   It will also compile with version 0.9.5 although that is discouraged
   due to security weaknesses in that release.
 */
@@ -52,6 +52,8 @@ char * GetAppData(int);
 #endif
 #endif /* OS2 */
 
+extern int quiet;                      /* fdc - Mon Nov 28 11:44:15 2005 */
+
 static int ssl_installed = 1;
 #endif /* CK_SSL */
 int
@@ -153,6 +155,7 @@ SSL *ssl_con = NULL;
 int ssl_debug_flag = 0;
 int ssl_verbose_flag = 0;
 int ssl_only_flag = 0;
+int ssl_raw_flag = 0;
 int ssl_active_flag = 0;
 int ssl_verify_flag = SSL_VERIFY_PEER;
 int ssl_certsok_flag = 0;
@@ -173,6 +176,7 @@ char *ssl_rnd_file = NULL;
 SSL_CTX *tls_ctx = NULL;
 SSL *tls_con = NULL;
 int tls_only_flag = 0;
+int tls_raw_flag = 0;
 int tls_active_flag = 0;
 
 int ssl_initialized = 0;
@@ -188,6 +192,13 @@ extern char szHostName[], szUserNameRequested[], szUserNameAuthenticated[];
 
 _PROTOTYP(int X509_to_user,(X509 *, char *, int));
 
+static int verbosity = 0;              /* Message control */
+static VOID
+setverbosity() {
+    verbosity = ssl_verbose_flag;
+    if (quiet) verbosity = 0;
+}
+
 int
 #ifdef CK_ANSIC
 ssl_server_verify_callback(int ok, X509_STORE_CTX * ctx)
@@ -205,6 +216,8 @@ X509_STORE_CTX *ctx;
     if ( ssl_certsok_flag )
         return(1);
 
+    setverbosity();
+
     error=X509_STORE_CTX_get_error(ctx);
     depth=X509_STORE_CTX_get_error_depth(ctx);
     xs=X509_STORE_CTX_get_current_cert(ctx);
@@ -240,7 +253,7 @@ X509_STORE_CTX *ctx;
         goto return_time;
     }
 
-    if (ssl_verbose_flag && !inserver && depth != ssl_verify_depth) {
+    if (verbosity && !inserver && depth != ssl_verify_depth) {
         printf("[%d] Certificate Subject:\r\n%s\r\n",depth,subject);
         printf("[%d] Certificate Issuer:\r\n%s\r\n",depth,issuer);
         ssl_verify_depth = depth;
@@ -330,6 +343,8 @@ X509_STORE_CTX *ctx;
     int depth, error, len;
     X509 *xs;
 
+    setverbosity();
+
     xs=X509_STORE_CTX_get_current_cert(ctx);
     error=X509_STORE_CTX_get_error(ctx);
     depth=X509_STORE_CTX_get_error_depth(ctx);
@@ -396,7 +411,7 @@ X509_STORE_CTX *ctx;
     }
 #endif /* XN_FLAG_SEP_MULTILINE */
 
-    if (ssl_verbose_flag && depth != ssl_verify_depth) {
+    if (verbosity && depth != ssl_verify_depth) {
         printf("[%d] Certificate Subject:\r\n%s\r\n",depth,subject);
         printf("[%d] Certificate Issuer:\r\n%s\r\n",depth,issuer);
         ssl_verify_depth = depth;
@@ -697,6 +712,8 @@ int ret;
     if (inserver || !ssl_debug_flag)
         return;
 
+    setverbosity();
+
     switch ( where ) {
     case SSL_CB_CONNECT_LOOP:
         printf("SSL_connect:%s %s\r\n",
@@ -755,6 +772,8 @@ ssl_client_cert_callback(s, x509, pkey)
     EVP_PKEY ** pkey;
 #endif /* CK_ANSIC */
 {
+    setverbosity();
+
     if ( ssl_debug_flag ) {
         const char * cipher_list=SSL_get_cipher(s);
         printf("ssl_client_cert_callback called (%s)\r\n",
@@ -796,7 +815,6 @@ int keylength;
 #endif /* CK_ANSIC */
 {
     static RSA *rsa_tmp=NULL;
-    extern int quiet;
 
 #ifndef NO_RSA
     if (rsa_tmp == NULL)
@@ -994,7 +1012,6 @@ int keylength;
 {
     static DH *dh_tmp=NULL;
     BIO *bio=NULL;
-    extern int quiet;
 
 #ifndef NO_DH
     if (dh_tmp == NULL)
@@ -1028,6 +1045,9 @@ int keylength;
 static void
 ssl_display_comp(SSL * ssl)
 {
+    if ( quiet )                       /* fdc - Mon Nov 28 11:44:15 2005 */
+        return;
+
     if ( !ck_ssleay_is_installed() )
         return;
 
@@ -1056,6 +1076,9 @@ int verbose;
     const char *cipher_list;
     char buf[512]="";
 
+    if ( quiet )                       /* fdc - Mon Nov 28 11:44:15 2005 */
+        return(0);
+
     if ( !ck_ssleay_is_installed() )
         return(0);
 
@@ -1141,14 +1164,13 @@ int
 tls_load_certs(SSL_CTX * ctx, SSL * con, int server)
 {
     int rc = 1;
-    extern int quiet;
 
     if ( !ck_ssleay_is_installed() )
         return(0);
 
-    debug(F111,"tls_load_certs","SSL_CTX",ctx);
-    debug(F111,"tls_load_certs","SSL",con);
-    debug(F111,"tls_load_certs","server",server);
+    debug(F110,"tls_load_certs","SSL_CTX",0);
+    debug(F110,"tls_load_certs","SSL",0);
+    debug(F110,"tls_load_certs","server",0);
 
     if ( con ) {
         if (ssl_rsa_cert_file) {
@@ -1336,10 +1358,34 @@ ssl_once_init()
 #endif /* CK_ANSIC */
 {
     COMP_METHOD * cm;
+    char * s;
 
     if ( !ck_ssleay_is_installed() )
         return;
-
+/*
+  Pre-OpenSSL 1.0.0 comment:
+  OpenSSL does not provide for ABI compatibility between releases prior
+  to version 1.0.0.  If the version does not match, it is not safe to
+  assume that any function you call takes the same parameters or does
+  the same thing with them.  Removing this test prior to the OpenSSL 1.0.0
+  release will result in an increase in unexplained or incorrect behaviors.
+  The test should be revised once OpenSSL 1.0.0 is released and we see what
+  its claims are as to ABI compatibility.
+*/
+/*
+  Post-OpenSSL 1.0.0 comment:
+  OpenSSL does not provide for ABI compatibility between releases prior
+  to version 1.0.0.  After 1.0, the following holds:
+
+  Changes to last letter: security and bugfix only, no new features.
+  E.g.  1.0.0->1.0.0a
+  Changes to last number: new ABI compatible features.
+  E.g. 1.0.0->1.0.1
+  Changes to middle number: major release, ABI compatibility not guaranteed.
+  E.g. 1.0.0->1.1.0
+
+  (per Dr. Stephen Henson)
+*/
     debug(F111,"Kermit built for OpenSSL",OPENSSL_VERSION_TEXT,SSLEAY_VERSION_NUMBER);
 #ifndef OS2ONLY
     debug(F111,"OpenSSL Library",SSLeay_version(SSLEAY_VERSION),
@@ -1349,7 +1395,10 @@ ssl_once_init()
     debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_PLATFORM),0);
 
     /* The following test is suggested by Richard Levitte */
-    if (((OPENSSL_VERSION_NUMBER ^ SSLeay()) & 0xffffff0f) 
+    /* if (((OPENSSL_VERSION_NUMBER ^ SSLeay()) & 0xffffff0f) */
+    /* Modified by Adam Friedlander for OpenSSL >= 1.0.0 */
+    if (OPENSSL_VERSION_NUMBER > SSLeay()
+         || ((OPENSSL_VERSION_NUMBER ^ SSLeay()) & COMPAT_VERSION_MASK)
 #ifdef OS2
          || ckstrcmp(OPENSSL_VERSION_TEXT,(char *)SSLeay_version(SSLEAY_VERSION),-1,1)
 #endif /* OS2 */
@@ -1357,8 +1406,56 @@ ssl_once_init()
         ssl_installed = 0;
         debug(F111,"OpenSSL Version does not match.  Built with",
                SSLeay_version(SSLEAY_VERSION),SSLEAY_VERSION_NUMBER);
-        printf("?OpenSSL libraries do not match required version.");
-        printf("  SSL\\TLS support disabled\r\n\r\n");
+        printf("?OpenSSL libraries do not match required version:\r\n");
+        printf("  . C-Kermit built with %s\r\n",OPENSSL_VERSION_TEXT);
+        printf("  . Version found  %s\r\n",SSLeay_version(SSLEAY_VERSION));
+#ifdef OPENSSL_100
+       printf("  OpenSSL versions 1.0.0 or newer must be the same\r\n");
+       printf("  major and minor version number, and Kermit may not\r\n");
+       printf("  be used with a version of OpenSSL older than the one\r\n");
+       printf("  supplied at compile time.\r\n");
+#else
+        printf("  OpenSSL versions prior to 1.0.0 must be the same.\r\n");
+#endif /* OPENSSL_100 */
+
+       s = "R";
+#ifdef SOLARIS
+       printf("  Set CD_LIBRARY_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
+       s = " Or r";
+#endif /* SOLARIS */
+
+#ifdef HPUX
+       printf("  Set SHLIB_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
+       s = " Or r";
+#endif /* HPUX */
+
+#ifdef AIX
+       printf("  Set LIBPATH for %s.\r\n",OPENSSL_VERSION_TEXT);
+       s = " Or r";
+#endif /* AIX */
+
+#ifdef LINUX
+       printf("  Set LD_LIBRARY_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
+       s = " Or r";
+#endif /* LINUX */
+
+        printf(" %sebuild C-Kermit from source on this computer to make \
+versions agree.\r\n",s);
+
+#ifdef KTARGET
+       {
+           char * s;
+           s = KTARGET;
+           if (!s) s = "";
+           if (!*s) s = "(unknown)";
+           printf("  C-Kermit makefile target: %s\r\n",s);
+       }
+#endif /* KTARGET */
+        printf("  Or if that is what you did then try to find out why\r\n");
+        printf("  the program loader (image activator) is choosing a\r\n");
+        printf("  different OpenSSL library than the one specified in \
+the build.\r\n\r\n");
+        printf("  All SSL/TLS features disabled.\r\n\r\n");
         bleep(BP_FAIL);
 #ifdef SSLDLL
         ck_ssl_unloaddll();
@@ -1369,8 +1466,8 @@ ssl_once_init()
 #endif /* OS2ONLY */
 
     /* init things so we will get meaningful error messages
-    * rather than numbers
-    */
+     * rather than numbers
+     */
     SSL_load_error_strings();
 
 #ifdef SSHBUILTIN
@@ -1507,27 +1604,48 @@ ssl_tn_init(mode) int mode;
             /* This can fail because we do not have RSA available */
             if ( !ssl_ctx ) {
                 debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
+#ifndef DISABLE_SSLV3
                 ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
             }
             if ( !ssl_ctx ) {
                 debug(F110,"ssl_tn_init","SSLv3_client_method failed",0);
+#endif
                 last_ssl_mode = -1;
                 return(0);
             }
-#ifndef COMMENT
+            /*
+              TLS 1.0 is the new default as of 5 Feb 2015.
+              Previously this was commented out because 
+              "too many web servers still do not support TLSv1".
+              Now we try TLS 1.0 first, falling back to SSL 2.3
+              and SSL 3.0 in that order.  Maybe there should be
+              an option not to fall back.
+            */ 
             tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_client_method());
-#else /* COMMENT */
-            tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
-            /* This can fail because we do not have RSA available */
-            if ( !tls_ctx ) {
-                debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
-                tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
-            }
-#endif /* COMMENT */
-            if ( !tls_ctx ) {
+            if ( tls_ctx ) {
+                debug(F110,"ssl_tn_init","TLSv1_client_method OK",0);
+            } else {
                 debug(F110,"ssl_tn_init","TLSv1_client_method failed",0);
-                last_ssl_mode = -1;
-                return(0);
+                /* This can fail because we do not have RSA available */
+                tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
+                if ( !tls_ctx ) {
+                    debug(F110,"ssl_tn_init","SSLv23_client_method OK",0);
+                } else {
+                    debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
+#ifndef DISABLE_SSLV3
+                    tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
+#endif /* DISABLE_SSLV3 */
+                    if ( !tls_ctx ) {
+#ifndef DISABLE_SSLV3
+                        debug(F110,
+                              "ssl_tn_init","SSLv3_client_method failed",0);
+#endif /* DISABLE_SSLV3 */
+                        debug(F110,
+                              "ssl_tn_init","All SSL client methods failed",0);
+                        last_ssl_mode = -1;
+                        return(0);
+                    }
+                }
             }
 #ifdef USE_CERT_CB
             SSL_CTX_set_client_cert_cb(ssl_ctx,ssl_client_cert_callback);
@@ -1539,10 +1657,12 @@ ssl_tn_init(mode) int mode;
             /* This can fail because we do not have RSA available */
             if ( !ssl_ctx ) {
                 debug(F110,"ssl_tn_init","SSLv23_server_method failed",0);
+#ifndef DISABLE_SSLV3
                 ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_server_method());
             }
             if ( !ssl_ctx ) {
                 debug(F110,"ssl_tn_init","SSLv3_server_method failed",0);
+#endif
                 last_ssl_mode = -1;
                 return(0);
             }
@@ -1576,9 +1696,17 @@ ssl_tn_init(mode) int mode;
          * that cannot read poorly written specs :-)
          * for TLS be sure to prevent use of SSLv2
          */
-        SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL|SSL_OP_NO_SSLv2);
+        SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL|SSL_OP_NO_SSLv2
+#ifdef DISABLE_SSLV3
+                                    |SSL_OP_NO_SSLv3
+#endif
+            );
         SSL_CTX_set_options(tls_ctx,
-                 SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA);
+                 SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA
+#ifdef DISABLE_SSLV3
+                 |SSL_OP_NO_SSLv3
+#endif
+            );
 
         SSL_CTX_set_info_callback(ssl_ctx,ssl_client_info_callback);
         SSL_CTX_set_info_callback(tls_ctx,ssl_client_info_callback);
@@ -2081,36 +2209,33 @@ ssl_http_init(hostname) char * hostname;
         printf("SSL_DEBUG_FLAG on\r\n");
 
     if (!tls_http_ctx ) {
-#ifdef COMMENT
-        /* too many web servers still do not support TLSv1 */
+        /*
+          TLS 1.0 is the new default as of 5 Feb 2015.
+          Previously this was commented out because 
+          "too many web servers still do not support TLSv1".
+          Now we try TLS 1.0 first, falling back to SSL 2.3
+          and SSL 3.0 in that order.  Maybe there should be
+          an option not to fall back.
+        */ 
         tls_http_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_client_method());
-#else /* COMMENT */
-        tls_http_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
-        /* This can fail because we do not have RSA available */
-        if ( !tls_http_ctx ) {
-            debug(F110,"ssl_http_init","SSLv23_client_method failed",0);
-            tls_http_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
-        }
-#endif /* COMMENT */
-        if ( !tls_http_ctx ) {
-            debug(F110,"ssl_http_init","TLSv1_client_method failed",0);
-            return(0);
+        if ( tls_http_ctx ) {
+            debug(F110,"ssl_http_init","TLSv1_client_method OK",0);
         }
-#ifdef USE_CERT_CB
-        SSL_CTX_set_client_cert_cb(tls_http_ctx,ssl_client_cert_callback);
-#endif /* USE_CERT_CB */
     }
-
     SSL_CTX_set_default_passwd_cb(tls_http_ctx,
                                   (pem_password_cb *)ssl_passwd_callback);
 
     /* for SSL switch on all the interoperability and bug
      * workarounds so that we will communicate with people
-     * that cannot read poorly written specs :-)
+     * who cannot read poorly written specs :-)
      * for TLS be sure to prevent use of SSLv2
      */
     SSL_CTX_set_options(tls_http_ctx,
-            SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA);
+            SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA
+#ifdef DISABLE_SSLV3
+            |SSL_OP_NO_SSLv3
+#endif
+        );
 
     SSL_CTX_set_info_callback(tls_http_ctx,ssl_client_info_callback);
 
@@ -2383,8 +2508,12 @@ ssl_get_dNSName(ssl) SSL * ssl;
         for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
             gen = sk_GENERAL_NAME_value(ialt, i);
             if (gen->type == GEN_DNS) {
-                if(!gen->d.ia5 || !gen->d.ia5->length)
-                    break;
+                if (!gen->d.ia5 || !gen->d.ia5->length)
+                 break;
+                if (strlen((char *)gen->d.ia5->data) != gen->d.ia5->length) {
+                    /* Ignoring IA5String containing null character */
+                    continue;
+                }
                 dns = malloc(gen->d.ia5->length + 1);
                 if (dns) {
                     memcpy(dns, gen->d.ia5->data, gen->d.ia5->length);
@@ -2402,21 +2531,32 @@ cleanup:
 }
 
 char *
-ssl_get_commonName(ssl) SSL * ssl;
-{
+ssl_get_commonName(ssl) SSL * ssl; {
     static char name[256];
+    int name_text_len;
     int err;
     X509 *server_cert;
 
+    name_text_len = 0;
     if (server_cert = SSL_get_peer_certificate(ssl)) {
-        err = X509_NAME_get_text_by_NID(X509_get_subject_name(server_cert),
-                NID_commonName, name, sizeof(name));
+        name_text_len =
+           X509_NAME_get_text_by_NID(X509_get_subject_name(server_cert),
+                                     NID_commonName, name, sizeof(name));
         X509_free(server_cert);
     }
+    if (name_text_len <= 0) {
+       /* Common Name was empty or not retrieved */
+        err = 0;
+    } else if (strlen(name) != name_text_len) {
+        /* Ignoring Common Name containing null character */
+       err = 0;
+    } else {
+       err = 1;
+    }
     if (err > 0)
-        return name;
+      return name;
     else
-        return NULL;
+      return NULL;
 }
 
 char *
@@ -2681,8 +2821,12 @@ tls_get_SAN_objs(SSL * ssl, int type)
              * with one and linked to the other we use this hack.
              */
             if ((gen->type | V_ASN1_CONTEXT_SPECIFIC) == (type | V_ASN1_CONTEXT_SPECIFIC)) {
-                if(!gen->d.ia5 || !gen->d.ia5->length)
-                    break;
+                if (!gen->d.ia5 || !gen->d.ia5->length)
+                 break;
+                if (strlen((char *)gen->d.ia5->data) != gen->d.ia5->length) {
+                    /* Ignoring IA5String containing null character */
+                    continue;
+                }
                 objs[j] = malloc(gen->d.ia5->length + 1);
                 if (objs[j]) {
                     memcpy(objs[j], gen->d.ia5->data, gen->d.ia5->length);
@@ -2703,7 +2847,7 @@ eject:
 static int
 dNSName_cmp(const char *host, const char *dNSName)
 {
-    int c1 = 0, c2 = 0, num_comp, rv = -1;
+    int c1 = 1, c2 = 1, num_comp, rv = -1;
     char *p, *p1, *p2, *host_copy=NULL, *dNSName_copy=NULL;
 
     /* first we count the number of domain name components in both parameters.
@@ -2765,6 +2909,7 @@ show_hostname_warning(char *s1, char *s2)
 {
     char prefix[1024];
     int ok = 1;
+    setverbosity();
     ckmakxmsg(prefix,1024,
               "Warning: Hostname (\"", s1, 
               "\") does not match server's certificate (\"", s2, "\")",
@@ -2773,25 +2918,31 @@ show_hostname_warning(char *s1, char *s2)
         ok = uq_ok(prefix,
                     "Continue? (Y/N) ",
                     3, NULL, 0);
-    else if (ssl_verbose_flag)
+    else if (verbosity)
         printf(prefix);
     return(ok);
 }
 
+#ifndef OSF50
 #ifndef HPUX10
 #ifndef HPUX1100
 #ifndef SCO_OSR505
 #ifndef OpenBSD
 #ifndef FREEBSD4
+#ifndef NETBSD15
 #ifndef LINUX
 #ifndef AIX41
 #ifndef UW7
+#ifndef IRIX65
 #ifndef SOLARIS9
 #ifndef SOLARIS8
 #ifndef SOLARIS7
+#ifndef MACOSX
 #ifdef DEC_TCPIP
 #define inet_aton INET_ATON
 #endif /* DEC_TCPIP */
+
+#ifndef NO_DCL_INET_ATON
 static int
 inet_aton(char * ipaddress, struct in_addr * ia) {
     struct stringarray * q;
@@ -2811,17 +2962,23 @@ inet_aton(char * ipaddress, struct in_addr * ia) {
     }
     return(0);
 }
+#endif /* NO_DCL_INET_ATON */
+
+#endif /* MACOSX */
 #endif /* SOLARIS7 */
 #endif /* SOLARIS8 */
 #endif /* SOLARIS9 */
+#endif /* IRIX65 */
 #endif /* UW7 */
 #endif /* AIX41 */
 #endif /* LINUX */
+#endif /* NETBSD15 */
 #endif /* FREEBSD4 */
 #endif /* OpenBSD */
 #endif /* SCO_OSR505 */
 #endif /* HPUX1100 */
 #endif /* HPUX10 */
+#endif /* OSF50 */
 
 int
 ssl_check_server_name(SSL * ssl, char * hostname)
@@ -2833,7 +2990,8 @@ ssl_check_server_name(SSL * ssl, char * hostname)
     struct in_addr ia;
     int rv;
 
-    if (ssl_verbose_flag && !inserver) {
+    setverbosity();
+    if (verbosity && !inserver) {
         if (dNSName = tls_get_SAN_objs(ssl,GEN_DNS)) {
             int i = 0;
             for (i = 0; dNSName[i]; i++) {
@@ -3082,6 +3240,7 @@ ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
 {
     char * str=NULL;
 
+    setverbosity();
     data += 4;                          /* Point to status byte */
     cnt  -= 4;
 
@@ -3094,7 +3253,7 @@ ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
     case SSL_ACCEPT:
         if (tn_deb || debses)
             tn_debug("[SSL - handshake starting]");
-        else if ( ssl_verbose_flag )
+        else if ( verbosity )
             printf("[SSL - handshake starting]\r\n");
         debug(F110,"ssl_reply","[SSL - handshake starting]",0);
 
@@ -3103,7 +3262,7 @@ ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
             if (ssl_dummy_flag) {
                 if (tn_deb || debses)
                     tn_debug("[SSL - Dummy Connected]");
-                else if ( ssl_verbose_flag ) {
+                else if ( verbosity ) {
                     printf("[SSL - Dummy Connected]\r\n");
                 }
                 debug(F110,"ssl_reply","[SSL - Dummy Connected]",0);
@@ -3120,7 +3279,7 @@ ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
                     printf(ssl_err);
-                } else if ( ssl_verbose_flag ) {
+                } else if ( verbosity ) {
                     printf("[SSL - FAILED]\r\n");
                     ERR_print_errors(bio_err);
                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
@@ -3134,13 +3293,13 @@ ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
             } else {
                 if (tn_deb || debses)
                     tn_debug("[SSL - OK]");
-                else if ( ssl_verbose_flag ) {
+                else if ( verbosity ) {
                     printf("[SSL - OK]\r\n");
                 }
                 debug(F110,"ssl_reply","[SSL - OK]",0);
 
                 ssl_active_flag = 1;
-                ssl_display_connect_details(ssl_con,0,ssl_verbose_flag);
+                ssl_display_connect_details(ssl_con,0,verbosity);
             }
         }
         auth_finished(AUTH_UNKNOWN);
@@ -3151,7 +3310,7 @@ ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
         if (tn_deb || debses) {
             tn_debug(
                  "[SSL - failed to switch on SSL - trying plaintext login]");
-        } else if ( ssl_verbose_flag ) {
+        } else if ( verbosity ) {
             printf("[SSL - failed to switch on SSL]\r\n");
             printf("Trying plaintext login:\r\n");
         }
@@ -3175,6 +3334,7 @@ ssl_is(data,cnt) unsigned char *data; int cnt;
     if ((cnt -= 4) < 1)
         return AUTH_FAILURE;
 
+    setverbosity();
     data += 4;
     switch(*data++) {
     case SSL_START:
@@ -3187,7 +3347,7 @@ ssl_is(data,cnt) unsigned char *data; int cnt;
 
             if (tn_deb || debses)
                 tn_debug("[SSL - handshake starting]");
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[SSL - handshake starting]\r\n");
             debug(F110,"ssl_is","[SSL - handshake starting]",0);
 
@@ -3198,7 +3358,7 @@ ssl_is(data,cnt) unsigned char *data; int cnt;
             if (ssl_dummy_flag) {
                 if (tn_deb || debses)
                     tn_debug("[SSL - Dummy Connected]");
-                else if ( ssl_verbose_flag ) {
+                else if ( verbosity ) {
                     printf("[SSL - Dummy Connected]\r\n");
                 }
                 debug(F110,"ssl_is","[SSL - Dummy Connected]",0);
@@ -3217,7 +3377,7 @@ ssl_is(data,cnt) unsigned char *data; int cnt;
                     tn_debug(errbuf);
                 else if ( ssl_debug_flag )
                     printf("%s\r\n",errbuf);
-                else if ( ssl_verbose_flag )
+                else if ( verbosity )
                     printf("[SSL - SSL_accept error]\r\n");
 
                 debug(F110,"ssl_is",errbuf,0);
@@ -3229,12 +3389,12 @@ ssl_is(data,cnt) unsigned char *data; int cnt;
 
             if (tn_deb || debses)
                 tn_debug("[SSL - OK]");
-            else if ( ssl_verbose_flag ) {
+            else if ( verbosity ) {
                 printf("[SSL - OK]\r\n");
             }
             debug(F110,"ssl_is","[SSL - OK]",0);
             ssl_active_flag = 1;
-            ssl_display_connect_details(ssl_con,1,ssl_verbose_flag);
+            ssl_display_connect_details(ssl_con,1,verbosity);
 
             /* now check to see that we got exactly what we
             * wanted from the caller ... if a certificate is
@@ -3294,6 +3454,7 @@ ck_tn_tls_negotiate(VOID)
     if ( !ck_ssleay_is_installed() )
         return(-1);
 
+    setverbosity();
     if (sstelnet) {
         /* server starts the TLS stuff now ... */
         if (!tls_only_flag) {
@@ -3304,14 +3465,14 @@ ck_tn_tls_negotiate(VOID)
 
             if (tn_deb || debses)
                 tn_debug("[TLS - handshake starting]");
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[TLS - handshake starting]\r\n");
             debug(F110,"ck_tn_tls_negotiate","[TLS - handshake starting]",0);
 
             if (ssl_dummy_flag) {
                 if (tn_deb || debses)
                     tn_debug("[TLS - Dummy Connected]");
-                else if ( ssl_verbose_flag ) {
+                else if ( verbosity ) {
                     printf("[TLS - Dummy Connected]\r\n");
                 }
                 debug(F110,"ck_tn_tls_negotiate","[TLS - Dummy Connected]",0);
@@ -3330,7 +3491,7 @@ ck_tn_tls_negotiate(VOID)
                     tn_debug(errbuf);
                 else if ( ssl_debug_flag )
                     printf("%s\r\n",errbuf);
-                else if ( ssl_verbose_flag )
+                else if ( verbosity )
                     printf("[TLS - SSL_accept error]\r\n");
 
                 debug(F110,"ck_tn_tls_negotiate",errbuf,0);
@@ -3340,13 +3501,13 @@ ck_tn_tls_negotiate(VOID)
 
             if (tn_deb || debses)
                 tn_debug("[TLS - OK]");
-            else if ( ssl_verbose_flag ) {
+            else if ( verbosity ) {
                 printf("[TLS - OK]\r\n");
             }
 
             debug(F110,"ck_tn_tls_negotiate","[TLS - OK]",0);
             tls_active_flag = 1;
-            ssl_display_connect_details(tls_con,1,ssl_verbose_flag);
+            ssl_display_connect_details(tls_con,1,verbosity);
 
 
 #ifdef SSL_KRB5
@@ -3408,7 +3569,7 @@ ck_tn_tls_negotiate(VOID)
                                            NID_commonName,str,
                                            256
                                            );
-                if ( ssl_verbose_flag )
+                if ( verbosity )
                     printf("[TLS - commonName=%s]\r\n",str);
 
                 X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
@@ -3420,7 +3581,7 @@ ck_tn_tls_negotiate(VOID)
                                            str,
                                            256
                                            );
-                if ( ssl_verbose_flag )
+                if ( verbosity )
                     printf("[TLS - uniqueIdentifier=%s]\r\n",str);
 
                 /* Try to determine user name */
@@ -3455,7 +3616,7 @@ ck_tn_tls_negotiate(VOID)
 
         if (tn_deb || debses)
             tn_debug("[TLS - handshake starting]");
-        else if ( ssl_verbose_flag )
+        else if ( verbosity )
             printf("[TLS - handshake starting]\r\n");
         debug(F110,"ck_tn_tls_negotiate","[TLS - handshake starting]",0);
 
@@ -3466,7 +3627,7 @@ ck_tn_tls_negotiate(VOID)
             if (ssl_dummy_flag) {
                 if (tn_deb || debses)
                     tn_debug("[TLS - Dummy Connected]");
-                else if ( ssl_verbose_flag ) {
+                else if ( verbosity ) {
                     printf("[TLS - Dummy Connected]\r\n");
                 }
                 debug(F110,"ck_tn_tls_negotiate","[TLS - Dummy Connected]",0);
@@ -3487,7 +3648,7 @@ ck_tn_tls_negotiate(VOID)
                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
                     printf(ssl_err);
-                } else if ( ssl_verbose_flag ) {
+                } else if ( verbosity ) {
                     printf("[TLS - FAILED]\r\n");
                     ERR_print_errors(bio_err);
                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
@@ -3510,7 +3671,7 @@ ck_tn_tls_negotiate(VOID)
                     {
                         if (tn_deb || debses)
                             tn_debug("[TLS - FAILED]");
-                        else if ( ssl_verbose_flag )
+                        else if ( verbosity )
                             printf("[TLS - FAILED]\r\n");
                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
                         auth_finished(AUTH_REJECT);
@@ -3522,7 +3683,7 @@ ck_tn_tls_negotiate(VOID)
                         if (!ok) {
                             if (tn_deb || debses)
                                 tn_debug("[TLS - FAILED]");
-                            else if ( ssl_verbose_flag )
+                            else if ( verbosity )
                                 printf("[TLS - FAILED]\r\n");
                             debug(F110,
                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
@@ -3533,7 +3694,7 @@ ck_tn_tls_negotiate(VOID)
                 } else if (ssl_check_server_name(tls_con, szHostName)) {
                     if (tn_deb || debses)
                         tn_debug("[TLS - FAILED]");
-                    else if ( ssl_verbose_flag )
+                    else if ( verbosity )
                         printf("[TLS - FAILED]\r\n");
                     debug(F110,
                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
@@ -3569,11 +3730,11 @@ ck_tn_tls_negotiate(VOID)
 
             if (tn_deb || debses)
                 tn_debug("[TLS - OK]");
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[TLS - OK]\r\n");
             debug(F110,"ck_tn_tls_negotiate","[TLS - OK]",0);
 
-            ssl_display_connect_details(tls_con,0,ssl_verbose_flag);
+            ssl_display_connect_details(tls_con,0,verbosity);
         }
         auth_finished(AUTH_REJECT);
     }
@@ -3593,6 +3754,7 @@ ck_ssl_incoming(fd) int fd;
 
     int timo = 2000;
 
+    setverbosity();
     if ( !ck_ssleay_is_installed() )
         return(-1);
 
@@ -3603,7 +3765,7 @@ ck_ssl_incoming(fd) int fd;
     if (tls_only_flag) {
         if (tn_deb || debses)
             tn_debug("[TLS - handshake starting]");
-        else if ( ssl_verbose_flag )
+        else if ( verbosity )
             printf("[TLS - handshake starting]\r\n");
         debug(F110,"ck_ssl_incoming","[TLS - handshake starting]",0);
 
@@ -3621,7 +3783,7 @@ ck_ssl_incoming(fd) int fd;
                 tn_debug(errbuf);
             else if ( ssl_debug_flag )
                 printf("%s\r\n",errbuf);
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[TLS - SSL_accept error]\r\n");
 
             debug(F110,"ck_ssl_incoming",errbuf,0);
@@ -3629,7 +3791,7 @@ ck_ssl_incoming(fd) int fd;
         } else {
             if (tn_deb || debses)
                 tn_debug("[TLS - OK]");
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[TLS - OK]\r\n");
             debug(F110,"ck_ssl_incoming","[TLS - OK]",0);
             tls_active_flag = 1;
@@ -3637,7 +3799,7 @@ ck_ssl_incoming(fd) int fd;
     } else if (ssl_only_flag) {
         if (tn_deb || debses)
             tn_debug("[SSL - handshake starting]");
-        else if ( ssl_verbose_flag )
+        else if ( verbosity )
             printf("[SSL - handshake starting]\r\n");
         debug(F110,"ck_ssl_incoming","[SSL - handshake starting]",0);
 
@@ -3655,7 +3817,7 @@ ck_ssl_incoming(fd) int fd;
                 tn_debug(errbuf);
             else if ( ssl_debug_flag )
                 printf("%s\r\n",errbuf);
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[SSL - SSL_accept error]\r\n");
 
             debug(F110,"ck_ssl_incoming",errbuf,0);
@@ -3663,7 +3825,7 @@ ck_ssl_incoming(fd) int fd;
         } else {
             if (tn_deb || debses)
                 tn_debug("[SSL - OK]");
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
             printf("[SSL - OK]\r\n");
             debug(F110,"ssl_is","[SSL - OK]",0);
             ssl_active_flag = 1;
@@ -3757,6 +3919,7 @@ ck_ssl_outgoing(fd) int fd;
 {
     int timo = 2000;
 
+    setverbosity();
     if ( !ck_ssleay_is_installed() )
         return(-1);
 
@@ -3774,7 +3937,7 @@ ck_ssl_outgoing(fd) int fd;
 #endif /* USE_CERT_CB */
         if (tn_deb || debses)
             tn_debug("[TLS - handshake starting]");
-        else if (ssl_verbose_flag)
+        else if (verbosity)
             printf("[TLS - handshake starting]\r\n");
         debug(F110,"ck_ssl_outgoing","[TLS - handshake starting]",0);
         if (SSL_connect(tls_con) <= 0) {
@@ -3790,7 +3953,7 @@ ck_ssl_outgoing(fd) int fd;
 
             if (tn_deb || debses)
                 tn_debug("[TLS - FAILED]");
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[TLS - FAILED]\r\n");
             debug(F110,"ck_ssl_outgoing","[TLS - FAILED]",0);
             netclos();
@@ -3806,7 +3969,7 @@ ck_ssl_outgoing(fd) int fd;
                     {
                         if (tn_deb || debses)
                             tn_debug("[TLS - FAILED]");
-                        else if ( ssl_verbose_flag )
+                        else if ( verbosity )
                             printf("[TLS - FAILED]\r\n");
                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
 
@@ -3820,7 +3983,7 @@ ck_ssl_outgoing(fd) int fd;
                         if (!ok) {
                             if (tn_deb || debses)
                                 tn_debug("[TLS - FAILED]");
-                            else if ( ssl_verbose_flag )
+                            else if ( verbosity )
                                 printf("[TLS - FAILED]\r\n");
                             debug(F110,
                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
@@ -3831,7 +3994,7 @@ ck_ssl_outgoing(fd) int fd;
                 } else if (ssl_check_server_name(tls_con, szHostName)) {
                     if (tn_deb || debses)
                         tn_debug("[TLS - FAILED]");
-                    else if ( ssl_verbose_flag )
+                    else if ( verbosity )
                         printf("[TLS - FAILED]\r\n");
                     debug(F110,
                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
@@ -3839,12 +4002,12 @@ ck_ssl_outgoing(fd) int fd;
                     return -1;
                 }
             }
-
-            printf("[TLS - OK]\r\n");
             if (tn_deb || debses)
                 tn_debug("[TLS - OK]");
+            else if (!quiet)
+               printf("[TLS - OK]\r\n");
             debug(F110,"ck_ssl_outgoing","[TLS - OK]",0);
-            ssl_display_connect_details(tls_con,0,ssl_verbose_flag);
+            ssl_display_connect_details(tls_con,0,verbosity);
         }
     }
     /* if we are doing raw SSL then start it now ... */
@@ -3855,7 +4018,7 @@ ck_ssl_outgoing(fd) int fd;
 #endif /* USE_CERT_CB */
         if (tn_deb || debses)
             tn_debug("[SSL - handshake starting]");
-        else if ( ssl_verbose_flag )
+        else if ( verbosity )
             printf("[SSL - handshake starting]\r\n");
         debug(F110,"ck_ssl_outgoing","[SSL - handshake starting]",0);
         if (SSL_connect(ssl_con) <= 0) {
@@ -3868,7 +4031,7 @@ ck_ssl_outgoing(fd) int fd;
             }
             if (tn_deb || debses)
                 tn_debug("[SSL - FAILED]");
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[SSL - FAILED]\r\n");
             debug(F110,"ck_ssl_outgoing","[SSL - FAILED]",0);
             return(-1);
@@ -3884,7 +4047,7 @@ ck_ssl_outgoing(fd) int fd;
                     {
                         if (tn_deb || debses)
                             tn_debug("[SSL - FAILED]");
-                        else if ( ssl_verbose_flag )
+                        else if ( verbosity )
                             printf("[SSL - FAILED]\r\n");
                         debug(F110,"ck_tn_tls_negotiate","[SSL - FAILED]",0);
 
@@ -3898,7 +4061,7 @@ ck_ssl_outgoing(fd) int fd;
                         if (!ok) {
                             if (tn_deb || debses)
                                 tn_debug("[SSL - FAILED]");
-                            else if ( ssl_verbose_flag )
+                            else if ( verbosity )
                                 printf("[SSL - FAILED]\r\n");
                             debug(F110,
                                    "ck_tn_tls_negotiate","[SSL - FAILED]",0);
@@ -3909,19 +4072,19 @@ ck_ssl_outgoing(fd) int fd;
                 } else if (ssl_check_server_name(ssl_con, szHostName)) {
                     if (tn_deb || debses)
                         tn_debug("[SSL - FAILED]");
-                    else if ( ssl_verbose_flag )
+                    else if ( verbosity )
                         printf("[SSL - FAILED]\r\n");
                     debug(F110, "ck_tn_tls_negotiate","[SSL - FAILED]",0);
                     auth_finished(AUTH_REJECT);
                     return -1;
                 }
             }
-
-            printf("[SSL - OK]\r\n");
             if (tn_deb || debses)
                 tn_debug("[SSL - OK]");
+           else if (!quiet)
+               printf("[SSL - OK]\r\n");
             debug(F110,"ck_ssl_outgoing","[SSL - OK]",0);
-            ssl_display_connect_details(ssl_con,0,ssl_verbose_flag);
+            ssl_display_connect_details(ssl_con,0,verbosity);
         }
     }
     return(0);  /* success */
@@ -3936,6 +4099,8 @@ ck_ssl_http_client(fd, hostname) int fd; char * hostname;
     if ( !ck_ssleay_is_installed() )
         return(-1);
 
+    setverbosity();
+
     /* bind in the network descriptor */
     SSL_set_fd(tls_http_con,fd);
 
@@ -3949,7 +4114,7 @@ ck_ssl_http_client(fd, hostname) int fd; char * hostname;
 #endif /* USE_CERT_CB */
         if (tn_deb || debses)
             tn_debug("[TLS - handshake starting]");
-        else if (ssl_verbose_flag)
+        else if (verbosity)
             printf("[TLS - handshake starting]\r\n");
         debug(F110,"ck_ssl_outgoing","[TLS - handshake starting]",0);
         if (SSL_connect(tls_http_con) <= 0) {
@@ -3965,7 +4130,7 @@ ck_ssl_http_client(fd, hostname) int fd; char * hostname;
 
             if (tn_deb || debses)
                 tn_debug("[TLS - FAILED]");
-            else if ( ssl_verbose_flag )
+            else if ( verbosity )
                 printf("[TLS - FAILED]\r\n");
             debug(F110,"ck_ssl_http_client","[TLS - FAILED]",0);
             http_close();
@@ -3981,7 +4146,7 @@ ck_ssl_http_client(fd, hostname) int fd; char * hostname;
                     {
                         if (tn_deb || debses)
                             tn_debug("[TLS - FAILED]");
-                        else if ( ssl_verbose_flag )
+                        else if ( verbosity )
                             printf("[TLS - FAILED]\r\n");
                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
                         return -1;
@@ -3993,7 +4158,7 @@ ck_ssl_http_client(fd, hostname) int fd; char * hostname;
                         if (!ok) {
                             if (tn_deb || debses)
                                 tn_debug("[TLS - FAILED]");
-                            else if ( ssl_verbose_flag )
+                            else if ( verbosity )
                                 printf("[TLS - FAILED]\r\n");
                             debug(F110,
                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
@@ -4003,7 +4168,7 @@ ck_ssl_http_client(fd, hostname) int fd; char * hostname;
                 } else if (ssl_check_server_name(tls_http_con, hostname)) {
                     if (tn_deb || debses)
                         tn_debug("[TLS - FAILED]");
-                    else if ( ssl_verbose_flag )
+                    else if ( verbosity )
                         printf("[TLS - FAILED]\r\n");
                     debug(F110,
                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
@@ -4015,7 +4180,7 @@ ck_ssl_http_client(fd, hostname) int fd; char * hostname;
             if (tn_deb || debses)
                 tn_debug("[TLS - OK]");
             debug(F110,"ck_ssl_outgoing","[TLS - OK]",0);
-            ssl_display_connect_details(tls_http_con,0,ssl_verbose_flag);
+            ssl_display_connect_details(tls_http_con,0,verbosity);
         }
     }
     return(0);  /* success */
@@ -4144,8 +4309,12 @@ X509_to_user(X509 *peer_cert, char *userid, int len)
     for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
         gen = sk_GENERAL_NAME_value(ialt, i);
         if (gen->type == GEN_DNS) {
-            if(!gen->d.ia5 || !gen->d.ia5->length)
-                break;
+            if (!gen->d.ia5 || !gen->d.ia5->length)
+             break;
+            if (strlen(gen->d.ia5->data) != gen->d.ia5->length) {
+                /* Ignoring IA5String containing null character */
+                continue;
+            }
             if ( gen->d.ia5->length + 1 > sizeof(email) ) {
                 goto cleanup;
             }