⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dgstauth.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				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 + -