} // RemoveSessionStateItem /// <summary> /// Gets a flattened view of the environment variables in session state /// </summary> /// /// <returns> /// An IDictionary representing the flattened view of the environment variables in /// session state. /// </returns> /// internal override IDictionary GetSessionStateTable() { // Environment variables are case-sensitive on Unix and // case-insensitive on Windows #if UNIX Dictionary <string, DictionaryEntry> providerTable = new Dictionary <string, DictionaryEntry>(StringComparer.Ordinal); #else Dictionary <string, DictionaryEntry> providerTable = new Dictionary <string, DictionaryEntry>(StringComparer.OrdinalIgnoreCase); #endif // The environment variables returns a dictionary of keys and values that are // both strings. We want to return a dictionary with the key as a string and // the value as the DictionaryEntry containing both the name and env variable // value. IDictionary environmentTable = Environment.GetEnvironmentVariables(); foreach (DictionaryEntry entry in environmentTable) { providerTable.Add((string)entry.Key, entry); } return(providerTable); } // GetSessionStateTable
} // SetSessionStateItem /// <summary> /// Removes the specified environment variable from session state. /// </summary> /// /// <param name="name"> /// The name of the environment variable to remove from session state. /// </param> /// internal override void RemoveSessionStateItem(string name) { Dbg.Diagnostics.Assert( !String.IsNullOrEmpty(name), "The caller should verify this parameter"); Environment.SetEnvironmentVariable(name, null); } // RemoveSessionStateItem
} // InitializeDefaultDrives #endregion DriveCmdletProvider overrides #region protected members /// <summary> /// Gets a environment variable from session state /// </summary> /// /// <param name="name"> /// The name of the environment variable to retrieve. /// </param> /// /// <returns> /// A DictionaryEntry that represents the value of the environment variable. /// </returns> /// internal override object GetSessionStateItem(string name) { Dbg.Diagnostics.Assert( !String.IsNullOrEmpty(name), "The caller should verify this parameter"); object result = null; string value = Environment.GetEnvironmentVariable(name); if (value != null) { result = new DictionaryEntry(name, value); } return(result); } // GetSessionStateItem
/// <summary> /// This value is not writable via the API and must be set using a text editor. /// </summary> /// <param name="scope"></param> /// <returns>Value if found, null otherwise. The behavior matches ModuleIntrinsics.GetExpandedEnvironmentVariable().</returns> internal override string GetModulePath(PropertyScope scope) { string scopeDirectory = psHomeConfigDirectory; // Defaults to system wide. if (PropertyScope.CurrentUser == scope) { scopeDirectory = appDataConfigDirectory; } string fileName = Path.Combine(scopeDirectory, configFileName); string modulePath = ReadValueFromFile <string>(fileName, "PsModulePath"); if (!string.IsNullOrEmpty(modulePath)) { modulePath = Environment.ExpandEnvironmentVariables(modulePath); } return(modulePath); }
/// <summary> /// Report that a module was loaded, but only do so for modules that *might* be authored by Microsoft. We can't /// be 100% certain, but we'll ignore non-Microsoft module names when looking at any data, so it's best to /// at least attempt avoiding collecting data we'll ignore. /// </summary> internal static void ReportModuleLoad(PSModuleInfo foundModule) { var modulePath = foundModule.Path; var companyName = foundModule.CompanyName; bool couldBeMicrosoftModule = (modulePath != null && (modulePath.StartsWith(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), StringComparison.OrdinalIgnoreCase) || // The following covers both 64 and 32 bit Program Files by assuming 32bit is just ...\Program Files + " (x86)" modulePath.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), StringComparison.OrdinalIgnoreCase))) || (companyName != null && foundModule.CompanyName.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase)); if (couldBeMicrosoftModule) { TelemetryWrapper.TraceMessage("PSImportModule", new { ModuleName = foundModule.Name, Version = foundModule.Version.ToString() }); } }
} // GetSessionStateItem /// <summary> /// Sets the environment variable of the specified name to the specified value /// </summary> /// /// <param name="name"> /// The name of the environment variable to set. /// </param> /// /// <param name="value"> /// The new value for the environment variable. /// </param> /// /// <param name="writeItem"> /// If true, the item that was set should be written to WriteItemObject. /// </param> /// internal override void SetSessionStateItem(string name, object value, bool writeItem) { Dbg.Diagnostics.Assert( !String.IsNullOrEmpty(name), "The caller should verify this parameter"); if (value == null) { Environment.SetEnvironmentVariable(name, null); } else { // First see if we got a DictionaryEntry which represents // an item for this provider. If so, use the value from // the dictionary entry. if (value is DictionaryEntry) { value = ((DictionaryEntry)value).Value; } string stringValue = value as string; if (stringValue == null) { // try using ETS to convert to a string. PSObject wrappedObject = PSObject.AsPSObject(value); stringValue = wrappedObject.ToString(); } Environment.SetEnvironmentVariable(name, stringValue); DictionaryEntry item = new DictionaryEntry(name, stringValue); if (writeItem) { WriteItemObject(item, name, false); } } } // SetSessionStateItem
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); } // Product binaries are always trusted if (SecuritySupport.IsProductBinary(path)) { 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); } #if !CORECLR // 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); } } #endif if (_executionPolicy == ExecutionPolicy.Unrestricted) { // 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[] { Environment.GetFolderPath(Environment.SpecialFolder.System), Environment.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); }