Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/aspnetwebstack.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Web.Mvc/SecurityUtil.cs')
-rw-r--r--src/System.Web.Mvc/SecurityUtil.cs79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/System.Web.Mvc/SecurityUtil.cs b/src/System.Web.Mvc/SecurityUtil.cs
new file mode 100644
index 00000000..becded41
--- /dev/null
+++ b/src/System.Web.Mvc/SecurityUtil.cs
@@ -0,0 +1,79 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using System.Security;
+
+namespace System.Web.Mvc
+{
+ internal static class SecurityUtil
+ {
+ private static Action<Action> _callInAppTrustThunk;
+
+ // !! IMPORTANT !!
+ // Do not try to optimize this method or perform any extra caching; doing so could lead to MVC not operating
+ // correctly until the AppDomain is restarted.
+ [SuppressMessage("Microsoft.Security", "CA2107:ReviewDenyAndPermitOnlyUsage",
+ Justification = "This is essentially the same logic as Page.ProcessRequest.")]
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
+ Justification = "If an exception is thrown, assume we're running in same trust level as the application itself, so we don't need to do anything special.")]
+ private static Action<Action> GetCallInAppTrustThunk()
+ {
+ // do we need to create the thunk?
+ if (_callInAppTrustThunk == null)
+ {
+ try
+ {
+ if (!typeof(SecurityUtil).Assembly.IsFullyTrusted /* bin-deployed */
+ || AppDomain.CurrentDomain.IsHomogenous /* .NET 4 CAS model */)
+ {
+ // we're already running in the application's trust level, so nothing to do
+ _callInAppTrustThunk = f => f();
+ }
+ else
+ {
+ // legacy CAS model - need to lower own permission level to be compatible with legacy systems
+ // This is essentially the same logic as Page.ProcessRequest(HttpContext)
+ NamedPermissionSet namedPermissionSet = (NamedPermissionSet)typeof(HttpRuntime).GetProperty("NamedPermissionSet", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
+ bool disableProcessRequestInApplicationTrust = (bool)typeof(HttpRuntime).GetProperty("DisableProcessRequestInApplicationTrust", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
+ if (namedPermissionSet != null && !disableProcessRequestInApplicationTrust)
+ {
+ _callInAppTrustThunk = f =>
+ {
+ // lower permissions
+ namedPermissionSet.PermitOnly();
+ f();
+ };
+ }
+ else
+ {
+ // application's trust level is FullTrust, so nothing to do
+ _callInAppTrustThunk = f => f();
+ }
+ }
+ }
+ catch
+ {
+ // MVC assembly is already running in application trust, so swallow exceptions
+ }
+ }
+
+ // if there was an error, just process transparently
+ return _callInAppTrustThunk ?? (Action<Action>)(f => f());
+ }
+
+ public static TResult ProcessInApplicationTrust<TResult>(Func<TResult> func)
+ {
+ TResult result = default(TResult);
+ ProcessInApplicationTrust(delegate
+ {
+ result = func();
+ });
+ return result;
+ }
+
+ public static void ProcessInApplicationTrust(Action action)
+ {
+ Action<Action> executor = GetCallInAppTrustThunk();
+ executor(action);
+ }
+ }
+}