public virtual object Create(Object parent, Object configContextObj, XmlNode section)
        {
            // if called through client config don't even load HttpRuntime
            if (!HandlerBase.IsServerConfiguration(configContextObj))
            {
                return(null);
            }


            HttpConfigurationContext configContext = configContextObj as HttpConfigurationContext;

            // section handlers can run in client mode with ConfigurationSettings.GetConfig("sectionName")
            // detect this case and return null to be ensure no exploits from secure client scenarios
            // see ASURT 123738
            if (configContext == null)
            {
                return(null);
            }

            if (HandlerBase.IsPathAtAppLevel(configContext.VirtualPath) == PathLevel.BelowApp)
            {
                throw new ConfigurationException(
                          HttpRuntime.FormatResourceString(SR.Cannot_specify_below_app_level, section.Name),
                          section);
            }

            return(new SecurityPolicyConfig((SecurityPolicyConfig)parent, section, ConfigurationException.GetXmlNodeFilename(section)));
        }
Ejemplo n.º 2
0
        public virtual object Create(Object parent, Object configContextObj, XmlNode section)
        {
            // if called through client config don't even load HttpRuntime
            if (!HandlerBase.IsServerConfiguration(configContextObj))
            {
                return(null);
            }

            HttpConfigurationContext configContext = configContextObj as HttpConfigurationContext;

            if (HandlerBase.IsPathAtAppLevel(configContext.VirtualPath) == PathLevel.BelowApp)
            {
                throw new ConfigurationException(
                          HttpRuntime.FormatResourceString(SR.Cannot_specify_below_app_level, "Authentication"),
                          section);
            }

            return(new AuthenticationConfig((AuthenticationConfig)parent, section));
        }
        // This function is named after a comment in the original code that sums up what it does nicely.
        //  // now we zip up the path, composing config
        HttpConfigurationRecord ComposeConfig(String reqPath, IHttpMapPath configmap)
        {
            // remove ending "/"
            if (reqPath != null && reqPath.Length > 0 && reqPath[reqPath.Length - 1] == '/')
            {
                reqPath = reqPath.Substring(0, reqPath.Length - 1);
            }

            if (configmap == null && reqPath != null)
            {
                //
                // s_contextlessMapPath only works for paths from machine-level to application-level
                // This is only exposed to internal APIs, so this is just to make sure we don't break ourselves.
                //
                Debug.Assert(reqPath != null && (reqPath.Length > s_contextlessMapPath.ApplicationPath.Length ||
                                                 s_contextlessMapPath.ApplicationPath.Substring(0, reqPath.Length) == reqPath));

                configmap = s_contextlessMapPath;
            }
            // QUICK: look up record in cache (case-insensitive)

            //
            // This is the common case because most pages are requested more than once every five minutes
            // Note: will be null on first invocation
            //
            HttpConfigurationRecord configRecord = CacheLookup(reqPath);

            if (configRecord != null)
            {
                return(configRecord);
            }

            DateTime utcStart = DateTime.UtcNow;

            // SLOW: hunt around

            //
            // Next, we start from the end of the request path and work our way toward the machine-level config
            // record.  The first record we find is the one we use.  Later we'll walk back down the path stack
            // building all the records that weren't found in the cache.
            //
            // Note: On first invocation for this appdomain we won't find anything in the cache, so we'll compose
            //      all config records from machine-level down.
            //
            ArrayList pathStack = new ArrayList();
            String    path      = reqPath;
            HttpConfigurationRecord parentRecord = null;

            for (;;)
            {
                // stack child
                pathStack.Add(path);

                // escape from root
                if (path == null)
                {
                    break;
                }

                // go to parent
                path = ParentPath(path);

                // look it up
                parentRecord = CacheLookup(path);

                if (parentRecord == null)
                {
                    configRecord = null;
                }
                else
                {
                    if (parentRecord.IsInheritable)   // only inherit from directory ConfigRecords, else keep looking
                    {
                        Debug.Trace("config", "Config located in cache " + QuoteString(path));
                        break;
                    }
                    configRecord = parentRecord;
                }
            }

            // now we zip down the path, composing config

            //
            // We walk down the path ...
            // For each directory, we build a config record and add a dependency on the config file
            // The first path that doesn't map to a directory we assume
            //   is a file (leaf in the config system and not inheritable)
            // Anything left in the path stack after the file* is assumed to
            //      be pathinfo** and is ignored.
            //
            // Notes:
            // * - we never verify the physical file, it's assumed if the mapped path
            //      is not a directory (is this correct behavior?)
            // ** - pathinfo is the possible junk on the path after the file path:
            //      example: http://localhost/myapp/foo.aspx/bar
            //          /myapp/foo.aspx - file path (see Request.FilePath)
            //          /bar            - pathinfo
            //
            bool          isDir         = true;
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;

            for (int i = pathStack.Count - 1; i >= 0 && isDir == true; i--)
            {
                String    configFile = null;
                String    mappedPath = null;
                Hashtable cachedeps  = null;

                path = (String)pathStack[i];


                if (path == null)
                {
                    mappedPath = "";
                    if (configmap == null)
                    {
                        configFile = HttpConfigurationSystemBase.MachineConfigurationFilePath;
                    }
                    else
                    {
                        configFile = configmap.MachineConfigPath;
                    }

                    // null MachineConfigPath -> never cache config - always return an empty record.
                    if (configFile == null)
                    {
                        return(HttpConfigurationRecord.Empty);
                    }

                    AddFileDependency(configFile);
                }
                else
                {
                    if (IsPath(path))
                    {
                        mappedPath = configmap.MapPath(path);

                        if (IsDirectory(mappedPath))
                        {
                            // for the directory case, grab the config file and a dependency on it
                            configFile = Path.Combine(mappedPath, WebConfigFileName);
                            AddFileDependency(configFile);
                        }
                        else
                        {
                            // otherwise, we're a file and we go ahead and compute as a file
                            isDir = false; // break loop (after record is built)

                            // we need make the cache item dependent on the mapped file location
                            // in case it becomes a directory.
                            if (mappedPath != null)
                            {
                                Debug.Assert(cachedeps == null, "ctracy investigation - cachedeps == null");
                                cachedeps             = new Hashtable(SymbolHashCodeProvider.Default, SymbolEqualComparer.Default);
                                cachedeps[mappedPath] = mappedPath;
                            }
                        }
                    }
                }

                configRecord = new HttpConfigurationRecord(configFile, parentRecord, /*mappedPath,*/ isDir, path);
                string          key        = CacheKey(path);
                CacheDependency dependency = GetCacheDependencies(cachedeps, utcStart);

                Debug.Trace("config_verbose", "Inserting :" + path);

                if (IsBreakOnUnrecognizedElement)
                {
                    // If the registry key is set to debug the rare 'Unrecognized Element'
                    // stress error, lets try to reproduce the error by having an absolute
                    // expiry of 5 minutes (this will cause us to re-read config much more
                    // often.  Before it took memory pressure.
                    DateTime absouteExpiry = DateTime.UtcNow + new TimeSpan(0, 5, 0);
                    cacheInternal.UtcInsert(key, configRecord, dependency, absouteExpiry, Cache.NoSlidingExpiration);
                }
                else
                {
                    if (configRecord.HasError)
                    {
                        cacheInternal.UtcInsert(key, configRecord, dependency,
                                                DateTime.UtcNow.AddSeconds(5), Cache.NoSlidingExpiration);
                    }
                    else
                    {
                        // default: default cache priority, sliding expiration
                        // this will make us rarely expire, config is expensive
                        cacheInternal.UtcInsert(key, configRecord, dependency);
                    }
                }

                // This is to wire-up notification of directories who exist (without a config file) and
                // are then deleted.  In this case we don't want to restart the appdomain because no config information has
                // changed.  We do want to remove the cache record and recreate it on the next request.  (Something in
                // the cache record might be assuming the directory still exists.)
                if (isDir && !FileUtil.FileExists(configFile) && HandlerBase.IsPathAtAppLevel(path) == PathLevel.BelowApp)
                {
                    //AddDirectoryDependency(mappedPath, path, configRecord);
                }

                configRecord.CheckCachedException();
                parentRecord = configRecord;
            }

            return(configRecord);
        }
Ejemplo n.º 4
0
            // CTor
            internal MachineKeyConfig(object parentObject, object contextObject, XmlNode node)
            {
                MachineKeyConfig parent = (MachineKeyConfig)parentObject;

                HttpConfigurationContext configContext = contextObject as HttpConfigurationContext;

                if (HandlerBase.IsPathAtAppLevel(configContext.VirtualPath) == PathLevel.BelowApp)
                {
                    throw new ConfigurationException(
                              HttpRuntime.FormatResourceString(SR.No_MachineKey_Config_In_subdir),
                              node);
                }

                if (parent != null)
                {
                    _ValidationKey  = parent.ValidationKey;
                    _DecryptionKey  = parent.DecryptionKey;
                    _ValidationMode = parent.ValidationMode;
                    _AutogenKey     = parent.AutogenKey;
                }

                XmlNode vNode = node.Attributes.RemoveNamedItem("validationKey");
                XmlNode dNode = node.Attributes.RemoveNamedItem("decryptionKey");

                int iMode = 0;

                string [] modeStrings = { "SHA1", "MD5", "3DES" };
                XmlNode   mNode       = HandlerBase.GetAndRemoveEnumAttribute(node, "validation", modeStrings, ref iMode);

                if (mNode != null)
                {
                    _ValidationMode = (MachineKeyValidationMode)iMode;
                }
                HandlerBase.CheckForUnrecognizedAttributes(node);
                HandlerBase.CheckForChildNodes(node);

                if (vNode != null && vNode.Value != null)
                {
                    String strKey       = vNode.Value;
                    bool   fAppSpecific = strKey.EndsWith(",IsolateApps");

                    if (fAppSpecific)
                    {
                        strKey = strKey.Substring(0, strKey.Length - ",IsolateApps".Length);
                    }

                    if (strKey == "AutoGenerate")   // case sensitive
                    {
                        _ValidationKey = new byte[64];
                        Buffer.BlockCopy(HttpRuntime.s_autogenKeys, 0, _ValidationKey, 0, 64);
                    }
                    else
                    {
                        if (strKey.Length > 128 || strKey.Length < 40)
                        {
                            throw new ConfigurationException(
                                      HttpRuntime.FormatResourceString(
                                          SR.Unable_to_get_cookie_authentication_validation_key, strKey.Length.ToString()),
                                      vNode);
                        }

                        _ValidationKey = HexStringToByteArray(strKey);
                        if (_ValidationKey == null)
                        {
                            throw new ConfigurationException(
                                      HttpRuntime.FormatResourceString(
                                          SR.Invalid_validation_key),
                                      vNode);
                        }
                    }

                    if (fAppSpecific)
                    {
                        int dwCode = SymbolHashCodeProvider.Default.GetHashCode(HttpContext.Current.Request.ApplicationPath);
                        _ValidationKey[0] = (byte)(dwCode & 0xff);
                        _ValidationKey[1] = (byte)((dwCode & 0xff00) >> 8);
                        _ValidationKey[2] = (byte)((dwCode & 0xff0000) >> 16);
                        _ValidationKey[3] = (byte)((dwCode & 0xff000000) >> 24);
                    }
                }

                if (dNode != null)
                {
                    String strKey       = dNode.Value;
                    bool   fAppSpecific = strKey.EndsWith(",IsolateApps");

                    if (fAppSpecific)
                    {
                        strKey = strKey.Substring(0, strKey.Length - ",IsolateApps".Length);
                    }

                    if (strKey == "AutoGenerate")   // case sensitive
                    {
                        _DecryptionKey = new byte[24];
                        Buffer.BlockCopy(HttpRuntime.s_autogenKeys, 64, _DecryptionKey, 0, 24);
                        _AutogenKey = true;
                    }
                    else
                    {
                        _AutogenKey = false;

                        if (strKey.Length == 48)   // Make sure Triple DES is installed
                        {
                            TripleDESCryptoServiceProvider oTemp = null;
                            try {
                                oTemp = new TripleDESCryptoServiceProvider();
                            }
                            catch (Exception) {
                            }
                            if (oTemp == null)
                            {
                                throw new ConfigurationException(
                                          HttpRuntime.FormatResourceString(
                                              SR.cannot_use_Triple_DES),
                                          dNode);
                            }
                        }

                        if (strKey.Length != 48 && strKey.Length != 16)
                        {
                            throw new ConfigurationException(
                                      HttpRuntime.FormatResourceString(
                                          SR.Unable_to_get_cookie_authentication_decryption_key, strKey.Length.ToString()),
                                      dNode);
                        }

                        _DecryptionKey = HexStringToByteArray(strKey);
                        if (_DecryptionKey == null)
                        {
                            throw new ConfigurationException(
                                      HttpRuntime.FormatResourceString(
                                          SR.Invalid_decryption_key),
                                      dNode);
                        }
                    }
                    if (fAppSpecific)
                    {
                        int dwCode = SymbolHashCodeProvider.Default.GetHashCode(HttpContext.Current.Request.ApplicationPath);
                        _DecryptionKey[0] = (byte)(dwCode & 0xff);
                        _DecryptionKey[1] = (byte)((dwCode & 0xff00) >> 8);
                        _DecryptionKey[2] = (byte)((dwCode & 0xff0000) >> 16);
                        _DecryptionKey[3] = (byte)((dwCode & 0xff000000) >> 24);
                    }
                }
            }