Patch to fix Cyrus-SASL unavailable mechanisms problem.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Tue, 5 Apr 2005 14:33:27 +0000 (14:33 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Tue, 5 Apr 2005 14:33:27 +0000 (14:33 +0000)
doc/doc-txt/ChangeLog
src/ACKNOWLEDGMENTS
src/src/auths/cyrus_sasl.c

index 8a72744..d5c6581 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.109 2005/04/05 14:02:30 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.110 2005/04/05 14:33:27 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -125,6 +125,31 @@ PH/22 Added support for macro redefinition, and (re)definition in between
 PH/23 The cyrus_sasl authenticator was expanding server_hostname, but then
       forgetting to use the resulting value; it was using the unexpanded value.
 
+PH/24 The cyrus_sasl authenticator was advertising mechanisms for which it
+      hadn't been configured. The fix is from Juergen Kreileder, who
+      understands it better than I do:
+
+      "Here's what I see happening with three configured cyrus_sasl
+      authenticators configured (plain, login, cram-md5):
+
+      On startup auth_cyrus_sasl_init() gets called for each of these.
+      This means three calls to sasl_listmech() without a specified mech_list.
+      => SASL tests which mechs of all available mechs actually work
+      => three warnings about OTP not working
+      => the returned list contains: plain, login, cram-md5, digest-md5, ...
+
+      With the patch, sasl_listmech() also gets called three times.  But now
+      SASL's mech_list option is set to the server_mech specified in the the
+      authenticator.  Or in other words, the answer from sasl_listmech()
+      gets limited to just the mech you're testing for (which is different
+      for each call.)
+      => the return list contains just 'plain' or 'login', 'cram-md5' or
+      nothing depending on the value of ob->server_mech.
+
+      I've just tested the patch: Authentication still works fine,
+      unavailable mechs specified in the exim configuration are still
+      caught, and the auth.log warnings about OTP are gone."
+
 
 A note about Exim versions 4.44 and 4.50
 ----------------------------------------
index ce5402e..86bc64f 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.19 2005/04/05 13:58:35 ph10 Exp $
+$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.20 2005/04/05 14:33:27 ph10 Exp $
 
 EXIM ACKNOWLEDGEMENTS
 
@@ -159,6 +159,7 @@ Alex Kiernan              Patch for libradius
 Tom Kistner               SPA server code
                           Writing and maintaining the content scanning
                             extension (exiscan)
+J├╝rgen Kreileder          Fix for cyrus_sasl advertisement problem
 Friso Kuipers             Patch for GDBM problem
 Chris Liddiard            Fix for bug in exiqsumm
 Chris Lightfoot           Patch for -restore-times in exim_lock
index 849c3d1..8651dc6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/auths/cyrus_sasl.c,v 1.2 2005/04/05 14:02:30 ph10 Exp $ */
+/* $Cambridge: exim/src/src/auths/cyrus_sasl.c,v 1.3 2005/04/05 14:33:27 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -7,7 +7,7 @@
 /* Copyright (c) University of Cambridge 1995 - 2003 */
 /* See the file NOTICE for conditions of use and distribution. */
 
-/* This code was contributed by Matthew Byng-Maddick */
+/* This code was originally contributed by Matthew Byng-Maddick */
 
 /* Copyright (c) A L Digital 2004 */
 
@@ -71,18 +71,42 @@ auth_cyrus_sasl_options_block auth_cyrus_sasl_option_defaults = {
 enable consistency checks to be done, or anything else that needs
 to be set up. */
 
+
+/* Auxiliary function, passed in data to sasl_server_init(). */
+
+static int
+mysasl_config(void *context,
+              const char *plugin_name,
+              const char *option,
+              const char **result,
+              unsigned int *len)
+{
+if (context && !strcmp(option, "mech_list"))
+  {
+  *result = context;
+  if (len != NULL) *len = strlen(*result);
+  return SASL_OK;
+  }
+return SASL_FAIL;
+}
+
+/* Here's the real function */
+
 void
 auth_cyrus_sasl_init(auth_instance *ablock)
 {
 auth_cyrus_sasl_options_block *ob =
   (auth_cyrus_sasl_options_block *)(ablock->options_block);
-sasl_callback_t cbs[]={{SASL_CB_LIST_END, NULL, NULL}};
-sasl_conn_t *conn;
 uschar *list, *listptr, *buffer;
 int rc, i;
 unsigned int len;
 uschar *rs_point;
 
+sasl_conn_t *conn;
+sasl_callback_t cbs[]={
+  {SASL_CB_GETOPT, NULL, NULL },
+  {SASL_CB_LIST_END, NULL, NULL}};
+
 /* default the mechanism to our "public name" */
 if(ob->server_mech == NULL)
   ob->server_mech=string_copy(ablock->public_name);
@@ -90,7 +114,12 @@ if(ob->server_mech == NULL)
 /* we're going to initialise the library to check that there is an
  * authenticator of type whatever mechanism we're using
  */
+
+cbs[0].proc = &mysasl_config;
+cbs[0].context = ob->server_mech;
+
 rc=sasl_server_init(cbs, "exim");
+
 if( rc != SASL_OK )
   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator:  "
       "couldn't initialise Cyrus SASL library.", ablock->name);