TrustManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / TrustManager.cs / 2 / TrustManager.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 */ 
using System;
using System.Security; 
using System.Security.Policy;
using System.Windows.Forms;
using System.Globalization;
using System.Text; 
using System.IO;
using System.Collections; 
using System.Reflection; 
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; 
using System.Security.Permissions;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates; 
using System.Deployment.Internal;
using System.Deployment.Internal.Isolation; 
using System.Deployment.Internal.Isolation.Manifest; 
using System.Deployment.Internal.CodeSigning;
using Microsoft.Win32; 
using System.Runtime.InteropServices;

namespace System.Security.Policy
{ 
    /// 
    internal class TrustManager : IApplicationTrustManager 
    { 
        public const string PromptingLevelKeyName = @"Software\Microsoft\.NETFramework\Security\TrustManager\PromptingLevel";
 
        /// 
        public TrustManager()
        {
        } 

        // IApplicationTrustManager Implementation 
 
        /// 
        [ 
            HostProtection(UI=true)
        ]
        public ApplicationTrust DetermineApplicationTrust(ActivationContext activationContext, TrustManagerContext trustManagerContext)
        { 
            if (activationContext == null)
            { 
                throw new ArgumentNullException("activationContext"); 
            }
 
            ApplicationSecurityInfo info = new ApplicationSecurityInfo(activationContext);
            ApplicationTrustExtraInfo appTrustExtraInfo = new ApplicationTrustExtraInfo();
            // ISSUE - fix this....
            HostContextInternal hostContextInternal = new HostContextInternal(trustManagerContext); 

            ICMS cms = (ICMS)InternalActivationContextHelper.GetDeploymentComponentManifest(activationContext); 
 
            ParsedData parsedData = new ParsedData();
            if (ParseManifest(cms, parsedData)) 
            {
                appTrustExtraInfo.RequestsShellIntegration = parsedData.RequestsShellIntegration;
            }
 
            string deploymentUrl = GetDeploymentUrl(info);
            string zoneName = GetZoneNameFromDeploymentUrl(deploymentUrl); 
            MemoryStream ms; 
            PromptsAllowed promptsAllowed;
 
            if (!ExtractManifestContent(cms, out ms))
            {
                // Block prompt
                return BlockingPrompt(activationContext, parsedData, deploymentUrl, info, appTrustExtraInfo, zoneName, AppRequestsBeyondDefaultTrust(info) /*permissionElevationRequired*/); 
            }
 
            bool distrustedPublisher, trustedPublisher, noCertificate; 
            AnalyzeCertificate(parsedData, ms, out distrustedPublisher, out trustedPublisher, out noCertificate);
 
            /// Check whether application manifest allows to use deployment manifest certificate.
            /// If not then we have to use application manifest certificate instead.
            ICMS applicationCms = (ICMS)InternalActivationContextHelper.GetApplicationComponentManifest(activationContext);
            ParsedData applicationParsedData = new ParsedData(); 
            if (ParseManifest(applicationCms, applicationParsedData))
            { 
                if (applicationParsedData.UseManifestForTrust) 
                {
                    MemoryStream applicationMs; 
                    if (ExtractManifestContent(applicationCms, out applicationMs))
                    {
                        /// Use the old parsedData.
                        bool applicationDistrustedPublisher, applicationTrustedPublisher, applicationNoCertificate; 
                        AnalyzeCertificate(parsedData, applicationMs, out applicationDistrustedPublisher, out applicationTrustedPublisher, out applicationNoCertificate);
                        distrustedPublisher = applicationDistrustedPublisher; 
                        trustedPublisher = applicationTrustedPublisher; 
                        noCertificate = applicationNoCertificate;
                        parsedData.AppName = applicationParsedData.AppName; 
                        parsedData.AppPublisher = applicationParsedData.AppPublisher;
                        parsedData.SupportUrl = applicationParsedData.SupportUrl;
                    }
                } 
            }
 
            if (distrustedPublisher) 
            {
                promptsAllowed = GetPromptsAllowed(hostContextInternal, zoneName, parsedData); 
                if (promptsAllowed == PromptsAllowed.None)
                {
                    // No prompt allowed, return Do Not Trust.
                    return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, false /*trust*/, false /*persist*/); 
                }
                return BlockingPrompt(activationContext, parsedData, deploymentUrl, info, appTrustExtraInfo, zoneName, AppRequestsBeyondDefaultTrust(info) /*permissionElevationRequired*/); 
            } 

            if (noCertificate) 
            {
                parsedData.AuthenticodedPublisher = null;
                parsedData.Certificate = null;
            } 

            if (!hostContextInternal.IgnorePersistedDecision) 
            { 
                // Check if there are previously trusted versions installed.
                ArrayList matchingTrusts; 
                if (SearchPreviousTrustedVersion(activationContext, hostContextInternal.PreviousAppId, out matchingTrusts))
                {
                    Debug.Assert(matchingTrusts != null && matchingTrusts.Count > 0);
 
                    // Found a matching app, with normally a different version.
                    if (ExistingTrustApplicable(info, matchingTrusts)) 
                    { 
                        // There is at least one old version that requires at the same or more permissions.
                        // ExistingTrustApplicable removed the non-applicable version from the matchingTrusts arrays. 
                        Debug.Assert(matchingTrusts != null && matchingTrusts.Count > 0);

                        // Check if the new app requires shell integration while none of the old ones did
                        if (appTrustExtraInfo.RequestsShellIntegration && 
                            !SomePreviousTrustedVersionRequiresShellIntegration(matchingTrusts) &&
                            !trustedPublisher) 
                        { 
                            promptsAllowed = GetPromptsAllowed(hostContextInternal, zoneName, parsedData);
                            switch (promptsAllowed) 
                            {
                                case PromptsAllowed.None:
                                    // No prompt allowed, return Do Not Trust.
                                    return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, false /*trust*/, false /*persist*/); 
                                case PromptsAllowed.BlockingOnly:
                                    return BlockingPrompt(activationContext, parsedData, deploymentUrl, info, appTrustExtraInfo, zoneName, AppRequestsBeyondDefaultTrust(info) /*permissionElevationRequired*/); 
                                case PromptsAllowed.All: 
                                    // New app requires shell integration - bring up the Basic Install Prompt
                                    return BasicInstallPrompt(activationContext, 
                                                              parsedData,
                                                              deploymentUrl,
                                                              hostContextInternal,
                                                              info, 
                                                              appTrustExtraInfo,
                                                              zoneName, 
                                                              AppRequestsBeyondDefaultTrust(info) /*permissionElevationRequired*/); 
                            }
                        } 

                        // No prompt, return Trust & Persist.
                        return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, true /*trust*/, hostContextInternal.Persist /*persist*/);
                    } 
                }
            } 
 
            bool permissionElevationRequired = AppRequestsBeyondDefaultTrust(info);
            if (!permissionElevationRequired || trustedPublisher) 
            {
                if (!trustedPublisher && appTrustExtraInfo.RequestsShellIntegration)
                {
                    Debug.Assert(!permissionElevationRequired); 
                    promptsAllowed = GetPromptsAllowed(hostContextInternal, zoneName, parsedData);
                    switch (promptsAllowed) 
                    { 
                        case PromptsAllowed.None:
                            // No prompt allowed, return Do Not Trust. 
                            return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, false /*trust*/, false /*persist*/);
                        case PromptsAllowed.BlockingOnly:
                            return BlockingPrompt(activationContext, parsedData, deploymentUrl, info, appTrustExtraInfo, zoneName, permissionElevationRequired);
                        case PromptsAllowed.All: 
                            // App shell integrates and is not from a trusted deployer, bring up the Basic Install Prompt.
                            return BasicInstallPrompt(activationContext, 
                                                      parsedData, 
                                                      deploymentUrl,
                                                      hostContextInternal, 
                                                      info,
                                                      appTrustExtraInfo,
                                                      zoneName,
                                                      false /*permissionElevationRequired*/); 
                    }
                } 
                else 
                {
                    // App does not shell integrate or is from a trusted deployer, return Trust 
                    return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, true /*trust*/, hostContextInternal.Persist /*persist*/);
                }
            }
 
            promptsAllowed = GetPromptsAllowed(hostContextInternal, zoneName, parsedData);
            switch (promptsAllowed) 
            { 
                case PromptsAllowed.None:
                    // No prompt allowed, return Do Not Trust. 
                    return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, false /*trust*/, false /*persist*/);
                case PromptsAllowed.BlockingOnly:
                    return BlockingPrompt(activationContext, parsedData, deploymentUrl, info, appTrustExtraInfo, zoneName, true /*permissionElevationRequired*/);
                default: // PromptsAllowed.All: 
                    // Bring up the HighRisk Install Prompt if the app shell integrates, or the HighRisk Run Prompt otherwise.
                    return HighRiskPrompt(activationContext, parsedData, deploymentUrl, hostContextInternal, info, appTrustExtraInfo, zoneName); 
            } 
        }
 
        // ISecurityEncodable implementation

        /// 
        public SecurityElement ToXml() 
        {
            SecurityElement elRoot = new SecurityElement("IApplicationTrustManager"); 
            elRoot.AddAttribute("class", SecurityElement.Escape(this.GetType().AssemblyQualifiedName)); 
            elRoot.AddAttribute("version", "1");
            return elRoot; 
        }

        /// 
        public void FromXml(SecurityElement element) 
        {
            if (element == null) 
            { 
                throw new ArgumentNullException("element");
            } 

            if (!String.Equals(element.Tag, "IApplicationTrustManager", StringComparison.Ordinal))
            {
                throw new ArgumentException(SR.GetString(SR.TrustManagerBadXml ,"IApplicationTrustManager")); 
            }
        } 
 
        [
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes") 
        ]
        private static string DefaultBrowserExePath
        {
            get 
            {
                try 
                { 
                    string strBrowserPath = null;
                    new RegistryPermission(PermissionState.Unrestricted).Assert(); 
                    try
                    {
                        RegistryKey key = Registry.ClassesRoot.OpenSubKey("http\\shell\\open\\command");
                        if (key != null) 
                        {
                            string strBrowserCommand = (string) key.GetValue(string.Empty); 
                            if (strBrowserCommand != null) 
                            {
                                strBrowserCommand = strBrowserCommand.Trim(); 
                                if (strBrowserCommand.Length != 0)
                                {
                                    if (strBrowserCommand[0] == '\"')
                                    { 
                                        int closingQuoteIndex = strBrowserCommand.IndexOf('"', 1);
                                        if (closingQuoteIndex != -1) 
                                        { 
                                            strBrowserPath = strBrowserCommand.Substring(1, closingQuoteIndex - 1);
                                        } 
                                    }
                                    else
                                    {
                                        int firstSpaceIndex = strBrowserCommand.IndexOf(' '); 
                                        if (firstSpaceIndex != -1)
                                        { 
                                            strBrowserPath = strBrowserCommand.Substring(0, firstSpaceIndex); 
                                        }
                                        else 
                                        {
                                            strBrowserPath = strBrowserCommand;
                                        }
                                    } 
                                }
                            } 
                        } 
                    }
                    finally 
                    {
                        System.Security.CodeAccessPermission.RevertAssert();
                    }
                    return strBrowserPath; 
                }
                catch (Exception ex) 
                { 
                    Debug.Fail("Exception occurred while locating default browser executable: " + ex.Message);
                    return null; 
                }
            }
        }
 
        [
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes") 
        ] 
        private static bool AnalyzeCertificate(ParsedData parsedData, MemoryStream ms, out bool distrustedPublisher, out bool trustedPublisher, out bool noCertificate)
        { 
            const int TRUST_E_REVOKED = unchecked((int) 0x80092010);

            Debug.Assert(parsedData != null);
            Debug.Assert(ms != null); 

            distrustedPublisher = false; 
            trustedPublisher = false; 
            noCertificate = false;
            SignedCmiManifest signedManifest = null; 
            try
            {
                XmlDocument deploymentManifestXmlDom = new XmlDocument();
                deploymentManifestXmlDom.PreserveWhitespace = true; 
                deploymentManifestXmlDom.Load(ms);
                signedManifest = new SignedCmiManifest(deploymentManifestXmlDom); 
                signedManifest.Verify(CmiManifestVerifyFlags.None); 
            }
            catch (Exception e) 
            {
                if (e is CryptographicException)
                {
                    // 
                    // AuthenticodeSignerInfo can be null if the manifest is only strong name signed
                    // but not authenticode signed. This can happen when the strong name 
                    // signature is invalid. 
                    //
                    if (signedManifest.AuthenticodeSignerInfo != null) 
                    {
                        int error = signedManifest.AuthenticodeSignerInfo.ErrorCode;
                        if (error == System.Deployment.Internal.CodeSigning.Win32.TRUST_E_EXPLICIT_DISTRUST || error == TRUST_E_REVOKED)
                        { 
                            distrustedPublisher = true;
                            return true; 
                        } 
                        else if (error == System.Deployment.Internal.CodeSigning.Win32.TRUST_E_SUBJECT_NOT_TRUSTED)
                        { 
                            // Certificate is valid but publisher is not in trusted list
                            return true;
                        }
                        else 
                        {
                            // No certificate is equivalent to strong name signing only - run app only with user consent 
                            noCertificate = true; 
                            return true;
                        } 
                    }
                }

                return false; 
            }
            finally 
            { 
                if (signedManifest != null &&
                    signedManifest.AuthenticodeSignerInfo != null && 
                    signedManifest.AuthenticodeSignerInfo.SignerChain != null)
                {
                    parsedData.Certificate = signedManifest.AuthenticodeSignerInfo.SignerChain.ChainElements[0].Certificate;
                    parsedData.AuthenticodedPublisher = parsedData.Certificate.GetNameInfo(X509NameType.SimpleName, false); 
                }
            } 
 
            if (signedManifest == null || signedManifest.AuthenticodeSignerInfo == null)
            { 
                noCertificate = true;
            }
            else
            { 
                trustedPublisher = true;
            } 
 
            return true;
        } 

        [
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")
        ] 
        private static bool AppRequestsBeyondDefaultTrust(ApplicationSecurityInfo info)
        { 
            Debug.Assert(info != null); 

            try 
            {
                PermissionSet permSetDefaultZone = SecurityManager.ResolveSystemPolicy(info.ApplicationEvidence);
                PermissionSet permSetRequested = GetRequestedPermissionSet(info);
 
                if (permSetDefaultZone == null && permSetRequested != null)
                { 
                    // No permissions are granted, and this launch requests some permissions 
                    return true;
                } 
                else if (permSetDefaultZone != null && permSetRequested == null)
                {
                    // Some permissions are granted, and this launch does not require any permissions
                    return false; 
                }
 
                Debug.Assert(permSetDefaultZone != null); 
                Debug.Assert(permSetRequested != null);
 
                return !permSetRequested.IsSubsetOf(permSetDefaultZone);
            }
            catch (Exception)
            { 
                return true;
            } 
        } 

        [ 
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")
        ]
        private static ApplicationTrust BasicInstallPrompt(ActivationContext activationContext,
                                                           ParsedData parsedData, 
                                                           String deploymentUrl,
                                                           HostContextInternal hostContextInternal, 
                                                           ApplicationSecurityInfo info, 
                                                           ApplicationTrustExtraInfo appTrustExtraInfo,
                                                           string zoneName, 
                                                           bool permissionElevationRequired)
        {
            DialogResult ret;
            TrustManagerPromptOptions options = CompletePromptOptions(permissionElevationRequired ? TrustManagerPromptOptions.RequiresPermissions : TrustManagerPromptOptions.None, appTrustExtraInfo, zoneName, info); 
            try
            { 
                TrustManagerPromptUIThread basicInstallDialog = new TrustManagerPromptUIThread(string.IsNullOrEmpty(parsedData.AppName) ? info.ApplicationId.Name : parsedData.AppName, 
                                                                                   DefaultBrowserExePath,
                                                                                   parsedData.SupportUrl, 
                                                                                   GetHostFromDeploymentUrl(deploymentUrl),
                                                                                   parsedData.AuthenticodedPublisher /*publisherName*/,
                                                                                   parsedData.Certificate,
                                                                                   options); 
                ret = basicInstallDialog.ShowDialog();
            } 
            catch (Exception ex) 
            {
                Debug.Fail("Error occurred while showing basic install dialog: " + ex.Message); 
                ret = DialogResult.No;
            }

            return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, ret == DialogResult.OK /*trust*/, hostContextInternal.Persist && ret == DialogResult.OK /*persist*/); 
        }
 
        private static TrustManagerPromptOptions CompletePromptOptions(TrustManagerPromptOptions options, 
                                                                       ApplicationTrustExtraInfo appTrustExtraInfo,
                                                                       string zoneName, 
                                                                       ApplicationSecurityInfo info)
        {
            if (appTrustExtraInfo.RequestsShellIntegration)
            { 
                options |= TrustManagerPromptOptions.AddsShortcut;
            } 
            if (zoneName != null) 
            {
                if (string.Compare(zoneName, "Internet", true, CultureInfo.InvariantCulture) == 0) 
                {
                    options |= TrustManagerPromptOptions.InternetSource;
                }
                else if (string.Compare(zoneName, "TrustedSites", true, CultureInfo.InvariantCulture) == 0) 
                {
                    options |= TrustManagerPromptOptions.TrustedSitesSource; 
                } 
                else if (string.Compare(zoneName, "UntrustedSites", true, CultureInfo.InvariantCulture) == 0)
                { 
                    options |= TrustManagerPromptOptions.UntrustedSitesSource;
                }
                else if (string.Compare(zoneName, "LocalIntranet", true, CultureInfo.InvariantCulture) == 0)
                { 
                    options |= TrustManagerPromptOptions.LocalNetworkSource;
                } 
                else if (string.Compare(zoneName, "MyComputer", true, CultureInfo.InvariantCulture) == 0) 
                {
                    options |= TrustManagerPromptOptions.LocalComputerSource; 
                }
            }
            if (info != null)
            { 
                PermissionSet pset = info.DefaultRequestSet;
                if (pset != null && pset.IsUnrestricted()) 
                { 
                    options |= TrustManagerPromptOptions.WillHaveFullTrust;
                } 
            }
            return options;
        }
 
        private static ApplicationTrust CreateApplicationTrust(ActivationContext activationContext,
                                                               ApplicationSecurityInfo info, 
                                                               ApplicationTrustExtraInfo appTrustExtraInfo, 
                                                               bool trust,
                                                               bool persist) 
        {
            ApplicationTrust appTrust = new ApplicationTrust(activationContext.Identity);

            appTrust.ExtraInfo = appTrustExtraInfo; 
            appTrust.IsApplicationTrustedToRun = trust;
            appTrust.DefaultGrantSet = new PolicyStatement(info.DefaultRequestSet, (PolicyStatementAttribute) 0); 
            appTrust.Persist = persist; 

            return appTrust; 
        }

        private static bool ExistingTrustApplicable(ApplicationSecurityInfo info,
                                                    ArrayList matchingTrusts) 
        {
            Debug.Assert(info != null); 
            Debug.Assert(matchingTrusts != null); 

            int entry = 0; 
            while (entry < matchingTrusts.Count)
            {
                ApplicationTrust matchingTrust = (ApplicationTrust) matchingTrusts[entry];
                if (!matchingTrust.IsApplicationTrustedToRun) 
                {
                    // [....]: Can this ever happen?  I have serious doubts... 
                    matchingTrusts.RemoveAt(entry); 
                }
 
                PermissionSet permSetRequested = GetRequestedPermissionSet(info);
                PermissionSet permSetGranted = matchingTrust.DefaultGrantSet.PermissionSet; //PolicyStatement makes of copy of its permission set here.

                if (permSetGranted == null && permSetRequested != null) 
                {
                    // No permissions were granted, and this launch requests some permissions 
                    matchingTrusts.RemoveAt(entry); 
                }
                else if (permSetGranted != null && permSetRequested == null) 
                {
                    // Some permissions were granted, and this launch does not require any permissions
                    entry++;
                    continue; 
                }
 
                Debug.Assert(permSetGranted != null); 
                Debug.Assert(permSetRequested != null);
 
                if (permSetRequested.IsSubsetOf(permSetGranted))
                {
                    entry++; // Found a version that requires at least as much
                } 
                else
                { 
                    // This version does not require as much 
                    matchingTrusts.RemoveAt(entry);
                } 
            }
            return matchingTrusts.Count > 0;
        }
 
        [
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes") 
        ] 
        private unsafe static bool ExtractManifestContent(ICMS cms, out MemoryStream ms)
        { 
            ms = new MemoryStream();
            try
            {
                System.Runtime.InteropServices.ComTypes.IStream pStream = cms as System.Runtime.InteropServices.ComTypes.IStream; 
                if (pStream == null)
                { 
                    return false; 
                }
 
                byte[] pv = new byte[4096];
                int size = 4096;
                do {
                    pStream.Read(pv, size, new IntPtr(&size)); 
                    ms.Write(pv, 0, size);
                } 
                while (size == 4096); 
                ms.Position = 0;
                return true; 
            }
            catch (Exception)
            {
                Debug.Fail("Exception occurred in ExtractDeploymentManifestContent."); 
                return false;
            } 
        } 

        private static PromptingLevel GetDefaultPromptingLevel(string zoneName) 
        {
            PromptingLevel promptingLevel;
            switch (zoneName)
            { 
                case "Internet":
                case "LocalIntranet": 
                case "MyComputer": 
                case "TrustedSites":
                    promptingLevel = PromptingLevel.Prompt; 
                    break;
                case "UntrustedSites":
                    promptingLevel = PromptingLevel.Disabled;
                    break; 
                default:
                    promptingLevel = PromptingLevel.Disabled; 
                    break; 
            }
            return promptingLevel; 
        }

        private static string GetDeploymentUrl(ApplicationSecurityInfo info)
        { 
            Debug.Assert(info != null);
            Evidence appEvidence = info.ApplicationEvidence; 
 
            IEnumerator hostEnumerator = appEvidence.GetHostEnumerator();
 
            while (hostEnumerator.MoveNext())
            {
                Type itemType = hostEnumerator.Current.GetType();
                if (itemType == typeof(System.Security.Policy.Url)) 
                {
                    System.Security.Policy.Url deploymentUrl = (System.Security.Policy.Url) hostEnumerator.Current; 
                    Debug.Assert(deploymentUrl != null); 
                    return deploymentUrl.Value;
                } 
            }

            // Couldn't find deployment Url
            return null; 
        }
 
        private static PermissionSet GetRequestedPermissionSet(ApplicationSecurityInfo info) 
        {
            Debug.Assert(info != null); 

            PermissionSet pset = info.DefaultRequestSet;
            PermissionSet permSetRequested = null;
            if (pset != null) 
            {
                permSetRequested = pset.Copy(); 
            } 
            return permSetRequested;
        } 

        [
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")
        ] 
        private static string GetHostFromDeploymentUrl(string deploymentUrl)
        { 
            if (deploymentUrl == null) 
            {
                return string.Empty; 
            }
            string host = null;
            try
            { 
                System.Uri uri = new System.Uri(deploymentUrl);
                if (uri.Scheme == System.Uri.UriSchemeHttp || uri.Scheme == System.Uri.UriSchemeHttps) 
                { 
                    host = uri.Host;
                } 
                if (string.IsNullOrEmpty(host))
                {
                    host = uri.AbsolutePath;
                    int separatorIndex = -1; 
                    if (string.IsNullOrEmpty(uri.Host) && host.StartsWith("/"))
                    { 
                        host = host.TrimStart('/'); 
                        separatorIndex = host.IndexOf('/');
                    } 
                    else if (uri.LocalPath.Length > 2 && (uri.LocalPath[1] == ':' || uri.LocalPath.StartsWith("\\\\")))
                    {
                        host = uri.LocalPath;
                        separatorIndex = host.LastIndexOf('\\'); 
                    }
                    if (separatorIndex != -1) 
                    { 
                        host = host.Remove(separatorIndex);
                    } 
                }
            }
            catch (Exception ex)
            { 
                Debug.Fail("Exception occurred in GetHostFromDeploymentUrl: " + ex.Message);
                return string.Empty; 
            } 
            return host;
        } 

        private static PromptsAllowed GetPromptsAllowed(HostContextInternal hostContextInternal,
                                                        string zoneName,
                                                        ParsedData parsedData) 
        {
            Debug.Assert(hostContextInternal != null); 
            Debug.Assert(zoneName != null); 
            Debug.Assert(parsedData != null);
 
            if (hostContextInternal.NoPrompt)
            {
                return PromptsAllowed.None;
            } 

            PromptingLevel promptingLevel = GetZonePromptingLevel(zoneName); 
            if (promptingLevel == PromptingLevel.Disabled || 
                (promptingLevel == PromptingLevel.PromptOnlyForAuthenticode && parsedData.AuthenticodedPublisher == null))
            { 
                return PromptsAllowed.BlockingOnly;
            }

            return PromptsAllowed.All; 
        }
 
        private static string GetZoneNameFromDeploymentUrl(String deploymentUrl) 
        {
            Zone zone = Zone.CreateFromUrl(deploymentUrl); 
            if (zone == null || zone.SecurityZone == SecurityZone.NoZone)
            {
                return "UntrustedSites";
            } 
            switch (zone.SecurityZone)
            { 
                case SecurityZone.Internet: 
                    return "Internet";
                case SecurityZone.Intranet: 
                    return "LocalIntranet";
                case SecurityZone.MyComputer:
                    return "MyComputer";
                case SecurityZone.Trusted: 
                    return "TrustedSites";
                case SecurityZone.Untrusted: 
                    return "UntrustedSites"; 
                default:
                    Debug.Fail("Unexpected SecurityZone in GetZoneNameFromDeploymentUrl"); 
                    return "UntrustedSites";
            }
        }
 
        [
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes") 
        ] 
        private static PromptingLevel GetZonePromptingLevel(string zoneName)
        { 
            try
            {
                string promptingLevelStr = null;
                new RegistryPermission(PermissionState.Unrestricted).Assert(); 
                try
                { 
                    using (RegistryKey key = Registry.LocalMachine.OpenSubKey(PromptingLevelKeyName)) 
                    {
                        if (key != null) 
                        {
                            promptingLevelStr = (string)key.GetValue(zoneName);
                        }
                    } 
                }
                finally 
                { 
                    System.Security.CodeAccessPermission.RevertAssert();
                } 

                if (string.IsNullOrEmpty(promptingLevelStr))
                {
                    return GetDefaultPromptingLevel(zoneName); 
                }
                else if (string.Compare(promptingLevelStr, "Enabled", true, CultureInfo.InvariantCulture) == 0) 
                { 
                    return PromptingLevel.Prompt;
                } 
                else if (string.Compare(promptingLevelStr, "Disabled", true, CultureInfo.InvariantCulture) == 0)
                {
                    return PromptingLevel.Disabled;
                } 
                else if (string.Compare(promptingLevelStr, "AuthenticodeRequired", true, CultureInfo.InvariantCulture) == 0)
                { 
                    return PromptingLevel.PromptOnlyForAuthenticode; 
                }
                else 
                {
                    return GetDefaultPromptingLevel(zoneName);
                }
            } 
            catch (Exception ex)
            { 
                Debug.Fail("Exception occurred in GetZonePromptingLevel: " + ex.Message); 
                return GetDefaultPromptingLevel(zoneName);
            } 
        }

        [
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes") 
        ]
        private static ApplicationTrust HighRiskPrompt(ActivationContext activationContext, 
                                                       ParsedData parsedData, 
                                                       String deploymentUrl,
                                                       HostContextInternal hostContextInternal, 
                                                       ApplicationSecurityInfo info,
                                                       ApplicationTrustExtraInfo appTrustExtraInfo,
                                                       string zoneName)
        { 
            DialogResult ret;
            TrustManagerPromptOptions options = CompletePromptOptions(TrustManagerPromptOptions.RequiresPermissions, appTrustExtraInfo, zoneName, info); 
            try 
            {
                TrustManagerPromptUIThread highRiskDialog = new TrustManagerPromptUIThread(string.IsNullOrEmpty(parsedData.AppName) ? info.ApplicationId.Name : parsedData.AppName, 
                                                                               DefaultBrowserExePath,
                                                                               parsedData.SupportUrl,
                                                                               GetHostFromDeploymentUrl(deploymentUrl),
                                                                               parsedData.AuthenticodedPublisher /*publisherName*/, 
                                                                               parsedData.Certificate,
                                                                               options); 
                ret = highRiskDialog.ShowDialog(); 
            }
            catch (Exception ex) 
            {
                Debug.Fail("Error occurred while showing high risk dialog: " + ex.Message);
                ret = DialogResult.No;
            } 

            return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, ret == DialogResult.OK /*trust*/, hostContextInternal.Persist && ret == DialogResult.OK /*persist*/); 
        } 

        [ 
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")
        ]
        private static ApplicationTrust BlockingPrompt(ActivationContext activationContext,
                                                       ParsedData parsedData, 
                                                       String deploymentUrl,
                                                       ApplicationSecurityInfo info, 
                                                       ApplicationTrustExtraInfo appTrustExtraInfo, 
                                                       string zoneName,
                                                       bool permissionElevationRequired) 
        {
            TrustManagerPromptOptions options = CompletePromptOptions(permissionElevationRequired ? (TrustManagerPromptOptions.StopApp | TrustManagerPromptOptions.RequiresPermissions) : TrustManagerPromptOptions.StopApp,
                                                                      appTrustExtraInfo, zoneName, info);
            try 
            {
                TrustManagerPromptUIThread errorDialog = new TrustManagerPromptUIThread(string.IsNullOrEmpty(parsedData.AppName) ? info.ApplicationId.Name : parsedData.AppName, 
                                                                            DefaultBrowserExePath, 
                                                                            parsedData.SupportUrl,
                                                                            GetHostFromDeploymentUrl(deploymentUrl), 
                                                                            parsedData.AuthenticodedPublisher /*publisherName*/,
                                                                            parsedData.Certificate,
                                                                            options);
                errorDialog.ShowDialog(); 
            }
            catch (Exception ex) 
            { 
                Debug.Fail("Error occurred while showing error dialog: " + ex.Message);
            } 

            // Trust Manager should prompt, but is not allowed to. Return Don't Trust and Don't Persist.
            return CreateApplicationTrust(activationContext, info, appTrustExtraInfo, false /*trust*/, false /*persist*/);
        } 

 
        [ 
            SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")
        ] 
        private static bool ParseManifest(ICMS cms, ParsedData parsedData)
        {
            // parsedData is safely initialized to requestsShellIntegration:false/supportUrl:null/authenticodedPublisher:null  //deploymentProviderCodebase:null
            try 
            {
                if (cms != null) 
                { 
                    // Extract SupportUrl and Shell Visibility
                    if (cms.MetadataSectionEntry != null) 
                    {
                        IMetadataSectionEntry metaDataSectionEntry = cms.MetadataSectionEntry as IMetadataSectionEntry;
                        if (metaDataSectionEntry != null)
                        { 
                            IDescriptionMetadataEntry description = metaDataSectionEntry.DescriptionData;
                            if (description != null) 
                            { 
                                parsedData.SupportUrl = description.SupportUrl;
                                parsedData.AppName = description.Product; 
                                parsedData.AppPublisher = description.Publisher;
                                // [....]: description.Publisher is accessible here. Ask JamieC if we should grab it.
                            }
 
                            IDeploymentMetadataEntry deployment = metaDataSectionEntry.DeploymentData;
                            if (deployment != null) 
                            { 
                                parsedData.RequestsShellIntegration = ((deployment.DeploymentFlags &
                                    (uint)(CMS_ASSEMBLY_DEPLOYMENT_FLAG.CMS_ASSEMBLY_DEPLOYMENT_FLAG_INSTALL)) != 0); 
                                // parsedData.DeploymentProviderCodebase = deployment.DeploymentProviderCodebase;
                            }

                            if ((metaDataSectionEntry.ManifestFlags & (uint)CMS_MANIFEST_FLAG.CMS_MANIFEST_FLAG_USEMANIFESTFORTRUST) != 0) 
                            {
                                parsedData.UseManifestForTrust = true; 
                            } 
                            else
                            { 
                                parsedData.UseManifestForTrust = false;
                            }
                        }
                    } 
                }
            } 
            catch (Exception e) 
            {
                Debug.Fail("Error parsing manifest: " + e.Message); 
                return false;
            }
            return true;
        } 

        private static bool SomePreviousTrustedVersionRequiresShellIntegration(ArrayList /*ApplicationTrust[]*/ matchingTrusts) 
        { 
            Debug.Assert(matchingTrusts != null);
            foreach (ApplicationTrust matchingTrust in matchingTrusts) 
            {
                ApplicationTrustExtraInfo matchingAppTrustExtraInfo = matchingTrust.ExtraInfo as ApplicationTrustExtraInfo;
                if (matchingAppTrustExtraInfo != null && matchingAppTrustExtraInfo.RequestsShellIntegration)
                { 
                    return true;
                } 
            } 
            // No previous trusted version requires shell integration
            return false; 
        }

        private static bool SearchPreviousTrustedVersion(ActivationContext activationContext,
                                                         ApplicationIdentity previousAppId, 
                                                         out ArrayList matchingTrusts)
        { 
            // No match found by default 
            matchingTrusts = null;
 
            ApplicationTrustCollection appTrusts = ApplicationSecurityManager.UserApplicationTrusts;
            foreach (ApplicationTrust appTrust in appTrusts) {
                IDefinitionAppId appTrustAppId = IsolationInterop.AppIdAuthority.TextToDefinition(0, appTrust.ApplicationIdentity.FullName);
                IDefinitionAppId actCtxAppId = IsolationInterop.AppIdAuthority.TextToDefinition(0, activationContext.Identity.FullName); 
                if (IsolationInterop.AppIdAuthority.AreDefinitionsEqual((uint) IAPPIDAUTHORITY_ARE_DEFINITIONS_EQUAL_FLAGS.IAPPIDAUTHORITY_ARE_DEFINITIONS_EQUAL_FLAG_IGNORE_VERSION, appTrustAppId, actCtxAppId))
                { 
                    // Found an older matching app (or same version app which should never occur in theory) 
                    if (matchingTrusts == null)
                    { 
                        matchingTrusts = new ArrayList();
                    }
                    matchingTrusts.Add(appTrust);
                } 
            }
 
            if (previousAppId != null) 
            {
                foreach (ApplicationTrust appTrust in appTrusts) { 
                    IDefinitionAppId appTrustDefAppId = IsolationInterop.AppIdAuthority.TextToDefinition(0, appTrust.ApplicationIdentity.FullName);
                    IDefinitionAppId previousDefAppId = IsolationInterop.AppIdAuthority.TextToDefinition(0, previousAppId.FullName);
                    if (IsolationInterop.AppIdAuthority.AreDefinitionsEqual((uint) IAPPIDAUTHORITY_ARE_DEFINITIONS_EQUAL_FLAGS.IAPPIDAUTHORITY_ARE_DEFINITIONS_EQUAL_FLAG_IGNORE_VERSION, appTrustDefAppId, previousDefAppId))
                    { 
                        // Found an older matching app (or same version app which should never occur in theory)
                        if (matchingTrusts == null) 
                        { 
                            matchingTrusts = new ArrayList();
                        } 
                        matchingTrusts.Add(appTrust);
                    }
                }
            } 

            // (matchingTrusts != null) <==> Found a prior version that was allowed to run. 
            return (matchingTrusts != null); 
        }
 
        private enum PromptingLevel
        {
            /// 
            ///      
            ///         In the cases the Trust Manager needs to prompt, it needs to show the blocking prompt
            ///      
            ///  
            Disabled = 0,
            ///  
            ///     
            ///         Prompting is allowed for strong named and authenticode signed application deployments
            ///     
            ///  
            Prompt = 1,
            ///  
            ///      
            ///         Prompting is allowed for authenticode signed application deployments only
            ///      
            /// 
            PromptOnlyForAuthenticode = 2
        }
 
        private enum PromptsAllowed
        { 
            ///  
            ///     
            ///         The Trust Manager is allowed to show any prompt 
            ///     
            /// 
            All = 0,
            ///  
            ///     
            ///         The Trust Manager is only allowed to show the blocking prompt 
            ///      
            /// 
            BlockingOnly = 1, 
            /// 
            ///     
            ///         The Trust Manager is not allowed to prompt at all
            ///      
            /// 
            None = 2 
        } 
    }
 
    [Serializable]
    internal class ApplicationTrustExtraInfo
    {
        private bool requestsShellIntegration = true;  // If manifest parsing fails, we assume shell integration is required. 

        public ApplicationTrustExtraInfo() 
        { 
        }
 
        public bool RequestsShellIntegration
        {
            get
            { 
                return this.requestsShellIntegration;
            } 
 
            set
            { 
                this.requestsShellIntegration = value;
            }
        }
    } 

    internal class TrustManagerPromptUIThread { 
        private string m_appName, m_defaultBrowserExePath, m_supportUrl, m_deploymentUrl, m_publisherName; 
        private X509Certificate2 m_certificate;
        private TrustManagerPromptOptions m_options; 
        private DialogResult m_ret = DialogResult.No;

        public TrustManagerPromptUIThread(string appName, string defaultBrowserExePath, string supportUrl, string deploymentUrl,
                                          string publisherName, X509Certificate2 certificate, TrustManagerPromptOptions options) { 
            this.m_appName = appName;
            this.m_defaultBrowserExePath = defaultBrowserExePath; 
            this.m_supportUrl = supportUrl; 
            this.m_deploymentUrl = deploymentUrl;
            this.m_publisherName = publisherName; 
            this.m_certificate = certificate;
            this.m_options = options;
        }
 
        public DialogResult ShowDialog() {
            System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(ShowDialogWork)); 
            thread.SetApartmentState(System.Threading.ApartmentState.STA); 
            thread.Start();
            thread.Join(); 
            return m_ret;
        }

        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 
        private void ShowDialogWork()
        { 
            try { 
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false); 
                using (TrustManagerPromptUI trustManagerDialog = new TrustManagerPromptUI(this.m_appName, this.m_defaultBrowserExePath,
                                                                                          this.m_supportUrl, this.m_deploymentUrl,
                                                                                          this.m_publisherName, this.m_certificate, this.m_options)) {
                    m_ret = trustManagerDialog.ShowDialog(); 
                }
            } 
            catch { 
            }
        } 
    }

    internal class ParsedData
    { 
        private bool requestsShellIntegration; /* == false by default. shellVisible attribute is optional */
        private string appName; 
        private string appPublisher; 
        private string supportUrl;
        private string authenticodedPublisher; 
        private bool disallowTrustOverride;
        private X509Certificate2 certificate;
//        private string deploymentProviderCodebase;
 
        public ParsedData()
        { 
        } 

        public bool RequestsShellIntegration 
        {
            get
            {
                return this.requestsShellIntegration; 
            }
            set 
            { 
                this.requestsShellIntegration = value;
            } 
        }

        public X509Certificate2 Certificate
        { 
            get
            { 
                return this.certificate; 
            }
            set 
            {
                this.certificate = value;
            }
        } 

        public string AppName 
        { 
            get
            { 
                return this.appName;
            }
            set
            { 
                this.appName = value;
            } 
        } 

        public string AppPublisher 
        {
            get
            {
                return this.appPublisher; 
            }
            set 
            { 
                this.appPublisher = value;
            } 
        }

        public string AuthenticodedPublisher
        { 
            get
            { 
                return this.authenticodedPublisher; 
            }
            set 
            {
                this.authenticodedPublisher = value;
            }
        } 

        public bool UseManifestForTrust 
        { 
            get
            { 
                return disallowTrustOverride;
            }

            set 
            {
                disallowTrustOverride = value; 
            } 
        }
 
//        public string DeploymentProviderCodebase
//        {
//            get
//            { 
//                return this.deploymentProviderCodebase;
//            } 
//            set 
//            {
//                this.deploymentProviderCodebase = value; 
//            }
//        }

        public string SupportUrl 
        {
            get 
            { 
                return this.supportUrl;
            } 
            set
            {
                this.supportUrl = value;
            } 
        }
    } 
 
    internal class HostContextInternal
    { 
        private bool ignorePersistedDecision;
        private bool noPrompt;
        private bool persist;
        private ApplicationIdentity previousAppId; 

        public HostContextInternal(TrustManagerContext trustManagerContext) 
        { 
            if (trustManagerContext == null)
            { 
                // Used in case DetermineApplicationTrust is not given a TrustManagerContext object.
                this.persist = true;
            }
            else 
            {
                // ISSUE - fix this... 
                // Note that exclusiveGrant is never set. It is read in CreateApplicationTrust however. 
                this.ignorePersistedDecision = trustManagerContext.IgnorePersistedDecision;
                this.noPrompt = trustManagerContext.NoPrompt; 
                this.persist = trustManagerContext.Persist;
                this.previousAppId = trustManagerContext.PreviousApplicationIdentity;
            }
        } 

        public bool IgnorePersistedDecision 
        { 
            get
            { 
                return this.ignorePersistedDecision;
            }
        }
 
        public bool NoPrompt
        { 
            get 
            {
                return this.noPrompt; 
            }
        }

        public bool Persist 
        {
            get 
            { 
                return this.persist;
            } 
        }

        public ApplicationIdentity PreviousAppId
        { 
            get
            { 
                return this.previousAppId; 
            }
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK