Skip to content

Remove XBAP-related dead code from Application/BrowserInteropHelper, finish cleanup #9865

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,6 @@ internal static Uri SiteOfOrigin
return siteOfOrigin;
}
}

internal static Uri BrowserSource
{
get
{
return _browserSource;
}
set
{
_browserSource = value;
}
}

#endregion

Expand Down Expand Up @@ -200,17 +188,6 @@ protected override PackagePart GetPartCore(Uri uri)

#endregion

//------------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------

#region Private Members

private static Uri _browserSource;

#endregion Private Members

//------------------------------------------------------
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,6 @@ internal static WebRequest CreateRequest(Uri uri)

CookieHandler.HandleWebRequest(httpRequest);

if (String.IsNullOrEmpty(httpRequest.Referer))
{
httpRequest.Referer = BindUriHelper.GetReferer(uri);
}

CustomCredentialPolicy.EnsureCustomCredentialPolicy();

// Enable NTLM authentication.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

Expand All @@ -13,12 +13,10 @@
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//

using MS.Win32;
using System.Windows;
using System.Windows.Interop;
using MS.Internal.Utility;
using MS.Win32;
using System.Runtime.InteropServices;
using MS.Internal.Documents.Application;

namespace MS.Internal.AppModel
{
Expand All @@ -31,9 +29,6 @@ enum LaunchResult

internal static class AppSecurityManager
{
#region Internal Methods


///<summary>
/// Safely launch the browser if you can.
/// If you can't demand unmanaged code permisison.
Expand Down Expand Up @@ -88,10 +83,7 @@ internal static LaunchResult SafeLaunchBrowserOnlyIfPossible(Uri originatingUri,
// For all other cases ( evil protocols etc).
// We will demand.
//
// The check of IsInitialViewerNavigation is necessary because viewer applications will probably
// need to call Navigate on the URI they receive, but we want them to be able to do it in partial trust.
if (!BrowserInteropHelper.IsInitialViewerNavigation &&
((fIsTopLevel && isKnownScheme) || fIsMailTo))
if ((fIsTopLevel && isKnownScheme) || fIsMailTo)
{
if (!isKnownScheme && fIsMailTo) // unnecessary if - but being paranoid.
{
Expand Down Expand Up @@ -145,285 +137,5 @@ the key used is (supposedly) HKCR\htmlfile\shell\opennew\ddeexec, and its value
throw new InvalidOperationException(SR.FailToLaunchDefaultBrowser,
new System.ComponentModel.Win32Exception(/*uses the last Win32 error*/));
}

#endregion Internal Methods

#region Private Methods

/// <summary>
/// Returns the HTTP "Referer" header.
/// </summary>
/// <returns>returns a string containing one or more HTTP headers separated by \r\n; the string must also be terminated with a \r\n</returns>
private static string GetHeaders(Uri destinationUri)
{
string referer = BindUriHelper.GetReferer(destinationUri);

if (!String.IsNullOrEmpty(referer))
{
// The headers we pass in to IWebBrowser2.Navigate must
// be terminated with a \r\n because the browser then
// concatenates its own headers on to the end of that string.
referer = $"{RefererHeader}{referer}\r\n";
}

return referer;
}

//
// Functionally equivalent copy of Trident's CanNavigateToUrlWithZoneCheck function
// Checks to see whether a navigation is considered a zone elevation.
// Once a zone elevation is identified - calls into urlmon to check settings.
//
private static LaunchResult CanNavigateToUrlWithZoneCheck(Uri originatingUri, Uri destinationUri)
{
LaunchResult launchResult = LaunchResult.NotLaunched; // fail securely - assume this is the default.
int targetZone = NativeMethods.URLZONE_LOCAL_MACHINE; // fail securely this is the most priveleged zone
int sourceZone = NativeMethods.URLZONE_INTERNET; // fail securely this is the least priveleged zone.
bool fEnabled = true;

EnsureSecurityManager();

// is this feature enabled ?
fEnabled = UnsafeNativeMethods.CoInternetIsFeatureEnabled(
NativeMethods.FEATURE_ZONE_ELEVATION,
NativeMethods.GET_FEATURE_FROM_PROCESS) != NativeMethods.S_FALSE;

targetZone = MapUrlToZone(destinationUri);

// Get source zone.

// Initialize sourceUri to null so that source zone defaults to the least privileged zone.
Uri sourceUri = null;

// If the MimeType is not a container, attempt to find sourceUri.
// sourceUri should be null for Container cases, since it always assumes
// the least privileged zone (InternetZone).
if (Application.Current.MimeType != MimeType.Document)
{
sourceUri = BrowserInteropHelper.Source;
}
else if (destinationUri.IsFile &&
System.IO.Path.GetExtension(destinationUri.LocalPath)
.Equals(DocumentStream.XpsFileExtension, StringComparison.OrdinalIgnoreCase))
{
// In this case we know the following:
// 1) We are currently a Container
// 2) The destination is a File and another Container

// In this case we want to treat the destination as internet too so Container
// can navigate to other Containers by passing zone checks
targetZone = NativeMethods.URLZONE_INTERNET;
}

if (sourceUri != null)
{
sourceZone = MapUrlToZone(sourceUri);
}
else
{
// 2 potential ways to get here.
// a) We aren't a fusion hosted app. Assume full-trust.
// b) Some bug in hosting caused source Uri to be null.
//
// For a - we will say there is no cross-domain check.
// b - we'll assume InternetZone, and use Source.
return LaunchResult.Launched;
}

// <Notes from Trident>
// ------------------------------
// Check if there is a zone elevation.
// Custom zones would have a higher value that URLZONE_UNTRUSTED, so this solution isn't quite complete.
// However, we don't know of any product actively using custom zones, so rolling this out.
// INTRANET and TRUSTED are treated as equals.
// ------------------------------
// </Notes from Trident>

//
// Note the negative logic - it first sees to see something is *not* a zone elevation.
//
if (
// Even if feature is disabled.
// We still block navigation to local machine.
// IF source zone is internet or restricted.

(!fEnabled &&
((sourceZone != NativeMethods.URLZONE_INTERNET &&
sourceZone != NativeMethods.URLZONE_UNTRUSTED) ||
targetZone != NativeMethods.URLZONE_LOCAL_MACHINE)) ||

// If feature is enabled
// It's not a zone elevation if
// the zones are equal OR
// the zones are both less than restricted and
// the sourceZone is more trusted than Target OR
// sourceZone and TargetZone are both Intranet or Trusted
//
// per aganjam - Intranet and Trusted are treated as equivalent
// as it was a common scenario for IE. ( website on intranet points to trusted site).
//

(fEnabled &&
(
sourceZone == targetZone ||
(
sourceZone <= NativeMethods.URLZONE_UNTRUSTED &&
targetZone <= NativeMethods.URLZONE_UNTRUSTED &&
(
sourceZone < targetZone ||
(
(sourceZone == NativeMethods.URLZONE_TRUSTED || sourceZone == NativeMethods.URLZONE_INTRANET) &&
(targetZone == NativeMethods.URLZONE_TRUSTED || targetZone == NativeMethods.URLZONE_INTRANET)
)
)
)
)))
{
// There is no zone elevation. You can launch away !
return LaunchResult.Launched;
}

launchResult = CheckBlockNavigation(sourceUri,
destinationUri,
fEnabled);

return launchResult;
}

///<summary>
/// Called when we suspect there is a zone elevation.
/// Calls the Urlmon IsFeatureZoneElevationEnabled which may pop UI based on settings.
/// functionally equivalent to the BlockNavigation: label in Trident's CanNavigateToUrlWithZoneCheck
///</summary>
private static LaunchResult CheckBlockNavigation(Uri originatingUri, Uri destinationUri, bool fEnabled)
{
if (fEnabled)
{
if (UnsafeNativeMethods.CoInternetIsFeatureZoneElevationEnabled(
BindUriHelper.UriToString(originatingUri),
BindUriHelper.UriToString(destinationUri),
_secMgr,
NativeMethods.GET_FEATURE_FROM_PROCESS) == NativeMethods.S_FALSE)
{
return LaunchResult.Launched;
}
else
{
if (IsZoneElevationSettingPrompt(destinationUri))
{
// url action is query, and we got a "no" answer back.
// we can assume user responded No.
return LaunchResult.NotLaunchedDueToPrompt;
}
else
return LaunchResult.NotLaunched;
}
}
else
{
return LaunchResult.Launched;
}
}

// Is ZoneElevation setting set to prompt ?
private static bool IsZoneElevationSettingPrompt(Uri target)
{
Invariant.Assert(_secMgr != null);

// Was this due to a prompt ?

int policy = NativeMethods.URLPOLICY_DISALLOW;

unsafe
{
String targetString = BindUriHelper.UriToString(target);

_secMgr.ProcessUrlAction(targetString,
NativeMethods.URLACTION_FEATURE_ZONE_ELEVATION,
(byte*)&policy,
sizeof(int),
null,
0,
NativeMethods.PUAF_NOUI,
0);
}

return (policy == NativeMethods.URLPOLICY_QUERY);
}

private static void EnsureSecurityManager()
{
// IMPORTANT: See comments in header r.e. IInternetSecurityManager

if (_secMgr == null)
{
lock (_lockObj)
{
if (_secMgr == null) // null check again - now that we're in the lock.
{
_secMgr = (UnsafeNativeMethods.IInternetSecurityManager)new InternetSecurityManager();

//
// Set the Security Manager Site.
// This enables any dialogs popped to be modal to our window.
//
_secMgrSite = new SecurityMgrSite();

_secMgr.SetSecuritySite((NativeMethods.IInternetSecurityMgrSite)_secMgrSite);
}
}
}
}



internal static void ClearSecurityManager()
{
if (_secMgr != null)
{
lock (_lockObj)
{
if (_secMgr != null)
{
_secMgr.SetSecuritySite(null);
_secMgrSite = null;
_secMgr = null;
}
}
}
}

internal static int MapUrlToZone(Uri url)
{
EnsureSecurityManager();
int zone;
_secMgr.MapUrlToZone(BindUriHelper.UriToString(url), out zone, 0);
return zone;
}

[ComImport, ComVisible(false), Guid("7b8a2d94-0ac9-11d1-896c-00c04Fb6bfc4")]
internal class InternetSecurityManager
{
}



#endregion Private Methods

#region Private Fields

private const string RefererHeader = "Referer: ";

private const string BrowserOpenCommandLookupKey = "htmlfile\\shell\\open\\command";

// Object to be used for locking. Using typeof(Util) causes an FxCop
// violation DoNotLockOnObjectsWithWeakIdentity
private static readonly object _lockObj = new object();

private static UnsafeNativeMethods.IInternetSecurityManager _secMgr;

private static SecurityMgrSite _secMgrSite;

#endregion Private Fields
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,4 @@ enum HostingFlags
};


//********************************************************************************************//
// IMPORTANT: IMPORTANT: IMPORTANT: IMPORTANT: //
//********************************************************************************************//
// If you change or update this interface, make sure you update the definitions in
// wcp\host\inc\hostservices.idl
// In addition, make sure the enum is updated in wcp\host\startup\shellhandler.cxx
internal enum MimeType
{
Unknown = 0,
Document = 1,
Application = 2,
Markup = 3
}
}
Loading