📄 dgstauth.cpp
字号:
const char *pBuf = PIIOBuffer_read( pPIHTTP->pBuffer, &iLen );
int toRead = atoi((const char *)pLength) - iLen;
while( toRead )
{
pBuf = PIIOBuffer_read( pPIHTTP->pBuffer, &iLen );
toRead -= iLen;
};
}
/* ---
Trigger redirection due to authentication failure
--- */
return HTTPUtil_doHTTPError( pPIHTTP, ST_UNAUTHORIZED );
} else {
HTTPCore_logError( pPIHTTP, "DigestAuth: Can't allocate challenge value");
return HTTPUtil_doHTTPError( pPIHTTP, ST_INTERNALERROR );
}
}
protected:
int Parameter( const char *pVariable, const char *pValue,
const char *pWhere )
{
assert( pVariable && pValue );
PIOStrStream os;
os << pWhere << "DigestAuth: ";
if ( !PIUtil_stricmp( pVariable, KEY_CONF_REALM ) )
{
sRealm = pValue;
}
else if ( !PIUtil_stricmp( pVariable, KEY_CONF_TIMEOUT ) )
{
tTimeout = atol(pValue);
}
else if ( !PIUtil_stricmp( pVariable, KEY_CONF_USER ) )
{
const char *pKey = DeQuote(pValue);
char *pVal = pKey ? strchr(pKey,':') : 0;
if (!pKey || !pVal)
{
os << "Bad User parameter '" << pValue << "'" << ends;
CONFIG_ERR( Object(), os.str() );
return 0;
}
else
{
pVal[0] = 0;
// Memory usage due to DuplicateString?
PIDB_replace( pUsers, PIDBTYPE_OPAQUE, pKey,
(void *)DuplicateString(++pVal), 0 );
};
}
else
{
os << "Unknown directive '" << pVariable << "'" << ends;
CONFIG_ERR( Object(), os.str() );
return 0;
};
return 1;
};
public:
DigestAuth( PIObject *pObject, int iArgc, const char *ppArgv[] )
: HandlerBaseHTTP( pObject ),
sRealm( 0 ),
pUsers( PIDB_new( 0, "DigestUsers" )),
tTimeout( 0 )
{
ReadParameters( iArgc, ppArgv );
char szKey[32+1];
if (ComputeKey(szKey) == PIAPI_COMPLETED) {
sKey = szKey;
} else {
PIOStrStream os;
os << "DigestAuth: Failed to generate private key." << ends;
CONFIG_ERR( Object(), os.str() );
SetOK(0);
}
};
~DigestAuth()
{
PIDB_delete( pUsers );
};
int Handle( int iPhase, PIHTTP &tPIHTTP, PIIOBuffer &tB )
{
if ( iPhase != PH_CHECKAUTH ) { return PIAPI_ERROR; };
/* --- Get the realm --- */
const char *szRealm = (const char *)PIDB_lookup( tPIHTTP.pResponseDB,
PIDBTYPE_STRING, KEY_INT_AUTHENTICATIONREALM, 0 );
/* --- Not for this handler to authenticate --- */
if ( !szRealm || strcmp( szRealm, sRealm ) )
{
return PIAPI_CONTINUE;
};
/*
** This realm applies. Set the authentication type to 'Digest'
*/
PIDB_replace( tPIHTTP.pResponseDB, PIDBTYPE_STRING, KEY_INT_AUTHTYPE,
(void *)DGST_AUTH_TYPE, 0 );
/* --- Get browser authentication string --- */
const char *pAuthenticate = (const char *)PIDB_lookup(tPIHTTP.pRequestDB,
PIDBTYPE_RFC822, KEY_HTTP_AUTHORIZATION, 0 );
if ( pAuthenticate )
{
/*
** Another authentication method for this realm? We should finish here!
*/
if (strncmp( pAuthenticate, "Digest ", 7 ))
{
return SendChallenge(&tPIHTTP, false);
};
const char *pUserName = 0;
const char *pRealm = 0;
const char *pUri = 0;
const char *pAlgorithm = 0;
const char *pNonce = 0;
const char *pResponse = 0;
StringTokenizer tTokens( pAuthenticate + 7, "," );
for(int i=0; i<tTokens.NumTokens(); i++)
{
const char *pToken = tTokens.GetToken(i);
/* --- skip leading whitespace --- */
for( ; *pToken && (isspace(*pToken)); pToken++ );
if (strstr(pToken,KEY_USER)) {
pUserName = DeQuote(strstr(pToken,KEY_USER)+sizeof(KEY_USER));
}
else if (strstr(pToken,KEY_REALM)) {
pRealm = DeQuote(strstr(pToken,KEY_REALM)+sizeof(KEY_REALM));
}
else if (strstr(pToken,KEY_URI)) {
pUri = DeQuote(strstr(pToken,KEY_URI)+sizeof(KEY_URI));
}
else if (strstr(pToken,KEY_ALGO)) {
pAlgorithm = DeQuote(strstr(pToken,KEY_ALGO)+sizeof(KEY_ALGO));
}
else if (strstr(pToken,KEY_NONCE)) {
pNonce = DeQuote(strstr(pToken,KEY_NONCE)+sizeof(KEY_NONCE));
}
else if (strstr(pToken,KEY_RESP)) {
pResponse = DeQuote(strstr(pToken,KEY_RESP)+sizeof(KEY_RESP));
}
};
/* --- Unsupported algorithm --- */
if (pAlgorithm && PIUtil_stricmp(pAlgorithm, "MD5"))
{
return SendChallenge(&tPIHTTP, false);
};
/* --- Search for user name in database --- */
const char *pHA1 = (const char *)PIDB_lookup(pUsers, PIDBTYPE_OPAQUE,
pUserName, 0 );
/* --- No H(A1) found, thus user doesn't exist --- */
if (!pHA1)
{
return SendChallenge(&tPIHTTP, false);
};
/* --- Check Nonce --- */
char szNonce[32+1];
if ( ComputeNonce(&tPIHTTP, szNonce) != PIAPI_COMPLETED )
{
HTTPCore_logError( &tPIHTTP, "DigestAuth: Can't compute nonce value.");
return HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
}
/* --- Nonce stale --- */
if (!pNonce || PIUtil_stricmp(pNonce, szNonce))
{
return SendChallenge(&tPIHTTP, true);
}
/*
** Compute H(A2) = MD5(Method:Uri)
*/
char szHA2[32+1];
const char *pMethod = (const char *)PIDB_lookup(tPIHTTP.pRequestDB,
PIDBTYPE_STRING, KEY_HTTP_METHOD, 0 );
if ( ComputeHA2(szHA2, pMethod, pUri) != PIAPI_COMPLETED )
{
HTTPCore_logError( &tPIHTTP, "DigestAuth: Can't compute digest value.");
return HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
}
/*
** Re-compute digest response R = KD(H(A1), Nonce:H(A2))
*/
char szDigest[32+1];
if ( ComputeDigest(szDigest, pHA1, pNonce, szHA2) != PIAPI_COMPLETED )
{
HTTPCore_logError( &tPIHTTP, "DigestAuth: Can't compute digest value.");
return HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
}
/*
** Check digest against response, this is THE authentication
*/
if (!pResponse || PIUtil_stricmp(pResponse, szDigest))
{
/* --- Send a fresh challenge --- */
return SendChallenge(&tPIHTTP, false);
};
/*
** We are through!
*/
PIDB_replace( tPIHTTP.pResponseDB, PIDBTYPE_STRING, KEY_INT_REMOTEUSER,
(void *)pUserName, 0);
PIDB_replace( tPIHTTP.pResponseDB, PIDBTYPE_STRING, KEY_INT_AUTHPASS,
(void *)pHA1, 0);
return PIAPI_COMPLETED;
}
else
{
/* --- Send a fresh challenge --- */
return SendChallenge(&tPIHTTP, false);
}
};
};
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int DigestAuth_constructor( PIObject *pObj,
int iArgc, const char *ppArgv[] )
{
return HandlerBaseHTTP_constructor( pObj, PI_NEW( DigestAuth( pObj,
iArgc, ppArgv ) ) );
};
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int DigestAuth_execute( PIObject *pObj, int iArgc,
const char *ppArgv[] )
{
if ( !pObj ) return PIAPI_ERROR;
return ((HandlerBaseHTTP *)PIObject_getUserData(pObj))->
Execute( iArgc, ppArgv );
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int DigestAuth_destructor( PIObject *pObj, int,
const char *[] )
{
delete (HandlerBaseHTTP *)PIObject_getUserData( pObj );
return PIAPI_COMPLETED;
}
#if 0
/*___+++CNF_BEGIN+++___*/
<Class>
Name DigestAuthClass
Type LogicExtension
Library HTTP
OnClassLoad HandlerBaseHTTP_onClassLoad
Constructor DigestAuth_constructor
CopyConstructor HandlerBaseHTTP_copyConstructor
Destructor DigestAuth_destructor
Execute DigestAuth_execute
</Class>
<Object>
Name DigestAuth
Class DigestAuthClass
</Object>
/*___+++CNF_END+++___*/
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -