private bool SetPolicyFromAuthenticodePrompt(string path, PSHost host, ref Exception reason, Signature signature) { bool policyCheckPassed = false; string reasonMessage; RunPromptDecision decision = AuthenticodePrompt(path, signature, host); switch (decision) { case RunPromptDecision.RunOnce: policyCheckPassed = true; break; case RunPromptDecision.AlwaysRun: { TrustPublisher(signature); policyCheckPassed = true; }; break; case RunPromptDecision.DoNotRun: policyCheckPassed = false; reasonMessage = StringUtil.Format(Authenticode.Reason_DoNotRun, path); reason = new UnauthorizedAccessException(reasonMessage); break; case RunPromptDecision.NeverRun: { UntrustPublisher(signature); reasonMessage = StringUtil.Format(Authenticode.Reason_NeverRun, path); reason = new UnauthorizedAccessException(reasonMessage); policyCheckPassed = false; }; break; } return(policyCheckPassed); }
private RunPromptDecision AuthenticodePrompt(string path, System.Management.Automation.Signature signature, PSHost host) { Collection <ChoiceDescription> authenticodePromptChoices; string authenticodePromptCaption; string str2; if ((host == null) || (host.UI == null)) { return(RunPromptDecision.DoNotRun); } RunPromptDecision doNotRun = RunPromptDecision.DoNotRun; if (signature == null) { return(doNotRun); } switch (signature.Status) { case SignatureStatus.Valid: authenticodePromptChoices = this.GetAuthenticodePromptChoices(); authenticodePromptCaption = Authenticode.AuthenticodePromptCaption; if (signature.SignerCertificate != null) { str2 = StringUtil.Format(Authenticode.AuthenticodePromptText, path, signature.SignerCertificate.SubjectName.Name); break; } str2 = StringUtil.Format(Authenticode.AuthenticodePromptText_UnknownPublisher, path); break; case SignatureStatus.UnknownError: case SignatureStatus.NotSigned: case SignatureStatus.HashMismatch: case SignatureStatus.NotSupportedFileFormat: return(RunPromptDecision.DoNotRun); default: return(RunPromptDecision.DoNotRun); } return((RunPromptDecision)host.UI.PromptForChoice(authenticodePromptCaption, str2, authenticodePromptChoices, 1)); }
private RunPromptDecision AuthenticodePrompt(string path, Signature signature, PSHost host) { if ((host == null) || (host.UI == null)) { return(RunPromptDecision.DoNotRun); } RunPromptDecision decision = RunPromptDecision.DoNotRun; if (signature == null) { return(decision); } switch (signature.Status) { // // we do not allow execution in any one of the // following cases // case SignatureStatus.UnknownError: case SignatureStatus.NotSigned: case SignatureStatus.HashMismatch: case SignatureStatus.NotSupportedFileFormat: decision = RunPromptDecision.DoNotRun; break; case SignatureStatus.Valid: Collection <ChoiceDescription> choices = GetAuthenticodePromptChoices(); string promptCaption = Authenticode.AuthenticodePromptCaption; string promptText; if (signature.SignerCertificate == null) { promptText = StringUtil.Format(Authenticode.AuthenticodePromptText_UnknownPublisher, path); } else { promptText = StringUtil.Format(Authenticode.AuthenticodePromptText, path, signature.SignerCertificate.SubjectName.Name ); } int userChoice = host.UI.PromptForChoice(promptCaption, promptText, choices, (int)RunPromptDecision.DoNotRun); decision = (RunPromptDecision)userChoice; break; // // if the publisher is not trusted, we prompt and // ask the user if s/he wants to allow it to run // default: decision = RunPromptDecision.DoNotRun; break; } return(decision); }
private bool CheckPolicy(ExternalScriptInfo script, PSHost host, out Exception reason) { bool policyCheckPassed = false; reason = null; string path = script.Path; string reasonMessage; // path is assumed to be fully qualified here if (path.IndexOf(System.IO.Path.DirectorySeparatorChar) < 0) { throw PSTraceSource.NewArgumentException("path"); } if (path.LastIndexOf(System.IO.Path.DirectorySeparatorChar) == (path.Length - 1)) { throw PSTraceSource.NewArgumentException("path"); } FileInfo fi = new FileInfo(path); // Return false if the file does not exist, so that // we don't introduce a race condition if (!fi.Exists) { reason = new FileNotFoundException(path); return(false); } // Quick exit if we don't support the file type if (!IsSupportedExtension(fi.Extension)) { return(true); } // Get the execution policy _executionPolicy = SecuritySupport.GetExecutionPolicy(_shellId); // See if they want to bypass the authorization manager if (_executionPolicy == ExecutionPolicy.Bypass) { return(true); } // Always check the SAFER APIs if code integrity isn't being handled system-wide through // WLDP or AppLocker. In those cases, the scripts will be run in ConstrainedLanguage. // Otherwise, block. // SAFER APIs are not on CSS or OneCore if (SystemPolicy.GetSystemLockdownPolicy() != SystemEnforcementMode.Enforce) { SaferPolicy saferPolicy = SaferPolicy.Disallowed; int saferAttempt = 0; bool gotSaferPolicy = false; // We need to put in a retry workaround, as the SAFER APIs fail when under stress. while ((!gotSaferPolicy) && (saferAttempt < 5)) { try { saferPolicy = SecuritySupport.GetSaferPolicy(path, null); gotSaferPolicy = true; } catch (System.ComponentModel.Win32Exception) { if (saferAttempt > 4) { throw; } saferAttempt++; System.Threading.Thread.Sleep(100); } } // If the script is disallowed via AppLocker, block the file // unless the system-wide lockdown policy is "Enforce" (where all PowerShell // scripts are in blocked). If the system policy is "Enforce", then the // script will be allowed (but ConstrainedLanguage will be applied). if (saferPolicy == SaferPolicy.Disallowed) { reasonMessage = StringUtil.Format(Authenticode.Reason_DisallowedBySafer, path); reason = new UnauthorizedAccessException(reasonMessage); return(false); } } if (_executionPolicy == ExecutionPolicy.Unrestricted) { // Product binaries are always trusted // This avoids signature and security zone checks if (SecuritySupport.IsProductBinary(path)) { return(true); } // We need to give the "Remote File" warning // if the file originated from the internet if (!IsLocalFile(fi.FullName)) { // Get the signature of the file. if (String.IsNullOrEmpty(script.ScriptContents)) { reasonMessage = StringUtil.Format(Authenticode.Reason_FileContentUnavailable, path); reason = new UnauthorizedAccessException(reasonMessage); return(false); } Signature signature = GetSignatureWithEncodingRetry(path, script); // The file is signed, with a publisher that // we trust if (signature.Status == SignatureStatus.Valid) { // The file is signed by a trusted publisher if (IsTrustedPublisher(signature, path)) { policyCheckPassed = true; } } // We don't care about the signature. If you distrust them, // or the signature does not exist, we prompt you only // because it's remote. if (!policyCheckPassed) { RunPromptDecision decision = RunPromptDecision.DoNotRun; // Get their remote prompt answer, allowing them to // enter nested prompts, if wanted. do { decision = RemoteFilePrompt(path, host); if (decision == RunPromptDecision.Suspend) { host.EnterNestedPrompt(); } } while (decision == RunPromptDecision.Suspend); switch (decision) { case RunPromptDecision.RunOnce: policyCheckPassed = true; break; case RunPromptDecision.DoNotRun: default: policyCheckPassed = false; reasonMessage = StringUtil.Format(Authenticode.Reason_DoNotRun, path); reason = new UnauthorizedAccessException(reasonMessage); break; } } } else { policyCheckPassed = true; } } // Don't need to check the signature if the file is local // and we're in "RemoteSigned" mode else if ((IsLocalFile(fi.FullName)) && (_executionPolicy == ExecutionPolicy.RemoteSigned)) { policyCheckPassed = true; } else if ((_executionPolicy == ExecutionPolicy.AllSigned) || (_executionPolicy == ExecutionPolicy.RemoteSigned)) { // if policy requires signature verification, // make it so. // Get the signature of the file. if (String.IsNullOrEmpty(script.ScriptContents)) { reasonMessage = StringUtil.Format(Authenticode.Reason_FileContentUnavailable, path); reason = new UnauthorizedAccessException(reasonMessage); return(false); } Signature signature = GetSignatureWithEncodingRetry(path, script); // The file is signed. if (signature.Status == SignatureStatus.Valid) { // The file is signed by a trusted publisher if (IsTrustedPublisher(signature, path)) { policyCheckPassed = true; } // The file is signed by an unknown publisher, // So prompt. else { policyCheckPassed = SetPolicyFromAuthenticodePrompt(path, host, ref reason, signature); } } // The file is UnknownError, NotSigned, HashMismatch, // NotTrusted, NotSupportedFileFormat else { policyCheckPassed = false; if (signature.Status == SignatureStatus.NotTrusted) { reason = new UnauthorizedAccessException( StringUtil.Format(Authenticode.Reason_NotTrusted, path, signature.SignerCertificate.SubjectName.Name)); } else { reason = new UnauthorizedAccessException( StringUtil.Format(Authenticode.Reason_Unknown, path, signature.StatusMessage)); } } } else // if(executionPolicy == ExecutionPolicy.Restricted) { // Deny everything policyCheckPassed = false; // But accept mshxml files from publishers that we // trust, or files in the system protected directories bool reasonSet = false; if (String.Equals(fi.Extension, ".ps1xml", StringComparison.OrdinalIgnoreCase)) { string[] trustedDirectories = new string[] { Platform.GetFolderPath(Environment.SpecialFolder.System), Platform.GetFolderPath(Environment.SpecialFolder.ProgramFiles) }; foreach (string trustedDirectory in trustedDirectories) { if (fi.FullName.StartsWith(trustedDirectory, StringComparison.OrdinalIgnoreCase)) { policyCheckPassed = true; } } if (!policyCheckPassed) { // Get the signature of the file. Signature signature = GetSignatureWithEncodingRetry(path, script); // The file is signed by a trusted publisher if (signature.Status == SignatureStatus.Valid) { if (IsTrustedPublisher(signature, path)) { policyCheckPassed = true; } // The file is signed by an unknown publisher, // So prompt. else { policyCheckPassed = SetPolicyFromAuthenticodePrompt(path, host, ref reason, signature); reasonSet = true; } } } } if (!policyCheckPassed && !reasonSet) { reason = new UnauthorizedAccessException( StringUtil.Format(Authenticode.Reason_RestrictedMode, path)); } } return(policyCheckPassed); }
private bool CheckPolicy(ExternalScriptInfo script, PSHost host, out Exception reason) { string str2; bool flag = false; reason = null; string path = script.Path; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { if (path.IndexOf('\\') < 0) { throw PSTraceSource.NewArgumentException("path"); } if (path.LastIndexOf('\\') == (path.Length - 1)) { throw PSTraceSource.NewArgumentException("path"); } } FileInfo info = new FileInfo(path); if (!info.Exists) { reason = new FileNotFoundException(path); return(false); } if (!IsSupportedExtension(info.Extension)) { return(true); } if (this.IsProductBinary(path)) { return(true); } this.executionPolicy = SecuritySupport.GetExecutionPolicy(this.shellId); if (this.executionPolicy == ExecutionPolicy.Bypass) { return(true); } SaferPolicy disallowed = SaferPolicy.Disallowed; int num = 0; bool flag2 = false; while (!flag2 && (num < 5)) { try { disallowed = SecuritySupport.GetSaferPolicy(path); flag2 = true; continue; } catch (Win32Exception) { if (num > 4) { throw; } num++; Thread.Sleep(100); continue; } } if (disallowed == SaferPolicy.Disallowed) { str2 = StringUtil.Format(Authenticode.Reason_DisallowedBySafer, path); reason = new UnauthorizedAccessException(str2); return(false); } if (this.executionPolicy != ExecutionPolicy.Unrestricted) { if (this.IsLocalFile(info.FullName) && (this.executionPolicy == ExecutionPolicy.RemoteSigned)) { return(true); } if ((this.executionPolicy == ExecutionPolicy.AllSigned) || (this.executionPolicy == ExecutionPolicy.RemoteSigned)) { if (string.IsNullOrEmpty(script.ScriptContents)) { str2 = StringUtil.Format(Authenticode.Reason_FileContentUnavailable, path); reason = new UnauthorizedAccessException(str2); return(false); } System.Management.Automation.Signature signature = this.GetSignatureWithEncodingRetry(path, script); if (signature.Status == SignatureStatus.Valid) { return(this.IsTrustedPublisher(signature, path) || this.SetPolicyFromAuthenticodePrompt(path, host, ref reason, signature)); } flag = false; if (signature.Status == SignatureStatus.NotTrusted) { reason = new UnauthorizedAccessException(StringUtil.Format(Authenticode.Reason_NotTrusted, path, signature.SignerCertificate.SubjectName.Name)); return(flag); } reason = new UnauthorizedAccessException(StringUtil.Format(Authenticode.Reason_Unknown, path, signature.StatusMessage)); return(flag); } flag = false; bool flag3 = false; if (string.Equals(info.Extension, ".ps1xml", StringComparison.OrdinalIgnoreCase)) { string[] strArray = new string[] { Environment.GetFolderPath(Environment.SpecialFolder.System), Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) }; foreach (string str3 in strArray) { if (info.FullName.StartsWith(str3, StringComparison.OrdinalIgnoreCase)) { flag = true; } } if (!flag) { System.Management.Automation.Signature signature3 = this.GetSignatureWithEncodingRetry(path, script); if (signature3.Status == SignatureStatus.Valid) { if (this.IsTrustedPublisher(signature3, path)) { flag = true; } else { flag = this.SetPolicyFromAuthenticodePrompt(path, host, ref reason, signature3); flag3 = true; } } } } if (!flag && !flag3) { reason = new UnauthorizedAccessException(StringUtil.Format(Authenticode.Reason_RestrictedMode, path)); } return(flag); } if (this.IsLocalFile(info.FullName)) { return(true); } if (string.IsNullOrEmpty(script.ScriptContents)) { str2 = StringUtil.Format(Authenticode.Reason_FileContentUnavailable, path); reason = new UnauthorizedAccessException(str2); return(false); } System.Management.Automation.Signature signatureWithEncodingRetry = this.GetSignatureWithEncodingRetry(path, script); if ((signatureWithEncodingRetry.Status == SignatureStatus.Valid) && this.IsTrustedPublisher(signatureWithEncodingRetry, path)) { flag = true; } if (flag) { return(flag); } RunPromptDecision doNotRun = RunPromptDecision.DoNotRun; Label_0149: doNotRun = this.RemoteFilePrompt(path, host); if (doNotRun == RunPromptDecision.Suspend) { host.EnterNestedPrompt(); } switch (doNotRun) { case RunPromptDecision.RunOnce: return(true); case RunPromptDecision.Suspend: goto Label_0149; } flag = false; str2 = StringUtil.Format(Authenticode.Reason_DoNotRun, path); reason = new UnauthorizedAccessException(str2); return(flag); }