X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/14a806d6c13afdfb2f44dce64e50bffa6cb6869c..HEAD:/src/src/auths/get_data.c diff --git a/src/src/auths/get_data.c b/src/src/auths/get_data.c index 8a05a82e4..3a9a0a46a 100644 --- a/src/src/auths/get_data.c +++ b/src/src/auths/get_data.c @@ -2,8 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim Maintainers 2020 - 2024 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" @@ -31,7 +33,7 @@ else uschar * clear, * end; int len; - if ((len = b64decode(data, &clear)) < 0) return BAD64; + if ((len = b64decode(data, &clear, GET_TAINTED)) < 0) return BAD64; DEBUG(D_auth) debug_printf("auth input decode:"); for (end = clear + len; clear < end && expand_nmax < EXPAND_MAXN; ) { @@ -53,17 +55,21 @@ return OK; * Issue a challenge and get a response * *************************************************/ -/* This function is used by authentication drivers to output a challenge -to the SMTP client and read the response line. +/* This function is used by authentication drivers to b64-encode and +output a challenge to the SMTP client, and read the response line. Arguments: aptr set to point to the response (which is in big_buffer) - challenge the challenge text (unencoded, may be binary) - challen the length of the challenge text + challenge the challenge data (unencoded, may be binary) + challen the length of the challenge data, in bytes Returns: OK on success BAD64 if response too large for buffer CANCELLED if response is "*" + +NOTE: the data came from the wire so should be tainted - but +big_buffer is not taint-tracked. EVERY CALLER needs to apply +tainting. */ int @@ -71,7 +77,7 @@ auth_get_data(uschar ** aptr, const uschar * challenge, int challen) { int c; int p = 0; -smtp_printf("334 %s\r\n", FALSE, b64encode(challenge, challen)); +smtp_printf("334 %s\r\n", SP_NO_MORE, b64encode(challenge, challen)); while ((c = receive_getc(GETC_BUFFER_UNLIMITED)) != '\n' && c != EOF) { if (p >= big_buffer_size - 1) return BAD64; @@ -95,7 +101,7 @@ uschar * resp, * clear, * end; if ((rc = auth_get_data(&resp, challenge, Ustrlen(challenge))) != OK) return rc; -if ((len = b64decode(resp, &clear)) < 0) +if ((len = b64decode(resp, &clear, GET_TAINTED)) < 0) return BAD64; end = clear + len; @@ -160,21 +166,27 @@ if (!ss) return CANCELLED; } string_format(buffer, buffsize, "expansion of \"%s\" failed in %s " - "authenticator: %s", *inout, ablock->name, expand_string_message); + "authenticator: %s", *inout, ablock->drinst.name, expand_string_message); return ERROR; } len = Ustrlen(ss); /* The character ^ is used as an escape for a binary zero character, which is -needed for the PLAIN mechanism. It must be doubled if really needed. */ +needed for the PLAIN mechanism. It must be doubled if really needed. + +The parsing ambiguity of ^^^ is taken as ^^ -> ^ ; ^ -> NUL - and there is +no way to get a leading ^ after a NUL. We would need to intro new syntax to +support that (probably preferring to take a more-standard exim list as a source +and concat the elements with intervening NULs. Either a magic marker on the +source string for client_send, or a new option). */ for (int i = 0; i < len; i++) if (ss[i] == '^') if (ss[i+1] != '^') ss[i] = 0; else - if (--len > ++i) memmove(ss + i, ss + i + 1, len - i); + if (--len > i+1) memmove(ss + i + 1, ss + i + 2, len - i); /* The first string is attached to the AUTH command; others are sent unembellished. */ @@ -213,14 +225,14 @@ if (flags & AUTH_ITEM_LAST) if (smtp_write_command(sx, SCMD_FLUSH, "*\r\n") >= 0) (void)smtp_read_response(sx, US buffer, buffsize, '2', timeout); string_format(buffer, buffsize, "Too few items in client_send in %s " - "authenticator", ablock->name); + "authenticator", ablock->drinst.name); return ERROR; } /* Now that we know we'll continue, we put the received data into $auth, if possible. First, decode it: buffer+4 skips over the SMTP status code. */ -clear_len = b64decode(buffer+4, &clear); +clear_len = b64decode(buffer+4, &clear, buffer+4); /* If decoding failed, the default is to terminate the authentication, and return FAIL, with the SMTP response still in the buffer. However, if client_