Blame SOURCES/squid-4.4.0-CVE-2019-12527.patch

3c336a
commit 7f73e9c5d17664b882ed32590e6af310c247f320
3c336a
Author: Amos Jeffries <yadij@users.noreply.github.com>
3c336a
Date:   2019-06-19 05:58:36 +0000
3c336a
3c336a
    Update HttpHeader::getAuth to SBuf (#416)
3c336a
    
3c336a
    Replace the fixed-size buffer for decoding base64 tokens with an
3c336a
    SBuf to avoid decoder issues on large inputs.
3c336a
    
3c336a
    Update callers to SBuf API operations for more efficient memory
3c336a
    management.
3c336a
3c336a
diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
3c336a
index 1e2b650..284a057 100644
3c336a
--- a/src/HttpHeader.cc
3c336a
+++ b/src/HttpHeader.cc
3c336a
@@ -1268,43 +1268,46 @@ HttpHeader::getContRange() const
3c336a
     return cr;
3c336a
 }
3c336a
 
3c336a
-const char *
3c336a
-HttpHeader::getAuth(Http::HdrType id, const char *auth_scheme) const
3c336a
+SBuf
3c336a
+HttpHeader::getAuthToken(Http::HdrType id, const char *auth_scheme) const
3c336a
 {
3c336a
     const char *field;
3c336a
     int l;
3c336a
     assert(auth_scheme);
3c336a
     field = getStr(id);
3c336a
 
3c336a
+    static const SBuf nil;
3c336a
     if (!field)         /* no authorization field */
3c336a
-        return NULL;
3c336a
+        return nil;
3c336a
 
3c336a
     l = strlen(auth_scheme);
3c336a
 
3c336a
     if (!l || strncasecmp(field, auth_scheme, l))   /* wrong scheme */
3c336a
-        return NULL;
3c336a
+        return nil;
3c336a
 
3c336a
     field += l;
3c336a
 
3c336a
     if (!xisspace(*field))  /* wrong scheme */
3c336a
-        return NULL;
3c336a
+        return nil;
3c336a
 
3c336a
     /* skip white space */
3c336a
     for (; field && xisspace(*field); ++field);
3c336a
 
3c336a
     if (!*field)        /* no authorization cookie */
3c336a
-        return NULL;
3c336a
+        return nil;
3c336a
 
3c336a
-    static char decodedAuthToken[8192];
3c336a
+    const auto fieldLen = strlen(field);
3c336a
+    SBuf result;
3c336a
+    char *decodedAuthToken = result.rawAppendStart(BASE64_DECODE_LENGTH(fieldLen));
3c336a
     struct base64_decode_ctx ctx;
3c336a
     base64_decode_init(&ctx;;
3c336a
     size_t decodedLen = 0;
3c336a
-    if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(decodedAuthToken), strlen(field), field) ||
3c336a
+    if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(decodedAuthToken), fieldLen, field) ||
3c336a
             !base64_decode_final(&ctx)) {
3c336a
-        return NULL;
3c336a
+        return nil;
3c336a
     }
3c336a
-    decodedAuthToken[decodedLen] = '\0';
3c336a
-    return decodedAuthToken;
3c336a
+    result.rawAppendFinish(decodedAuthToken, decodedLen);
3c336a
+    return result;
3c336a
 }
3c336a
 
3c336a
 ETag
3c336a
diff --git a/src/HttpHeader.h b/src/HttpHeader.h
3c336a
index a26b127..3b262be 100644
3c336a
--- a/src/HttpHeader.h
3c336a
+++ b/src/HttpHeader.h
3c336a
@@ -134,7 +134,7 @@ public:
3c336a
     HttpHdrRange *getRange() const;
3c336a
     HttpHdrSc *getSc() const;
3c336a
     HttpHdrContRange *getContRange() const;
3c336a
-    const char *getAuth(Http::HdrType id, const char *auth_scheme) const;
3c336a
+    SBuf getAuthToken(Http::HdrType id, const char *auth_scheme) const;
3c336a
     ETag getETag(Http::HdrType id) const;
3c336a
     TimeOrTag getTimeOrTag(Http::HdrType id) const;
3c336a
     int hasListMember(Http::HdrType id, const char *member, const char separator) const;
3c336a
diff --git a/src/cache_manager.cc b/src/cache_manager.cc
3c336a
index da22f7a..2fae767 100644
3c336a
--- a/src/cache_manager.cc
3c336a
+++ b/src/cache_manager.cc
3c336a
@@ -27,6 +27,7 @@
3c336a
 #include "mgr/FunAction.h"
3c336a
 #include "mgr/QueryParams.h"
3c336a
 #include "protos.h"
3c336a
+#include "sbuf/StringConvert.h"
3c336a
 #include "SquidConfig.h"
3c336a
 #include "SquidTime.h"
3c336a
 #include "Store.h"
3c336a
@@ -243,20 +244,20 @@ CacheManager::ParseHeaders(const HttpRequest * request, Mgr::ActionParams &param
3c336a
     // TODO: use the authentication system decode to retrieve these details properly.
3c336a
 
3c336a
     /* base 64 _decoded_ user:passwd pair */
3c336a
-    const char *basic_cookie = request->header.getAuth(Http::HdrType::AUTHORIZATION, "Basic");
3c336a
+    const auto basic_cookie(request->header.getAuthToken(Http::HdrType::AUTHORIZATION, "Basic"));
3c336a
 
3c336a
-    if (!basic_cookie)
3c336a
+    if (basic_cookie.isEmpty())
3c336a
         return;
3c336a
 
3c336a
-    const char *passwd_del;
3c336a
-    if (!(passwd_del = strchr(basic_cookie, ':'))) {
3c336a
+    const auto colonPos = basic_cookie.find(':');
3c336a
+    if (colonPos == SBuf::npos) {
3c336a
         debugs(16, DBG_IMPORTANT, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'");
3c336a
         return;
3c336a
     }
3c336a
 
3c336a
     /* found user:password pair, reset old values */
3c336a
-    params.userName.limitInit(basic_cookie, passwd_del - basic_cookie);
3c336a
-    params.password = passwd_del + 1;
3c336a
+    params.userName = SBufToString(basic_cookie.substr(0, colonPos));
3c336a
+    params.password = SBufToString(basic_cookie.substr(colonPos+1));
3c336a
 
3c336a
     /* warning: this prints decoded password which maybe not be what you want to do @?@ @?@ */
3c336a
     debugs(16, 9, "CacheManager::ParseHeaders: got user: '" <<
3c336a
diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc
3c336a
index b958b14..7ca5d24 100644
3c336a
--- a/src/clients/FtpGateway.cc
3c336a
+++ b/src/clients/FtpGateway.cc
3c336a
@@ -1050,7 +1050,7 @@ Ftp::Gateway::checkAuth(const HttpHeader * req_hdr)
3c336a
 
3c336a
 #if HAVE_AUTH_MODULE_BASIC
3c336a
     /* Check HTTP Authorization: headers (better than defaults, but less than URL) */
3c336a
-    const SBuf auth(req_hdr->getAuth(Http::HdrType::AUTHORIZATION, "Basic"));
3c336a
+    const auto auth(req_hdr->getAuthToken(Http::HdrType::AUTHORIZATION, "Basic"));
3c336a
     if (!auth.isEmpty()) {
3c336a
         flags.authenticated = 1;
3c336a
         loginParser(auth, false);