diff options
author | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-03-02 12:50:27 +0300 |
---|---|---|
committer | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-03-02 12:50:27 +0300 |
commit | d0f80d5e60d77854f9d6262a59a7349e2b21f9d2 (patch) | |
tree | 01f1e033ce5519d96b7d6a83718221dcb8021eec /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth | |
parent | 26286f616cee657612a9d820be6da2cdbd4de0ef (diff) | |
download | ydb-d0f80d5e60d77854f9d6262a59a7349e2b21f9d2.tar.gz |
intermediate changes
ref:40ac71fae6ea311a73473cf4297ca93bf27559c3
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth')
4 files changed, 150 insertions, 2 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp index de4826fa5b..0baa00058f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp @@ -417,7 +417,7 @@ bool AWSAuthV4Signer::ServiceRequireUnsignedPayload(const Aws::String& serviceNa // However, other services (for example RDS) implement the specification as outlined here: // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html // which states that body-less requests should use the empty-string SHA256 hash. - return "s3" == serviceName; + return "s3" == serviceName || "s3-object-lambda" == serviceName; } Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp index 31e28b996f..bf20ede35e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp @@ -383,7 +383,7 @@ void ProcessCredentialsProvider::Reload() const Aws::String &command = profile.GetCredentialProcess(); if (command.empty()) { - AWS_LOGSTREAM_ERROR(PROCESS_LOG_TAG, "Failed to find credential process's profile: " << m_profileToUse); + AWS_LOGSTREAM_INFO(PROCESS_LOG_TAG, "Failed to find credential process's profile: " << m_profileToUse); return; } m_credentials = GetCredentialsFromProcess(command); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp index 373136d96a..8b019a1664 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp @@ -5,6 +5,7 @@ #include <aws/core/auth/AWSCredentialsProviderChain.h> #include <aws/core/auth/STSCredentialsProvider.h> +#include <aws/core/auth/SSOCredentialsProvider.h> #include <aws/core/platform/Environment.h> #include <aws/core/utils/memory/AWSMemory.h> #include <aws/core/utils/StringUtils.h> @@ -38,6 +39,7 @@ DefaultAWSCredentialsProviderChain::DefaultAWSCredentialsProviderChain() : AWSCr AddProvider(Aws::MakeShared<ProfileConfigFileAWSCredentialsProvider>(DefaultCredentialsProviderChainTag)); AddProvider(Aws::MakeShared<ProcessCredentialsProvider>(DefaultCredentialsProviderChainTag)); AddProvider(Aws::MakeShared<STSAssumeRoleWebIdentityCredentialsProvider>(DefaultCredentialsProviderChainTag)); + AddProvider(Aws::MakeShared<SSOCredentialsProvider>(DefaultCredentialsProviderChainTag)); //ECS TaskRole Credentials only available when ENVIRONMENT VARIABLE is set const auto relativeUri = Aws::Environment::GetEnv(AWS_ECS_CONTAINER_CREDENTIALS_RELATIVE_URI); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp new file mode 100644 index 0000000000..e8f780762e --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp @@ -0,0 +1,146 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#include <aws/core/auth/SSOCredentialsProvider.h> +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/internal/AWSHttpResourceClient.h> +#include <aws/core/platform/Environment.h> +#include <aws/core/platform/FileSystem.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/FileSystemUtils.h> +#include <aws/core/client/SpecifiedRetryableErrorsRetryStrategy.h> +#include <aws/core/utils/UUID.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/json/JsonSerializer.h> + +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; +using namespace Aws::Auth; +using namespace Aws::Internal; +using namespace Aws::FileSystem; +using namespace Aws::Client; +using Aws::Utils::Threading::ReaderLockGuard; + + +static const char SSO_CREDENTIALS_PROVIDER_LOG_TAG[] = "SSOCredentialsProvider"; + +SSOCredentialsProvider::SSOCredentialsProvider() : m_profileToUse(GetConfigProfileName()) +{ + AWS_LOGSTREAM_INFO(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Setting sso credentials provider to read config from " << m_profileToUse); +} + +SSOCredentialsProvider::SSOCredentialsProvider(const Aws::String& profile) : m_profileToUse(profile) +{ + AWS_LOGSTREAM_INFO(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Setting sso credentials provider to read config from " << m_profileToUse); +} + +AWSCredentials SSOCredentialsProvider::GetAWSCredentials() +{ + RefreshIfExpired(); + ReaderLockGuard guard(m_reloadLock); + return m_credentials; +} + +void SSOCredentialsProvider::Reload() +{ + auto profile = Aws::Config::GetCachedConfigProfile(m_profileToUse); + + Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoStartUrl())); + auto profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory(); + Aws::StringStream ssToken; + ssToken << profileDirectory; + ssToken << PATH_DELIM << "sso" << PATH_DELIM << "cache" << PATH_DELIM << hashedStartUrl << ".json"; + auto ssoTokenPath = ssToken.str(); + AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Loading token from: " << ssoTokenPath) + Aws::String accessToken = LoadAccessTokenFile(ssoTokenPath); + if (accessToken.empty()) { + AWS_LOGSTREAM_TRACE(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Access token for SSO not available"); + return; + } + if (m_expiresAt < Aws::Utils::DateTime::Now()) { + AWS_LOGSTREAM_ERROR(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Cached Token expired at " << m_expiresAt.ToGmtString(DateFormat::ISO_8601)); + return; + } + SSOCredentialsClient::SSOGetRoleCredentialsRequest request; + request.m_ssoAccountId = profile.GetSsoAccountId(); + request.m_ssoRoleName = profile.GetSsoRoleName(); + request.m_accessToken = accessToken; + + Aws::Client::ClientConfiguration config; + config.scheme = Aws::Http::Scheme::HTTPS; + config.region = profile.GetSsoRegion(); + AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Passing config to client for region: " << m_ssoRegion); + + Aws::Vector<Aws::String> retryableErrors; + retryableErrors.push_back("TooManyRequestsException"); + + config.retryStrategy = Aws::MakeShared<SpecifiedRetryableErrorsRetryStrategy>(SSO_CREDENTIALS_PROVIDER_LOG_TAG, retryableErrors, 3/*maxRetries*/); + m_client = Aws::MakeUnique<Aws::Internal::SSOCredentialsClient>(SSO_CREDENTIALS_PROVIDER_LOG_TAG, config); + + AWS_LOGSTREAM_TRACE(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Requesting credentials with AWS_ACCESS_KEY: " << m_ssoAccountId); + auto result = m_client->GetSSOCredentials(request); + AWS_LOGSTREAM_TRACE(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Successfully retrieved credentials with AWS_ACCESS_KEY: " << result.creds.GetAWSAccessKeyId()); + + m_credentials = result.creds; +} + +void SSOCredentialsProvider::RefreshIfExpired() +{ + ReaderLockGuard guard(m_reloadLock); + if (!m_credentials.IsExpiredOrEmpty()) + { + return; + } + + guard.UpgradeToWriterLock(); + if (!m_credentials.IsExpiredOrEmpty()) // double-checked lock to avoid refreshing twice + { + return; + } + + Reload(); +} + +Aws::String SSOCredentialsProvider::LoadAccessTokenFile(const Aws::String& ssoAccessTokenPath) +{ + AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Preparing to load token from: " << ssoAccessTokenPath); + + Aws::IFStream inputFile(ssoAccessTokenPath.c_str()); + if(inputFile) + { + AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Reading content from token file: " << ssoAccessTokenPath); + + Json::JsonValue tokenDoc(inputFile); + if (!tokenDoc.WasParseSuccessful()) + { + AWS_LOGSTREAM_ERROR(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Failed to parse token file: " << ssoAccessTokenPath); + return ""; + } + Utils::Json::JsonView tokenView(tokenDoc); + Aws::String tmpAccessToken, expirationStr; + tmpAccessToken = tokenView.GetString("accessToken"); + expirationStr = tokenView.GetString("expiresAt"); + DateTime expiration(expirationStr, DateFormat::ISO_8601); + + AWS_LOGSTREAM_TRACE(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Token cache file contains accessToken [" << tmpAccessToken << "], expiration [" << expirationStr << "]"); + + if (tmpAccessToken.empty() || !expiration.WasParseSuccessful()) { + AWS_LOG_ERROR(SSO_CREDENTIALS_PROVIDER_LOG_TAG, R"(The SSO session associated with this profile has expired or is otherwise invalid. To refresh this SSO session run aws sso login with the corresponding profile.)"); + AWS_LOGSTREAM_TRACE(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Token cache file failed because " + << (tmpAccessToken.empty()?"AccessToken was empty ":"") + << (!expiration.WasParseSuccessful()? "failed to parse expiration":"")); + return ""; + } + m_expiresAt = expiration; + return tmpAccessToken; + } + else + { + AWS_LOGSTREAM_INFO(SSO_CREDENTIALS_PROVIDER_LOG_TAG,"Unable to open token file on path: " << ssoAccessTokenPath); + return ""; + } +}
\ No newline at end of file |