Skip to content

Commit

Permalink
Remove XBAP-related dead code from Application/BrowserInteropHelper, …
Browse files Browse the repository at this point in the history
…finish cleanup (#9865)

* Remove IBrowserCallbackServices XBAP-related dead code

* Remove code paths called via ApplicationProxyInternal

* Keep IsViewer to better show intent (MimeType was never set on .NET Core)

* Explain why IsInitialViewerNavigation is always false

* Remove IsInitialViewerNavigation from conditions where the value does not matter

* Remove some remarks to RootBrowserWindow that no longer exists

* Remove IInternetSecurityMgrSite as it is no longer used without XBAP support

* Final cleanup in AppSecurityManager

* Cleanup after #9855 merge

* Add back a forgotten using for UnsafeNativeMethods
  • Loading branch information
h3xds1nz authored Jan 3, 2025
1 parent 14c9db3 commit 605ebf9
Show file tree
Hide file tree
Showing 10 changed files with 25 additions and 542 deletions.
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

0 comments on commit 605ebf9

Please sign in to comment.