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 | |
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')
15 files changed, 489 insertions, 14 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp index 1eaa477fca..33856b968a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp @@ -65,6 +65,11 @@ namespace Aws Aws::Utils::Crypto::SetMD5Factory(options.cryptoOptions.md5Factory_create_fn()); } + if(options.cryptoOptions.sha1Factory_create_fn) + { + Aws::Utils::Crypto::SetSha1Factory(options.cryptoOptions.sha1Factory_create_fn()); + } + if(options.cryptoOptions.sha256Factory_create_fn) { Aws::Utils::Crypto::SetSha256Factory(options.cryptoOptions.sha256Factory_create_fn()); 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 diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp index e1ff064840..4b2a38b4e6 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp @@ -137,7 +137,7 @@ void AWSClient::SetServiceClientName(const Aws::String& name) if (!m_customizedUserAgent) { Aws::StringStream ss; - ss << "aws-sdk-cpp/" << Version::GetVersionString() << "/" << m_serviceName << "/" << Aws::OSVersionInfo::ComputeOSVersionString() + ss << "aws-sdk-cpp/" << Version::GetVersionString() << " " << Aws::OSVersionInfo::ComputeOSVersionString() << " " << Version::GetCompilerVersionString(); m_userAgent = ss.str(); } @@ -626,7 +626,7 @@ void AWSClient::AddContentBodyToRequest(const std::shared_ptr<Aws::Http::HttpReq } //Add transfer-encoding:chunked to header - if (body && isChunked) + if (body && isChunked && !httpRequest->HasHeader(Http::CONTENT_LENGTH_HEADER)) { httpRequest->SetTransferEncoding(CHUNKED_VALUE); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp index 9ec2e54f55..bb6acd0b3a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp @@ -67,6 +67,10 @@ namespace Aws static const char ACCESS_KEY_ID_KEY[] = "aws_access_key_id"; static const char SECRET_KEY_KEY[] = "aws_secret_access_key"; static const char SESSION_TOKEN_KEY[] = "aws_session_token"; + static const char SSO_START_URL_KEY[] = "sso_start_url"; + static const char SSO_REGION_KEY[] = "sso_region"; + static const char SSO_ACCOUNT_ID_KEY[] = "sso_account_id"; + static const char SSO_ROLE_NAME_KEY[] = "sso_role_name"; static const char ROLE_ARN_KEY[] = "role_arn"; static const char EXTERNAL_ID_KEY[] = "external_id"; static const char CREDENTIAL_PROCESS_COMMAND[] = "credential_process"; @@ -184,6 +188,33 @@ namespace Aws profile.SetCredentials(Aws::Auth::AWSCredentials(accessKey, secretKey, sessionToken)); } + auto ssoStartUrlIter = m_profileKeyValuePairs.find(SSO_START_URL_KEY); + auto ssoRegionIter = m_profileKeyValuePairs.find(SSO_REGION_KEY); + auto ssoRoleNameIter = m_profileKeyValuePairs.find(SSO_ROLE_NAME_KEY); + auto ssoAccountIdIter = m_profileKeyValuePairs.find(SSO_ACCOUNT_ID_KEY); + if (ssoStartUrlIter != m_profileKeyValuePairs.end() + || ssoRegionIter != m_profileKeyValuePairs.end() + || ssoRoleNameIter != m_profileKeyValuePairs.end() + || ssoAccountIdIter != m_profileKeyValuePairs.end()) + { + if (ssoStartUrlIter != m_profileKeyValuePairs.end() + && ssoRegionIter != m_profileKeyValuePairs.end() + && ssoRoleNameIter != m_profileKeyValuePairs.end() + && ssoAccountIdIter != m_profileKeyValuePairs.end()) + { + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_start_url " << ssoStartUrlIter->second); + profile.SetSsoStartUrl(ssoStartUrlIter->second); + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_region " << ssoRegionIter->second); + profile.SetSsoRegion(ssoRegionIter->second); + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_account_id " << ssoAccountIdIter->second); + profile.SetSsoAccountId(ssoAccountIdIter->second); + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_role_name " << ssoRoleNameIter->second); + profile.SetSsoRoleName(ssoRoleNameIter->second); + } else { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "invalid configuration for sso profile " << profile.GetName()); + } + } + auto assumeRoleArnIter = m_profileKeyValuePairs.find(ROLE_ARN_KEY); if (assumeRoleArnIter != m_profileKeyValuePairs.end()) { diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp index 2fb9cc9643..95132f5df0 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp @@ -142,8 +142,9 @@ struct CurlWriteCallbackContext struct CurlReadCallbackContext { - CurlReadCallbackContext(const CurlHttpClient* client, HttpRequest* request, Aws::Utils::RateLimits::RateLimiterInterface* limiter) : + CurlReadCallbackContext(const CurlHttpClient* client, CURL* curlHandle, HttpRequest* request, Aws::Utils::RateLimits::RateLimiterInterface* limiter) : m_client(client), + m_curlHandle(curlHandle), m_rateLimiter(limiter), m_request(request) {} @@ -236,10 +237,10 @@ static size_t ReadBody(char* ptr, size_t size, size_t nmemb, void* userdata) { if (request->IsEventStreamRequest()) { - // Waiting for next available character to read. - // Without peek(), readsome() will keep reading 0 byte from the stream. - ioStream->peek(); - ioStream->readsome(ptr, amountToRead); + if (ioStream->readsome(ptr, amountToRead) == 0 && !ioStream->eof()) + { + return CURL_READFUNC_PAUSE; + } } else { @@ -304,6 +305,33 @@ static size_t SeekBody(void* userdata, curl_off_t offset, int origin) return CURL_SEEKFUNC_OK; } +#if LIBCURL_VERSION_NUM >= 0x072000 // 7.32.0 +static int CurlProgressCallback(void *userdata, curl_off_t, curl_off_t, curl_off_t, curl_off_t) +#else +static int CurlProgressCallback(void *userdata, double, double, double, double) +#endif +{ + CurlReadCallbackContext* context = reinterpret_cast<CurlReadCallbackContext*>(userdata); + + const std::shared_ptr<Aws::IOStream>& ioStream = context->m_request->GetContentBody(); + if (ioStream->eof()) + { + curl_easy_pause(context->m_curlHandle, CURLPAUSE_CONT); + return 0; + } + char output[1]; + if (ioStream->readsome(output, 1) > 0) + { + ioStream->unget(); + if (!ioStream->good()) + { + AWS_LOGSTREAM_WARN(CURL_HTTP_CLIENT_TAG, "Input stream failed to perform unget()."); + } + curl_easy_pause(context->m_curlHandle, CURLPAUSE_CONT); + } + + return 0; +} void SetOptCodeForHttpMethod(CURL* requestHandle, const std::shared_ptr<HttpRequest>& request) { @@ -456,6 +484,16 @@ CurlHttpClient::CurlHttpClient(const ClientConfiguration& clientConfig) : { m_allowRedirects = true; } + if(clientConfig.nonProxyHosts.GetLength() > 0) + { + Aws::StringStream ss; + ss << clientConfig.nonProxyHosts.GetItem(0); + for (auto i=1u; i < clientConfig.nonProxyHosts.GetLength(); i++) + { + ss << "," << clientConfig.nonProxyHosts.GetItem(i); + } + m_nonProxyHosts = ss.str(); + } } @@ -521,7 +559,7 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< } CurlWriteCallbackContext writeContext(this, request.get(), response.get(), readLimiter); - CurlReadCallbackContext readContext(this, request.get(), writeLimiter); + CurlReadCallbackContext readContext(this, connectionHandle, request.get(), writeLimiter); SetOptCodeForHttpMethod(connectionHandle, request); @@ -595,6 +633,7 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< curl_easy_setopt(connectionHandle, CURLOPT_PROXYUSERNAME, m_proxyUserName.c_str()); curl_easy_setopt(connectionHandle, CURLOPT_PROXYPASSWORD, m_proxyPassword.c_str()); } + curl_easy_setopt(connectionHandle, CURLOPT_NOPROXY, m_nonProxyHosts.c_str()); #ifdef CURL_HAS_TLS_PROXY if (!m_proxySSLCertPath.empty()) { @@ -629,6 +668,17 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &readContext); curl_easy_setopt(connectionHandle, CURLOPT_SEEKFUNCTION, SeekBody); curl_easy_setopt(connectionHandle, CURLOPT_SEEKDATA, &readContext); + if (request->IsEventStreamRequest()) + { + curl_easy_setopt(connectionHandle, CURLOPT_NOPROGRESS, 0L); +#if LIBCURL_VERSION_NUM >= 0x072000 // 7.32.0 + curl_easy_setopt(connectionHandle, CURLOPT_XFERINFOFUNCTION, CurlProgressCallback); + curl_easy_setopt(connectionHandle, CURLOPT_XFERINFODATA, &readContext); +#else + curl_easy_setopt(connectionHandle, CURLOPT_PROGRESSFUNCTION, CurlProgressCallback); + curl_easy_setopt(connectionHandle, CURLOPT_PROGRESSDATA, &readContext); +#endif + } } OverrideOptionsOnConnectionHandle(connectionHandle); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp index 24145e4d92..2f372ec82a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp @@ -35,6 +35,7 @@ static const char EC2_IMDS_TOKEN_HEADER[] = "x-aws-ec2-metadata-token"; static const char RESOURCE_CLIENT_CONFIGURATION_ALLOCATION_TAG[] = "AWSHttpResourceClient"; static const char EC2_METADATA_CLIENT_LOG_TAG[] = "EC2MetadataClient"; static const char ECS_CREDENTIALS_CLIENT_LOG_TAG[] = "ECSCredentialsClient"; +static const char SSO_GET_ROLE_RESOURCE[] = "/federation/credentials"; namespace Aws { @@ -160,7 +161,7 @@ namespace Aws if (!m_retryStrategy->ShouldRetry(error, retries)) { - AWS_LOGSTREAM_ERROR(m_logtag.c_str(), "Can not retrive resource from " << httpRequest->GetURIString()); + AWS_LOGSTREAM_ERROR(m_logtag.c_str(), "Can not retrieve resource from " << httpRequest->GetURIString()); return {{}, response->GetHeaders(), error.GetResponseCode()}; } auto sleepMillis = m_retryStrategy->CalculateDelayBeforeNextRetry(error, retries); @@ -502,5 +503,73 @@ namespace Aws } return result; } + + static const char SSO_RESOURCE_CLIENT_LOG_TAG[] = "SSOResourceClient"; + SSOCredentialsClient::SSOCredentialsClient(const Aws::Client::ClientConfiguration& clientConfiguration) + : AWSHttpResourceClient(clientConfiguration, SSO_RESOURCE_CLIENT_LOG_TAG) + { + SetErrorMarshaller(Aws::MakeUnique<Aws::Client::JsonErrorMarshaller>(SSO_RESOURCE_CLIENT_LOG_TAG)); + + Aws::StringStream ss; + if (clientConfiguration.scheme == Aws::Http::Scheme::HTTP) + { + ss << "http://"; + } + else + { + ss << "https://"; + } + + static const int CN_NORTH_1_HASH = Aws::Utils::HashingUtils::HashString(Aws::Region::CN_NORTH_1); + static const int CN_NORTHWEST_1_HASH = Aws::Utils::HashingUtils::HashString(Aws::Region::CN_NORTHWEST_1); + auto hash = Aws::Utils::HashingUtils::HashString(clientConfiguration.region.c_str()); + + AWS_LOGSTREAM_DEBUG(SSO_RESOURCE_CLIENT_LOG_TAG, "Preparing SSO client for region: " << clientConfiguration.region); + + ss << "portal.sso." << clientConfiguration.region << ".amazonaws.com/federation/credentials"; + if (hash == CN_NORTH_1_HASH || hash == CN_NORTHWEST_1_HASH) + { + ss << ".cn"; + } + m_endpoint = ss.str(); + + AWS_LOGSTREAM_INFO(SSO_RESOURCE_CLIENT_LOG_TAG, "Creating SSO ResourceClient with endpoint: " << m_endpoint); + } + + SSOCredentialsClient::SSOGetRoleCredentialsResult SSOCredentialsClient::GetSSOCredentials(const SSOGetRoleCredentialsRequest &request) + { + Aws::StringStream ssUri; + ssUri << m_endpoint << SSO_GET_ROLE_RESOURCE; + + std::shared_ptr<HttpRequest> httpRequest(CreateHttpRequest(m_endpoint, HttpMethod::HTTP_GET, + Aws::Utils::Stream::DefaultResponseStreamFactoryMethod)); + + httpRequest->SetHeaderValue("x-amz-sso_bearer_token", request.m_accessToken); + + httpRequest->SetUserAgent(ComputeUserAgentString()); + + httpRequest->AddQueryStringParameter("account_id", Aws::Utils::StringUtils::URLEncode(request.m_ssoAccountId.c_str())); + httpRequest->AddQueryStringParameter("role_name", Aws::Utils::StringUtils::URLEncode(request.m_ssoRoleName.c_str())); + + Aws::String credentialsStr = GetResourceWithAWSWebServiceResult(httpRequest).GetPayload(); + + Json::JsonValue credentialsDoc(credentialsStr); + AWS_LOGSTREAM_TRACE(SSO_RESOURCE_CLIENT_LOG_TAG, "Raw creds returned: " << credentialsStr); + Aws::Auth::AWSCredentials creds; + if (!credentialsDoc.WasParseSuccessful()) + { + AWS_LOGSTREAM_ERROR(SSO_RESOURCE_CLIENT_LOG_TAG, "Failed to load credential from running. Error: " << credentialsStr); + return SSOGetRoleCredentialsResult{creds}; + } + Utils::Json::JsonView credentialsView(credentialsDoc); + auto roleCredentials = credentialsView.GetObject("roleCredentials"); + creds.SetAWSAccessKeyId(roleCredentials.GetString("accessKeyId")); + creds.SetAWSSecretKey(roleCredentials.GetString("secretAccessKey")); + creds.SetSessionToken(roleCredentials.GetString("sessionToken")); + creds.SetExpiration(roleCredentials.GetInt64("expiration")); + SSOCredentialsClient::SSOGetRoleCredentialsResult result; + result.creds = creds; + return result; + } } } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp index 147bddf33e..0e49a61634 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp @@ -9,6 +9,7 @@ #include <aws/core/utils/base64/Base64.h> #include <aws/core/utils/crypto/Sha256.h> #include <aws/core/utils/crypto/Sha256HMAC.h> +#include <aws/core/utils/crypto/Sha1.h> #include <aws/core/utils/crypto/MD5.h> #include <aws/core/utils/Outcome.h> #include <aws/core/utils/memory/stl/AWSStringStream.h> @@ -209,6 +210,18 @@ ByteBuffer HashingUtils::HexDecode(const Aws::String& str) return hexBuffer; } +ByteBuffer HashingUtils::CalculateSHA1(const Aws::String& str) +{ + Sha1 hash; + return hash.Calculate(str).GetResult(); +} + +ByteBuffer HashingUtils::CalculateSHA1(Aws::IOStream& stream) +{ + Sha1 hash; + return hash.Calculate(stream).GetResult(); +} + ByteBuffer HashingUtils::CalculateMD5(const Aws::String& str) { MD5 hash; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha1.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha1.cpp new file mode 100644 index 0000000000..5da3e63d28 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha1.cpp @@ -0,0 +1,30 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#include <aws/core/utils/crypto/Sha1.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/crypto/Factories.h> + +using namespace Aws::Utils::Crypto; + +Sha1::Sha1() : + m_hashImpl(CreateSha1Implementation()) +{ +} + +Sha1::~Sha1() +{ +} + +HashResult Sha1::Calculate(const Aws::String& str) +{ + return m_hashImpl->Calculate(str); +} + +HashResult Sha1::Calculate(Aws::IStream& stream) +{ + return m_hashImpl->Calculate(stream); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp index 178df00d37..a8aa5ae879 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp @@ -10,7 +10,7 @@ using namespace Aws::Utils::Crypto; -Sha256::Sha256() : +Sha256::Sha256() : m_hashImpl(CreateSha256Implementation()) { } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp index bff0382241..88ca147d11 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp @@ -35,6 +35,12 @@ static std::shared_ptr<HashFactory>& GetMD5Factory() return s_MD5Factory; } +static std::shared_ptr<HashFactory>& GetSha1Factory() +{ + static std::shared_ptr<HashFactory> s_Sha1Factory(nullptr); + return s_Sha1Factory; +} + static std::shared_ptr<HashFactory>& GetSha256Factory() { static std::shared_ptr<HashFactory> s_Sha256Factory(nullptr); @@ -130,6 +136,51 @@ public: } }; +class DefaultSHA1Factory : public HashFactory +{ +public: + std::shared_ptr<Hash> CreateImplementation() const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<Sha1BcryptImpl>(s_allocationTag); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<Sha1OpenSSLImpl>(s_allocationTag); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<Sha1CommonCryptoImpl>(s_allocationTag); +#else + return nullptr; +#endif + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + class DefaultSHA256Factory : public HashFactory { public: @@ -616,6 +667,16 @@ void Aws::Utils::Crypto::InitCrypto() GetMD5Factory()->InitStaticState(); } + if(GetSha1Factory()) + { + GetSha1Factory()->InitStaticState(); + } + else + { + GetSha1Factory() = Aws::MakeShared<DefaultSHA1Factory>(s_allocationTag); + GetSha1Factory()->InitStaticState(); + } + if(GetSha256Factory()) { GetSha256Factory()->InitStaticState(); @@ -693,6 +754,12 @@ void Aws::Utils::Crypto::CleanupCrypto() GetMD5Factory() = nullptr; } + if(GetSha1Factory()) + { + GetSha1Factory()->CleanupStaticState(); + GetSha1Factory() = nullptr; + } + if(GetSha256Factory()) { GetSha256Factory()->CleanupStaticState(); @@ -742,6 +809,11 @@ void Aws::Utils::Crypto::SetMD5Factory(const std::shared_ptr<HashFactory>& facto GetMD5Factory() = factory; } +void Aws::Utils::Crypto::SetSha1Factory(const std::shared_ptr<HashFactory>& factory) +{ + GetSha1Factory() = factory; +} + void Aws::Utils::Crypto::SetSha256Factory(const std::shared_ptr<HashFactory>& factory) { GetSha256Factory() = factory; @@ -782,8 +854,12 @@ std::shared_ptr<Hash> Aws::Utils::Crypto::CreateMD5Implementation() return GetMD5Factory()->CreateImplementation(); } -std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha256Implementation() +std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha1Implementation() { + return GetSha1Factory()->CreateImplementation(); +} + +std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha256Implementation() { return GetSha256Factory()->CreateImplementation(); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp index 911838864b..3a89265e6e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp @@ -222,6 +222,56 @@ namespace Aws return HashResult(std::move(hash)); } + HashResult Sha1OpenSSLImpl::Calculate(const Aws::String& str) + { + OpensslCtxRAIIGuard guard; + auto ctx = guard.getResource(); + EVP_DigestInit_ex(ctx, EVP_sha1(), nullptr); + EVP_DigestUpdate(ctx, str.c_str(), str.size()); + + ByteBuffer hash(EVP_MD_size(EVP_sha1())); + EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); + + return HashResult(std::move(hash)); + } + + HashResult Sha1OpenSSLImpl::Calculate(Aws::IStream& stream) + { + OpensslCtxRAIIGuard guard; + auto ctx = guard.getResource(); + + EVP_DigestInit_ex(ctx, EVP_sha1(), nullptr); + + auto currentPos = stream.tellg(); + if (currentPos == -1) + { + currentPos = 0; + stream.clear(); + } + + stream.seekg(0, stream.beg); + + char streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE]; + while (stream.good()) + { + stream.read(streamBuffer, Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE); + auto bytesRead = stream.gcount(); + + if (bytesRead > 0) + { + EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead)); + } + } + + stream.clear(); + stream.seekg(currentPos, stream.beg); + + ByteBuffer hash(EVP_MD_size(EVP_sha1())); + EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); + + return HashResult(std::move(hash)); + } + HashResult Sha256OpenSSLImpl::Calculate(const Aws::String& str) { OpensslCtxRAIIGuard guard; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ConcurrentStreamBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ConcurrentStreamBuf.cpp index 3f59dbe96d..1ef4ee6758 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ConcurrentStreamBuf.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ConcurrentStreamBuf.cpp @@ -89,7 +89,10 @@ namespace Aws std::streamsize ConcurrentStreamBuf::showmanyc() { std::unique_lock<std::mutex> lock(m_lock); - AWS_LOGSTREAM_TRACE(TAG, "stream how many character? " << m_backbuf.size()); + if (!m_backbuf.empty()) + { + AWS_LOGSTREAM_TRACE(TAG, "Stream characters in buffer: " << m_backbuf.size()); + } return m_backbuf.size(); } |