|
//----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
namespace System.ServiceModel
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Web;
using System.Web.Hosting;
// wrapper class that helps with partial trust analysis
// -- HostingEnvironment does a number of Demands and LinkDemands
// -- this wrapper encapsulates access into "Safe" and "Unsafe" methods that do the appropriate asserts
// -- it is recommended that ALL HostingEnvironment access go through this class
// -- "Safe" methods are [SecurityCritical, SecurityTreatAsSafe] or not [SecurityCritical]
// -- "Unsafe" methods are [SecurityCritical]
// -- because each method does precisely one access, we use declarative asserts for clarity
static class HostingEnvironmentWrapper
{
public static string ApplicationVirtualPath
{
get
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
return HostingEnvironment.ApplicationVirtualPath;
}
}
public static bool IsHosted
{
get { return HostingEnvironment.IsHosted; }
}
[Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
public static VirtualPathProvider VirtualPathProvider
{
[SecuritySafeCritical]
get
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
return HostingEnvironment.VirtualPathProvider;
}
}
[Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.NoInlining)]
public static void DecrementBusyCount()
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
HostingEnvironment.DecrementBusyCount();
}
// demands SecurityPermission(ControlPrincipal) -- use Unsafe version to assert
public static IDisposable Impersonate()
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
return HostingEnvironment.Impersonate();
}
// demands SecurityPermission(Unrestricted) -- use Unsafe version to assert
public static IDisposable Impersonate(IntPtr token)
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
return HostingEnvironment.Impersonate(token);
}
[Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.NoInlining)]
public static void IncrementBusyCount()
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
HostingEnvironment.IncrementBusyCount();
}
public static string MapPath(string virtualPath)
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
return HostingEnvironment.MapPath(virtualPath);
}
public static string UnsafeApplicationID
{
[SuppressMessage(FxCop.Category.Security, FxCop.Rule.SecureAsserts, Justification = "Users cannot pass arbitrary data to this code.")]
[Fx.Tag.SecurityNote(Critical = "Asserts SecurityPermission in order to call HostingEnvironment.get_ApplicationID.")]
[SecurityCritical]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.Assert, Level = AspNetHostingPermissionLevel.High)]
get
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
return HostingEnvironment.ApplicationID;
}
}
[SuppressMessage(FxCop.Category.Security, FxCop.Rule.SecureAsserts, Justification = "Users cannot pass arbitrary data to this code.")]
[Fx.Tag.SecurityNote(Critical = "Asserts SecurityPermission in order to call HostingEnvironment.UnsafeImpersonate.")]
[SecurityCritical]
[SecurityPermission(SecurityAction.Assert, ControlPrincipal = true)]
public static IDisposable UnsafeImpersonate()
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
return HostingEnvironment.Impersonate();
}
[Fx.Tag.SecurityNote(Critical = "Asserts SecurityPermission in order to call HostingEnvironment.UnsafeImpersonate.")]
[SecurityCritical]
[SecurityPermission(SecurityAction.Assert, Unrestricted = true)]
public static IDisposable UnsafeImpersonate(IntPtr token)
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
return HostingEnvironment.Impersonate(token);
}
[SuppressMessage(FxCop.Category.Security, FxCop.Rule.SecureAsserts, Justification = "This is an internal SecurityCritical method and its only caller passes in non-user data. Users cannot pass arbitrary data to this code.")]
[Fx.Tag.SecurityNote(Critical = "Asserts SecurityPermission in order to call HostingEnvironment.RegisterObject.")]
[SecurityCritical]
[SecurityPermission(SecurityAction.Assert, Unrestricted = true)]
public static void UnsafeRegisterObject(IRegisteredObject target)
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
HostingEnvironment.RegisterObject(target);
}
[Fx.Tag.SecurityNote(Critical = "Asserts SecurityPermission in order to call HostingEnvironment.UnregisterObject.")]
[SecurityCritical]
[SecurityPermission(SecurityAction.Assert, Unrestricted = true)]
public static void UnsafeUnregisterObject(IRegisteredObject target)
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
HostingEnvironment.UnregisterObject(target);
}
[Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeImpersonate in order to check whether the service file exists.",
Safe = "Does not leak anything, does not let caller influence impersonation.")]
[SecuritySafeCritical]
public static bool ServiceFileExists(string normalizedVirtualPath)
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
IDisposable unsafeImpersonate = null;
try
{
try
{
try
{
}
finally
{
unsafeImpersonate = HostingEnvironmentWrapper.UnsafeImpersonate();
}
return HostingEnvironment.VirtualPathProvider.FileExists(normalizedVirtualPath);
}
finally
{
if (null != unsafeImpersonate)
{
unsafeImpersonate.Dispose();
}
}
}
catch
{
throw;
}
}
[Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeImpersonate in order to get service file.",
Safe = "Does not leak anything, does not let caller influence impersonation.")]
[SecuritySafeCritical]
public static VirtualFile GetServiceFile(string normalizedVirtualPath)
{
AspNetPartialTrustHelpers.FailIfInPartialTrustOutsideAspNet();
IDisposable unsafeImpersonate = null;
try
{
try
{
try
{
}
finally
{
unsafeImpersonate = HostingEnvironmentWrapper.UnsafeImpersonate();
}
return HostingEnvironment.VirtualPathProvider.GetFile(normalizedVirtualPath);
}
finally
{
if (null != unsafeImpersonate)
{
unsafeImpersonate.Dispose();
}
}
}
catch
{
throw;
}
}
}
}
|