]> 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)
committerAmos Jeffries <yadij@users.noreply.github.com>
Thu, 4 Jul 2019 11:01:16 +0000 (23:01 +1200)
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

index 9f747f99582bf14640255feb5c067f919dd12382..dd320d5629127e8fa5c2bd30062857e9b7de7393 100644 (file)
@@ -1268,43 +1268,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 64fd2781e405b8702768b324fdcf2e2cbebbefad..35a941058cb270c1ab141f75878585c5848842a0 100644 (file)
@@ -134,7 +134,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 f88cd1c46b6b65e0f5e311302bbb8a25aa034911..3556a44618709779e742a674cef6191de5185b4d 100644 (file)
@@ -27,6 +27,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"
@@ -243,20 +244,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 9afe3781cd11b904d74594214c8bbadf47a072f3..140c4413940f1b2fbbc0472dfe760521dbae17d4 100644 (file)
@@ -1039,7 +1039,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);