/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.Runtime.CredentialManagement; using Amazon.Runtime.Internal; using Amazon.Runtime.Internal.Util; using Amazon.Util; using System; using System.IO; namespace Amazon.Runtime { /// /// /// Credentials that are retrieved using a stored profile. /// /// /// Unless otherwise specified priority is given to loading credentials from the SDK credential store /// file which is shared between the SDK, PowerShell CLI and Toolkit. Credentials in profiles in this /// file are encrypted and can only be used by the user account on the current machine that stored the /// profile. Credentials can also be loaded from the plain-text ini-format credential file which is /// shared with other AWS SDKs. This file is expected to exist in a '.aws' folder in the user's home /// directory but alternate locations can be specified using either the AWSProfilesLocation setting in /// the application configuration file, or by using the AWS_SHARED_CREDENTIALS_FILE environment variable. /// /// /// The profile name can be specified in the App.config using the AWSProfileName setting. /// /// [Obsolete("This class is obsolete and will be removed in a future release. Please use Amazon.Runtime.CredentialManagement.NetSDKCredentialsFile or SharedCredentialsFile.. Visit http://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html for further details.")] public class StoredProfileAWSCredentials : AWSCredentials { private AWSCredentials _wrappedCredentials; public AWSCredentials WrappedCredentials { get { return _wrappedCredentials; } } #region Public constructors /// /// Constructs an instance for credentials stored in a profile. This constructor searches for credentials /// using the account name specified using the AWSProfileName setting, if set, in the application configuration /// file. If the configuration file setting is not set the SDK will attempt to locate a profile with the name /// 'default'. /// public StoredProfileAWSCredentials() : this(AWSConfigs.AWSProfileName) { } /// /// Constructs an instance for credentials stored in a profile with the specified name. The SDK will /// check the SDK credential store file first before looking for the shared ini-format credentials /// file unless the application configuration file contains a setting for the 'AWSProfilesLocation' /// indicating the search should be constrained to the shared credentials file at the specified /// location. /// /// The name of the profile in which the credentials were stored. public StoredProfileAWSCredentials(string profileName) : this(profileName, AWSConfigs.AWSProfilesLocation) { } /// /// Constructs an instance for credentials stored in a profile with the specified name. /// /// The profile name to search for credentials for /// /// Optional; instructs the SDK to check for the profile in the shared credentials file at the /// specified location. If not set, the SDK will inspect its own credential store file first before /// attempting to locate a shared credential file using either the default location beneath the user's /// home profile folder or the location specified in the AWS_SHARED_CREDENTIALS_FILE environment /// variable. /// /// /// If credential materials cannot be read or are invalid due to missing data an InvalidDataException /// is thrown. If no credentials can be located with the specified profile name, an ArgumentException /// is thrown. /// public StoredProfileAWSCredentials(string profileName, string profilesLocation) { var lookupName = string.IsNullOrEmpty(profileName) ? StoredProfileCredentials.DEFAULT_PROFILE_NAME : profileName; ProfileName = lookupName; ProfilesLocation = null; // If not overriding the credentials lookup location check the SDK Store for credentials. If an override is being used then // assume the intent is to use the credentials file. if (string.IsNullOrEmpty(profilesLocation) && ProfileManager.IsProfileKnown(lookupName) && ProfileManager.IsAvailable) { if (ProfileManager.IsProfileKnown(lookupName) && AWSCredentialsProfile.CanCreateFrom(lookupName)) { _wrappedCredentials = ProfileManager.GetAWSCredentials(lookupName); var logger = Logger.GetLogger(typeof(StoredProfileAWSCredentials)); logger.InfoFormat("Credentials found using account name {0} and looking in SDK account store.", lookupName); } } // If credentials weren't found in the SDK store then search the shared credentials file. if (this._wrappedCredentials == null) { var credentialsFilePath = StoredProfileCredentials.ResolveSharedCredentialFileLocation(profilesLocation); if (!string.IsNullOrEmpty(credentialsFilePath)) { var sharedCredentialsFile = new SharedCredentialsFile(credentialsFilePath); CredentialProfile profile; if (sharedCredentialsFile.TryGetProfile(lookupName, out profile) && AWSCredentialsFactory.TryGetAWSCredentials(profile, sharedCredentialsFile, out _wrappedCredentials)) { var logger = Logger.GetLogger(typeof(StoredProfileAWSCredentials)); logger.InfoFormat("Credentials found using account name {0} and looking in {1}.", lookupName, credentialsFilePath); } ProfilesLocation = credentialsFilePath; } } // No credentials found so error out. if (this._wrappedCredentials == null) { throw new ArgumentException("App.config does not contain credentials information. Either add the AWSAccessKey and AWSSecretKey properties or the AWSProfileName property."); } } #endregion #region Public properties /// /// Name of the profile being used. /// public string ProfileName { get; private set; } /// /// Location of the profiles, if used. /// public string ProfilesLocation { get; private set; } #endregion /// /// Tests if a profile has been registered in either the SDK store or the specified credential /// file. /// /// The name of the profile to test /// /// Optional; instructs the SDK to check for the profile in the shared credentials file at the /// specified location. If not set, the SDK will inspect its own credential store file first before /// attempting to locate a shared credential file using either the default location beneath the user's /// home profile folder or the location specified in the AWS_SHARED_CREDENTIALS_FILE environment /// variable. /// /// True if a profile with the specified name has been registered. public static bool IsProfileKnown(string profileName, string profilesLocation) { if (string.IsNullOrEmpty(profilesLocation) && ProfileManager.IsProfileKnown(profileName)) { return true; } else { return ValidCredentialsExistInSharedFile(profilesLocation, profileName); } } /// /// Tests if an instance can be created from the persisted profile data. /// If profilesLocation is null/empty, the SDK store is searched for the /// profile data before probing for the profile in the shared the ini-format /// credential file. /// /// The name of the profile to test /// /// If null/empty, the SDK store is searched for the named profile otherwise /// the ini-format credential file at the specified location is inspected. /// /// True if the persisted data would yield a valid credentials instance. public static bool CanCreateFrom(string profileName, string profilesLocation) { if (string.IsNullOrEmpty(profilesLocation) && ProfileManager.IsProfileKnown(profileName)) { return AWSCredentialsProfile.CanCreateFrom(profileName); } else { return ValidCredentialsExistInSharedFile(profilesLocation, profileName); } } private static bool ValidCredentialsExistInSharedFile(string profilesLocation, string profileName) { var credentialsFilePath = StoredProfileCredentials.ResolveSharedCredentialFileLocation(profilesLocation); if (!string.IsNullOrEmpty(credentialsFilePath)) { var doLog = false; try { var file = new SharedCredentialsFile(credentialsFilePath); CredentialProfile profile = null; if (file.TryGetProfile(profileName, out profile) && profile.CanCreateAWSCredentials) { return true; } else { doLog = true; } } catch (InvalidDataException) { doLog = true; } if (doLog) { var logger = Logger.GetLogger(typeof(StoredProfileAWSCredentials)); logger.InfoFormat("Credentials file {0} does not contain a valid profile named {1}.", credentialsFilePath, profileName); } } else { var logger = Logger.GetLogger(typeof(StoredProfileAWSCredentials)); logger.InfoFormat("Credentials file not found {0}.", credentialsFilePath); } return false; } #region Abstract class overrides /// /// Returns an instance of ImmutableCredentials for this instance /// /// public override ImmutableCredentials GetCredentials() { return _wrappedCredentials.GetCredentials(); } #endregion } }