]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Update HttpHeader::getAuth to SBuf (#416)
authorAmos Jeffries <yadij@users.noreply.github.com>
Wed, 19 Jun 2019 05:58:36 +0000 (05:58 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Wed, 19 Jun 2019 14:27:18 +0000 (14:27 +0000)
Replace the fixed-size buffer for decoding base64 tokens with an
SBuf to avoid decoder issues on large inputs.

Update callers to SBuf API operations for more efficient memory
management.

src/HttpHeader.cc
src/HttpHeader.h
src/cache_manager.cc
src/clients/FtpGateway.cc
src/tests/stub_HttpHeader.cc

index 930b4a5263ed418f188a0758abf9948e3c571d29..86de081ed3bcf49a09bf631b6c2717fb1445d6fe 100644 (file)
@@ -1289,43 +1289,46 @@ HttpHeader::getContRange() const
     return cr;
 }
 
-const char *
-HttpHeader::getAuth(Http::HdrType id, const char *auth_scheme) const
+SBuf
+HttpHeader::getAuthToken(Http::HdrType id, const char *auth_scheme) const
 {
     const char *field;
     int l;
     assert(auth_scheme);
     field = getStr(id);
 
+    static const SBuf nil;
     if (!field)         /* no authorization field */
-        return NULL;
+        return nil;
 
     l = strlen(auth_scheme);
 
     if (!l || strncasecmp(field, auth_scheme, l))   /* wrong scheme */
-        return NULL;
+        return nil;
 
     field += l;
 
     if (!xisspace(*field))  /* wrong scheme */
-        return NULL;
+        return nil;
 
     /* skip white space */
     for (; field && xisspace(*field); ++field);
 
     if (!*field)        /* no authorization cookie */
-        return NULL;
+        return nil;
 
-    static char decodedAuthToken[8192];
+    const auto fieldLen = strlen(field);
+    SBuf result;
+    char *decodedAuthToken = result.rawAppendStart(BASE64_DECODE_LENGTH(fieldLen));
     struct base64_decode_ctx ctx;
     base64_decode_init(&ctx);
     size_t decodedLen = 0;
-    if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(decodedAuthToken), strlen(field), field) ||
+    if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(decodedAuthToken), fieldLen, field) ||
             !base64_decode_final(&ctx)) {
-        return NULL;
+        return nil;
     }
-    decodedAuthToken[decodedLen] = '\0';
-    return decodedAuthToken;
+    result.rawAppendFinish(decodedAuthToken, decodedLen);
+    return result;
 }
 
 ETag
index 24e98c5f3647b75b792a6934f11a5595989c5cee..31915f640c60f6d2413804a31d5d335e1224da91 100644 (file)
@@ -148,7 +148,7 @@ public:
     HttpHdrRange *getRange() const;
     HttpHdrSc *getSc() const;
     HttpHdrContRange *getContRange() const;
-    const char *getAuth(Http::HdrType id, const char *auth_scheme) const;
+    SBuf getAuthToken(Http::HdrType id, const char *auth_scheme) const;
     ETag getETag(Http::HdrType id) const;
     TimeOrTag getTimeOrTag(Http::HdrType id) const;
     int hasListMember(Http::HdrType id, const char *member, const char separator) const;
index 21db8798154d4d1bb0131dbb99beb7258c22cd24..244f7cc3cbbf5fd4948ad4d8922b304f59fbf513 100644 (file)
@@ -28,6 +28,7 @@
 #include "mgr/FunAction.h"
 #include "mgr/QueryParams.h"
 #include "protos.h"
+#include "sbuf/StringConvert.h"
 #include "SquidConfig.h"
 #include "SquidTime.h"
 #include "Store.h"
@@ -244,20 +245,20 @@ CacheManager::ParseHeaders(const HttpRequest * request, Mgr::ActionParams &param
     // TODO: use the authentication system decode to retrieve these details properly.
 
     /* base 64 _decoded_ user:passwd pair */
-    const char *basic_cookie = request->header.getAuth(Http::HdrType::AUTHORIZATION, "Basic");
+    const auto basic_cookie(request->header.getAuthToken(Http::HdrType::AUTHORIZATION, "Basic"));
 
-    if (!basic_cookie)
+    if (basic_cookie.isEmpty())
         return;
 
-    const char *passwd_del;
-    if (!(passwd_del = strchr(basic_cookie, ':'))) {
+    const auto colonPos = basic_cookie.find(':');
+    if (colonPos == SBuf::npos) {
         debugs(16, DBG_IMPORTANT, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'");
         return;
     }
 
     /* found user:password pair, reset old values */
-    params.userName.limitInit(basic_cookie, passwd_del - basic_cookie);
-    params.password = passwd_del + 1;
+    params.userName = SBufToString(basic_cookie.substr(0, colonPos));
+    params.password = SBufToString(basic_cookie.substr(colonPos+1));
 
     /* warning: this prints decoded password which maybe not be what you want to do @?@ @?@ */
     debugs(16, 9, "CacheManager::ParseHeaders: got user: '" <<
index b28007f26ad6a7868b17e50e270e9e71ea2767f8..0f5b0be48044da6ad01ebb0d2660c35b0b132fe4 100644 (file)
@@ -1038,7 +1038,7 @@ Ftp::Gateway::checkAuth(const HttpHeader * req_hdr)
 
 #if HAVE_AUTH_MODULE_BASIC
     /* Check HTTP Authorization: headers (better than defaults, but less than URL) */
-    const SBuf auth(req_hdr->getAuth(Http::HdrType::AUTHORIZATION, "Basic"));
+    const auto auth(req_hdr->getAuthToken(Http::HdrType::AUTHORIZATION, "Basic"));
     if (!auth.isEmpty()) {
         flags.authenticated = 1;
         loginParser(auth, false);
index e898fa8e04334839a4ccca49be4cabfe7fa7027a..b1c72c7a791f69c246a4cd5665841e5e9a772dc2 100644 (file)
@@ -74,7 +74,7 @@ HttpHdrCc *HttpHeader::getCc() const STUB_RETVAL(nullptr)
 HttpHdrRange *HttpHeader::getRange() const STUB_RETVAL(nullptr)
 HttpHdrSc *HttpHeader::getSc() const STUB_RETVAL(nullptr)
 HttpHdrContRange *HttpHeader::getContRange() const STUB_RETVAL(nullptr)
-const char *HttpHeader::getAuth(Http::HdrType, const char *auth_scheme) const STUB_RETVAL(nullptr)
+SBuf HttpHeader::getAuthToken(Http::HdrType, const char *) const STUB_RETVAL(SBuf())
 ETag HttpHeader::getETag(Http::HdrType) const STUB_RETVAL(ETag())
 TimeOrTag HttpHeader::getTimeOrTag(Http::HdrType) const STUB_RETVAL(TimeOrTag())
 int HttpHeader::hasListMember(Http::HdrType, const char *, const char) const STUB_RETVAL(0)