GSASL: feature macro
[users/jgh/exim.git] / src / src / auths / gsasl_exim.c
index db14a40e0ad2fe6b8117a6d23034d760f58909d9..7003b0cbb01183b631ce598c6a0f0b8fc4b021b8 100644 (file)
@@ -44,6 +44,11 @@ static void dummy(int x) { dummy2(x-1); }
 #endif
 
 
+#if GSASL_VERSION_MINOR >= 9
+# define EXIM_GSASL_HAVE_SCRAM_SHA_256
+#endif
+
+
 /* Authenticator-specific options. */
 /* I did have server_*_condition options for various mechanisms, but since
 we only ever handle one mechanism at a time, I didn't see the point in keeping
@@ -96,10 +101,18 @@ auth_gsasl_options_block auth_gsasl_option_defaults = {
 /* Dummy values */
 void auth_gsasl_init(auth_instance *ablock) {}
 int auth_gsasl_server(auth_instance *ablock, uschar *data) {return 0;}
-int auth_gsasl_client(auth_instance *ablock, smtp_inblock * sx,
+int auth_gsasl_client(auth_instance *ablock, void * sx,
   int timeout, uschar *buffer, int buffsize) {return 0;}
 void auth_gsasl_version_report(FILE *f) {}
 
+void
+auth_gsasl_macros(void)
+{
+# ifdef EXIM_GSASL_HAVE_SCRAM_SHA_256
+  builtin_macro_create(US"_HAVE_AUTH_GSASL_SCRAM_SHA_256");
+# endif
+}
+
 #else   /*!MACRO_PREDEF*/
 
 
@@ -301,14 +314,24 @@ HDEBUG(D_auth)
       ablock->name, ob->server_mech);
 
 #ifndef DISABLE_TLS
+if (tls_in.channelbinding && ob->server_channelbinding)
+  {
+# ifdef EXPERIMENTAL_TLS_RESUME
+  if (!tls_in.ext_master_secret && tls_in.resumption == RESUME_USED)
+    {          /* per RFC 7677 section 4 */
+    HDEBUG(D_auth) debug_printf(
+      "channel binding not usable on resumed TLS without extended-master-secret");
+    return FAIL;
+    }
+# endif
 # ifdef CHANNELBIND_HACK
 /* This is a gross hack to get around the library a) requiring that
 c-b was already set, at the _start() call, and b) caching a b64'd
 version of the binding then which it never updates. */
 
-if (tls_in.channelbinding && ob->server_channelbinding)
   gsasl_callback_hook_set(gsasl_ctx, tls_in.channelbinding);
 # endif
+  }
 #endif
 
 if ((rc = gsasl_server_start(gsasl_ctx, CCS ob->server_mech, &sctx)) != GSASL_OK)
@@ -362,7 +385,7 @@ if (tls_in.channelbinding)
     {
     HDEBUG(D_auth) debug_printf("Auth %s: Enabling channel-binding\n",
        ablock->name);
-# ifdef CHANNELBIND_HACK
+# ifndef CHANNELBIND_HACK
     gsasl_property_set(sctx, GSASL_CB_TLS_UNIQUE, CCS tls_in.channelbinding);
 # endif
     }
@@ -720,7 +743,7 @@ return TRUE;
 int
 auth_gsasl_client(
   auth_instance *ablock,               /* authenticator block */
-  smtp_inblock * sx,                   /* connection */
+  void * sx,                           /* connection */
   int timeout,                         /* command timeout */
   uschar *buffer,                      /* buffer for reading response */
   int buffsize)                                /* size of buffer */
@@ -740,13 +763,24 @@ HDEBUG(D_auth)
 *buffer = 0;
 
 #ifndef DISABLE_TLS
-/* This is a gross hack to get around the library a) requiring that
-c-b was already set, at the _start() call, and b) caching a b64'd
-version of the binding then which it never updates. */
+if (tls_out.channelbinding && ob->client_channelbinding)
+  {
+# ifdef EXPERIMENTAL_TLS_RESUME
+  if (!tls_out.ext_master_secret && tls_out.resumption == RESUME_USED)
+    {          /* per RFC 7677 section 4 */
+    string_format(buffer, buffsize, "%s",
+      "channel binding not usable on resumed TLS without extended-master-secret");
+    return FAIL;
+    }
+# endif
+# ifdef CHANNELBIND_HACK
+  /* This is a gross hack to get around the library a) requiring that
+  c-b was already set, at the _start() call, and b) caching a b64'd
+  version of the binding then which it never updates. */
 
-if (tls_out.channelbinding)
-  if (ob->client_channelbinding)
-    gsasl_callback_hook_set(gsasl_ctx, tls_out.channelbinding);
+  gsasl_callback_hook_set(gsasl_ctx, tls_out.channelbinding);
+# endif
+  }
 #endif
 
 if ((rc = gsasl_client_start(gsasl_ctx, CCS ob->server_mech, &sctx)) != GSASL_OK)
@@ -780,7 +814,7 @@ if (tls_out.channelbinding)
     {
     HDEBUG(D_auth) debug_printf("Auth %s: Enabling channel-binding\n",
        ablock->name);
-# ifdef CHANNELBIND_HACK
+# ifndef CHANNELBIND_HACK
     gsasl_property_set(sctx, GSASL_CB_TLS_UNIQUE, CCS tls_out.channelbinding);
 # endif
     }
@@ -884,6 +918,11 @@ fprintf(f, "Library version: GNU SASL: Compile: %s\n"
        GSASL_VERSION, runtime);
 }
 
+
+
+/* Dummy */
+void auth_gsasl_macros(void) {}
+
 #endif   /*!MACRO_PREDEF*/
 #endif  /* AUTH_GSASL */