1 //------------------------------------------------------------------------------ 2 // <copyright file="VirtualDirectoryMapping.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 namespace System.Web.Configuration { 8 using System; 9 using System.Configuration; 10 using System.IO; 11 using System.Web.Util; 12 using System.Security.Permissions; 13 14 // 15 // Maps a virtual directory to a physical directory and its config file. 16 // 17 public sealed class VirtualDirectoryMapping { 18 VirtualPath _virtualDirectory; 19 string _physicalDirectory; 20 string _configFileBaseName; 21 bool _isAppRoot; 22 23 const string DEFAULT_BASE_NAME = "web.config"; 24 VirtualDirectoryMapping(string physicalDirectory, bool isAppRoot)25 public VirtualDirectoryMapping(string physicalDirectory, bool isAppRoot) 26 : this(null, physicalDirectory, isAppRoot, DEFAULT_BASE_NAME) { 27 28 } 29 VirtualDirectoryMapping(string physicalDirectory, bool isAppRoot, string configFileBaseName)30 public VirtualDirectoryMapping(string physicalDirectory, bool isAppRoot, string configFileBaseName) 31 : this(null, physicalDirectory, isAppRoot, configFileBaseName) { 32 } 33 VirtualDirectoryMapping(VirtualPath virtualDirectory, string physicalDirectory, bool isAppRoot, string configFileBaseName)34 private VirtualDirectoryMapping(VirtualPath virtualDirectory, string physicalDirectory, bool isAppRoot, string configFileBaseName) { 35 _virtualDirectory = virtualDirectory; 36 _isAppRoot = isAppRoot; 37 38 PhysicalDirectory = physicalDirectory; 39 ConfigFileBaseName = configFileBaseName; 40 } 41 Clone()42 internal VirtualDirectoryMapping Clone() { 43 return new VirtualDirectoryMapping(_virtualDirectory, _physicalDirectory, _isAppRoot, _configFileBaseName); 44 } 45 46 // 47 // Get the virtual directory. 48 // Not settable because it is set when it is added to a collection. 49 // 50 public string VirtualDirectory { 51 get { 52 return (_virtualDirectory != null) ? _virtualDirectory.VirtualPathString : string.Empty; 53 } 54 } 55 56 internal VirtualPath VirtualDirectoryObject { 57 get { 58 return _virtualDirectory; 59 } 60 } 61 SetVirtualDirectory(VirtualPath virtualDirectory)62 internal void SetVirtualDirectory(VirtualPath virtualDirectory) { 63 _virtualDirectory = virtualDirectory; 64 } 65 66 // 67 // The physical directory. 68 // 69 public string PhysicalDirectory { 70 get { 71 return _physicalDirectory; 72 } 73 74 set { 75 string physicalDirectory = value; 76 if (String.IsNullOrEmpty(physicalDirectory)) { 77 physicalDirectory = null; 78 } 79 else { 80 // remove trailing '\' if any 81 if (UrlPath.PathEndsWithExtraSlash(physicalDirectory)) { 82 physicalDirectory = physicalDirectory.Substring(0, physicalDirectory.Length - 1); 83 } 84 85 // Throw if the resulting physical path is not canonical, to prevent potential 86 // security issues (VSWhidbey 418125) 87 if (FileUtil.IsSuspiciousPhysicalPath(physicalDirectory)) { 88 throw ExceptionUtil.ParameterInvalid("PhysicalDirectory"); 89 } 90 } 91 92 _physicalDirectory = physicalDirectory; 93 } 94 } 95 96 // 97 // Indicates whether the virtual directory is the location of an application. 98 // 99 public bool IsAppRoot { 100 get { 101 return _isAppRoot; 102 } 103 104 set { 105 _isAppRoot = value; 106 } 107 108 } 109 110 // 111 // The base name of the config file. 112 // If not specified, "web.config" is used. 113 // 114 public string ConfigFileBaseName { 115 get { 116 return _configFileBaseName; 117 } 118 119 set { 120 if (string.IsNullOrEmpty(value)) { 121 throw ExceptionUtil.PropertyInvalid("ConfigFileBaseName"); 122 } 123 124 _configFileBaseName = value; 125 } 126 } 127 Validate()128 internal void Validate() { 129 if (_physicalDirectory != null) { 130 // 131 // Ensure that the caller has PathDiscovery to the resulting config file, 132 // and that the web.config file does not have ".." that could lead to a 133 // different directory. 134 // 135 string configFilename = Path.Combine(_physicalDirectory, _configFileBaseName); 136 string fullConfigFilename = Path.GetFullPath(configFilename); 137 if ( Path.GetDirectoryName(fullConfigFilename) != _physicalDirectory || 138 Path.GetFileName(fullConfigFilename) != _configFileBaseName || 139 FileUtil.IsSuspiciousPhysicalPath(configFilename)) { 140 141 throw ExceptionUtil.ParameterInvalid("configFileBaseName"); 142 } 143 } 144 } 145 } 146 } 147