GnuTLS: debug output for how to get TLS 1.3 keying
[exim.git] / src / src / tls-openssl.c
index d37c789704336c119e09a62b76bec61c3c588a00..c7b22a0db3e490a92ded847f197e470c428518b3 100644 (file)
@@ -114,7 +114,9 @@ change this guard and punt the issue for a while longer. */
 # ifndef EXIM_HAVE_OPENSSL_CIPHER_GET_ID
 #  define SSL_CIPHER_get_id(c) (c->id)
 # endif
-# include "tls-cipher-stdname.c"
+# ifndef MACRO_PREDEF
+#  include "tls-cipher-stdname.c"
+# endif
 #endif
 
 /*************************************************
@@ -289,6 +291,7 @@ Server:
 typedef struct {
   SSL_CTX *    ctx;
   SSL *                ssl;
+  gstring *    corked;
 } exim_openssl_client_tls_ctx;
 
 static SSL_CTX *server_ctx = NULL;
@@ -2344,12 +2347,8 @@ DEBUG(D_tls)
 
 #ifdef EXIM_HAVE_OPENSSL_KEYLOG
   {
-  BIO * bp = BIO_new(BIO_s_mem());
-  uschar * s;
-  int len;
+  BIO * bp = BIO_new_fp(debug_file, BIO_NOCLOSE);
   SSL_SESSION_print_keylog(bp, SSL_get_session(server_ssl));
-  len = (int) BIO_get_mem_data(bp, CSS &s);
-  debug_printf("%.*s", len, s);
   BIO_free(bp);
   }
 #endif
@@ -2523,6 +2522,7 @@ BOOL require_ocsp = FALSE;
 rc = store_pool;
 store_pool = POOL_PERM;
 exim_client_ctx = store_get(sizeof(exim_openssl_client_tls_ctx));
+exim_client_ctx->corked = NULL;
 store_pool = rc;
 
 #ifdef SUPPORT_DANE
@@ -2722,18 +2722,9 @@ DEBUG(D_tls)
   debug_printf("SSL_connect succeeded\n");
 #ifdef EXIM_HAVE_OPENSSL_KEYLOG
   {
-  BIO * bp = BIO_new(BIO_s_mem());
-  if (bp)
-    {
-    uschar * s;
-    int len;
-    SSL_SESSION_print_keylog(bp, SSL_get_session(exim_client_ctx->ssl));
-    len = (int) BIO_get_mem_data(bp, CSS &s);
-    debug_printf("%.*s", len, s);
-    BIO_free(bp);
-    }
-  else
-    debug_printf("(alloc failure for keylog)\n");
+  BIO * bp = BIO_new_fp(debug_file, BIO_NOCLOSE);
+  SSL_SESSION_print_keylog(bp, SSL_get_session(exim_client_ctx->ssl));
+  BIO_free(bp);
   }
 #endif
   }
@@ -2979,8 +2970,12 @@ tls_write(void * ct_ctx, const uschar *buff, size_t len, BOOL more)
 {
 size_t olen = len;
 int outbytes, error;
-SSL * ssl = ct_ctx ? ((exim_openssl_client_tls_ctx *)ct_ctx)->ssl : server_ssl;
-static gstring * corked = NULL;
+SSL * ssl = ct_ctx
+  ? ((exim_openssl_client_tls_ctx *)ct_ctx)->ssl : server_ssl;
+static gstring * server_corked = NULL;
+gstring ** corkedp = ct_ctx
+  ? &((exim_openssl_client_tls_ctx *)ct_ctx)->corked : &server_corked;
+gstring * corked = *corkedp;
 
 DEBUG(D_tls) debug_printf("%s(%p, %lu%s)\n", __FUNCTION__,
   buff, (unsigned long)len, more ? ", more" : "");
@@ -2988,7 +2983,9 @@ DEBUG(D_tls) debug_printf("%s(%p, %lu%s)\n", __FUNCTION__,
 /* Lacking a CORK or MSG_MORE facility (such as GnuTLS has) we copy data when
 "more" is notified.  This hack is only ok if small amounts are involved AND only
 one stream does it, in one context (i.e. no store reset).  Currently it is used
-for the responses to the received SMTP MAIL , RCPT, DATA sequence, only. */
+for the responses to the received SMTP MAIL , RCPT, DATA sequence, only.
+We support callouts done by the server process by using a separate client
+context for the stashed information. */
 /* + if PIPE_COMMAND, banner & ehlo-resp for smmtp-on-connect. Suspect there's
 a store reset there, so use POOL_PERM. */
 /* + if CHUNKING, cmds EHLO,MAIL,RCPT(s),BDAT */
@@ -3007,10 +3004,13 @@ if ((more || corked))
 #endif
 
   if (more)
+    {
+    *corkedp = corked;
     return len;
+    }
   buff = CUS corked->s;
   len = corked->ptr;
-  corked = NULL;
+  *corkedp = NULL;
   }
 
 for (int left = len; left > 0;)
@@ -3415,8 +3415,8 @@ for (uschar * s = option_spec; *s != '\0'; /**/)
     DEBUG(D_tls) debug_printf("openssl option setting unrecognised: \"%s\"\n", s);
     return FALSE;
     }
-  DEBUG(D_tls) debug_printf("openssl option, %s from %lx: %lx (%s)\n",
-      adding ? "adding" : "removing", result, item, s);
+  DEBUG(D_tls) debug_printf("openssl option, %s %8lx: %lx (%s)\n",
+      adding ? "adding to    " : "removing from", result, item, s);
   if (adding)
     result |= item;
   else