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))); }
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); }
// 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); } } }