Backport of: From dd46b5417809647f561d8a5e0e74c3aacd235258 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Tue, 21 May 2019 21:31:31 +0000 Subject: [PATCH] Replace uudecode with libnettle base64 decoder (#406) Since RFC 7235 updated the HTTP Authentication credentials token to the token68 characterset it is possible that characters uudecode cannot cope with are received. The Nettle decoder better handles characters which are valid but not to be used for Basic auth token. --- include/uudecode.h | 21 ------------ lib/Makefile.am | 3 +- lib/uudecode.c | 73 ---------------------------------------- src/auth/basic/Config.cc | 20 ++++++++--- 4 files changed, 17 insertions(+), 100 deletions(-) delete mode 100644 include/uudecode.h delete mode 100644 lib/uudecode.c Index: squid-4.4/lib/Makefile.am =================================================================== --- squid-4.4.orig/lib/Makefile.am 2019-07-16 12:03:04.428684097 -0400 +++ squid-4.4/lib/Makefile.am 2019-07-16 12:03:04.424684101 -0400 @@ -61,8 +61,7 @@ libmiscencoding_la_SOURCES = \ html_quote.c \ md5.c \ rfc1738.c \ - rfc2617.c \ - uudecode.c + rfc2617.c libmisccontainers_la_SOURCES = \ hash.cc Index: squid-4.4/src/auth/basic/Config.cc =================================================================== --- squid-4.4.orig/src/auth/basic/Config.cc 2019-07-16 12:03:04.428684097 -0400 +++ squid-4.4/src/auth/basic/Config.cc 2019-07-16 12:03:04.424684101 -0400 @@ -20,6 +20,7 @@ #include "auth/CredentialsCache.h" #include "auth/Gadgets.h" #include "auth/State.h" +#include "base64.h" #include "cache_cf.h" #include "charset.h" #include "helper.h" @@ -30,7 +31,6 @@ #include "SquidTime.h" #include "Store.h" #include "util.h" -#include "uudecode.h" #include "wordlist.h" /* Basic Scheme */ @@ -169,10 +169,17 @@ Auth::Basic::Config::decodeCleartext(con // XXX: really? is the \n actually still there? does the header parse not drop it? char *eek = xstrdup(proxy_auth); strtok(eek, "\n"); - char *cleartext = uudecode(eek); - safe_free(eek); - if (cleartext) { + const size_t srcLen = strlen(eek); + char *cleartext = static_cast(xmalloc(BASE64_DECODE_LENGTH(srcLen)+1)); + + struct base64_decode_ctx ctx; + base64_decode_init(&ctx); + + size_t dstLen = 0; + if (base64_decode_update(&ctx, &dstLen, reinterpret_cast(cleartext), srcLen, eek) && base64_decode_final(&ctx)) { + cleartext[dstLen] = '\0'; + /* * Don't allow NL or CR in the credentials. * Oezguer Kesim @@ -183,7 +190,12 @@ Auth::Basic::Config::decodeCleartext(con debugs(29, DBG_IMPORTANT, "WARNING: Bad characters in authorization header '" << httpAuthHeader << "'"); safe_free(cleartext); } + } else { + debugs(29, 2, "WARNING: Invalid Base64 character in authorization header '" << httpAuthHeader << "'"); + safe_free(cleartext); } + + safe_free(eek); return cleartext; } Index: squid-4.4/include/uudecode.h =================================================================== --- squid-4.4.orig/include/uudecode.h 2019-07-16 12:03:04.428684097 -0400 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -/* - * Copyright (C) 1996-2018 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef _SQUID_UUDECODE_H -#define _SQUID_UUDECODE_H - -#ifdef __cplusplus -extern "C" -#else -extern -#endif - -char *uudecode(const char *); - -#endif /* _SQUID_UUDECODE_H */ - Index: squid-4.4/lib/uudecode.c =================================================================== --- squid-4.4.orig/lib/uudecode.c 2019-07-16 12:03:04.428684097 -0400 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (C) 1996-2018 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#include "squid.h" -#include "uudecode.h" - -/* aaaack but it's fast and const should make it shared text page. */ -const int pr2six[256] = { - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 -}; - -char * -uudecode(const char *bufcoded) -{ - int nbytesdecoded; - const unsigned char *bufin; - char *bufplain; - unsigned char *bufout; - int nprbytes; - - /* Strip leading whitespace. */ - - while (*bufcoded == ' ' || *bufcoded == '\t') - bufcoded++; - - /* Figure out how many characters are in the input buffer. - * Allocate this many from the per-transaction pool for the result. - */ - bufin = (const unsigned char *) bufcoded; - while (pr2six[*(bufin++)] <= 63); - nprbytes = (const char *) bufin - bufcoded - 1; - nbytesdecoded = ((nprbytes + 3) / 4) * 3; - - bufplain = xmalloc(nbytesdecoded + 1); - bufout = (unsigned char *) bufplain; - bufin = (const unsigned char *) bufcoded; - - while (nprbytes > 0) { - *(bufout++) = - (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); - *(bufout++) = - (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); - *(bufout++) = - (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); - bufin += 4; - nprbytes -= 4; - } - - if (nprbytes & 03) { - if (pr2six[bufin[-2]] > 63) - nbytesdecoded -= 2; - else - nbytesdecoded -= 1; - } - bufplain[nbytesdecoded] = '\0'; - return bufplain; -} - Index: squid-4.4/lib/Makefile.in =================================================================== --- squid-4.4.orig/lib/Makefile.in 2018-10-27 21:50:06.000000000 -0400 +++ squid-4.4/lib/Makefile.in 2019-07-16 12:03:48.588632154 -0400 @@ -185,7 +185,7 @@ am__v_lt_0 = --silent am__v_lt_1 = libmiscencoding_la_LIBADD = am_libmiscencoding_la_OBJECTS = base64.lo charset.lo html_quote.lo \ - md5.lo rfc1738.lo rfc2617.lo uudecode.lo + md5.lo rfc1738.lo rfc2617.lo libmiscencoding_la_OBJECTS = $(am_libmiscencoding_la_OBJECTS) libmiscutil_la_LIBADD = am_libmiscutil_la_OBJECTS = getfullhostname.lo heap.lo iso3307.lo \ @@ -836,8 +835,7 @@ libmiscencoding_la_SOURCES = \ html_quote.c \ md5.c \ rfc1738.c \ - rfc2617.c \ - uudecode.c + rfc2617.c libmisccontainers_la_SOURCES = \ hash.cc @@ -970,7 +968,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sspwin32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub_memaccount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uudecode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xusleep.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/testRFC1738.Po@am__quote@