222 lines
5.1 KiB
C++
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;
|
|
}
|
|
|