/// Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Globalization; using System.IO; using Microsoft.VisualStudio.Build.ComInteropWrapper; namespace Microsoft.VisualStudio.Project { /// /// Does security validation of a user project before loading the project. /// public class UserProjectSecurityChecker : ProjectSecurityChecker { #region fields /// /// The project shim for the main project file. /// We need this otherwise the msbuild API cannot check the user file. /// private ProjectShim mainProjectShim; #endregion #region ctors /// /// Overloaded Constructor /// /// path to the project file /// A service provider. public UserProjectSecurityChecker(IServiceProvider serviceProvider, string projectFilePath) : base(serviceProvider, projectFilePath) { } #endregion #region properties /// /// The main projects' shim. /// internal protected ProjectShim MainProjectShim { get { return this.mainProjectShim; } internal set { this.mainProjectShim = value; } } #endregion #region overridden method /// /// Checks if the user file is safe with imports. If it has then the user file is considered unsafe. /// /// At return describes the reason why the projects is not considered safe. /// true if the user project is safe regarding imports. protected override bool IsProjectSafeWithImports(out string securityErrorMessage) { securityErrorMessage = String.Empty; string[] directImports = this.SecurityCheckHelper.GetDirectlyImportedProjects(this.ProjectShim); if(directImports != null && directImports.Length > 0) { securityErrorMessage = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.DetailsUserImport, CultureInfo.CurrentUICulture), Path.GetFileName(this.ProjectShim.FullFileName), directImports[0]); return false; } return true; } /// /// Checks if the project is safe regarding properties. /// /// At return describes the reason why the projects is not considered safe. /// true if the project has only safe properties. protected override bool IsProjectSafeWithProperties(out string securityErrorMessage) { securityErrorMessage = String.Empty; // Now ask the security check heper for the safe properties. string reasonForFailure; bool isUserFile; bool isProjectSafe = this.SecurityCheckHelper.IsProjectSafe(ProjectSecurityChecker.DangerousPropertyProperty, ProjectSecurityChecker.DefaultDangerousProperties, this.mainProjectShim, this.ProjectShim, SecurityCheckPass.Properties, out reasonForFailure, out isUserFile); // Main project gets precedence over the user project. // Do not report that since this is only for the user file. if(!isUserFile) { return true; } if(!isProjectSafe) { securityErrorMessage = this.GetMessageString(reasonForFailure, SR.DetailsProperty); } return isProjectSafe; } /// /// Checks if the project is safe regarding targets. /// /// At return describes the reason why the projects is not considered safe. /// true if the project has only safe targets. protected override bool IsProjectSafeWithTargets(out string securityErrorMessage) { securityErrorMessage = String.Empty; // Now ask the security check heper for the safe targets. string reasonForFailure; bool isUserFile; bool isProjectSafe = this.SecurityCheckHelper.IsProjectSafe(ProjectSecurityChecker.DangerousTargetProperty, ProjectSecurityChecker.DefaultDangerousTargets, this.mainProjectShim, this.ProjectShim, SecurityCheckPass.Targets, out reasonForFailure, out isUserFile); // Main project gets precedence over the user project. // Do not report that since this is only for the user file. if(!isUserFile) { return true; } if(!isProjectSafe) { securityErrorMessage = this.GetMessageString(reasonForFailure, SR.DetailsTarget); } return isProjectSafe; } /// /// Checks if the project is safe regarding items. /// /// At return describes the reason why the projects is not considered safe. /// true if the project has only safe items. protected override bool IsProjectSafeWithItems(out string securityErrorMessage) { securityErrorMessage = String.Empty; // Now ask the security check heper for the safe items. string reasonForFailure; bool isUserFile; bool isProjectSafe = this.SecurityCheckHelper.IsProjectSafe(ProjectSecurityChecker.DangerousItemsProperty, ProjectSecurityChecker.DefaultDangerousItems, this.mainProjectShim, this.ProjectShim, SecurityCheckPass.Items, out reasonForFailure, out isUserFile); // Main project gets precedence over the user project. // Do not report that since this is only for the user file. if(!isUserFile) { return true; } if(!isProjectSafe) { securityErrorMessage = this.GetMessageString(reasonForFailure, SR.DetailsItem); } return isProjectSafe; } #endregion } }