]> git.netwichtig.de Git - user/henk/code/exim.git/blobdiff - src/src/tls-gnu.c
TLS: restore TLS protocol version to default Received: header
[user/henk/code/exim.git] / src / src / tls-gnu.c
index 13bf905a0153a836f5be183c8986ff43abd0165b..fc426a25114b4f00ad3ac94f7cc92c6a517dea28 100644 (file)
@@ -70,6 +70,16 @@ require current GnuTLS, then we'll drop support for the ancient libraries).
 #if GNUTLS_VERSION_NUMBER >= 0x03010a
 # define SUPPORT_GNUTLS_SESS_DESC
 #endif
+#if GNUTLS_VERSION_NUMBER >= 0x030300
+# define GNUTLS_AUTO_GLOBAL_INIT
+# define GNUTLS_AUTO_PKCS11_MANUAL
+#endif
+#if (GNUTLS_VERSION_NUMBER >= 0x030404) \
+  || (GNUTLS_VERSION_NUMBER >= 0x030311) && (GNUTLS_VERSION_NUMBER & 0xffff00 == 0x030300)
+# ifndef DISABLE_OCSP
+#  define EXIM_HAVE_OCSP
+# endif
+#endif
 #if GNUTLS_VERSION_NUMBER >= 0x030500
 # define SUPPORT_GNUTLS_KEYLOG
 #endif
@@ -123,6 +133,12 @@ builtin_macro_create_var(US"_RESUME_DECODE", RESUME_DECODE_STRING );
 # ifdef EXIM_HAVE_TLS1_3
 builtin_macro_create(US"_HAVE_TLS1_3");
 # endif
+# ifdef EXIM_HAVE_OCSP
+builtin_macro_create(US"_HAVE_TLS_OCSP");
+# endif
+# ifdef SUPPORT_SRV_OCSP_STACK
+builtin_macro_create(US"_HAVE_TLS_OCSP_LIST");
+# endif
 }
 #else
 
@@ -464,6 +480,7 @@ Sets:
   tls_bits                  strength indicator
   tls_certificate_verified  bool indicator
   tls_channelbinding_b64    for some SASL mechanisms
+  tls_ver                   a string
   tls_cipher                a string
   tls_peercert              pointer to library internal
   tls_peerdn                a string
@@ -1497,7 +1514,7 @@ if (!exim_gnutls_base_init_done)
   {
   DEBUG(D_tls) debug_printf("GnuTLS global init required.\n");
 
-#ifdef HAVE_GNUTLS_PKCS11
+#if defined(HAVE_GNUTLS_PKCS11) && !defined(GNUTLS_AUTO_PKCS11_MANUAL)
   /* By default, gnutls_global_init will init PKCS11 support in auto mode,
   which loads modules from a config file, which sounds good and may be wanted
   by some sysadmin, but also means in common configurations that GNOME keyring
@@ -1508,8 +1525,10 @@ if (!exim_gnutls_base_init_done)
       return tls_error_gnu(US"gnutls_pkcs11_init", rc, host, errstr);
 #endif
 
+#ifndef GNUTLS_AUTO_GLOBAL_INIT
   if ((rc = gnutls_global_init()))
     return tls_error_gnu(US"gnutls_global_init", rc, host, errstr);
+#endif
 
 #if EXIM_GNUTLS_LIBRARY_LOG_LEVEL >= 0
   DEBUG(D_tls)
@@ -1748,11 +1767,17 @@ old_pool = store_pool;
     /* debug_printf("peer_status: gnutls_session_get_desc %s\n", s); */
 
     for (s++; (c = *s) && c != ')'; s++) g = string_catn(g, s, 1);
+
+    tlsp->ver = string_copyn(g->s, g->ptr);
+    for (uschar * p = US tlsp->ver; *p; p++)
+      if (*p == '-') { *p = '\0'; break; }     /* TLS1.0-PKIX -> TLS1.0 */
+
     g = string_catn(g, US":", 1);
     if (*s) s++;               /* now on _ between groups */
     while ((c = *s))
       {
-      for (*++s && ++s; (c = *s) && c != ')'; s++) g = string_catn(g, c == '-' ? US"_" : s, 1);
+      for (*++s && ++s; (c = *s) && c != ')'; s++)
+       g = string_catn(g, c == '-' ? US"_" : s, 1);
       /* now on ) closing group */
       if ((c = *s) && *++s == '-') g = string_catn(g, US"__", 2);
       /* now on _ between groups */
@@ -1772,6 +1797,8 @@ old_pool = store_pool;
   releases did return "TLS 1.0"; play it safe, just in case. */
 
   for (uschar * p = state->ciphersuite; *p; p++) if (isspace(*p)) *p = '-';
+  tlsp->ver = string_copyn(state->ciphersuite,
+                       Ustrchr(state->ciphersuite, ':') - state->ciphersuite);
 #endif
 
 /* debug_printf("peer_status: ciphersuite %s\n", state->ciphersuite); */
@@ -2252,17 +2279,17 @@ post_handshake_debug(exim_gnutls_state_st * state)
 #ifdef SUPPORT_GNUTLS_SESS_DESC
 debug_printf("%s\n", gnutls_session_get_desc(state->session));
 #endif
-#ifdef SUPPORT_GNUTLS_KEYLOG
 
+#ifdef SUPPORT_GNUTLS_KEYLOG
 # ifdef EXIM_HAVE_TLS1_3
 if (gnutls_protocol_get_version(state->session) < GNUTLS_TLS1_3)
-#else
+# else
 if (TRUE)
-#endif
+# endif
   {
   gnutls_datum_t c, s;
   gstring * gc, * gs;
-  /* we only want the client random and the master secret */
+  /* For TLS1.2 we only want the client random and the master secret */
   gnutls_session_get_random(state->session, &c, &s);
   gnutls_session_get_master_secret(state->session, &s);
   gc = ddump(&c);
@@ -2275,7 +2302,8 @@ else
     " add SSLKEYLOGFILE to keep_environment in the exim config\n"
     " run exim as root\n"
     " if using sudo, add SSLKEYLOGFILE to env_keep in /etc/sudoers\n"
-    " (works for TLS1.2 also, and saves cut-paste into file)\n");
+    " (works for TLS1.2 also, and saves cut-paste into file)"
+    " Trying to use add_environment for this will not work\n");
 #endif
 }
 
@@ -3417,24 +3445,33 @@ gnutls_priority_t priority_cache;
 const char *errpos;
 uschar * dummy_errstr;
 
-#define validate_check_rc(Label) do { \
+#ifdef GNUTLS_AUTO_GLOBAL_INIT
+# define validate_check_rc(Label) do { \
+  if (rc != GNUTLS_E_SUCCESS) { if (exim_gnutls_base_init_done) \
+    return string_sprintf("%s failed: %s", (Label), gnutls_strerror(rc)); } } while (0)
+# define return_deinit(Label) do { return (Label); } while (0)
+#else
+# define validate_check_rc(Label) do { \
   if (rc != GNUTLS_E_SUCCESS) { if (exim_gnutls_base_init_done) gnutls_global_deinit(); \
-  return string_sprintf("%s failed: %s", (Label), gnutls_strerror(rc)); } } while (0)
-#define return_deinit(Label) do { gnutls_global_deinit(); return (Label); } while (0)
+    return string_sprintf("%s failed: %s", (Label), gnutls_strerror(rc)); } } while (0)
+# define return_deinit(Label) do { gnutls_global_deinit(); return (Label); } while (0)
+#endif
 
 if (exim_gnutls_base_init_done)
   log_write(0, LOG_MAIN|LOG_PANIC,
       "already initialised GnuTLS, Exim developer bug");
 
-#ifdef HAVE_GNUTLS_PKCS11
+#if defined(HAVE_GNUTLS_PKCS11) && !defined(GNUTLS_AUTO_PKCS11_MANUAL)
 if (!gnutls_allow_auto_pkcs11)
   {
   rc = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
   validate_check_rc(US"gnutls_pkcs11_init");
   }
 #endif
+#ifndef GNUTLS_AUTO_GLOBAL_INIT
 rc = gnutls_global_init();
 validate_check_rc(US"gnutls_global_init()");
+#endif
 exim_gnutls_base_init_done = TRUE;
 
 if (!(tls_require_ciphers && *tls_require_ciphers))
@@ -3457,7 +3494,9 @@ validate_check_rc(string_sprintf(
 
 #undef return_deinit
 #undef validate_check_rc
+#ifndef GNUTLS_AUTO_GLOBAL_INIT
 gnutls_global_deinit();
+#endif
 
 return NULL;
 }