/// <summary> /// Translates enum into a friendlier 'from xxx' display string /// </summary> /// <param name="creds"></param> /// <returns></returns> internal static string FormatCredentialSourceForDisplay(AWSPSCredentials creds) { switch (creds.Source) { case CredentialsSource.CredentialsObject: return("supplied credentials object"); case CredentialsSource.Container: return("container environment"); case CredentialsSource.InstanceProfile: return("instance profile"); case CredentialsSource.Profile: return(String.Format("stored profile named '{0}'", creds.Name)); case CredentialsSource.Session: return("shell variable $" + SessionKeys.AWSCredentialsVariableName); case CredentialsSource.Strings: return("the supplied key parameters"); } // fallback return(Enum.GetName(typeof(CredentialsSource), creds.Source)); }
/// <summary> /// Try to obtain an <see cref="AWSCredentials"/> from the PowerShell session variable <c>StoredAWSCredentials</c> by reflection. /// Because we have duplicated some of the credential classes we have conflicting types, therefore we have to get to the underlying /// common credentials using reflection. /// </summary> /// <param name="sessionVariableValue">The session variable value.</param> /// <param name="credentials">The credentials.</param> /// <returns><c>true</c> if credentials obtained from PowerShell session; else <c>false</c>.</returns> private static bool TryGetAWSPSCredentialsFromConflictingType(object sessionVariableValue, out AWSPSCredentials credentials) { credentials = null; if (sessionVariableValue == null) { return(false); } var properties = sessionVariableValue.GetType().GetProperties( System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var credentialsProperty = properties.FirstOrDefault(p => typeof(AWSCredentials).IsAssignableFrom(p.PropertyType)); var nameProperty = properties.FirstOrDefault(p => p.Name == "Name" && p.PropertyType == typeof(string)); if (credentialsProperty != null) { credentials = new AWSPSCredentials( (AWSCredentials)credentialsProperty.GetValue(sessionVariableValue), nameProperty != null ? (string)nameProperty.GetValue(sessionVariableValue) : "none", CredentialsSource.Session); return(true); } return(false); }
/// <summary> /// Safely emit a diagnostic message indicating where the credentials we are about to use /// originated from. /// </summary> /// <param name="awsPSCredentials"></param> protected void WriteCredentialSourceDiagnostic(AWSPSCredentials awsPSCredentials) { try { WriteCredentialSourceDiagnostic(FormatCredentialSourceForDisplay(awsPSCredentials)); } catch { } }
/// <summary> /// update the custom state we have applied to hold the host and any network credential /// the user has supplied to us as a shell default to fall back on if we get called to /// show the password dialog /// </summary> /// <param name="currentCredentials"></param> private void SetUpIfFederatedCredentials(AWSPSCredentials currentCredentials) { var callbackState = (currentCredentials.Credentials as FederatedAWSCredentials)?.Options.CustomCallbackState as SAMLCredentialCallbackState; #if DESKTOP if (callbackState == null) { #pragma warning disable CS0618 //A class was marked with the Obsolete attribute callbackState = (currentCredentials.Credentials as StoredProfileFederatedCredentials)?.CustomCallbackState as SAMLCredentialCallbackState; #pragma warning restore CS0618 //A class was marked with the Obsolete attribute } #endif if (callbackState != null) // is our callback that's attached { callbackState.ShellNetworkCredentialParameter = NetworkCredential; } }
private void GetFromCommandLine(out AWSPSCredentials awsPSCredentialsFromCommandLine, out RegionEndpoint regionFromCommandLine) { // Retrieve credentials if passed in (or from Instance Profile) if (this.TryGetCredentials(Host, out awsPSCredentialsFromCommandLine, SessionState)) { WriteVerbose(string.Format("{0}: Credentials for this shell were set from {1}", MyInvocation.MyCommand.Name, ServiceCmdlet.FormatCredentialSourceForDisplay(awsPSCredentialsFromCommandLine))); } RegionSource regionSource; if (this.TryGetRegion(true, out regionFromCommandLine, out regionSource, SessionState)) { WriteVerbose(string.Format("{0}: Region '{1}' was set for this shell from {2}", MyInvocation.MyCommand.Name, regionFromCommandLine.SystemName, ServiceCmdlet.FormatRegionSourceForDisplay(regionSource))); } }
protected override void ProcessRecord() { AWSPSCredentials currentCredentials = null; if (this.TryGetCredentials(Host, out currentCredentials, SessionState)) { // used to be equivalent of write-host but got customer feedback that the inability to // suppress it interfered with console output (https://forums.aws.amazon.com/thread.jspa?threadID=211600&tstart=0). WriteVerbose(InitializeDefaultConfigurationCmdlet.CredentialsSourceMessage(currentCredentials)); } else { this.ThrowTerminatingError(new ErrorRecord(new ArgumentException("Cannot determine credentials from supplied parameters"), "ArgumentException", ErrorCategory.InvalidArgument, this)); } if (currentCredentials != null) { WriteObject(currentCredentials.Credentials); } }
private void GetFromDefaultProfile(out AWSPSCredentials awsPSCredentialsFromDefaultProfile, out RegionEndpoint regionFromDefaultProfile) { CredentialProfile profile; if (SettingsStore.TryGetProfile(SettingsStore.PSDefaultSettingName, ProfileLocation, out profile)) { AWSCredentials defaultAWSCredentials; if (SettingsStore.TryGetAWSCredentials(SettingsStore.PSDefaultSettingName, ProfileLocation, out defaultAWSCredentials)) { awsPSCredentialsFromDefaultProfile = new AWSPSCredentials(defaultAWSCredentials, SettingsStore.PSDefaultSettingName, CredentialsSource.Profile); } else { awsPSCredentialsFromDefaultProfile = null; } regionFromDefaultProfile = profile.Region; } else { awsPSCredentialsFromDefaultProfile = null; regionFromDefaultProfile = null; } }
public static bool TryGetCredentials( this IAWSCredentialsArguments self, PSHost psHost, out AWSPSCredentials credentials, SessionState sessionState) { if (self == null) { throw new ArgumentNullException("self"); } credentials = null; string name = null; var source = CredentialsSource.Unknown; var userSpecifiedProfile = !string.IsNullOrEmpty(self.ProfileName); var profileChain = new CredentialProfileStoreChain(self.ProfileLocation); // we probe for credentials by first checking the bound parameters to see if explicit credentials // were supplied (keys, profile name, credential object), overriding anything in the shell environment if (AWSCredentialsFactory.TryGetAWSCredentials( self.GetCredentialProfileOptions(), profileChain, out var innerCredentials)) { source = CredentialsSource.Strings; name = "Supplied Key Parameters"; SetProxyAndCallbackIfNecessary(innerCredentials, self, psHost, sessionState); } // user gave us the profile name? if (innerCredentials == null && userSpecifiedProfile) { if (profileChain.TryGetProfile(self.ProfileName, out var credentialProfile)) { innerCredentials = AWSCredentialsFactory.GetAWSCredentials(credentialProfile, profileChain); source = CredentialsSource.Profile; name = self.ProfileName; SetProxyAndCallbackIfNecessary(innerCredentials, self, psHost, sessionState); } else { // if the user gave us an explicit profile name (and optional location) it's an error if we // don't find it as otherwise we could drop through and pick up a 'default' profile that is // for a different account return(false); } } // how about an aws credentials object? if (innerCredentials == null && self.Credential != null) { innerCredentials = self.Credential; source = CredentialsSource.CredentialsObject; name = "Credentials Object"; // don't set proxy and callback, use self.Credential as-is } // shell session variable set (this allows override of machine-wide environment variables) if (innerCredentials == null && sessionState != null) { if (TryGetAWSPSCredentialsFromConflictingType( sessionState.PSVariable.GetValue(SessionKeys.AWSCredentialsVariableName), out var psCredentials)) { credentials = psCredentials; source = CredentialsSource.Session; innerCredentials = credentials.Credentials; // so remaining probes are skipped // don't set proxy and callback, use credentials.Credentials as-is } } // no explicit command-level or shell instance override set, start to inspect the environment // starting environment variables if (innerCredentials == null) { try { var environmentCredentials = new EnvironmentVariablesAWSCredentials(); innerCredentials = environmentCredentials; source = CredentialsSource.Environment; name = "Environment Variables"; // no need to set proxy and callback - only basic or session credentials } catch { } } // get credentials from a 'default' profile? if (innerCredentials == null && !userSpecifiedProfile) { if (profileChain.TryGetProfile(SettingsStore.PSDefaultSettingName, out var credentialProfile) && credentialProfile.CanCreateAWSCredentials) { innerCredentials = AWSCredentialsFactory.GetAWSCredentials(credentialProfile, profileChain); source = CredentialsSource.Profile; name = SettingsStore.PSDefaultSettingName; SetProxyAndCallbackIfNecessary(innerCredentials, self, psHost, sessionState); } } // get credentials from a legacy default profile name? if (innerCredentials == null) { if (profileChain.TryGetProfile(SettingsStore.PSLegacyDefaultSettingName, out var credentialProfile) && credentialProfile.CanCreateAWSCredentials) { if (AWSCredentialsFactory.TryGetAWSCredentials( credentialProfile, profileChain, out innerCredentials)) { source = CredentialsSource.Profile; name = SettingsStore.PSLegacyDefaultSettingName; SetProxyAndCallbackIfNecessary(innerCredentials, self, psHost, sessionState); } } } if (innerCredentials == null) { // try and load credentials from ECS endpoint (if the relevant environment variable is set) // or EC2 Instance Profile as a last resort try { var relativeUri = Environment.GetEnvironmentVariable(ECSTaskCredentials.ContainerCredentialsURIEnvVariable); var fullUri = Environment.GetEnvironmentVariable( ECSTaskCredentials.ContainerCredentialsFullURIEnvVariable); if (!string.IsNullOrEmpty(relativeUri) || !string.IsNullOrEmpty(fullUri)) { innerCredentials = new ECSTaskCredentials(); source = CredentialsSource.Container; name = "Container"; // no need to set proxy and callback } else { innerCredentials = new InstanceProfileAWSCredentials(); source = CredentialsSource.InstanceProfile; name = "Instance Profile"; // no need to set proxy and callback } } catch { innerCredentials = null; } } if (credentials == null && innerCredentials != null) { credentials = new AWSPSCredentials(innerCredentials, name, source); } return(credentials != null); }
protected override void ProcessRecord() { AWSPSCredentials currentCredentials = null; if (this.TryGetCredentials(Host, out currentCredentials, SessionState)) { WriteVerbose(InitializeDefaultConfigurationCmdlet.CredentialsSourceMessage(currentCredentials)); if (string.IsNullOrEmpty(StoreAs)) { SetUpIfFederatedCredentials(currentCredentials); string scope = MyInvocation.BoundParameters.ContainsKey("Scope") ? Scope.ToString() + ":" : ""; this.SessionState.PSVariable.Set(scope + SessionKeys.AWSCredentialsVariableName, currentCredentials); } else { if (MyInvocation.BoundParameters.ContainsKey("Scope")) { this.ThrowTerminatingError(new ErrorRecord( new ArgumentException("Parameters Scope and StoreAs cannot be used together."), "ArgumentException", ErrorCategory.InvalidArgument, this)); } if (string.Equals(AWSCredentialsArgumentsFullCmdlet.AWSCredentialsObjectSet, ParameterSetName, StringComparison.Ordinal)) { // We're storing from the -Credential parameter to a credentials file. // Only some types of AWSCredentials are supported. var options = CredentialProfileOptionsExtractor.ExtractProfileOptions(currentCredentials.Credentials); if (options != null) { SettingsStore.RegisterProfile(options, StoreAs, ProfileLocation, null); } } else { if (string.Equals(AWSCredentialsArgumentsFullCmdlet.StoredProfileSet, ParameterSetName, StringComparison.Ordinal)) { // We're copying from one profile to another. var chain = new CredentialProfileStoreChain(ProfileLocation); CredentialProfile profile; if (chain.TryGetProfile(ProfileName, out profile)) { profile.CredentialProfileStore.CopyProfile(ProfileName, StoreAs, true); } else { // Parameters.TryGetCredentials has already tested for this but... this.ThrowTerminatingError(new ErrorRecord( new ArgumentException("Cannot determine credentials from supplied parameters"), "ArgumentException", ErrorCategory.InvalidArgument, this)); } } else { // We're storing from individual command line values to a credentials file. SettingsStore.RegisterProfile(GetCredentialProfileOptions(), StoreAs, ProfileLocation, null); } } if (string.IsNullOrEmpty(ProfileLocation)) { WriteVerbose("Updated .NET credentials file."); } else { WriteVerbose("Updated shared credentials file at " + ProfileLocation); } } } else { this.ThrowTerminatingError(new ErrorRecord(new ArgumentException("Cannot determine credentials from supplied parameters"), "ArgumentException", ErrorCategory.InvalidArgument, this)); } }
protected override void ProcessRecord() { AWSPSCredentials awsPSCredentialsFromCommandLine; RegionEndpoint regionFromCommandLine; AWSPSCredentials awsPSCredentialsFromDefaultProfile; RegionEndpoint regionFromDefaultProfile; AWSPSCredentials awsPSCredentialsFromPromptingUser = null; RegionEndpoint regionFromPromptingUser = null; // get what was passed in on the command line, and what's already in defaults GetFromCommandLine(out awsPSCredentialsFromCommandLine, out regionFromCommandLine); GetFromDefaultProfile(out awsPSCredentialsFromDefaultProfile, out regionFromDefaultProfile); // if the command line and defaults don't provide us what we need then prompt the user if (awsPSCredentialsFromCommandLine == null && awsPSCredentialsFromDefaultProfile == null) { awsPSCredentialsFromPromptingUser = PromptUserForCredentials(); } if (regionFromCommandLine == null && regionFromDefaultProfile == null) { regionFromPromptingUser = PromptUserForRegion(); } // figure out what needs to be saved to disk and what needs to get put in session var awsPSCredentialsToPersist = awsPSCredentialsFromCommandLine == null ? awsPSCredentialsFromPromptingUser : awsPSCredentialsFromCommandLine; var awsPSCredentialsToPutInSession = awsPSCredentialsToPersist == null ? awsPSCredentialsFromDefaultProfile : awsPSCredentialsToPersist; var regionToPersist = regionFromCommandLine == null ? regionFromPromptingUser : regionFromCommandLine; var regionToPutInSession = regionToPersist == null ? regionFromDefaultProfile : regionToPersist; // save credentials and region to disk if necessary if (awsPSCredentialsToPersist != null || regionToPersist != null) { if (string.Equals(AWSCredentialsArgumentsFullCmdlet.AWSCredentialsObjectSet, ParameterSetName, StringComparison.Ordinal)) { // We're storing from the -Credential parameter to a credentials file. // Only some types of AWSCredentials are supported. var options = CredentialProfileOptionsExtractor.ExtractProfileOptions(awsPSCredentialsToPersist.Credentials); if (options != null) { SettingsStore.RegisterProfile(options, SettingsStore.PSDefaultSettingName, ProfileLocation, regionToPersist); } } else { if (string.Equals(AWSCredentialsArgumentsFullCmdlet.StoredProfileSet, ParameterSetName, StringComparison.Ordinal)) { // We're copying from one profile to another. var chain = new CredentialProfileStoreChain(ProfileLocation); CredentialProfile profile; if (chain.TryGetProfile(ProfileName, out profile)) { profile.CredentialProfileStore.CopyProfile(ProfileName, SettingsStore.PSDefaultSettingName, true); SettingsStore.RegisterProfile(new CredentialProfileOptions(), SettingsStore.PSDefaultSettingName, ProfileLocation, regionToPersist); } else { // Parameters.TryGetCredentials has already tested for this but... this.ThrowTerminatingError(new ErrorRecord( new ArgumentException("Cannot determine credentials from supplied parameters"), "ArgumentException", ErrorCategory.InvalidArgument, this)); } } else { // We're storing from individual command line values to the default profile. SettingsStore.RegisterProfile(GetCredentialProfileOptions(), SettingsStore.PSDefaultSettingName, ProfileLocation, regionToPersist); } } if (string.IsNullOrEmpty(ProfileLocation)) { WriteVerbose("Updated SDK profile store."); } else { WriteVerbose("Updated credential file at " + ProfileLocation); } WriteVerbose(string.Format("Default credentials and/or region have been stored to credentials profile '{0}' and set active for this shell.", SettingsStore.PSDefaultSettingName)); } string scope = MyInvocation.BoundParameters.ContainsKey("Scope") ? Scope.ToString() + ":" : ""; // put credentials and region in session this.SessionState.PSVariable.Set(scope + SessionKeys.AWSCredentialsVariableName, awsPSCredentialsToPutInSession); this.SessionState.PSVariable.Set(scope + SessionKeys.AWSRegionVariableName, regionToPutInSession.SystemName); }
internal static string CredentialsSourceMessage(AWSPSCredentials creds) { return(string.Format(CredentialsSourceMsg, ServiceCmdlet.FormatCredentialSourceForDisplay(creds))); }