private static FileSecurityDescriptorWrapper GetFileSecurityDescriptorWrapper(string fileName, out bool freeDescriptor)
        {
            if (CachedPathData.DoNotCacheUrlMetadata)
            {
                freeDescriptor = true;
                return(new FileSecurityDescriptorWrapper(fileName));
            }
            freeDescriptor = false;
            string key = "h" + fileName;
            FileSecurityDescriptorWrapper wrapper = HttpRuntime.CacheInternal.Get(key) as FileSecurityDescriptorWrapper;

            if (wrapper == null)
            {
                wrapper = new FileSecurityDescriptorWrapper(fileName);
                string cacheDependencyPath = wrapper.GetCacheDependencyPath();
                if (cacheDependencyPath == null)
                {
                    return(wrapper);
                }
                try
                {
                    CacheDependency dependencies = new CacheDependency(0, cacheDependencyPath);
                    TimeSpan        urlMetadataSlidingExpiration = CachedPathData.UrlMetadataSlidingExpiration;
                    HttpRuntime.CacheInternal.UtcInsert(key, wrapper, dependencies, Cache.NoAbsoluteExpiration, urlMetadataSlidingExpiration, CacheItemPriority.Normal, new CacheItemRemovedCallback(wrapper.OnCacheItemRemoved));
                }
                catch (Exception)
                {
                    freeDescriptor = true;
                }
            }
            return(wrapper);
        }
        private static FileSecurityDescriptorWrapper GetFileSecurityDescriptorWrapper(string fileName, out bool freeDescriptor)
        {
            if (CachedPathData.DoNotCacheUrlMetadata)
            {
                freeDescriptor = true;
                return(new FileSecurityDescriptorWrapper(fileName));
            }

            freeDescriptor = false;
            string oCacheKey = CacheInternal.PrefixFileSecurity + fileName;
            FileSecurityDescriptorWrapper oSecDesc = HttpRuntime.CacheInternal.Get(oCacheKey) as FileSecurityDescriptorWrapper;

            // If it's not present in the cache, then create it and add to the cache
            if (oSecDesc == null)
            {
                Debug.Trace("FAM", "GetFileSecurityDescriptorWrapper: cache miss for " + fileName);
                oSecDesc = new FileSecurityDescriptorWrapper(fileName);
                string cacheDependencyPath = oSecDesc.GetCacheDependencyPath();
                if (cacheDependencyPath != null)
                {
                    // Add it to the cache: ignore failures, since a different thread may have added it or the file doesn't exist
                    try {
                        Debug.Trace("FAM", "GetFileSecurityDescriptorWrapper: inserting into cache with dependency on " + cacheDependencyPath);
                        CacheDependency dependency = new CacheDependency(0, cacheDependencyPath);
                        TimeSpan        slidingExp = CachedPathData.UrlMetadataSlidingExpiration;
                        HttpRuntime.CacheInternal.UtcInsert(oCacheKey, oSecDesc, dependency, Cache.NoAbsoluteExpiration, slidingExp,
                                                            CacheItemPriority.Default, new CacheItemRemovedCallback(oSecDesc.OnCacheItemRemoved));
                    } catch (Exception e) {
                        Debug.Trace("internal", e.ToString());
                        freeDescriptor = true;
                    }
                }
            }
            return(oSecDesc);
        }
        internal static bool RequestRequiresAuthorization(HttpContext context)
        {
            if (!IsWindowsIdentity(context))
            {
                return(false);
            }
            string key  = "h" + context.Request.PhysicalPathInternal;
            object obj2 = HttpRuntime.CacheInternal.Get(key);

            if ((obj2 != null) && (obj2 is FileSecurityDescriptorWrapper))
            {
                FileSecurityDescriptorWrapper wrapper = (FileSecurityDescriptorWrapper)obj2;
                if (wrapper._AnonymousAccessChecked && wrapper._AnonymousAccess)
                {
                    return(false);
                }
            }
            return(true);
        }
        private static FileSecurityDescriptorWrapper GetFileSecurityDescriptorWrapper(string fileName, out bool freeDescriptor) {
            if (CachedPathData.DoNotCacheUrlMetadata) {
                freeDescriptor = true;
                return new FileSecurityDescriptorWrapper(fileName);
            }

            freeDescriptor = false;
            string                          oCacheKey   = CacheInternal.PrefixFileSecurity + fileName;
            FileSecurityDescriptorWrapper   oSecDesc    = HttpRuntime.CacheInternal.Get(oCacheKey) as FileSecurityDescriptorWrapper;

            // If it's not present in the cache, then create it and add to the cache
            if (oSecDesc == null) {
                Debug.Trace("FAM", "GetFileSecurityDescriptorWrapper: cache miss for " + fileName);
                oSecDesc = new FileSecurityDescriptorWrapper(fileName);
                string cacheDependencyPath = oSecDesc.GetCacheDependencyPath();
                if (cacheDependencyPath != null) {
                    // Add it to the cache: ignore failures, since a different thread may have added it or the file doesn't exist
                    try {
                        Debug.Trace("FAM", "GetFileSecurityDescriptorWrapper: inserting into cache with dependency on " + cacheDependencyPath);
                        CacheDependency dependency = new CacheDependency(0, cacheDependencyPath);
                        TimeSpan slidingExp = CachedPathData.UrlMetadataSlidingExpiration;
                        HttpRuntime.CacheInternal.UtcInsert(oCacheKey, oSecDesc, dependency, Cache.NoAbsoluteExpiration, slidingExp,
                                                            CacheItemPriority.Default, new CacheItemRemovedCallback(oSecDesc.OnCacheItemRemoved));
                    } catch (Exception e){
                        Debug.Trace("internal", e.ToString());
                        freeDescriptor = true;
                    }
                }
            }
            return oSecDesc;
        }
示例#5
0
        public static bool CheckFileAccessForUser(String virtualPath, IntPtr token, string verb)
        {
            if (virtualPath == null)
            {
                throw new ArgumentNullException("virtualPath");
            }
            if (token == IntPtr.Zero)
            {
                throw new ArgumentNullException("token");
            }
            if (verb == null)
            {
                throw new ArgumentNullException("verb");
            }
            VirtualPath vPath = VirtualPath.Create(virtualPath);

            if (!vPath.IsWithinAppRoot)
            {
                throw new ArgumentException(SR.GetString(SR.Virtual_path_outside_application_not_supported), "virtualPath");
            }

            if (!s_EnabledDetermined)
            {
                if (HttpRuntime.UseIntegratedPipeline)
                {
                    s_Enabled = true; // always enabled in Integrated Mode
                }
                else
                {
                    HttpModulesSection modulesSection = RuntimeConfig.GetConfig().HttpModules;
                    int len = modulesSection.Modules.Count;
                    for (int iter = 0; iter < len; iter++)
                    {
                        HttpModuleAction module = modulesSection.Modules[iter];
                        if (Type.GetType(module.Type, false) == typeof(FileAuthorizationModule))
                        {
                            s_Enabled = true;
                            break;
                        }
                    }
                }
                s_EnabledDetermined = true;
            }
            if (!s_Enabled)
            {
                return(true);
            }
            ////////////////////////////////////////////////////////////
            // Step 3: Check the cache for the file-security-descriptor
            //        for the requested file
            bool freeDescriptor;
            FileSecurityDescriptorWrapper oSecDesc = GetFileSecurityDescriptorWrapper(vPath.MapPath(), out freeDescriptor);

            ////////////////////////////////////////////////////////////
            // Step 4: Check if access is allowed
            int iAccess = 3;

            if (verb == "GET" || verb == "POST" || verb == "HEAD" || verb == "OPTIONS")
            {
                iAccess = 1;
            }
            bool fAllowed = oSecDesc.IsAccessAllowed(token, iAccess);

            ////////////////////////////////////////////////////////////
            // Step 5: Free the security descriptor if adding to cache failed
            if (freeDescriptor)
            {
                oSecDesc.FreeSecurityDescriptor();
            }
            return(fAllowed);
        }
示例#6
0
        private static bool IsUserAllowedToFile(HttpContext context, string fileName)
        {
            ////////////////////////////////////////////////////////////
            // Step 1: Check if this is WindowsLogin
            // It's not a windows authenticated user: allow access
            if (!IsWindowsIdentity(context))
            {
                return(true);
            }

            if (fileName == null)
            {
                fileName = context.Request.PhysicalPathInternal;
            }

            bool           isAnonymousUser = (context.User == null || !context.User.Identity.IsAuthenticated);
            CachedPathData pathData        = null;
            int            iAccess         = 3;
            HttpVerb       verb            = context.Request.HttpVerb;

            if (verb == HttpVerb.GET ||
                verb == HttpVerb.POST ||
                verb == HttpVerb.HEAD ||
                context.Request.HttpMethod == "OPTIONS")
            {
                iAccess = 1;

                ////////////////////////////////////////////////////////////
                // iff it's a GET or POST or HEAD or OPTIONs verb, we can use the cached result
                if (!CachedPathData.DoNotCacheUrlMetadata)
                {
                    pathData = context.GetConfigurationPathData();
                    // as a perf optimization, we cache results for annoymous access
                    //  to CachedPathData.PhysicalPath, and avoid doing the full check
                    if (!StringUtil.EqualsIgnoreCase(fileName, pathData.PhysicalPath))
                    {
                        // set to null so we don't attempt to update it after the full check below
                        pathData = null;
                    }
                    else
                    {
                        if (pathData.AnonymousAccessAllowed)   // fast path when everyone has access
                        {
                            Debug.Trace("FAM", "IsUserAllowedToFile: pathData.AnonymousAccessAllowed");
                            return(true);
                        }
                        if (pathData.AnonymousAccessChecked && isAnonymousUser)   // fast path for anonymous user
                        // another thread could be modifying CachedPathData, so return the
                        // value of AnonymousAccessAllowed instead of assuming it is false
                        {
                            Debug.Trace("FAM", "IsUserAllowedToFile: pathData.AnonymousAccessChecked && isAnonymousUser");
                            return(pathData.AnonymousAccessAllowed);
                        }
                    }
                }
            }


            // Step 3: Check the cache for the file-security-descriptor
            //        for the requested file
            bool freeDescriptor;
            FileSecurityDescriptorWrapper oSecDesc = GetFileSecurityDescriptorWrapper(fileName, out freeDescriptor);

            ////////////////////////////////////////////////////////////
            // Step 4: Check if access is allowed
            bool fAllowed;

            if (iAccess == 1)   // iff it's a GET or POST or HEAD or OPTIONs verb, we can cache the result
            {
                if (oSecDesc._AnonymousAccessChecked && isAnonymousUser)
                {
                    Debug.Trace("FAM", "IsUserAllowedToFile: oSecDesc._AnonymousAccessChecked && isAnonymousUser");
                    fAllowed = oSecDesc._AnonymousAccess;
                }
                else
                {
                    Debug.Trace("FAM", "IsUserAllowedToFile: calling oSecDesc.IsAccessAllowed with iAccess == 1");
                    fAllowed = oSecDesc.IsAccessAllowed(context.WorkerRequest.GetUserToken(), iAccess);
                }

                if (!oSecDesc._AnonymousAccessChecked && isAnonymousUser)
                {
                    oSecDesc._AnonymousAccess        = fAllowed;
                    oSecDesc._AnonymousAccessChecked = true;
                }

                // Cache results in CachedPathData if the file exists and annonymous access has been checked.
                // Note that if CachedPathData.Exists is false, then it does not have a dependency on the file path,
                // and won't be expunged if the file changes.
                if (pathData != null && pathData.Exists && oSecDesc._AnonymousAccessChecked)
                {
                    Debug.Trace("FAM", "IsUserAllowedToFile: updating pathData");
                    pathData.AnonymousAccessAllowed = oSecDesc._AnonymousAccess;
                    pathData.AnonymousAccessChecked = true;
                }
            }
            else
            {
                Debug.Trace("FAM", "IsUserAllowedToFile: calling oSecDesc.IsAccessAllowed with iAccess != 1");
                fAllowed = oSecDesc.IsAccessAllowed(context.WorkerRequest.GetUserToken(), iAccess); // don't cache this anywhere
            }

            ////////////////////////////////////////////////////////////
            // Step 5: Free the security descriptor if adding to cache failed
            if (freeDescriptor)
            {
                oSecDesc.FreeSecurityDescriptor();
            }

            if (fAllowed)
            {
                WebBaseEvent.RaiseSystemEvent(null, WebEventCodes.AuditFileAuthorizationSuccess);
            }
            else
            {
                if (!isAnonymousUser)
                {
                    WebBaseEvent.RaiseSystemEvent(null, WebEventCodes.AuditFileAuthorizationFailure);
                }
            }

            return(fAllowed);
        }
        void OnEnter(Object source, EventArgs eventArgs)
        {
            HttpApplication app;
            HttpContext     context;

            app     = (HttpApplication)source;
            context = app.Context;

            ////////////////////////////////////////////////////////////
            // Step 1: Check if this is WindowsLogin
            if (context.User == null ||
                context.User.Identity == null ||
                (context.User.Identity is WindowsIdentity) == false)
            {
                // It's not a windows authenticated user: allow access
                return;
            }


            int iAccess = 0;

            if (String.Compare(context.Request.HttpMethod, "GET", false, CultureInfo.InvariantCulture) == 0 ||
                String.Compare(context.Request.HttpMethod, "HEAD", false, CultureInfo.InvariantCulture) == 0 ||
                String.Compare(context.Request.HttpMethod, "POST", false, CultureInfo.InvariantCulture) == 0)
            {
                iAccess = 1;
            }
            else
            {
                iAccess = 3;
            }
            ////////////////////////////////////////////////////////////
            // Step 3: Check the cache for the file-security-descriptor
            //        for the requested file
            Object sec;
            FileSecurityDescriptorWrapper oSecDesc;
            string oCacheKey;
            bool   fCacheAddFailed     = false;
            string requestPhysicalPath = context.Request.PhysicalPathInternal;

            oCacheKey = "System.Web.Security.FileSecurityDescriptorWrapper:" + requestPhysicalPath;

            sec = HttpRuntime.CacheInternal.Get(oCacheKey);

            // If it's not present in the cache, then create it and add to the cache
            if (sec == null || !(sec is FileSecurityDescriptorWrapper))
            {
                // If the file doesn't exist on disk, we'll send back a 404
                //if (!FileUtil.FileExists(requestPhysicalPath))
                //    return;

                // Make it a "sensitive" dependency object so it won't filter out notification
                // if the access time is sooner than dependency creation time.
                // The problem is that setting the ACL won't change the access time of a file.
                // Get the file-security descriptor from native code:
                //   ctor of FileSecurityDescriptorWrapper does that
                oSecDesc = new FileSecurityDescriptorWrapper(requestPhysicalPath);

                if (oSecDesc.IsHandleValid())
                {
                    // Add it to the cache: ignore failures, since a different thread may have added it or the file doesn't exist
                    try {
                        CacheDependency dependency = new CacheDependency(true, requestPhysicalPath);
                        HttpRuntime.CacheInternal.UtcInsert(
                            oCacheKey,
                            oSecDesc,
                            dependency,
                            Cache.NoAbsoluteExpiration,
                            Cache.NoSlidingExpiration,
                            CacheItemPriority.Default,
                            new CacheItemRemovedCallback(oSecDesc.OnCacheItemRemoved));
                    }
                    catch (Exception) {
                        fCacheAddFailed = true;
                    }
                }
            }
            else   // Cast it to the appropiate type
            {
                oSecDesc = (FileSecurityDescriptorWrapper)sec;
            }

            ////////////////////////////////////////////////////////////
            // Step 4: Check if access is allowed
            bool fAllowed;

            if (oSecDesc._AnonymousAccessChecked && !context.User.Identity.IsAuthenticated)
            {
                fAllowed = oSecDesc._AnonymousAccess;
            }
            else
            {
                fAllowed = oSecDesc.IsAccessAllowed(context.WorkerRequest.GetUserToken(), iAccess);
            }

            if (!oSecDesc._AnonymousAccessChecked && !context.User.Identity.IsAuthenticated)
            {
                oSecDesc._AnonymousAccess        = fAllowed;
                oSecDesc._AnonymousAccessChecked = true;
            }

            ////////////////////////////////////////////////////////////
            // Step 5: Free the security descriptor if adding to cache failed
            if (fCacheAddFailed)
            {
                oSecDesc.FreeSecurityDescriptor();
            }


            ////////////////////////////////////////////////////////////
            // Step 6: Allow or deny access
            if (fAllowed)   // Allow access
            {
                return;
            }
            else   // Disallow access
            {
                context.Response.StatusCode = 401;
                WriteErrorMessage(context);
                app.CompleteRequest();
                return;
            }
        }
        public static bool CheckFileAccessForUser(string virtualPath, IntPtr token, string verb)
        {
            bool flag;

            if (virtualPath == null)
            {
                throw new ArgumentNullException("virtualPath");
            }
            if (token == IntPtr.Zero)
            {
                throw new ArgumentNullException("token");
            }
            if (verb == null)
            {
                throw new ArgumentNullException("verb");
            }
            VirtualPath path = VirtualPath.Create(virtualPath);

            if (!path.IsWithinAppRoot)
            {
                throw new ArgumentException(System.Web.SR.GetString("Virtual_path_outside_application_not_supported"), "virtualPath");
            }
            if (!s_EnabledDetermined)
            {
                if (HttpRuntime.UseIntegratedPipeline)
                {
                    s_Enabled = true;
                }
                else
                {
                    HttpModulesSection httpModules = RuntimeConfig.GetConfig().HttpModules;
                    int count = httpModules.Modules.Count;
                    for (int i = 0; i < count; i++)
                    {
                        HttpModuleAction action = httpModules.Modules[i];
                        if (Type.GetType(action.Type, false) == typeof(FileAuthorizationModule))
                        {
                            s_Enabled = true;
                            break;
                        }
                    }
                }
                s_EnabledDetermined = true;
            }
            if (!s_Enabled)
            {
                return(true);
            }
            FileSecurityDescriptorWrapper fileSecurityDescriptorWrapper = GetFileSecurityDescriptorWrapper(path.MapPath(), out flag);
            int iAccess = 3;

            if (((verb == "GET") || (verb == "POST")) || ((verb == "HEAD") || (verb == "OPTIONS")))
            {
                iAccess = 1;
            }
            bool flag2 = fileSecurityDescriptorWrapper.IsAccessAllowed(token, iAccess);

            if (flag)
            {
                fileSecurityDescriptorWrapper.FreeSecurityDescriptor();
            }
            return(flag2);
        }
        private static bool IsUserAllowedToFile(HttpContext context, string fileName)
        {
            bool flag2;
            bool flag3;

            if (!IsWindowsIdentity(context))
            {
                return(true);
            }
            if (fileName == null)
            {
                fileName = context.Request.PhysicalPathInternal;
            }
            bool           flag = (context.User == null) || !context.User.Identity.IsAuthenticated;
            CachedPathData configurationPathData = null;
            int            iAccess  = 3;
            HttpVerb       httpVerb = context.Request.HttpVerb;

            if (((httpVerb == HttpVerb.GET) || (httpVerb == HttpVerb.POST)) || ((httpVerb == HttpVerb.HEAD) || (context.Request.HttpMethod == "OPTIONS")))
            {
                iAccess = 1;
                if (!CachedPathData.DoNotCacheUrlMetadata)
                {
                    configurationPathData = context.GetConfigurationPathData();
                    if (!StringUtil.EqualsIgnoreCase(fileName, configurationPathData.PhysicalPath))
                    {
                        configurationPathData = null;
                    }
                    else
                    {
                        if (configurationPathData.AnonymousAccessAllowed)
                        {
                            return(true);
                        }
                        if (configurationPathData.AnonymousAccessChecked && flag)
                        {
                            return(configurationPathData.AnonymousAccessAllowed);
                        }
                    }
                }
            }
            FileSecurityDescriptorWrapper fileSecurityDescriptorWrapper = GetFileSecurityDescriptorWrapper(fileName, out flag2);

            if (iAccess == 1)
            {
                if (fileSecurityDescriptorWrapper._AnonymousAccessChecked && flag)
                {
                    flag3 = fileSecurityDescriptorWrapper._AnonymousAccess;
                }
                else
                {
                    flag3 = fileSecurityDescriptorWrapper.IsAccessAllowed(context.WorkerRequest.GetUserToken(), iAccess);
                }
                if (!fileSecurityDescriptorWrapper._AnonymousAccessChecked && flag)
                {
                    fileSecurityDescriptorWrapper._AnonymousAccess        = flag3;
                    fileSecurityDescriptorWrapper._AnonymousAccessChecked = true;
                }
                if (((configurationPathData != null) && configurationPathData.Exists) && fileSecurityDescriptorWrapper._AnonymousAccessChecked)
                {
                    configurationPathData.AnonymousAccessAllowed = fileSecurityDescriptorWrapper._AnonymousAccess;
                    configurationPathData.AnonymousAccessChecked = true;
                }
            }
            else
            {
                flag3 = fileSecurityDescriptorWrapper.IsAccessAllowed(context.WorkerRequest.GetUserToken(), iAccess);
            }
            if (flag2)
            {
                fileSecurityDescriptorWrapper.FreeSecurityDescriptor();
            }
            if (flag3)
            {
                WebBaseEvent.RaiseSystemEvent(null, 0xfa4);
                return(flag3);
            }
            if (!flag)
            {
                WebBaseEvent.RaiseSystemEvent(null, 0xfa8);
            }
            return(flag3);
        }
 private static FileSecurityDescriptorWrapper GetFileSecurityDescriptorWrapper(string fileName, out bool freeDescriptor)
 {
     if (CachedPathData.DoNotCacheUrlMetadata)
     {
         freeDescriptor = true;
         return new FileSecurityDescriptorWrapper(fileName);
     }
     freeDescriptor = false;
     string key = "h" + fileName;
     FileSecurityDescriptorWrapper wrapper = HttpRuntime.CacheInternal.Get(key) as FileSecurityDescriptorWrapper;
     if (wrapper == null)
     {
         wrapper = new FileSecurityDescriptorWrapper(fileName);
         string cacheDependencyPath = wrapper.GetCacheDependencyPath();
         if (cacheDependencyPath == null)
         {
             return wrapper;
         }
         try
         {
             CacheDependency dependencies = new CacheDependency(0, cacheDependencyPath);
             TimeSpan urlMetadataSlidingExpiration = CachedPathData.UrlMetadataSlidingExpiration;
             HttpRuntime.CacheInternal.UtcInsert(key, wrapper, dependencies, Cache.NoAbsoluteExpiration, urlMetadataSlidingExpiration, CacheItemPriority.Normal, new CacheItemRemovedCallback(wrapper.OnCacheItemRemoved));
         }
         catch (Exception)
         {
             freeDescriptor = true;
         }
     }
     return wrapper;
 }