/*++ Copyright (c) 1998-2002 Microsoft Corporation. All rights reserved. --*/ #include "stdafx.h" #include "MyAuthFilterImpl.h" #include "MyAuthFilter.h" #include "Outputdebugstringf.h" #include "msfpccom_i.c" const WCHAR* x_wcsMyAuthFilterGuid = L"{648105C8-7EAF-4966-A80D-2CB15CCC6646}"; const WCHAR* x_wcsMyAuthSchemeGuid = L"{2E233588-CCFF-4512-AF70-CF1C391B9A6C}"; const WCHAR* x_wcsMyAuthFilterName = L"My Auth Filter"; const WCHAR* x_wcsMyAuthFilterRelativePath = L"MyAuthFilter.dll"; const WCHAR* x_wcsMyAuthFilterVersion = L"4.0"; const WCHAR* x_wcsMyAuthFilterDescription = L"This is my auth Filter"; const WCHAR* x_wcsMyAuthFilterVendor = L"Microsoft (R) Corporation"; const WCHAR* x_wcsMyAuthFilter_AuthScheme = L"MyAuthScheme"; const char* x_szMyAuthFilter_AuthScheme = "MyAuthScheme"; ///////////////////////////////////////////////////////////////////////////// // CMyAuthFilter() ///////////////////////////////////////////////////////////////////////////// CMyAuthFilter::CMyAuthFilter(): m_fCalledInit(FALSE) { } ///////////////////////////////////////////////////////////////////////////// // ~CMyAuthFilter() ///////////////////////////////////////////////////////////////////////////// CMyAuthFilter::~CMyAuthFilter() { } ///////////////////////////////////////////////////////////////////////////// // Init() // Called when filter is loaded by the proxy ///////////////////////////////////////////////////////////////////////////// DWORD CMyAuthFilter::Init() { if (m_fCalledInit) { return ERROR_SUCCESS; } m_fCalledInit = TRUE; return m_FilterImpl.Init(); } ///////////////////////////////////////////////////////////////////////////// // Reload() // Called when configuration was changed and filter need to reload it own configuration ///////////////////////////////////////////////////////////////////////////// DWORD CMyAuthFilter::Reload() { return m_FilterImpl.Reload(); } ///////////////////////////////////////////////////////////////////////////// // Shutdown() // Called when filter is unloaded by the proxy ///////////////////////////////////////////////////////////////////////////// DWORD CMyAuthFilter::Shutdown() { return m_FilterImpl.Shutdown(); } ///////////////////////////////////////////////////////////////////////////// // Register() // Register our web filter and the new authentication scheme. Called when // filter is registered. ///////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilter::Register() { HRESULT hr = S_OK; CComPtr spWebFilters; CComPtr spAuthSchemes; hr = CoInitialize(NULL); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: CoInitialize Failed. Error code is %lx\n", hr); return hr; } // // Get web filters collection // hr = GetWebFilters(&spWebFilters); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Get the web filters object failed. Error code is %lx\n", hr); CoUninitialize(); return hr; } // // get authentication schemes collection // hr = GetAuthenticationSchemes( &spAuthSchemes ); if (FAILED(hr) ) { OutputDebugStringF("MYAUTH: Failed to get auth schemes. Error code is %lx\n", hr); CoUninitialize(); return hr; } // // Add this web filter to the collection of web filters // hr = AddWebFilter(spWebFilters); if (FAILED(hr) ) { OutputDebugStringF("MYAUTH: Failed to register the web filter. Error code is %lx\n", hr); CoUninitialize(); return hr; } // // Register the new authentication scheme // hr = RegisterAuthentication(spAuthSchemes); if (FAILED(hr) ) { RemoveWebFilter(spWebFilters); OutputDebugStringF("MYAUTH: Failed to register the auth scheme. Error code is %lx\n", hr); CoUninitialize(); return hr; } CoUninitialize(); return hr; } ///////////////////////////////////////////////////////////////////////////// // Unregister() // Unregister our web filter and the new authentication scheme. Called when // filter is unregistered. ///////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilter::Unregister() { HRESULT hr = S_OK; CComPtr spWebFilters; CComPtr spAuthSchemes; hr = CoInitialize(NULL); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: CoInitialize Failed. Error code is %lx\n", hr); return hr; } // // Get web filters collection // hr = GetWebFilters(&spWebFilters); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Get the web filters object failed. Error code is %lx\n", hr); CoUninitialize(); return hr; } // // get authentication schemes collection // hr = GetAuthenticationSchemes( &spAuthSchemes ); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to get auth schemes. Error code is %lx\n", hr); CoUninitialize(); return hr; } // // Unregister our authentication schemes // hr = UnregisterAuthentication(spAuthSchemes); if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { hr = S_OK; } if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Remove authentication scheme failed. Error code is %lx\n", hr); CoUninitialize(); return hr; } // // Unregister our web filter // hr = RemoveWebFilter(spWebFilters); if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { hr = S_OK; } if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Remove web filter failed. Error code is %lx\n", hr); CoUninitialize(); return hr; } CoUninitialize(); return hr; } ///////////////////////////////////////////////////////////////////////////// // RegisterISAPINotifications() // Define which ISAPI notification the filter is interested in. ///////////////////////////////////////////////////////////////////////////// BOOL CMyAuthFilter::RegisterISAPINotifications(PHTTP_FILTER_VERSION pVer) { pVer->dwFilterVersion = WPX_HTTP_FILTER_REVISION; pVer->dwFlags = SF_NOTIFY_AUTHENTICATION | SF_NOTIFY_END_OF_REQUEST; return TRUE; } ///////////////////////////////////////////////////////////////////////////// // RegisterWpxNotifications() // Define which WPX specific notification the filter is interested in. ///////////////////////////////////////////////////////////////////////////// BOOL CMyAuthFilter::RegisterWpxNotifications(PHTTP_FILTER_VERSION pVer) { pVer->dwFilterVersion = WPX_HTTP_FILTER_REVISION; pVer->dwFlags = 0; //currently we don't register for any WPX specific notifications return TRUE; } ///////////////////////////////////////////////////////////////////////////// // HttpFilterProc() // Handle ISAPI notifications. ///////////////////////////////////////////////////////////////////////////// DWORD CMyAuthFilter::HttpFilterProc ( PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification) { assert (pfc); SetLastError(ERROR_SUCCESS); DWORD dwRes = 0; switch (notificationType) { case SF_NOTIFY_AUTHENTICATION: { PWPX_FILTER_AUTHENT_EX p = (PWPX_FILTER_AUTHENT_EX) pvNotification; dwRes = m_FilterImpl.OnAuthentication(pfc, p); break; } case SF_NOTIFY_END_OF_REQUEST: { dwRes = m_FilterImpl.OnEndOfRequest(pfc); break; } default: { assert(FALSE); break; } } return dwRes; } ///////////////////////////////////////////////////////////////////////////// // HttpWpxFilterProc() // Handle WPX specific notifications. ///////////////////////////////////////////////////////////////////////////// DWORD CMyAuthFilter::HttpWpxFilterProc ( PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification) { assert (pfc); SetLastError(ERROR_SUCCESS); assert(FALSE); //since we didn't register to any WPX specific notifications return 0; } //////////////////////////////////////////////////////////////////////////// // GetWebFilters() // Helper function which retrieves the WebFilters container from ISA storage // using ISA COM interface. //////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilter::GetWebFilters(IFPCWebFilters** ppWebFilters) { assert(ppWebFilters); HRESULT hr = S_OK; CComPtr spFpc; CComPtr spCurrentArray; CComPtr spExtentions; hr = CoCreateInstance ( CLSID_FPC, NULL, CLSCTX_SERVER, IID_IFPC, (VOID**)&spFpc); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed retrieving interface. Error code is %lx\n", hr); return hr; } hr = spFpc->GetContainingArray(&spCurrentArray); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to query for current array. Error code is %lx\n", hr); return hr; } hr = spCurrentArray->get_Extensions(&spExtentions); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to query for array extentions. Error code is %lx\n", hr); return hr; } hr = spExtentions->get_WebFilters(ppWebFilters); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to query for Web filters. Error code is %lx\n", hr); return hr; } return hr; } ////////////////////////////////////////////////////////////////////////////////// // AddWebFilter(): // Helper function which adds our filter to the ISA WebFilters container using ISA // COM interface. ////////////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilter::AddWebFilter(IFPCWebFilters* pWebFilters) { HRESULT hr = S_OK; CComBSTR bstrTemp; CComBSTR bstrGuid; CComBSTR bstrName; CComBSTR bstrPath; CComPtr spFilter; bstrGuid = x_wcsMyAuthFilterGuid; if (!bstrGuid) { return E_OUTOFMEMORY; } bstrName = x_wcsMyAuthFilterName; if (!bstrName) { return E_OUTOFMEMORY; } bstrPath = x_wcsMyAuthFilterRelativePath; if (!bstrPath) { return E_OUTOFMEMORY; } hr = pWebFilters->Add( bstrGuid, bstrName, bstrPath, fpcFilterPriority_High, fpcFilterDirectionBoth, &spFilter); if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) // Filter already registered { return S_OK; } OutputDebugStringF("MYAUTH: Failed to add the Web filter. Error code is %lx\n", hr); return hr; } bstrTemp = x_wcsMyAuthFilterDescription; if (!bstrTemp) { return E_OUTOFMEMORY; } hr = spFilter->put_Description(bstrTemp); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to set the filter's description. Error code is %lx\n", hr); return hr; } bstrTemp = x_wcsMyAuthFilterVendor; if (!bstrTemp) { return E_OUTOFMEMORY; } hr = spFilter->put_Vendor(bstrTemp); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to set the filter's vendor. Error code is %lx\n", hr); return hr; } bstrTemp = x_wcsMyAuthFilterVersion; if (!bstrTemp) { return E_OUTOFMEMORY; } hr = spFilter->put_Version(bstrTemp); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to set the filter's version. Error code is %lx\n", hr); return hr; } hr = spFilter->put_Enabled(VARIANT_TRUE); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to Enable the filter. Error code is %lx\n", hr); return hr; } hr = pWebFilters->Save(); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to save the filter. Error code is %lx\n", hr); return hr; } return hr; } /////////////////////////////////////////////////////////////////////////////////////// // RemoveWebFilter(): // Helper function which removes our filter to the ISA WebFilters container using ISA // COM interface. ////////////////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilter::RemoveWebFilter(IFPCWebFilters* pWebFilters) { HRESULT hr = S_OK; CComVariant vtFilterGuid(x_wcsMyAuthFilterGuid); if (vtFilterGuid.vt != VT_BSTR || !vtFilterGuid.bstrVal) { return E_OUTOFMEMORY; } hr = pWebFilters->Remove(vtFilterGuid); if (FAILED (hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) // Filter not registered, was already removed { return S_OK; } OutputDebugStringF("MYAUTH: Failed to remove the Web filter. Error code is %lx\n", hr); return hr; } hr = pWebFilters->Save(); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to save. Error code is %lx\n", hr); return hr; } return hr; } ///////////////////////////////////////////////////////////////////////////// // GetAuthenticationSchemes() // Retrieves the AuthenticationSchemes container from ISA storage //////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilter::GetAuthenticationSchemes( IFPCAuthenticationSchemes** ppAuthSchemes ) { HRESULT hr = S_OK; CComPtr spFpc; CComPtr spCurrentArray; CComPtr spRuleElements; hr = CoCreateInstance ( CLSID_FPC, NULL, CLSCTX_SERVER, IID_IFPC, (VOID**)&spFpc); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed retrieving interface. Error code is %lx\n", hr); return hr; } hr = spFpc->GetContainingArray(&spCurrentArray); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to query for current array. Error code is %lx\n", hr); return hr; } hr = spCurrentArray->get_RuleElements( &spRuleElements ); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to query for rule elements. Error code is %lx\n", hr); return hr; } hr = spRuleElements->get_AuthenticationSchemes( ppAuthSchemes ); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to query for auth schemes. Error code is %lx\n", hr); return hr; } return hr; } ///////////////////////////////////////////////////////////////////////////// // RegisterAuthentication() // Adds the new authentication scheme to the authentication schemes collection ///////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilter::RegisterAuthentication(IFPCAuthenticationSchemes* pAuthSchemes) { HRESULT hr = S_OK; CComPtr spAuthScheme; CComBSTR bstrTemp, bstrTemp1; bstrTemp = x_wcsMyAuthFilter_AuthScheme; bstrTemp1 = x_wcsMyAuthSchemeGuid; if (!bstrTemp || !bstrTemp1) { return E_OUTOFMEMORY; } hr = pAuthSchemes->Add(bstrTemp, bstrTemp1, &spAuthScheme); if (FAILED (hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) { return S_OK; //assume all other parameters match } OutputDebugStringF("MYAUTH: Failed to add the Auth Scheme. Error code is %lx\n", hr); return hr; } bstrTemp = x_wcsMyAuthFilterDescription; if (!bstrTemp) { return E_OUTOFMEMORY; } hr = spAuthScheme->put_Description(bstrTemp); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to add the filter's description. Error code is %lx\n", hr); return hr; } hr = spAuthScheme->put_Services(fpcServiceTypeWebProxyBoth); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to set filters services. Error code is %lx\n", hr); return hr; } hr = spAuthScheme->put_Provides(fpcAuthenticationSchemeProvidesBoth); if (FAILED(hr)) { OutputDebugStringF("MYAUTH: Failed to set filters provides. Error code is %lx\n", hr); return hr; } bstrTemp = x_wcsMyAuthFilterVendor; if (!bstrTemp) { return E_OUTOFMEMORY; } hr = spAuthScheme->put_Vendor(bstrTemp); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to set filters vendor. Error code is %lx\n", hr); return hr; } bstrTemp = x_wcsMyAuthFilterVersion; if (!bstrTemp) { return E_OUTOFMEMORY; } hr = spAuthScheme->put_Version(bstrTemp); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to set filters version. Error code is %lx\n", hr); return hr; } hr = pAuthSchemes->Save(); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to save. Error code is %lx\n", hr); return hr; } return hr; } ///////////////////////////////////////////////////////////////////////////// // UnregisterAuthentication() // Removes our authentication scheme from the authentication schemes collection ///////////////////////////////////////////////////////////////////////////// HRESULT CMyAuthFilter::UnregisterAuthentication(IFPCAuthenticationSchemes *pAuthSchemes) { HRESULT hr = S_OK; CComVariant vtAuthScheme = x_wcsMyAuthFilter_AuthScheme; if (vtAuthScheme.vt != VT_BSTR || !vtAuthScheme.bstrVal) { return E_OUTOFMEMORY; } hr = pAuthSchemes->Remove(vtAuthScheme); if ( FAILED(hr) ) { if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) { return S_OK; } OutputDebugStringF("MYAUTH: Failed to remove auth scheme. Error code is %lx\n", hr); return hr; } hr = pAuthSchemes->Save(); if (FAILED (hr)) { OutputDebugStringF("MYAUTH: Failed to save. Error code is %lx\n", hr); return hr; } return hr; }