summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2006-02-23 12:41:22 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2006-02-23 12:41:22 +0000
commit4730f9424e0addeb902cc842508eea3f47a131ca (patch)
tree1aecf2add22e0e8206feb5ca136d626c765d294e
parented72ace5f09d07c620b96efaf72d328d6e7439be (diff)
Make server prompts available in $auth<n> when plaintext is running as a
client.
-rw-r--r--doc/doc-txt/ChangeLog11
-rw-r--r--doc/doc-txt/NewStuff15
-rw-r--r--doc/doc-txt/OptionLists.txt5
-rw-r--r--src/ACKNOWLEDGMENTS5
-rw-r--r--src/src/auths/README5
-rw-r--r--src/src/auths/cram_md5.c10
-rw-r--r--src/src/auths/plaintext.c45
-rw-r--r--src/src/auths/plaintext.h3
-rw-r--r--src/src/auths/spa.c4
-rw-r--r--src/src/transports/smtp.c9
-rw-r--r--test/confs/34015
-rw-r--r--test/confs/34041
-rw-r--r--test/log/340110
-rw-r--r--test/scripts/3400-plaintext/340146
-rw-r--r--test/scripts/3400-plaintext/34042
-rw-r--r--test/stdout/340148
-rw-r--r--test/stdout/34074
17 files changed, 209 insertions, 19 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 905e8d046..45ea2866d 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.312 2006/02/22 15:10:28 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.313 2006/02/23 12:41:22 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -227,6 +227,15 @@ PH/43 If retry_interval_max is set greater than 24 hours, it is quietly reset
PH/44 Added STRIP_COMMAND=/usr/bin/strip to the FreeBSD Makefile.
+PH/45 When the plaintext authenticator is running as a client, the server's
+ challenges are checked to ensure they are valid base64 strings. By
+ default, the authentication attempt is cancelled if an invalid string is
+ received. Setting client_ignore_invalid_base64 true ignores these errors.
+ The decoded challenge strings are now placed in $auth1, $auth2, etc. as
+ they are received. Thus, the responses can be made to depend on the
+ challenges. If an invalid string is ignored, an empty string is placed in
+ the variable.
+
Exim version 4.60
-----------------
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 14e08ee78..c807d931b 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.89 2006/02/22 15:08:20 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.90 2006/02/23 12:41:22 ph10 Exp $
New Features in Exim
--------------------
@@ -74,6 +74,19 @@ PH/11 If retry_interval_max is set greater than 24 hours, it is quietly reset
and H retry rules, and it seems reasonable to require a retry at least
once a day.
+PH/12 When the plaintext authenticator is running as a client, the server
+ challenges are now checked to ensure they are valid base64 strings. The
+ default action on failure is to abort the authentication. However, if
+ client_ignore_invalid_base64 is set true, invalid responses are ignored.
+
+PH/13 When the plaintext authenticator is running as a client, the challenges
+ from the server are placed in $auth1, $auth2, etc. as they are received.
+ Thus, the challege that is received in response to sending the first
+ string (with the AUTH command) can be used in the expansion of the second
+ string, and so on. Currently, up to 3 challenge strings are available in
+ this way. If an invalid base64 string is received when client_ignore_
+ invalid_base64 is set, an empty string is put in the $auth<n> variable.
+
Version 4.60
------------
diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
index 17627e41c..5e5815b42 100644
--- a/doc/doc-txt/OptionLists.txt
+++ b/doc/doc-txt/OptionLists.txt
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.17 2006/02/20 16:31:48 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.18 2006/02/23 12:41:22 ph10 Exp $
LISTS OF EXIM OPTIONS
---------------------
@@ -11,7 +11,7 @@ This file contains complete lists of four kinds of Exim option:
4. Those that can appear in the build time configuration for the Exim monitor
(Local/eximon.conf).
-This file was last updated for Exim release 4.60.
+This file was last updated for Exim release 4.61.
1. RUN TIME OPTIONS
@@ -124,6 +124,7 @@ check_spool_space integer 0 main
check_string string "From " appendfile 3.03
unset pipe 3.03
check_srv string* unset dnslookup 4.31
+client_ignore_invalid_base64 boolean false plaintext 4.61
client_name string* + cram_md5 3.10
client_secret string* unset cram_md5 3.10
client_send string* unset plaintext 3.10
diff --git a/src/ACKNOWLEDGMENTS b/src/ACKNOWLEDGMENTS
index b0285c65e..ce145ce21 100644
--- a/src/ACKNOWLEDGMENTS
+++ b/src/ACKNOWLEDGMENTS
@@ -1,4 +1,4 @@
-$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.41 2006/02/14 15:24:10 ph10 Exp $
+$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.42 2006/02/23 12:41:22 ph10 Exp $
EXIM ACKNOWLEDGEMENTS
@@ -20,7 +20,7 @@ relatively small patches.
Philip Hazel
Lists created: 20 November 2002
-Last updated: 13 February 2006
+Last updated: 23 February 2006
THE OLD LIST
@@ -71,6 +71,7 @@ Claus Assmann Example code for OpenSSL CRL support
Ian Bell Analysis of a bug and an infelicity in clock tick code
Patch for ${quote_local_part
Peter Benie A number mistakes found by analysing the code
+Johannes Berg Suggested patch for authentication client $auth<n> support
Matt Bernstein LMTP over socket
Suggested patch for dnslists '&' feature
Mike Bethune Help with debugging an elusive ALRM signal bug
diff --git a/src/src/auths/README b/src/src/auths/README
index 9143b9e91..780e15dc4 100644
--- a/src/src/auths/README
+++ b/src/src/auths/README
@@ -1,4 +1,4 @@
-$Cambridge: exim/src/src/auths/README,v 1.4 2006/02/10 14:25:43 ph10 Exp $
+$Cambridge: exim/src/src/auths/README,v 1.5 2006/02/23 12:41:22 ph10 Exp $
AUTHS
@@ -87,7 +87,8 @@ The yield of a client authentication check must be one of:
FAIL failed after reading a response;
either errno is set (for timeouts, I/O failures) or
the buffer contains the SMTP response line
- FORCEFAIL failed without reading a response (often "fail" in expansion)
+ CANCELLED the client cancelled authentication (often "fail" in expansion)
+ the buffer may contain a message; if not, *buffer = 0
ERROR local problem (typically expansion error); message in buffer
To communicate with the remote host the client should call
diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c
index 7b5598762..26521fbe9 100644
--- a/src/src/auths/cram_md5.c
+++ b/src/src/auths/cram_md5.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/auths/cram_md5.c,v 1.4 2006/02/10 14:25:43 ph10 Exp $ */
+/* $Cambridge: exim/src/src/auths/cram_md5.c,v 1.5 2006/02/23 12:41:22 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -250,7 +250,7 @@ auth_cram_md5_client(
smtp_inblock *inblock, /* input connection */
smtp_outblock *outblock, /* output connection */
int timeout, /* command timeout */
- uschar *buffer, /* for reading response */
+ uschar *buffer, /* for reading response */
int buffsize) /* size of buffer */
{
auth_cram_md5_options_block *ob =
@@ -266,7 +266,11 @@ or ERROR, as approriate. */
if (secret == NULL || name == NULL)
{
- if (expand_string_forcedfail) return CANCELLED;
+ if (expand_string_forcedfail)
+ {
+ *buffer = 0; /* No message */
+ return CANCELLED;
+ }
string_format(buffer, buffsize, "expansion of \"%s\" failed in "
"%s authenticator: %s",
(secret == NULL)? ob->client_secret : ob->client_name,
diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c
index e5f261a16..2aea4a492 100644
--- a/src/src/auths/plaintext.c
+++ b/src/src/auths/plaintext.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/auths/plaintext.c,v 1.4 2006/02/10 14:25:43 ph10 Exp $ */
+/* $Cambridge: exim/src/src/auths/plaintext.c,v 1.5 2006/02/23 12:41:22 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -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 @@ int auth_plaintext_options_count =
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 */
};
@@ -216,6 +219,7 @@ uschar *text = ob->client_send;
uschar *s;
BOOL first = TRUE;
int sep = 0;
+int auth_var_idx = 0;
/* The text is broken up into a number of different data items, which are
sent one by one. The first one is sent with the AUTH command; the remainder are
@@ -223,8 +227,9 @@ sent in response to subsequent prompts. Each is expanded before being sent. */
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;
/* Forced expansion failure is not an error; authentication is abandoned. On
all but the first string, we have to abandon the authentication attempt by
@@ -239,7 +244,11 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size)) != NULL
if (smtp_write_command(outblock, FALSE, "*\r\n") >= 0)
(void) smtp_read_response(inblock, US buffer, buffsize, '2', timeout);
}
- if (expand_string_forcedfail) return CANCELLED;
+ if (expand_string_forcedfail)
+ {
+ *buffer = 0; /* No message */
+ return CANCELLED;
+ }
string_format(buffer, buffsize, "expansion of \"%s\" failed in %s "
"authenticator: %s", ssave, ablock->name, expand_string_message);
return ERROR;
@@ -304,6 +313,34 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size)) != NULL
"authenticator", ablock->name);
return ERROR;
}
+
+ /* Now that we know we'll continue, we put the received data into $auth<n>,
+ if possible. First, decode it: buffer+4 skips over the SMTP status code. */
+
+ clear_len = auth_b64decode(buffer+4, &clear);
+
+ /* If decoding failed, the default is to terminate the authentication, and
+ return FAIL, with the SMTP response still in the buffer. However, if client_
+ ignore_invalid_base64 is set, we ignore the error, and put an empty string
+ into $auth<n>. */
+
+ if (clear_len < 0)
+ {
+ uschar *save_bad = string_copy(buffer);
+ if (!ob->client_ignore_invalid_base64)
+ {
+ if (smtp_write_command(outblock, FALSE, "*\r\n") >= 0)
+ (void)smtp_read_response(inblock, US buffer, buffsize, '2', timeout);
+ string_format(buffer, buffsize, "Invalid base64 string in server "
+ "response \"%s\"", save_bad);
+ return CANCELLED;
+ }
+ clear = US"";
+ clear_len = 0;
+ }
+
+ if (auth_var_idx < AUTH_VARS)
+ auth_vars[auth_var_idx++] = string_copy(clear);
}
/* Control should never actually get here. */
diff --git a/src/src/auths/plaintext.h b/src/src/auths/plaintext.h
index 46983d044..7499a01d8 100644
--- a/src/src/auths/plaintext.h
+++ b/src/src/auths/plaintext.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/auths/plaintext.h,v 1.3 2006/02/07 11:19:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/auths/plaintext.h,v 1.4 2006/02/23 12:41:22 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -13,6 +13,7 @@ typedef struct {
uschar *server_condition;
uschar *server_prompts;
uschar *client_send;
+ BOOL client_ignore_invalid_base64;
} auth_plaintext_options_block;
/* Data for reading the private options. */
diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c
index 264887607..3fd4bde6a 100644
--- a/src/src/auths/spa.c
+++ b/src/src/auths/spa.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/auths/spa.c,v 1.6 2006/02/10 14:25:43 ph10 Exp $ */
+/* $Cambridge: exim/src/src/auths/spa.c,v 1.7 2006/02/23 12:41:22 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -263,6 +263,8 @@ auth_spa_client(
/* Code added by PH to expand the options */
+ *buffer = 0; /* Default no message when cancelled */
+
username = CS expand_string(ob->spa_username);
if (username == NULL)
{
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 3c915a4e1..93cbd221f 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/smtp.c,v 1.21 2006/02/21 16:24:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/smtp.c,v 1.22 2006/02/23 12:41:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -1211,9 +1211,14 @@ if (continue_hostname == NULL
/* Failure by some other means. In effect, the authenticator
decided it wasn't prepared to handle this case. Typically this
is the result of "fail" in an expansion string. Do we need to
- log anything here? */
+ log anything here? Feb 2006: a message is now put in the buffer
+ if logging is required. */
case CANCELLED:
+ if (*buffer != 0)
+ log_write(0, LOG_MAIN, "%s authenticator cancelled "
+ "authentication H=%s [%s] %s", au->name, host->name,
+ host->address, buffer);
break;
/* Internal problem, message in buffer. */
diff --git a/test/confs/3401 b/test/confs/3401
index d2cf9c972..6406e3178 100644
--- a/test/confs/3401
+++ b/test/confs/3401
@@ -28,6 +28,11 @@ plain:
public_name = PLAIN
client_send = ^userx^secret
+xlogin:
+ driver = plaintext
+ public_name = XLOGIN
+ client_send = : $auth1 : $auth1+$auth2
+
# ----- Routers -----
diff --git a/test/confs/3404 b/test/confs/3404
index afff4bf73..dc556e961 100644
--- a/test/confs/3404
+++ b/test/confs/3404
@@ -27,6 +27,7 @@ login:
driver = plaintext
public_name = LOGIN
client_send = :userx:secret
+ client_ignore_invalid_base64
# ----- Routers -----
diff --git a/test/log/3401 b/test/log/3401
index dad29127a..30e4b45bc 100644
--- a/test/log/3401
+++ b/test/log/3401
@@ -29,3 +29,13 @@
1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmbF-0005vi-00 => forcesender@domain.com R=try T=smtp_try H=127.0.0.1 [127.0.0.1]
1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbG-0005vi-00 login authenticator cancelled authentication H=127.0.0.1 [127.0.0.1] Invalid base64 string in server response "334 User?"
+1999-03-02 09:44:33 10HmbG-0005vi-00 ** userx@domain.com R=try T=smtp_try: SMTP error from remote mail server after MAIL FROM:<CALLER@myhost.test.ex>: host 127.0.0.1 [127.0.0.1]: 550 Not now
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= <> R=10HmbG-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmbH-0005vi-00 ** CALLER@myhost.test.ex: Unrouteable address
+1999-03-02 09:44:33 10HmbH-0005vi-00 Frozen (delivery error message)
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbI-0005vi-00 => userx@domain.com R=try T=smtp_try H=127.0.0.1 [127.0.0.1]
+1999-03-02 09:44:33 10HmbI-0005vi-00 Completed
diff --git a/test/scripts/3400-plaintext/3401 b/test/scripts/3400-plaintext/3401
index b3e7c6a0a..590ae4333 100644
--- a/test/scripts/3400-plaintext/3401
+++ b/test/scripts/3400-plaintext/3401
@@ -138,4 +138,50 @@ QUIT
exim -odi forcesender@domain.com
.
****
+# Bad basd64 from server; client aborts
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250-HELP
+250 AUTH LOGIN
+AUTH LOGIN
+334 User?
+*
+501 Authentication cancelled
+MAIL FROM:
+550 Not now
+QUIT
+250 OK
+****
+exim -odi userx@domain.com
+.
+****
+# Test the server challenges in $auth<n>
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250-HELP
+250 AUTH XLOGIN
+AUTH XLOGIN
+334 Y2hhbGxlbmdlLTE=
+Y2hhbGxlbmdlLTE=
+334 YW5vdGhlcm9uZQ==
+Y2hhbGxlbmdlLTErYW5vdGhlcm9uZQ==
+235 Authentication successful
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 Recipient OK
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+****
+exim -odi userx@domain.com
+.
+****
no_msglog_check
diff --git a/test/scripts/3400-plaintext/3404 b/test/scripts/3400-plaintext/3404
index 98f737eac..6f67b8512 100644
--- a/test/scripts/3400-plaintext/3404
+++ b/test/scripts/3400-plaintext/3404
@@ -45,6 +45,8 @@ QUIT
exim -v -oMas xxx@yyy -oMai zzz -odi userx@domain.com
.
****
+# The server prompts sent here are not b64 encoded; hence they test
+# client_ignore_invalid_base64.
server PORT_S
220 ESMTP
EHLO
diff --git a/test/stdout/3401 b/test/stdout/3401
index fdaf26cd6..fda6814c5 100644
--- a/test/stdout/3401
+++ b/test/stdout/3401
@@ -150,3 +150,51 @@ Date: Tue, 2 Mar 1999 09:44:33 +0000
QUIT
250 OK
End of script
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 ESMTP
+EHLO myhost.test.ex
+250-OK
+250-HELP
+250 AUTH LOGIN
+AUTH LOGIN
+334 User?
+*
+501 Authentication cancelled
+MAIL FROM:<CALLER@myhost.test.ex>
+550 Not now
+QUIT
+250 OK
+End of script
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 ESMTP
+EHLO myhost.test.ex
+250-OK
+250-HELP
+250 AUTH XLOGIN
+AUTH XLOGIN
+334 Y2hhbGxlbmdlLTE=
+Y2hhbGxlbmdlLTE=
+334 YW5vdGhlcm9uZQ==
+Y2hhbGxlbmdlLTErYW5vdGhlcm9uZQ==
+235 Authentication successful
+MAIL FROM:<CALLER@myhost.test.ex> AUTH=CALLER@myhost.test.ex
+250 Sender OK
+RCPT TO:<userx@domain.com>
+250 Recipient OK
+DATA
+354 Send data
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbI-0005vi-00
+ for userx@domain.com; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbI-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+.
+250 OK
+QUIT
+250 OK
+End of script
diff --git a/test/stdout/3407 b/test/stdout/3407
index 3888ec9ed..d08999e28 100644
--- a/test/stdout/3407
+++ b/test/stdout/3407
@@ -6,6 +6,7 @@ server_advertise_condition =
server_debug_print =
server_mail_auth_condition =
server_set_id =
+no_client_ignore_invalid_base64
client_send =
server_condition = xxx
server_prompts =
@@ -17,6 +18,7 @@ server_advertise_condition =
server_debug_print =
server_mail_auth_condition =
server_set_id =
+no_client_ignore_invalid_base64
client_send =
server_condition =
server_prompts =
@@ -28,6 +30,7 @@ server_advertise_condition =
server_debug_print =
server_mail_auth_condition =
server_set_id =
+no_client_ignore_invalid_base64
client_send =
server_condition =
server_prompts =
@@ -39,6 +42,7 @@ server_advertise_condition =
server_debug_print =
server_mail_auth_condition =
server_set_id =
+no_client_ignore_invalid_base64
client_send =
server_condition =
server_prompts =