/// <summary> /// Gets the list of special directories. This method should be optimized if called more then once. /// </summary> /// <returns>The list of special directories</returns> private static IList <Uri> SetSpecialFolders() { string[] specialFolderArray = new string[5] { Environment.GetFolderPath(Environment.SpecialFolder.System), Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), Environment.GetFolderPath(Environment.SpecialFolder.Startup), ItemSecurityChecker.GetSpecialDirectoryFromNative(NativeMethods.ExtendedSpecialFolder.Windows), ItemSecurityChecker.GetSpecialDirectoryFromNative(NativeMethods.ExtendedSpecialFolder.CommonStartup) }; List <Uri> specialFolders = new List <Uri>(5); // Add trailing backslash to the folders. foreach (string specialFolder in specialFolderArray) { string tempFolder = specialFolder; if (!tempFolder.EndsWith("\\", StringComparison.Ordinal)) { tempFolder += "\\"; } specialFolders.Add(new Uri(tempFolder)); } return(specialFolders); }
protected virtual bool CheckItemsLocation(out string securityErrorMessage) { securityErrorMessage = String.Empty; // Get the <LoadTimeCheckItemLocation> property from the project string itemLocationProperty = this.projectShim.GetEvaluatedProperty(ProjectSecurityChecker.CheckItemLocationProperty); if (String.IsNullOrEmpty(itemLocationProperty)) { return(true); } // Takes a semicolon separated list of entries, splits them and puts them into a list with values trimmed. string[] items = itemLocationProperty.Split(ProjectSecurityChecker.DangerousListSeparator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); IList <string> itemsToCheck = new List <string>(); foreach (string item in items) { itemsToCheck.Add(item.Trim()); } // Now check the items for being defined in a safe location. string reasonForFailure; ItemSecurityChecker itemsSecurityChecker = new ItemSecurityChecker(this.serviceProvider, this.projectShim.FullFileName); if (!itemsSecurityChecker.CheckItemsSecurity(this.projectShim, itemsToCheck, out reasonForFailure)) { securityErrorMessage = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.DetailsItemLocation, CultureInfo.CurrentUICulture), Path.GetFileName(this.projectShim.FullFileName), reasonForFailure); return(false); } return(true); }
/// <summary> /// Overloaded Constructor /// </summary> /// <param name="projectFilePath">path to the project file</param> /// <param name="serviceProvider">A service provider.</param> internal ItemSecurityChecker(IServiceProvider serviceProvider, string projectFullPath) { this.serviceProvider = serviceProvider; // Initialize the project and solution folders. this.SetProjectFolder(projectFullPath); this.SetSolutionFolder(); // Set the special folders. Maybe this should be a static. this.specialFolders = ItemSecurityChecker.SetSpecialFolders(); }
protected virtual bool CheckItemsLocation(out string securityErrorMessage) { securityErrorMessage = String.Empty; // Get the <LoadTimeCheckItemLocation> property from the project string itemLocationProperty = this.projectShim.GetEvaluatedProperty(ProjectSecurityChecker.CheckItemLocationProperty); if(String.IsNullOrEmpty(itemLocationProperty)) { return true; } // Takes a semicolon separated list of entries, splits them and puts them into a list with values trimmed. string[] items = itemLocationProperty.Split(ProjectSecurityChecker.DangerousListSeparator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); IList<string> itemsToCheck = new List<string>(); foreach(string item in items) { itemsToCheck.Add(item.Trim()); } // Now check the items for being defined in a safe location. string reasonForFailure; ItemSecurityChecker itemsSecurityChecker = new ItemSecurityChecker(this.serviceProvider, this.projectShim.FullFileName); if(!itemsSecurityChecker.CheckItemsSecurity(this.projectShim, itemsToCheck, out reasonForFailure)) { securityErrorMessage = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.DetailsItemLocation, CultureInfo.CurrentUICulture), Path.GetFileName(this.projectShim.FullFileName), reasonForFailure); return false; } return true; }
/// <summary> /// Checks whether a set of project items described by the LoadTimeCheckItemLocation are in a safe location. /// </summary> /// <param name="projectShim">The project shim containing the items to be checked.</param> /// <param name="itemsToCheck">The list of items to check if they are in the project cone.</param> /// <param name="reasonForFailure">The reason for failure if any of the files fails</param> /// <returns>true if all project items are in the project cone. Otherwise false.</returns> internal bool CheckItemsSecurity(ProjectShim projectShim, IList <string> itemsToCheck, out string reasonForFailure) { reasonForFailure = String.Empty; // If nothing to check assume that everything is ok. if (itemsToCheck == null) { return(true); } Debug.Assert(projectShim != null, "Cannot check the items if no project has been defined!"); foreach (string itemName in itemsToCheck) { BuildItemGroupShim group = projectShim.GetEvaluatedItemsByNameIgnoringCondition(itemName); if (group != null) { IEnumerator enumerator = group.GetEnumerator(); while (enumerator.MoveNext()) { BuildItemShim item = enumerator.Current as BuildItemShim; string finalItem = item.FinalItemSpec; if (!String.IsNullOrEmpty(finalItem)) { // Perform the actual check - start with normalizing the path. Relative paths // should be treated as relative to the project file. string fullPath = this.GetFullPath(finalItem); // If the fullpath of the item is suspiciously short do not check it. if (fullPath.Length >= 3) { Uri uri = null; // If we cannot create a uri from the item path return with the error if (!Uri.TryCreate(fullPath, UriKind.Absolute, out uri)) { reasonForFailure = fullPath; return(false); } // Check if the item points to a network share if (uri.IsUnc) { reasonForFailure = fullPath; return(false); } // Check if the item is located in a drive root directory if (uri.Segments.Length == 3 && uri.Segments[1] == ":" && uri.Segments[2][0] == Path.DirectorySeparatorChar) { reasonForFailure = fullPath; return(false); } //Check if the item is not in a special folder. foreach (Uri specialFolder in this.specialFolders) { if (ItemSecurityChecker.IsItemInCone(uri, specialFolder)) { reasonForFailure = fullPath; return(false); } } } else { reasonForFailure = fullPath; return(false); } } } } } return(true); }