Skip to content

Commit

Permalink
Update HttpHeader::getAuth to SBuf (#416)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
yadij committed Jul 4, 2019
1 parent c6a4c28 commit 7f73e9c
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 19 deletions.
25 changes: 14 additions & 11 deletions src/HttpHeader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/HttpHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class HttpHeader
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;
Expand Down
13 changes: 7 additions & 6 deletions src/cache_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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: '" <<
Expand Down
2 changes: 1 addition & 1 deletion src/clients/FtpGateway.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 7f73e9c

Please sign in to comment.