Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / AppModel / AppSecurityManager.cs / 3 / AppSecurityManager.cs
//------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2001 // // File: appsecuritymanager.cs // // Description: AppSecurityManager class. // //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // IMPORTANT: We are creating an instance of IInternetSecurityManager here. This // is currently also done in the CustomCredentialPolicy at the Core level. Any // modification to either of these classes--especially concerning MapUrlToZone-- // should be considered for both classes. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // // History: 04-24-02 - [....] - created //----------------------------------------------------------------------------- using System; using System.Collections; using System.Diagnostics; using System.Globalization; using System.Security; using System.Security.Permissions; using Microsoft.Win32; using System.IO.Packaging; using System.Windows; using System.Windows.Interop; using MS.Internal.Utility; using MS.Internal.PresentationFramework; // SecurityHelper using MS.Win32; using System.Runtime.InteropServices; using MS.Internal.Documents.Application; namespace MS.Internal.AppModel { enum LaunchResult { Launched, NotLaunched, NotLaunchedDueToPrompt }; internal static class AppSecurityManager { #region Internal Methods ////// Safely launch the browser if you can. /// If you can't demand unmanaged code permisison. /// /// originatingUri = the current uri /// destinationUri = the uri you are going to. /// ////// Critical - gets access to critical resource (uri), calls critical code (launch browser) /// TreatAsSafe because /// we consider navigates to http or http to the top-level browser as safe. /// we consider navigates to mailto as safe. /// for all other cases - we demand Unmanaged Code Permission /// [SecurityCritical, SecurityTreatAsSafe] internal static void SafeLaunchBrowserDemandWhenUnsafe( Uri originatingUri, Uri destinationUri, bool fIsTopLevel ) { LaunchResult launched = LaunchResult.NotLaunched; launched = SafeLaunchBrowserOnlyIfPossible( originatingUri, destinationUri, fIsTopLevel ) ; if ( launched == LaunchResult.NotLaunched ) { SecurityHelper.DemandUnmanagedCode(); UnsafeLaunchBrowser( destinationUri ); } } ////// Safely launch the browser if it's possible to do so in partial trust /// Returns enum indicating whether we safely launched ( or at least think we did). /// /// This function is appropriate for use when we launch the browser from partial trust /// ( as it doesn't perform demands for the "unsafe" cases ) /// internal static LaunchResult SafeLaunchBrowserOnlyIfPossible(Uri originatingUri, Uri destinationUri, bool fIsTopLevel) { return SafeLaunchBrowserOnlyIfPossible(originatingUri, destinationUri, null, fIsTopLevel); } ////// Safely launch the browser if it's possible to do so in partial trust /// Returns enum indicating whether we safely launched ( or at least think we did). /// Html target names can be passed in with this. /// This function is appropriate for use when we launch the browser from partial trust /// ( as it doesn't perform demands for the "unsafe" cases ) /// ////// Critical - gets access to critical resource (uri), calls critical code (launch browser) /// /// TreatAsSafe because /// we consider navigates to http or http to the top-level browser as safe. /// we consider navigates to mailto as safe. /// /// for all other cases - we don't launch the browser - and return a result /// indicating that we didn't launch. /// [SecurityCritical, SecurityTreatAsSafe] internal static LaunchResult SafeLaunchBrowserOnlyIfPossible(Uri originatingUri, Uri destinationUri, string targetName, bool fIsTopLevel ) { LaunchResult launched = LaunchResult.NotLaunched ; // // check to see if this is a sub-classed URI // if it is a sub-class - demand unmanaged code permission. // this prevents exploits where the Uri has been subclassed, and overrides toString() // // Note that in whidbey RTM - these types of exploits will not be possible. // As there is inheritance demand on callers. // if ( destinationUri.GetType().IsSubclassOf( typeof( Uri ))) { SecurityHelper.DemandInfrastructurePermission(); } bool isKnownScheme = (Object.ReferenceEquals(destinationUri.Scheme, Uri.UriSchemeHttp)) || (Object.ReferenceEquals(destinationUri.Scheme, Uri.UriSchemeHttps)) || destinationUri.IsFile; bool fIsMailTo = String.Compare(destinationUri.Scheme, Uri.UriSchemeMailto, StringComparison.OrdinalIgnoreCase) == 0 ; // We elevate to navigate the browser iff: // We are user initiated AND // Scheme == http/https & topLevel OR scheme == mailto. // // 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 && SecurityHelper.CallerHasUserInitiatedNavigationPermission()) && ((fIsTopLevel && isKnownScheme) || fIsMailTo ) ) { if (isKnownScheme) { IBrowserCallbackServices ibcs = ( Application.Current != null ) ? Application.Current.BrowserCallbackServices : null ; if (ibcs != null) { launched = CanNavigateToUrlWithZoneCheck(originatingUri , destinationUri); if ( launched == LaunchResult.Launched ) { // resetting launched to NotLaunched here; if the assert succeeds // and ibcs.DelegateNavigation does not throw then we will set it to Launched. launched = LaunchResult.NotLaunched; // Browser app. // ibcs.DelegateNavigation( BindUriHelper.UriToString( destinationUri ), targetName, GetHeaders(destinationUri)); launched = LaunchResult.Launched ; } } } else if ( fIsMailTo ) // unnecessary if - but being paranoid. { // Shell-Exec the browser to the mailto url. // assumed safe - because we're only allowing this for mailto urls. // UnsafeNativeMethods.ShellExecute( new HandleRef( null, IntPtr.Zero) , /*hwnd*/ null, /*operation*/ BindUriHelper.UriToString( destinationUri ), /*file*/ null, /*parameters*/ null, /*directory*/ 0 ); /*nShowCmd*/ launched = LaunchResult.Launched ; } } return launched ; } // This invokes the browser unsafely. // Whoever is calling this function should do the right demands. ////// Critical - gets access to critical resource (uri and browsercallback services), calls critical code (launch browser) /// [SecurityCritical] internal static void UnsafeLaunchBrowser(Uri uri) { // This'll likely go into SafeLaunchBrowser() function. if (Application.Current != null) { IBrowserCallbackServices ibcs = Application.Current.BrowserCallbackServices; if (ibcs != null) { // Browser app. // ibcs.DelegateNavigation(BindUriHelper.UriToString(uri), null, GetHeaders(uri)); return; } } ShellExecuteDefaultBrowser(uri); } ////// Opens the default browser for the passed in Uri. /// ////// Critical - calls critical code (ShellExecuteEx) /// [SecurityCritical] internal static void ShellExecuteDefaultBrowser(Uri uri) { UnsafeNativeMethods.ShellExecuteInfo sei = new UnsafeNativeMethods.ShellExecuteInfo(); sei.cbSize = Marshal.SizeOf(sei); sei.fMask = UnsafeNativeMethods.ShellExecuteFlags.SEE_MASK_FLAG_DDEWAIT; /* There is a bug on Windows Vista (with IE 7): ShellExecute via SEE_MASK_CLASSNAME fails for an http[s]:// URL. It works fine for file://. The cause appears to be that the DDE command template defined in HKCR\IE.AssocFile.HTM\shell\opennew\ddeexec is used: [file://%1",-1,,,,,]. On XP, the the key used is (supposedly) HKCR\htmlfile\shell\opennew\ddeexec, and its value is ["%1",,-1,0,,,,]. The workaround here is to add the SEE_MASK_CLASSNAME flag only for non-HTTP URLs. For HTTP, "plain" ShellExecute just works, incl. with Firefox/Netscape as the default browser. */ if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) { sei.fMask |= UnsafeNativeMethods.ShellExecuteFlags.SEE_MASK_CLASSNAME; sei.lpClass = ".htm"; // The default browser is looked up by this. } sei.lpFile = uri.ToString(); if (!UnsafeNativeMethods.ShellExecuteEx(sei)) throw new InvalidOperationException(SR.Get(SRID.FailToLaunchDefaultBrowser), new System.ComponentModel.Win32Exception(/*uses the last Win32 error*/)); } #endregion Internal Methods #region Private Methods ////// Returns the HTTP "Referer" header. /// ///returns a string containing one or more HTTP headers separated by \r\n; the string must also be terminated with a \r\n 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. // ////// Critical - performs elevations to call IsFeatureEnabled, calls EnsureSecurityManager, /// call critical method MUTZ /// /// TreatAsSafe - information disclosed is whether a navigation is "safe" or not. /// considered ok to give out. you will be able to get this anyway by trapping exceptions /// or seeing whether a navigation succeeded/failed. /// [SecurityCritical, SecurityTreatAsSafe ] 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 ; // Get target zone. string destinationUriString = BindUriHelper.UriToString( destinationUri ); _secMgr.MapUrlToZone( destinationUriString , out targetZone, 0 ); // 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 ) { string sourceUriString = BindUriHelper.UriToString( sourceUri ); _secMgr.MapUrlToZone( sourceUriString , out sourceZone, 0 ); } 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. bool fTrusted = SecurityHelper.CheckUnmanagedCodePermission(); if ( fTrusted ) { return LaunchResult.Launched; } else { // // If we didn't get a SourceUri, we'll assume internet zone. // And use Source for the uri of origin. // // This isn't quite right - but the sourceUri is only used to show a message to the user. // Worse case is confusing user experience. ( this uri is not used in the elevation determination). // sourceZone = NativeMethods.URLZONE_INTERNET ; sourceUri = originatingUri ; } } //// ------------------------------ // 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. // ------------------------------ // // // 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 ; } ////// 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 /// ////// Critical - calls a function that has a SUC on it. ( CoIntenrnetIsFeatureZoneElevationEnabled) /// [SecurityCritical] 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 ? ////// Critical - elevates to call ProcessUrlAction. /// TreatAsSafe - information return indicates whether we will prompt for the current zone. /// considered ok to expose. /// [SecurityCritical, SecurityTreatAsSafe] 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 ) ; new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert: try { _secMgr.ProcessUrlAction( targetString, NativeMethods.URLACTION_FEATURE_ZONE_ELEVATION , (byte*) & policy , Marshal.SizeOf( typeof (int) ), null, 0, NativeMethods.PUAF_NOUI, 0 ); } finally { CodeAccessPermission.RevertAssert(); } } return ( policy == NativeMethods.URLPOLICY_QUERY ) ; } ////// Critical - elevates to call unmanaged code to set the security site. /// [SecurityCritical ] 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(); new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert: try { _secMgr.SetSecuritySite( (NativeMethods.IInternetSecurityMgrSite) _secMgrSite ) ; } finally { CodeAccessPermission.RevertAssert(); } } } } } ////// Critical - elevates to call SetSecuritySite. /// TreatAsSafe - clearing the security site is considered safe. /// worse that can happen is any urlmon prompts will be non-modal. /// [SecurityCritical, SecurityTreatAsSafe ] internal static void ClearSecurityManager() { if (_secMgr != null ) { new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert: try { lock ( _lockObj ) { if ( _secMgr != null ) { _secMgr.SetSecuritySite( null ) ; _secMgrSite = null ; _secMgr = null ; } } } finally { CodeAccessPermission.RevertAssert(); } } } [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 object _lockObj = new object(); ////// Critical - requires an elevation to create. /// [SecurityCritical] private static UnsafeNativeMethods.IInternetSecurityManager _secMgr ; private static SecurityMgrSite _secMgrSite ; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ColumnResizeUndoUnit.cs
- ADRoleFactory.cs
- DockEditor.cs
- StringComparer.cs
- UIPropertyMetadata.cs
- WhiteSpaceTrimStringConverter.cs
- OleDragDropHandler.cs
- CancellableEnumerable.cs
- ConsoleTraceListener.cs
- Descriptor.cs
- ColorAnimationBase.cs
- StatusStrip.cs
- TextServicesHost.cs
- Profiler.cs
- CorrelationManager.cs
- HitTestDrawingContextWalker.cs
- DesignTimeVisibleAttribute.cs
- TokenizerHelper.cs
- XmlSchemaAttributeGroupRef.cs
- ChildTable.cs
- ManualResetEvent.cs
- TraceSwitch.cs
- StylusButtonEventArgs.cs
- ArraySet.cs
- TextDecoration.cs
- PathGeometry.cs
- SqlGatherProducedAliases.cs
- StreamAsIStream.cs
- Debug.cs
- TypeDescriptionProvider.cs
- SrgsElementList.cs
- CodeTypeDelegate.cs
- SystemColors.cs
- SQLInt64Storage.cs
- PartManifestEntry.cs
- SubpageParaClient.cs
- MouseDevice.cs
- CategoryAttribute.cs
- OperatingSystem.cs
- PageCodeDomTreeGenerator.cs
- CommonDialog.cs
- ComponentCommands.cs
- ProxyWebPartManager.cs
- XamlFilter.cs
- CheckBoxField.cs
- StringPropertyBuilder.cs
- BamlRecordWriter.cs
- XmlLangPropertyAttribute.cs
- ActivityXRefConverter.cs
- SharedPerformanceCounter.cs
- AspNetHostingPermission.cs
- QueryCacheManager.cs
- ProxyWebPart.cs
- DesignerProperties.cs
- BevelBitmapEffect.cs
- HttpRawResponse.cs
- TriState.cs
- ParallelTimeline.cs
- MethodMessage.cs
- DatePickerDateValidationErrorEventArgs.cs
- HtmlButton.cs
- ColumnReorderedEventArgs.cs
- TextEncodedRawTextWriter.cs
- panel.cs
- GridErrorDlg.cs
- Component.cs
- ObservableDictionary.cs
- DataListDesigner.cs
- SecurityState.cs
- XmlSchemaValidationException.cs
- NeutralResourcesLanguageAttribute.cs
- PipelineModuleStepContainer.cs
- DateTimeOffsetStorage.cs
- MenuAdapter.cs
- __Error.cs
- Guid.cs
- IteratorDescriptor.cs
- NameScope.cs
- CountdownEvent.cs
- PathFigureCollectionConverter.cs
- DataGridViewComboBoxColumn.cs
- HttpClientProtocol.cs
- HttpResponseBase.cs
- HotSpot.cs
- FormViewInsertEventArgs.cs
- ParseHttpDate.cs
- EditorBrowsableAttribute.cs
- elementinformation.cs
- ByteAnimationUsingKeyFrames.cs
- NGCPageContentSerializerAsync.cs
- TypeNameConverter.cs
- PersonalizationStateInfoCollection.cs
- MsmqIntegrationInputMessage.cs
- PointAnimationBase.cs
- ContactManager.cs
- FieldAccessException.cs
- Resources.Designer.cs
- mediaeventargs.cs
- SqlGenericUtil.cs
- WebFormDesignerActionService.cs