aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal
diff options
context:
space:
mode:
authordakovalkov <dakovalkov@yandex-team.com>2023-12-03 13:33:55 +0300
committerdakovalkov <dakovalkov@yandex-team.com>2023-12-03 14:04:39 +0300
commit2a718325637e5302334b6d0a6430f63168f8dbb3 (patch)
tree64be81080b7df9ec1d86d053a0c394ae53fcf1fe /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal
parente0d94a470142d95c3007e9c5d80380994940664a (diff)
downloadydb-2a718325637e5302334b6d0a6430f63168f8dbb3.tar.gz
Update contrib/libs/aws-sdk-cpp to 1.11.37
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal')
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp175
1 files changed, 158 insertions, 17 deletions
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 2f372ec82a..ca664cc6c4 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
@@ -140,12 +140,12 @@ namespace Aws
}
const Aws::Client::AWSError<Aws::Client::CoreErrors> error = [this, &response]() {
- if (response->HasClientError() || response->GetResponseBody().tellp() < 1)
+ if (response->HasClientError() || response->GetResponseCode() == HttpResponseCode::REQUEST_NOT_MADE)
{
AWS_LOGSTREAM_ERROR(m_logtag.c_str(), "Http request to retrieve credentials failed");
return AWSError<CoreErrors>(CoreErrors::NETWORK_CONNECTION, true); // Retryable
}
- else if (m_errorMarshaller)
+ else if (m_errorMarshaller && response->GetResponseBody().tellp() > 0)
{
return m_errorMarshaller->Marshall(*response);
}
@@ -170,14 +170,23 @@ namespace Aws
}
}
- EC2MetadataClient::EC2MetadataClient(const char* endpoint)
- : AWSHttpResourceClient(EC2_METADATA_CLIENT_LOG_TAG), m_endpoint(endpoint), m_tokenRequired(true)
+ EC2MetadataClient::EC2MetadataClient(const char *endpoint) :
+ AWSHttpResourceClient(EC2_METADATA_CLIENT_LOG_TAG),
+ m_endpoint(endpoint),
+ m_disableIMDS(false),
+ m_tokenRequired(true)
{
+
}
- EC2MetadataClient::EC2MetadataClient(const Aws::Client::ClientConfiguration &clientConfiguration, const char *endpoint)
- : AWSHttpResourceClient(clientConfiguration, EC2_METADATA_CLIENT_LOG_TAG), m_endpoint(endpoint), m_tokenRequired(true)
+ EC2MetadataClient::EC2MetadataClient(const Aws::Client::ClientConfiguration &clientConfiguration,
+ const char *endpoint) :
+ AWSHttpResourceClient(clientConfiguration, EC2_METADATA_CLIENT_LOG_TAG),
+ m_endpoint(endpoint),
+ m_disableIMDS(clientConfiguration.disableIMDS),
+ m_tokenRequired(true)
{
+
}
EC2MetadataClient::~EC2MetadataClient()
@@ -190,15 +199,20 @@ namespace Aws
return GetResource(m_endpoint.c_str(), resourcePath, nullptr/*authToken*/);
}
+#if !defined(DISABLE_IMDSV1)
Aws::String EC2MetadataClient::GetDefaultCredentials() const
{
+ if (m_disableIMDS) {
+ AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Skipping call to IMDS Service");
+ return {};
+ }
std::unique_lock<std::recursive_mutex> locker(m_tokenMutex);
if (m_tokenRequired)
{
return GetDefaultCredentialsSecurely();
}
- AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Getting default credentials for ec2 instance");
+ AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Getting default credentials for ec2 instance from " << m_endpoint);
auto result = GetResourceWithAWSWebServiceResult(m_endpoint.c_str(), EC2_SECURITY_CREDENTIALS_RESOURCE, nullptr);
Aws::String credentialsString = result.GetPayload();
auto httpResponseCode = result.GetResponseCode();
@@ -232,14 +246,20 @@ namespace Aws
AWS_LOGSTREAM_DEBUG(m_logtag.c_str(), "Calling EC2MetadataService resource " << ss.str());
return GetResource(ss.str().c_str());
}
+#endif
Aws::String EC2MetadataClient::GetDefaultCredentialsSecurely() const
{
+ if (m_disableIMDS) {
+ AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Skipping call to IMDS Service");
+ return {};
+ }
std::unique_lock<std::recursive_mutex> locker(m_tokenMutex);
- if (!m_tokenRequired)
- {
+#if !defined(DISABLE_IMDSV1)
+ if (!m_tokenRequired) {
return GetDefaultCredentials();
}
+#endif
Aws::StringStream ss;
ss << m_endpoint << EC2_IMDS_TOKEN_RESOURCE;
@@ -257,12 +277,14 @@ namespace Aws
{
return {};
}
+#if !defined(DISABLE_IMDSV1)
else if (result.GetResponseCode() != HttpResponseCode::OK || trimmedTokenString.empty())
{
m_tokenRequired = false;
AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Calling EC2MetadataService to get token failed, falling back to less secure way.");
return GetDefaultCredentials();
}
+#endif
m_token = trimmedTokenString;
locker.unlock();
ss.str("");
@@ -278,7 +300,7 @@ namespace Aws
AWS_LOGSTREAM_DEBUG(m_logtag.c_str(), "Calling EC2MetadataService resource, " << EC2_SECURITY_CREDENTIALS_RESOURCE
<< " with token returned profile string " << trimmedProfileString);
- if (securityCredentials.size() == 0)
+ if (securityCredentials.empty())
{
AWS_LOGSTREAM_WARN(m_logtag.c_str(), "Calling EC2Metadataservice to get profiles failed");
return {};
@@ -296,6 +318,10 @@ namespace Aws
Aws::String EC2MetadataClient::GetCurrentRegion() const
{
+ if (m_disableIMDS) {
+ AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Skipping call to IMDS Service");
+ return {};
+ }
if (!m_region.empty())
{
return m_region;
@@ -311,6 +337,7 @@ namespace Aws
std::lock_guard<std::recursive_mutex> locker(m_tokenMutex);
if (m_tokenRequired)
{
+ GetDefaultCredentialsSecurely();
regionRequest->SetHeaderValue(EC2_IMDS_TOKEN_HEADER, m_token);
}
}
@@ -351,6 +378,16 @@ namespace Aws
return region;
}
+ void EC2MetadataClient::SetEndpoint(const Aws::String& endpoint)
+ {
+ m_endpoint = endpoint;
+ }
+
+ Aws::String EC2MetadataClient::GetEndpoint() const
+ {
+ return Aws::String(m_endpoint);
+ }
+
#ifdef _MSC_VER
// VS2015 compiler's bug, warning s_ec2metadataClient: symbol will be dynamically initialized (implementation limitation)
AWS_SUPPRESS_WARNING(4592,
@@ -366,7 +403,39 @@ namespace Aws
{
return;
}
- s_ec2metadataClient = Aws::MakeShared<EC2MetadataClient>(EC2_METADATA_CLIENT_LOG_TAG);
+ Aws::String ec2MetadataServiceEndpoint = Aws::Environment::GetEnv("AWS_EC2_METADATA_SERVICE_ENDPOINT");
+ if (ec2MetadataServiceEndpoint.empty())
+ {
+ Aws::String ec2MetadataServiceEndpointMode = Aws::Environment::GetEnv("AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE").c_str();
+ if (ec2MetadataServiceEndpointMode.length() == 0 )
+ {
+ ec2MetadataServiceEndpoint = "http://169.254.169.254"; //default to IPv4 default endpoint
+ }
+ else
+ {
+ if (ec2MetadataServiceEndpointMode.length() == 4 )
+ {
+ if (Aws::Utils::StringUtils::CaselessCompare(ec2MetadataServiceEndpointMode.c_str(), "ipv4"))
+ {
+ ec2MetadataServiceEndpoint = "http://169.254.169.254"; //default to IPv4 default endpoint
+ }
+ else if (Aws::Utils::StringUtils::CaselessCompare(ec2MetadataServiceEndpointMode.c_str(), "ipv6"))
+ {
+ ec2MetadataServiceEndpoint = "http://[fd00:ec2::254]";
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(EC2_METADATA_CLIENT_LOG_TAG, "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE can only be set to ipv4 or ipv6, received: " << ec2MetadataServiceEndpointMode );
+ }
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(EC2_METADATA_CLIENT_LOG_TAG, "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE can only be set to ipv4 or ipv6, received: " << ec2MetadataServiceEndpointMode );
+ }
+ }
+ }
+ AWS_LOGSTREAM_INFO(EC2_METADATA_CLIENT_LOG_TAG, "Using IMDS endpoint: " << ec2MetadataServiceEndpoint);
+ s_ec2metadataClient = Aws::MakeShared<EC2MetadataClient>(EC2_METADATA_CLIENT_LOG_TAG, ec2MetadataServiceEndpoint.c_str());
}
void CleanupEC2MetadataClient()
@@ -383,7 +452,6 @@ namespace Aws
return s_ec2metadataClient;
}
-
ECSCredentialsClient::ECSCredentialsClient(const char* resourcePath, const char* endpoint, const char* token)
: AWSHttpResourceClient(ECS_CREDENTIALS_CLIENT_LOG_TAG),
m_resourcePath(resourcePath), m_endpoint(endpoint), m_token(token)
@@ -510,6 +578,17 @@ namespace Aws
{
SetErrorMarshaller(Aws::MakeUnique<Aws::Client::JsonErrorMarshaller>(SSO_RESOURCE_CLIENT_LOG_TAG));
+ m_endpoint = buildEndpoint(clientConfiguration, "portal.sso.", "federation/credentials");
+ m_oidcEndpoint = buildEndpoint(clientConfiguration, "oidc.", "token");
+
+ AWS_LOGSTREAM_INFO(SSO_RESOURCE_CLIENT_LOG_TAG, "Creating SSO ResourceClient with endpoint: " << m_endpoint);
+ }
+
+ Aws::String SSOCredentialsClient::buildEndpoint(
+ const Aws::Client::ClientConfiguration& clientConfiguration,
+ const Aws::String& domain,
+ const Aws::String& endpoint)
+ {
Aws::StringStream ss;
if (clientConfiguration.scheme == Aws::Http::Scheme::HTTP)
{
@@ -525,15 +604,12 @@ namespace Aws
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";
+ ss << domain << clientConfiguration.region << ".amazonaws.com/" << endpoint;
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);
+ return ss.str();
}
SSOCredentialsClient::SSOGetRoleCredentialsResult SSOCredentialsClient::GetSSOCredentials(const SSOGetRoleCredentialsRequest &request)
@@ -571,5 +647,70 @@ namespace Aws
result.creds = creds;
return result;
}
+
+ // An internal SSO CreateToken implementation to lightweight core package and not introduce a dependency on sso-oidc
+ SSOCredentialsClient::SSOCreateTokenResult SSOCredentialsClient::CreateToken(const SSOCreateTokenRequest& request)
+ {
+ std::shared_ptr<HttpRequest> httpRequest(CreateHttpRequest(m_oidcEndpoint, HttpMethod::HTTP_POST,
+ Aws::Utils::Stream::DefaultResponseStreamFactoryMethod));
+ SSOCreateTokenResult result;
+ if(!httpRequest) {
+ AWS_LOGSTREAM_FATAL(SSO_RESOURCE_CLIENT_LOG_TAG, "Failed to CreateHttpRequest: nullptr returned");
+ return result;
+ }
+ httpRequest->SetUserAgent(ComputeUserAgentString());
+
+ Json::JsonValue requestDoc;
+ if(!request.clientId.empty()) {
+ requestDoc.WithString("clientId", request.clientId);
+ }
+ if(!request.clientSecret.empty()) {
+ requestDoc.WithString("clientSecret", request.clientSecret);
+ }
+ if(!request.grantType.empty()) {
+ requestDoc.WithString("grantType", request.grantType);
+ }
+ if(!request.refreshToken.empty()) {
+ requestDoc.WithString("refreshToken", request.refreshToken);
+ }
+
+ std::shared_ptr<Aws::IOStream> body = Aws::MakeShared<Aws::StringStream>("SSO_BEARER_TOKEN_CREATE_TOKEN");
+ if(!body) {
+ AWS_LOGSTREAM_FATAL(SSO_RESOURCE_CLIENT_LOG_TAG, "Failed to allocate body"); // exceptions disabled
+ return result;
+ }
+ *body << requestDoc.View().WriteReadable();;
+
+ httpRequest->AddContentBody(body);
+ body->seekg(0, body->end);
+ auto streamSize = body->tellg();
+ body->seekg(0, body->beg);
+ Aws::StringStream contentLength;
+ contentLength << streamSize;
+ httpRequest->SetContentLength(contentLength.str());
+ httpRequest->SetContentType("application/json");
+
+ Aws::String rawReply = GetResourceWithAWSWebServiceResult(httpRequest).GetPayload();
+ Json::JsonValue refreshTokenDoc(rawReply);
+ Utils::Json::JsonView jsonValue = refreshTokenDoc.View();
+
+ if(jsonValue.ValueExists("accessToken")) {
+ result.accessToken = jsonValue.GetString("accessToken");
+ }
+ if(jsonValue.ValueExists("tokenType")) {
+ result.tokenType = jsonValue.GetString("tokenType");
+ }
+ if(jsonValue.ValueExists("expiresIn")) {
+ result.expiresIn = jsonValue.GetInteger("expiresIn");
+ }
+ if(jsonValue.ValueExists("idToken")) {
+ result.idToken = jsonValue.GetString("idToken");
+ }
+ if(jsonValue.ValueExists("refreshToken")) {
+ result.refreshToken = jsonValue.GetString("refreshToken");
+ }
+
+ return result;
+ }
}
}