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

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