2025-04-27 07:49:33 -04:00

222 lines
5.1 KiB
C++

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
AuthParse.cpp
Abstract:
Implementation of the ParseAuthorizationHeader function.
Author:
Darren L. Anderson (darrenan) 20-Aug-1998
Revision History:
20-Aug-1998 darrenan - Created
27-Mar-2000 cambler - Fixed logic problem in ParseAuthorizationHeader()
--*/
#include "precomp.h"
LPCSTR g_ppszDigestNames[] =
{
"username",
"realm",
"nonce",
"uri",
"response",
"digest",
"algorithm",
"opaque",
"cnonce",
"qop",
"nc"
};
LPSTR
SkipWhite(
LPSTR p
)
/*++
Routine Description:
Skip white space and ','
Arguments:
p - ptr to string
Return Value:
updated ptr after skiping white space
--*/
{
while (isspace(*p) || *p == ',' )
{
++p;
}
return p;
}
BOOL
ParseAuthorizationHeader(
LPSTR pszHeader,
LPSTR pValueTable[DIGEST_AUTH_LAST]
)
/*++
Routine Description:
ParseAuthorizationHeader - This method takes a single string containing a
Digest authorization header and returns an array of
pointers to header values such as 'username', 'nonce',
etc.
Arguments:
pszHeader - Pointer to the authorization header. The header should not contain
the "Authorization: Digest " portion of the header, just the name/
value pairs themselves.
pValueTable - An array of string pointers. The elements of the array will be
filled in by this method. Elements in the array corresponding to
non-existent name/value pairs will be NULL on return.
Return Value:
TRUE - The header was parsed successfully.
FALSE - The header was not parsed. Bad structure in the header.
(RAID 4798: or the header was empty, or contained gibberish with at least one space)
--*/
{
BOOL bReturn = FALSE;
PSTR pszBeginName;
PSTR pszEndName;
PSTR pszBeginVal;
PSTR pszEndVal;
int ch;
// NULL the array.
for (UINT uTable = 0; uTable < DIGEST_AUTH_LAST; uTable++)
pValueTable[uTable] = NULL;
while (*pszHeader) {
pszEndVal = NULL;
pszHeader = SkipWhite(pszHeader);
if (*pszHeader == '\0')
break;
pszBeginName = pszHeader;
for (pszEndName = pszHeader ; (ch = *pszEndName) && ch != '=' && ch != ' ' ; ++pszEndName)
{
// Loop does the work - advance the pszEndName pointer until it's either an "=" or " " (or NULL)
}
if (*pszEndName) {
*pszEndName = '\0';
// We now have a name, pointed to by pszBeginName. Let's get a value...
if (*(pszEndName + 1) == '"') {
// The value starts with a quote
for (pszBeginVal = ++pszEndName ; (ch = *pszBeginVal) && ch != '"' ; ++pszBeginVal)
{
// Loop does the work - advance the pszBeginVal pointer until it's a quote (or NULL)
}
if (*pszBeginVal == '"') {
// The value was bound by quotes
++pszBeginVal;
for (pszEndVal = pszBeginVal ; (ch = *pszEndVal) ; ++pszEndVal)
{
if (ch == '"')
{
break;
}
}
}
} else {
pszBeginVal = ++pszEndName;
for ( pszEndVal = pszBeginVal ; (ch = *pszEndVal) && ch != ',' ; ++pszEndVal)
{
// Loop does the work - advance the pszEndVal pointer until it's a comma (or NULL)
}
}
//
// At this point, pszBeginName points to the parsed parameter name, and
// pszBeginVal points to the parsed parameter value.
//
// find name in table
UINT nCurrent;
for (nCurrent = 0 ; nCurrent < DIGEST_AUTH_LAST ; ++nCurrent)
if (!_stricmp( g_ppszDigestNames[nCurrent], pszBeginName))
break;
// Set the table entry equal to the value and note that we've actually found something
if (nCurrent < DIGEST_AUTH_LAST) {
pValueTable[nCurrent] = pszBeginVal;
bReturn = TRUE;
}
// Are we at the end of the header string?
if (pszEndVal && *pszEndVal) {
// No, terminate value and loop.
*pszEndVal = '\0';
pszHeader = ++pszEndVal;
continue;
} else
// yes, break out of the loop and return.
break;
} else
// yes, break out of the loop and return. We got to the end without
// finding "=" or " ", so there's nothing else to do.
break;
}
return bReturn;
}