You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
502 lines
11 KiB
502 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
urlzone.cxx
|
|
|
|
Abstract:
|
|
|
|
Glue layer to zone security manager, now residing in urlmon.dll
|
|
|
|
Author:
|
|
|
|
Rajeev Dujari (rajeevd) 02-Aug-1997
|
|
|
|
Contents:
|
|
|
|
UrlZonesAttach
|
|
UrlZonesDetach
|
|
GetCredPolicy
|
|
|
|
--*/
|
|
|
|
|
|
#include <wininetp.h>
|
|
#include "urlmon.h"
|
|
|
|
//
|
|
// prototypes
|
|
//
|
|
typedef HRESULT (*PFNCREATESECMGR)(IServiceProvider * pSP, IInternetSecurityManager **ppSM, DWORD dwReserved);
|
|
typedef HRESULT (*PFNCREATEZONEMGR)(IServiceProvider * pSP, IInternetZoneManager **ppZM, DWORD dwReserved);
|
|
|
|
//
|
|
// globals
|
|
//
|
|
IInternetSecurityManager* g_pSecMgr = NULL;
|
|
IInternetZoneManager* g_pZoneMgr = NULL;
|
|
|
|
static BOOL g_bAttemptedInit = FALSE;
|
|
static HINSTANCE g_hInstUrlMon = NULL;
|
|
static PFNCREATESECMGR g_pfnCreateSecMgr = NULL;
|
|
static PFNCREATEZONEMGR g_pfnCreateZoneMgr = NULL;
|
|
|
|
//
|
|
// Handy class which uses a stack buffer if possible, otherwise allocates.
|
|
//
|
|
struct FlexBuf
|
|
{
|
|
BYTE Buf[512];
|
|
LPBYTE pbBuf;
|
|
|
|
FlexBuf()
|
|
{
|
|
pbBuf = NULL;
|
|
}
|
|
|
|
~FlexBuf()
|
|
{
|
|
if (pbBuf != NULL) {
|
|
delete [] pbBuf;
|
|
}
|
|
}
|
|
|
|
LPBYTE GetPtr (DWORD cbBuf)
|
|
{
|
|
if (cbBuf < sizeof(Buf))
|
|
return Buf;
|
|
pbBuf = new BYTE [cbBuf];
|
|
return pbBuf;
|
|
}
|
|
};
|
|
|
|
struct UnicodeBuf : public FlexBuf
|
|
{
|
|
LPWSTR Convert (LPCSTR pszUrl)
|
|
{
|
|
DWORD cbUrl = lstrlenA (pszUrl) + 1;
|
|
LPWSTR pwszUrl = (LPWSTR) GetPtr (sizeof(WCHAR) * cbUrl);
|
|
if (!pwszUrl)
|
|
return NULL;
|
|
MultiByteToWideChar
|
|
(CP_ACP, 0, pszUrl, cbUrl, pwszUrl, cbUrl);
|
|
return pwszUrl;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Dynaload urlmon and create security manager object on demand.
|
|
//
|
|
|
|
BOOL UrlZonesAttach (void)
|
|
{
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
BOOL bRet = FALSE;
|
|
HRESULT hr;
|
|
|
|
if (g_bAttemptedInit)
|
|
{
|
|
bRet = (g_pSecMgr != NULL && g_pZoneMgr != NULL);
|
|
goto End;
|
|
}
|
|
|
|
g_bAttemptedInit = TRUE;
|
|
|
|
g_hInstUrlMon = LoadLibraryA(URLMON_DLL);
|
|
if (!g_hInstUrlMon)
|
|
{
|
|
bRet = FALSE;
|
|
goto End;
|
|
}
|
|
|
|
g_pfnCreateSecMgr = (PFNCREATESECMGR)
|
|
GetProcAddress(g_hInstUrlMon, "CoInternetCreateSecurityManager");
|
|
if (!g_pfnCreateSecMgr)
|
|
{
|
|
bRet = FALSE;
|
|
goto End;
|
|
}
|
|
|
|
g_pfnCreateZoneMgr = (PFNCREATEZONEMGR)
|
|
GetProcAddress(g_hInstUrlMon, "CoInternetCreateZoneManager");
|
|
if (!g_pfnCreateZoneMgr)
|
|
{
|
|
bRet = FALSE;
|
|
goto End;
|
|
}
|
|
|
|
hr = (*g_pfnCreateSecMgr)(NULL, &g_pSecMgr, NULL);
|
|
if( hr != S_OK )
|
|
{
|
|
bRet = FALSE;
|
|
goto End;
|
|
}
|
|
|
|
hr = (*g_pfnCreateZoneMgr)(NULL, &g_pZoneMgr, NULL);
|
|
bRet = (hr == S_OK);
|
|
|
|
End:
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
return bRet;
|
|
}
|
|
|
|
//
|
|
// Clean up upon process detach.
|
|
//
|
|
|
|
STDAPI_(void) UrlZonesDetach (void)
|
|
{
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
|
|
if (g_pSecMgr)
|
|
{
|
|
g_pSecMgr->Release();
|
|
g_pSecMgr = NULL;
|
|
}
|
|
if (g_pZoneMgr)
|
|
{
|
|
g_pZoneMgr->Release();
|
|
g_pZoneMgr = NULL;
|
|
}
|
|
if (g_hInstUrlMon)
|
|
{
|
|
FreeLibrary(g_hInstUrlMon);
|
|
g_hInstUrlMon = NULL;
|
|
}
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
}
|
|
|
|
extern "C" DWORD GetZoneFromUrl(LPCSTR pszUrl);
|
|
|
|
DWORD GetZoneFromUrl(LPCSTR pszUrl)
|
|
{
|
|
DWORD dwZone;
|
|
dwZone = URLZONE_UNTRUSTED; // null URL indicates restricted zone.
|
|
|
|
UnicodeBuf ub;
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
if (!g_pSecMgr && !UrlZonesAttach())
|
|
goto err;
|
|
|
|
LPWSTR pwszUrl;
|
|
if (!pszUrl)
|
|
pwszUrl = NULL;
|
|
else
|
|
{
|
|
pwszUrl = ub.Convert (pszUrl);
|
|
if (!pwszUrl)
|
|
goto err;
|
|
}
|
|
|
|
if (pszUrl)
|
|
{
|
|
// Otherwise determine the zone for this URL.
|
|
g_pSecMgr->MapUrlToZone (pwszUrl, &dwZone, 0);
|
|
}
|
|
|
|
err:
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
return dwZone;
|
|
}
|
|
|
|
//
|
|
// Routine to get the Routine to indicate whether ntlm logon credential is allowed.
|
|
//
|
|
|
|
DWORD GetCredPolicy (LPSTR pszUrl)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwPolicy;
|
|
|
|
UnicodeBuf ub;
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
|
|
if (!UrlZonesAttach())
|
|
goto err;
|
|
|
|
LPWSTR pwszUrl;
|
|
if (!pszUrl)
|
|
pwszUrl = NULL;
|
|
else
|
|
{
|
|
pwszUrl = ub.Convert (pszUrl);
|
|
if (!pwszUrl)
|
|
goto err;
|
|
}
|
|
|
|
hr = g_pSecMgr->ProcessUrlAction (pwszUrl, URLACTION_CREDENTIALS_USE,
|
|
(LPBYTE) &dwPolicy, sizeof(dwPolicy), NULL, 0, PUAF_NOUI, 0);
|
|
|
|
|
|
// Resolve the ambiguous "Prompt if Intranet zone policy".
|
|
|
|
if (dwPolicy == URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT)
|
|
{
|
|
DWORD dwZone;
|
|
dwZone = URLZONE_UNTRUSTED; // null URL indicates restricted zone.
|
|
|
|
if (pszUrl)
|
|
{
|
|
// Otherwise determine the zone for this URL.
|
|
hr = g_pSecMgr->MapUrlToZone (pwszUrl, &dwZone, 0);
|
|
if (hr != S_OK)
|
|
goto err;
|
|
}
|
|
|
|
if (dwZone == URLZONE_INTRANET)
|
|
dwPolicy = URLPOLICY_CREDENTIALS_SILENT_LOGON_OK;
|
|
else
|
|
dwPolicy = URLPOLICY_CREDENTIALS_MUST_PROMPT_USER;
|
|
}
|
|
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
return dwPolicy;
|
|
|
|
err:
|
|
INET_ASSERT (FALSE);
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
return URLPOLICY_CREDENTIALS_MUST_PROMPT_USER;
|
|
}
|
|
|
|
/*
|
|
Main-switch for the cookie feature has 3 states.
|
|
1. ALLOW: all cookies are accepted/replayed (including leashed ones)
|
|
2. QUERY: received cookies are subject to P3P evaluation,
|
|
leashed cookies are not replayed
|
|
3. DISALLOW:no cookies are accepted/replayed.
|
|
*/
|
|
DWORD GetCookieMainSwitch(DWORD dwZone) {
|
|
|
|
DWORD dwPolicy = URLPOLICY_DISALLOW;
|
|
|
|
if (!UrlZonesAttach())
|
|
return dwPolicy;
|
|
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
|
|
HRESULT hr = g_pZoneMgr->GetZoneActionPolicy(dwZone, URLACTION_COOKIES_ENABLED,
|
|
(LPBYTE)&dwPolicy, sizeof(dwPolicy),
|
|
URLZONEREG_DEFAULT);
|
|
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
|
|
return SUCCEEDED(hr) ? dwPolicy : URLPOLICY_ALLOW;
|
|
}
|
|
|
|
DWORD GetCookieMainSwitch(LPCSTR pszURL) {
|
|
|
|
return GetCookieMainSwitch(GetZoneFromUrl(pszURL));
|
|
}
|
|
|
|
DWORD GetCookiePolicy (LPCSTR pszUrl, DWORD dwUrlAction, BOOL fRestricted)
|
|
{
|
|
if (GlobalSuppressCookiesPolicy)
|
|
{
|
|
return URLPOLICY_ALLOW;
|
|
}
|
|
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
UnicodeBuf ub;
|
|
DWORD dwCP;
|
|
|
|
if (!UrlZonesAttach())
|
|
goto err;
|
|
|
|
// Convert to unicode.
|
|
LPWSTR pwszUrl;
|
|
pwszUrl = ub.Convert (pszUrl);
|
|
if (!pwszUrl)
|
|
goto err;
|
|
|
|
DWORD dwPolicy;
|
|
HRESULT hr;
|
|
DWORD dwFlags;
|
|
|
|
dwFlags = PUAF_NOUI;
|
|
if (fRestricted)
|
|
dwFlags |= PUAF_ENFORCERESTRICTED;
|
|
|
|
hr = g_pSecMgr->ProcessUrlAction (pwszUrl, dwUrlAction,
|
|
(LPBYTE) &dwPolicy, sizeof(dwPolicy), NULL, 0, dwFlags, 0);
|
|
|
|
if (!SUCCEEDED(hr) )
|
|
goto err;
|
|
|
|
dwCP = GetUrlPolicyPermissions(dwPolicy);
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
return dwCP;
|
|
|
|
err:
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
INET_ASSERT (FALSE);
|
|
return URLPOLICY_QUERY;
|
|
}
|
|
|
|
DWORD GetClientCertPromptPolicy (LPCSTR pszUrl, BOOL fRestricted /* = FALSE */)
|
|
{
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
UnicodeBuf ub;
|
|
DWORD dwCP;
|
|
DWORD dwUrlAction = URLACTION_CLIENT_CERT_PROMPT;
|
|
DWORD dwFlags;
|
|
|
|
if (!UrlZonesAttach())
|
|
goto err;
|
|
|
|
// Convert to unicode.
|
|
LPWSTR pwszUrl;
|
|
pwszUrl = ub.Convert (pszUrl);
|
|
if (!pwszUrl)
|
|
goto err;
|
|
|
|
DWORD dwPolicy;
|
|
|
|
dwFlags = PUAF_NOUI;
|
|
if (fRestricted)
|
|
dwFlags |= PUAF_ENFORCERESTRICTED;
|
|
|
|
HRESULT hr;
|
|
|
|
hr = g_pSecMgr->ProcessUrlAction (pwszUrl, dwUrlAction,
|
|
(LPBYTE) &dwPolicy, sizeof(dwPolicy), NULL, 0, dwFlags, 0);
|
|
|
|
if (!SUCCEEDED(hr) )
|
|
goto err;
|
|
|
|
dwCP = GetUrlPolicyPermissions(dwPolicy);
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
return dwCP;
|
|
|
|
err:
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
INET_ASSERT (FALSE);
|
|
return URLPOLICY_QUERY;
|
|
}
|
|
|
|
VOID SetStopWarning( LPCSTR pszUrl, DWORD dwPolicy, DWORD dwUrlAction)
|
|
{
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
UnicodeBuf ub;
|
|
ZONEATTRIBUTES za = {0};
|
|
|
|
if (!UrlZonesAttach())
|
|
goto err;
|
|
|
|
// Convert to unicode.
|
|
LPWSTR pwszUrl;
|
|
pwszUrl = ub.Convert (pszUrl);
|
|
if (!pwszUrl)
|
|
goto err;
|
|
|
|
HRESULT hr;
|
|
DWORD dwZone;
|
|
hr = g_pSecMgr->MapUrlToZone(pwszUrl, &dwZone, 0);
|
|
if (!SUCCEEDED(hr) )
|
|
goto err;
|
|
|
|
DWORD dwZonePolicy;
|
|
|
|
hr = g_pZoneMgr->GetZoneActionPolicy(
|
|
dwZone,
|
|
dwUrlAction,
|
|
(LPBYTE)&dwZonePolicy,
|
|
sizeof(dwZonePolicy),
|
|
URLZONEREG_DEFAULT );
|
|
|
|
if (!SUCCEEDED(hr) )
|
|
goto err;
|
|
|
|
// set the policy back with passed value
|
|
SetUrlPolicyPermissions(dwZonePolicy, dwPolicy);
|
|
|
|
hr = g_pZoneMgr->SetZoneActionPolicy(
|
|
dwZone,
|
|
dwUrlAction,
|
|
(LPBYTE) &dwZonePolicy,
|
|
sizeof(dwZonePolicy),
|
|
URLZONEREG_DEFAULT );
|
|
|
|
if (!SUCCEEDED(hr) )
|
|
goto err;
|
|
|
|
// change the generic zone setting to 'custom' now we've changed something
|
|
za.cbSize = sizeof(ZONEATTRIBUTES);
|
|
g_pZoneMgr->GetZoneAttributes(dwZone, &za);
|
|
za.dwTemplateCurrentLevel = URLTEMPLATE_CUSTOM;
|
|
g_pZoneMgr->SetZoneAttributes(dwZone, &za);
|
|
|
|
|
|
err:
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Set and query no cookies mode
|
|
//
|
|
BOOL IsNoCookies(DWORD dwZone)
|
|
{
|
|
BOOL fNoCookies = FALSE;
|
|
HRESULT hr;
|
|
DWORD dwZonePolicy;
|
|
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
|
|
if (!UrlZonesAttach())
|
|
goto exit;
|
|
|
|
hr = g_pZoneMgr->GetZoneActionPolicy(
|
|
dwZone,
|
|
URLACTION_COOKIES_ENABLED,
|
|
(LPBYTE)&dwZonePolicy,
|
|
sizeof(dwZonePolicy),
|
|
URLZONEREG_DEFAULT );
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
dwZonePolicy = GetUrlPolicyPermissions(dwZonePolicy);
|
|
if(URLPOLICY_DISALLOW == dwZonePolicy)
|
|
{
|
|
fNoCookies = TRUE;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
return fNoCookies;
|
|
}
|
|
|
|
void SetNoCookies(DWORD dwZone, DWORD dwNewPolicy)
|
|
{
|
|
DWORD dwZonePolicy;
|
|
HRESULT hr;
|
|
|
|
EnterCriticalSection(&ZoneMgrCritSec);
|
|
|
|
if (!UrlZonesAttach())
|
|
goto exit;
|
|
|
|
hr = g_pZoneMgr->GetZoneActionPolicy(
|
|
dwZone,
|
|
URLACTION_COOKIES_ENABLED,
|
|
(LPBYTE)&dwZonePolicy,
|
|
sizeof(dwZonePolicy),
|
|
URLZONEREG_DEFAULT );
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
SetUrlPolicyPermissions(dwZonePolicy, dwNewPolicy);
|
|
|
|
g_pZoneMgr->SetZoneActionPolicy(
|
|
dwZone,
|
|
URLACTION_COOKIES_ENABLED,
|
|
(LPBYTE)&dwZonePolicy,
|
|
sizeof(dwZonePolicy),
|
|
URLZONEREG_DEFAULT );
|
|
}
|
|
|
|
exit:
|
|
LeaveCriticalSection(&ZoneMgrCritSec);
|
|
}
|