a897b8f02645405630003683633d76b6058866e4
galt
  Tue Dec 21 23:15:54 2021 -0800
Adding ability to pass the hostName for logging since self-signed certs sometimes just say localhost and certs with wildcards and multiple hosts also do not tell you exactly which specific host is being used, so now we will know it.

diff --git src/lib/https.c src/lib/https.c
index 0a66313..2da53a5 100644
--- src/lib/https.c
+++ src/lib/https.c
@@ -6,30 +6,39 @@
 #include "openssl/ssl.h"
 #include "openssl/err.h"
 
 #include <sys/socket.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <signal.h>
 
 #include "common.h"
 #include "internet.h"
 #include "errAbort.h"
 #include "hash.h"
 #include "net.h"
 
 
+// For use with callback. Set a variable into the connection itself,
+// and then use that during the callback.
+struct myData
+    {
+    char *hostName;
+    };
+
+int myDataIndex = -1;
+
 static pthread_mutex_t *mutexes = NULL;
  
 static unsigned long openssl_id_callback(void)
 {
 return ((unsigned long)pthread_self());
 }
  
 static void openssl_locking_callback(int mode, int n, const char * file, int line)
 {
 if (mode & CRYPTO_LOCK)
     pthread_mutex_lock(&mutexes[n]);
 else
     pthread_mutex_unlock(&mutexes[n]);
 }
  
@@ -64,30 +73,31 @@
 }
 
 void openSslInit()
 /* do only once */
 {
 static boolean done = FALSE;
 static pthread_mutex_t osiMutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_lock( &osiMutex );
 if (!done)
     {
     SSL_library_init();
     ERR_load_crypto_strings();
     ERR_load_SSL_strings();
     OpenSSL_add_all_algorithms();
     openssl_pthread_setup();
+    myDataIndex = SSL_get_ex_new_index(0, "myDataIndex", NULL, NULL, NULL);
     done = TRUE;
     }
 pthread_mutex_unlock( &osiMutex );
 }
 
 
 void *netConnectHttpsThread(void *threadParam)
 /* use a thread to run socket back to user */
 {
 /* child */
 
 struct netConnectHttpsParams *params = threadParam;
 
 pthread_detach(params->thread);  // this thread will never join back with it's progenitor
 
@@ -260,72 +270,83 @@
 
 BIO_free_all(params->sbio);  // will free entire chain of bios
 close(fd);     // Needed because we use BIO_NOCLOSE above. Someday might want to re-use a connection.
 close(params->sv[1]);  /* we are done with it */
 
 return NULL;
 }
 
 
 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
 {
 char    buf[256];
 X509   *cert;
 int     err, depth;
 
+struct myData *myData;
+SSL    *ssl;
+
 cert = X509_STORE_CTX_get_current_cert(ctx);
 err = X509_STORE_CTX_get_error(ctx);
 depth = X509_STORE_CTX_get_error_depth(ctx);
 
 /*
 * Retrieve the pointer to the SSL of the connection currently treated
 * and the application specific data stored into the SSL object.
 */
 
 X509_NAME_oneline(X509_get_subject_name(cert), buf, 256);
 
 /*
 * Catch a too long certificate chain. The depth limit set using
 * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so
 * that whenever the "depth>verify_depth" condition is met, we
 * have violated the limit and want to log this error condition.
 * We must do it here, because the CHAIN_TOO_LONG error would not
 * be found explicitly; only errors introduced by cutting off the
 * additional certificates would be logged.
 */
+
+ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+myData = SSL_get_ex_data(ssl, myDataIndex);
+
+
 if (depth > atoi(getenv("https_cert_check_depth")))
     {
     preverify_ok = 0;
     err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
     X509_STORE_CTX_set_error(ctx, err);
     }
 if (sameString(getenv("https_cert_check_verbose"), "on"))
     {
     fprintf(stderr,"depth=%d:%s\n", depth, buf);
     }
 if (!preverify_ok) 
     {
     if (getenv("SCRIPT_NAME"))  // CGI mode
 	{
-	fprintf(stderr, "verify error:num=%d:%s:depth=%d:%s CGI=%s\n", err,
-	    X509_verify_cert_error_string(err), depth, buf, getenv("SCRIPT_NAME"));
+	fprintf(stderr, "verify error:num=%d:%s:depth=%d:%s hostName=%s CGI=%s\n", err,
+	    X509_verify_cert_error_string(err), depth, buf, myData->hostName, getenv("SCRIPT_NAME"));
 	}
     if (!sameString(getenv("https_cert_check"), "log"))
 	{
 	char *cn = strstr(buf, "/CN=");
 	if (cn) cn+=4;  // strlen /CN=
+	if (sameString(cn, myData->hostName))
 	    warn("%s on %s", X509_verify_cert_error_string(err), cn);
+	else
+	    warn("%s on %s (%s)", X509_verify_cert_error_string(err), cn, myData->hostName);
 	}
     }
 /* err contains the last verification error.  */
 if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))
     {
     X509_NAME_oneline(X509_get_issuer_name(cert), buf, 256);
     fprintf(stderr, "issuer= %s\n", buf);
     }
 if (sameString(getenv("https_cert_check"), "warn") || sameString(getenv("https_cert_check"), "log"))
     return 1;
 else
     return preverify_ok;
 }
 
 
@@ -493,30 +514,32 @@
 
 BIO *fbio=NULL;  // file descriptor bio
 BIO *sbio=NULL;  // ssl bio
 SSL_CTX *ctx;
 SSL *ssl;
 
 openSslInit();
 
 ctx = SSL_CTX_new(SSLv23_client_method());
 
 fd_set readfds;
 fd_set writefds;
 int err;
 struct timeval tv;
 
+struct myData myData;
+boolean doSetMyData = FALSE;
 
 if (!sameString(getenv("https_cert_check"), "none"))
     {
     if (checkIfInHashWithWildCard(hostName))
 	{
 	// old existing domains which are not (yet) compatible with openssl.
 	if (getenv("SCRIPT_NAME"))  // CGI mode
 	    {
 	    fprintf(stderr, "domain %s cert check skipped because it is white-listed as an exception.\n", hostName);
 	    }
 	}
     else
 	{
 
 	// verify peer cert of the server.
@@ -532,30 +555,35 @@
 
 	// verify_callback gets called once per certificate returned by the server.
 	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
 
 	/*
 	 * Let the verify_callback catch the verify_depth error so that we get
 	 * an appropriate error in the logfile.
 	 */
 	SSL_CTX_set_verify_depth(ctx, atoi(getenv("https_cert_check_depth")) + 1);
 
 	// VITAL FOR PROPER VERIFICATION OF CERTS
 	if (!SSL_CTX_set_default_verify_paths(ctx)) 
 	    {
 	    warn("SSL set default verify paths failed");
 	    }
+
+	// add the hostName to the structure and set it here, making it available during callback.
+	myData.hostName = hostName;
+	doSetMyData = TRUE;
+
 	} 
     }
 
 // Don't want any retries since we are non-blocking bio now
 // This is available on newer versions of openssl
 //SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
 
 
 // Support for Http Proxy
 struct netParsedUrl pxy;
 if (proxyUrl)
     {
     netParseUrl(proxyUrl, &pxy);
     if (!sameString(pxy.protocol, "http"))
 	{
@@ -612,30 +640,32 @@
     }
 sbio = BIO_new_ssl(ctx, 1);
 if (sbio == NULL) 
     {
     warn("BIO_new_ssl() failed");
     goto cleanup2;
     }
 sbio = BIO_push(sbio, fbio);
 BIO_get_ssl(sbio, &ssl);
 if(!ssl) 
     {
     warn("Can't locate SSL pointer");
     goto cleanup2;
     }
 
+if (doSetMyData)
+    SSL_set_ex_data(ssl, myDataIndex, &myData);
 
 /* 
 Server Name Indication (SNI)
 Required to complete tls ssl negotiation for systems which house multiple domains. (SNI)
 This is common when serving HTTPS requests with a wildcard certificate (*.domain.tld).
 This line will allow the ssl connection to send the hostname at tls negotiation time.
 It tells the remote server which hostname the client is connecting to.
 The hostname must not be an IP address.
 */ 
 if (!isIpv4Address(hostName) && !isIpv6Address(hostName))
     SSL_set_tlsext_host_name(ssl,hostName);
 
 BIO_set_nbio(sbio, 1);     /* non-blocking mode */
 
 while (1)