/*++ Copyright (c) 1998-2002 Microsoft Corporation. All rights reserved. --*/ #include "stdafx.h" #include "MyAuthFilterImpl.h" #include "MyAuthFilter.h" #include "OutputDebugStringF.h" // // our authentication form: // char Response[] = "HTTP/1.1 200 OK\r\n" \ "Content-Length: 208\r\n" \ "Content-Type: text/html\r\n" \ "\r\n" \ "\r\n" \ "
\r\n" \ "\r\n" \ " \r\n" \ "\r\n" \ "\r\n" \ ""; #define STRING_CONST_SIZE(x) (sizeof(x) - 1) #define USER_TOKEN_STRING "User=" // // Helper functions: // BOOL ParseUrl( char* pBuffer, DWORD dwBufSize, char** ppUserName, DWORD* pdwUserNameSize ) { assert(ppUserName != NULL && pdwUserNameSize != NULL && dwBufSize > 0); *ppUserName = NULL; *pdwUserNameSize = 0; pBuffer[dwBufSize - 1] = '\0'; //just to make sure char* pParams = strchr( pBuffer, '?' ); //look for the parameters if (pParams == NULL ) { OutputDebugStringF("MYAUTH: No '?' is found in the URL\n"); return FALSE; } DWORD dwLength = 0; pParams++; //for the '?' if (strncmp(USER_TOKEN_STRING, pParams, STRING_CONST_SIZE(USER_TOKEN_STRING)) != 0) { OutputDebugStringF("MYAUTH: No 'User=' is found in the URL\n"); return FALSE; } pParams += STRING_CONST_SIZE(USER_TOKEN_STRING); //point to the user name dwLength = (DWORD)strlen(pParams); if (dwLength == 0) { OutputDebugStringF("MYAUTH: No user name supplied or user name is too long\n"); return FALSE; } *ppUserName = pParams; *pdwUserNameSize = dwLength; return TRUE; } BOOL SendAuthForm(PHTTP_FILTER_CONTEXT pfc) { DWORD dwLength = sizeof(Response) - 1; return pfc->WriteClient(pfc, Response,&dwLength, 0 ); } ///////////////////////////////////////////////////////////////////////////// // CMyAuthFilterImpl() ///////////////////////////////////////////////////////////////////////////// CMyAuthFilterImpl::CMyAuthFilterImpl() { } ///////////////////////////////////////////////////////////////////////////// // ~CMyAuthFilterImpl() ///////////////////////////////////////////////////////////////////////////// CMyAuthFilterImpl::~CMyAuthFilterImpl() { } ///////////////////////////////////////////////////////////////////////////// // Init() ///////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilterImpl::Init() { //Initialize our stuff return S_OK; } ///////////////////////////////////////////////////////////////////////////// // Reload() ///////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilterImpl::Reload() { //Reload new configuration stuff return S_OK; } ///////////////////////////////////////////////////////////////////////////// // Shutdown() ///////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilterImpl::Shutdown() { //Shutdown/cleanup our stuff return S_OK; } ///////////////////////////////////////////////////////////////////////////// // OnAuthentication() // Handle the SF_NOTIFY_AUTHENTICATION notification ///////////////////////////////////////////////////////////////////////////// DWORD CMyAuthFilterImpl::OnAuthentication( PHTTP_FILTER_CONTEXT pfc, PWPX_FILTER_AUTHENT_EX pAuth) { OutputDebugStringF("MYAUTH: OnAuthentication called\n"); assert(pfc); char Buffer[2048]; DWORD dwLength = 2048; if ( pfc->Revision != WPX_HTTP_FILTER_REVISION ) { return SF_STATUS_REQ_NEXT_NOTIFICATION; } PWPX_FILTER_CONTEXT pWPX = TO_WPX_FILTER_CONTEXT(pfc); assert(pWPX != NULL); BOOL fEnabled; BOOL fRes = pWPX->GetAuthSchemeStatus( pfc, x_szMyAuthFilter_AuthScheme, &fEnabled ); if (!fRes || !fEnabled) //auth scheme is not enabled for the current listener associated with this session { OutputDebugStringF("MYAUTH: Authentication scheme is not enabled\n"); return SF_STATUS_REQ_NEXT_NOTIFICATION; } if (!pAuth->fAuthIsRequired) //we ignore authentication notification for anonymous, authenticate only if required by proxy { OutputDebugStringF("MYAUTH: authentication is not required, use anonymous\n"); return SF_STATUS_REQ_NEXT_NOTIFICATION; } if( pfc->pFilterContext == NULL ) { if (!pfc->GetServerVariable( pfc, "URL", Buffer, &dwLength )) { OutputDebugStringF("MYAUTH: Could not retrieve URL, possibly buffer too small\n"); return SF_STATUS_REQ_NEXT_NOTIFICATION; } char* pszUserName = NULL; DWORD dwUserNameLength = 0; if (!ParseUrl( Buffer, dwLength, &pszUserName, &dwUserNameLength )) { OutputDebugStringF("MYAUTH: Failed to get user name, sending the auth form\n"); // // There is no user name, lets ask the user for it // if (!SendAuthForm(pfc)) { OutputDebugStringF("MYAUTH: Failed to send the auth form. Error:0x%x\n", GetLastError()); return SF_STATUS_REQ_ERROR; //Failed to send } return SF_STATUS_REQ_FINISHED; } OutputDebugStringF("MYAUTH: We have a user name: %s\n", pszUserName); // // We have a user name, save it in our context (we don't really need it, it's just to show allocation of memory per request) // pfc->pFilterContext = pWPX->AllocMemoryPerRequest(pfc, dwUserNameLength + 1, 0); if (pfc->pFilterContext == NULL) //failed to allocate { OutputDebugStringF("MYAUTH: Failed to allocate memory for user name\n"); return SF_STATUS_REQ_ERROR; } strcpy((char *)pfc->pFilterContext, pszUserName); } // // Tell the proxy about our user name // if (!pAuth->SetAuthenticatedUser( pfc, (char *)pfc->pFilterContext, x_szMyAuthFilter_AuthScheme, NULL )) { OutputDebugStringF("MYAUTH: Failed to SetAuthenticatedUser\n"); return SF_STATUS_REQ_ERROR; } return SF_STATUS_REQ_NEXT_NOTIFICATION ; } ///////////////////////////////////////////////////////////////////////////// // OnEndOfRequest() // Handle the SF_NOTIFY_END_OF_REQUEST notification ///////////////////////////////////////////////////////////////////////////// DWORD CMyAuthFilterImpl::OnEndOfRequest( PHTTP_FILTER_CONTEXT pfc) { OutputDebugStringF("MYAUTH: OnEndOfRequest called\n"); pfc->pFilterContext = NULL; //Memory will be freed by the proxy since we allocated with AllocMemoryPerRequest return SF_STATUS_REQ_NEXT_NOTIFICATION ; }