[exim-dev] [PATCH] allow to use server responses in client p…

Top Page
Delete this message
Reply to this message
Author: Johannes Berg
Date:  
To: exim-dev
Subject: [exim-dev] [PATCH] allow to use server responses in client plaintext authenticator
Hi,

For some experiments with different authentication algorithms I wanted
to implement them in exim -- on the server side this isn't too hard, but
on the client side it doesn't give me what the server said.

The following patch allows the use of $0, $1, ... in the client_send
variable and introduces a new option called client_ignore_invalid_base64
that controls whether base64 decoding errors on server responses are
ignored (current behaviour since it isn't even decoded) or not.

The patch also includes documentation updates, though I'm not sure the
format is correct.

I'd appreciate comments on this.

Thanks,
johannes

[patch follows]
--- exim4-4.60/doc/OptionLists.txt    2005-11-28 11:57:32.000000000 +0100
+++ exim4-4.60.mod/doc/OptionLists.txt    2006-02-20 13:28:35.710453000 +0100
@@ -124,6 +124,7 @@
 check_string                         string          "From "       appendfile        3.03
                                                      unset         pipe              3.03
 check_srv                            string*         unset         dnslookup         4.31
+client_ignore_invalid_base64         boolean         true          plaintext         XXXX
 client_name                          string*         +             cram_md5          3.10
 client_secret                        string*         unset         cram_md5          3.10
 client_send                          string*         unset         plaintext         3.10
--- exim4-4.60/doc/spec.txt    2006-02-20 13:15:43.794457000 +0100
+++ exim4-4.60.mod/doc/spec.txt    2006-02-20 16:22:08.627395000 +0100
@@ -19874,7 +19874,14 @@


34.5 Using plaintext in a client

-The plaintext authenticator has just one client option:
+The plaintext authenticator has two client options:
+
++-----------------------------------------------------------------------------+
+|client_ignore_invalid_base64 | Use: plaintext | Type: boolean | Default: true|
++-----------------------------------------------------------------------------+
+
+If this option is set, the client will not fail when the server sends invalid
+base64 encoded strings during the authentication.

 +-----------------------------------------------------------------------------+
 |client_send     |   Use: plaintext   |  Type: string*   |      Default: unset|
@@ -19914,6 +19921,12 @@
 The initial colon means that the first string is empty, so no data is sent with
 the AUTH command itself. The remaining strings are sent in response to prompts.


+Within the strings, the expansion variables $0, $1, ... are available with the
+server responses (only after those are sent, of course, so in the first part
+you cannot use any, in the second part you can use $0, in the third $0 and $1
+etc.). If client_ignore_invalid_base64 is set, a string that could not be
+decoded is empty instead.
+
35. The cram_md5 authenticator

 The CRAM-MD5 authentication mechanism is described in RFC 2195. The server
--- exim4-4.60/src/auths/plaintext.c    2005-11-28 11:57:32.000000000 +0100
+++ exim4-4.60.mod/src/auths/plaintext.c    2006-02-20 16:25:45.573393000 +0100
@@ -14,6 +14,8 @@
 /* Options specific to the plaintext authentication mechanism. */


 optionlist auth_plaintext_options[] = {
+  { "client_ignore_invalid_base64", opt_bool,
+      (void *)(offsetof(auth_plaintext_options_block, client_ignore_invalid_base64)) },
   { "client_send",        opt_stringptr,
       (void *)(offsetof(auth_plaintext_options_block, client_send)) },
   { "server_condition",   opt_stringptr,
@@ -33,7 +35,8 @@
 auth_plaintext_options_block auth_plaintext_option_defaults = {
   NULL,              /* server_condition */
   NULL,              /* server_prompts */
-  NULL               /* client_send */
+  NULL,              /* client_send */
+  FALSE              /* client_ignore_invalid_base64 */
 };



@@ -214,8 +217,11 @@

while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size)) != NULL)
{
- int i, len;
+ int i, len, clear_len;
uschar *ss = expand_string(s);
+ uschar *clear, *noclear = "";
+
+ expand_nmax = -1;

   /* Forced expansion failure is not an error; authentication is abandoned. On
   all but the first string, we have to abandon the authentication attempt by
@@ -295,6 +301,28 @@
       "authenticator", ablock->name);
     return ERROR;
     }
+
+  /* now that we know we'll continue, we put the received data into $n,
+   * if possible */
+  clear_len = auth_b64decode(buffer+4, &clear);
+  if (clear_len < 0) {
+    if (!ob->client_ignore_invalid_base64) {
+      /* the server sent an invalid base64 string...
+       * we should explicitly terminate this AUTH anyway */
+      if (smtp_write_command(outblock, FALSE, "*\r\n") >= 0)
+        (void) smtp_read_response(inblock, US buffer, buffsize, '2', timeout);
+      return FAIL;
+    }
+    /* ignore this and put an empty string into the $n var */
+    clear_len = 0;
+    clear = noclear;
+  }
+  if ((clear_len >= 0) && (expand_nmax < EXPAND_MAXN)) {
+    expand_nmax++;
+    expand_nstring[expand_nmax] = string_copy(clear);
+    expand_nlength[expand_nmax] = Ustrlen(expand_nstring[expand_nmax]);
+  }
+
   }


 /* Control should never actually get here. */
--- exim4-4.60/src/auths/plaintext.h    2005-11-28 11:57:32.000000000 +0100
+++ exim4-4.60.mod/src/auths/plaintext.h    2006-02-20 12:26:46.000000000 +0100
@@ -13,6 +13,7 @@
   uschar *server_condition;
   uschar *server_prompts;
   uschar *client_send;
+  BOOL    client_ignore_invalid_base64;
 } auth_plaintext_options_block;


/* Data for reading the private options. */