From: Amos Jeffries Date: Wed, 19 Jun 2019 05:58:36 +0000 (+0000) Subject: Update HttpHeader::getAuth to SBuf (#416) X-Git-Tag: SQUID_5_0_1~80 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2582f64a7a33577cd31a82f34da95f3c6e4f5415;p=thirdparty%2Fsquid.git Update HttpHeader::getAuth to SBuf (#416) 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. --- diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc index 930b4a5263..86de081ed3 100644 --- a/src/HttpHeader.cc +++ b/src/HttpHeader.cc @@ -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(decodedAuthToken), strlen(field), field) || + if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast(decodedAuthToken), fieldLen, field) || !base64_decode_final(&ctx)) { - return NULL; + return nil; } - decodedAuthToken[decodedLen] = '\0'; - return decodedAuthToken; + result.rawAppendFinish(decodedAuthToken, decodedLen); + return result; } ETag diff --git a/src/HttpHeader.h b/src/HttpHeader.h index 24e98c5f36..31915f640c 100644 --- a/src/HttpHeader.h +++ b/src/HttpHeader.h @@ -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; diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 21db879815..244f7cc3cb 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -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 ¶m // 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: '" << diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc index b28007f26a..0f5b0be480 100644 --- a/src/clients/FtpGateway.cc +++ b/src/clients/FtpGateway.cc @@ -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); diff --git a/src/tests/stub_HttpHeader.cc b/src/tests/stub_HttpHeader.cc index e898fa8e04..b1c72c7a79 100644 --- a/src/tests/stub_HttpHeader.cc +++ b/src/tests/stub_HttpHeader.cc @@ -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)