commit 7f73e9c5d17664b882ed32590e6af310c247f320 Author: Amos Jeffries Date: 2019-06-19 05:58:36 +0000 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 1e2b650..284a057 100644 --- a/src/HttpHeader.cc +++ b/src/HttpHeader.cc @@ -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(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 a26b127..3b262be 100644 --- a/src/HttpHeader.h +++ b/src/HttpHeader.h @@ -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; diff --git a/src/cache_manager.cc b/src/cache_manager.cc index da22f7a..2fae767 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -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 ¶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 b958b14..7ca5d24 100644 --- a/src/clients/FtpGateway.cc +++ b/src/clients/FtpGateway.cc @@ -1050,7 +1050,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);