1 /** 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * SPDX-License-Identifier: Apache-2.0. 4 */ 5 6 #pragma once 7 8 #include <aws/core/Core_EXPORTS.h> 9 #include <aws/core/utils/memory/AWSMemory.h> 10 #include <aws/core/utils/memory/stl/AWSString.h> 11 #include <aws/core/client/ClientConfiguration.h> 12 #include <aws/core/client/AWSErrorMarshaller.h> 13 #include <aws/core/auth/AWSCredentials.h> 14 #include <aws/core/AmazonWebServiceResult.h> 15 #include <aws/core/utils/DateTime.h> 16 #include <memory> 17 #include <mutex> 18 namespace Aws 19 { 20 namespace Http 21 { 22 class HttpClient; 23 class HttpRequest; 24 enum class HttpResponseCode; 25 } // namespace Http 26 27 namespace Internal 28 { 29 /** 30 * Simple client for accessing the AWS remote data by Http. 31 * Currently we use it to access EC2 Metadata and ECS Credential. 32 */ 33 class AWS_CORE_API AWSHttpResourceClient 34 { 35 public: 36 /** 37 * Builds an AWSHttpResourceClient instance by using default http stack. 38 */ 39 AWSHttpResourceClient(const char* logtag = "AWSHttpResourceClient"); 40 AWSHttpResourceClient(const Client::ClientConfiguration& clientConfiguration, const char* logtag = "AWSHttpResourceClient"); 41 42 AWSHttpResourceClient& operator =(const AWSHttpResourceClient& rhs) = delete; 43 AWSHttpResourceClient(const AWSHttpResourceClient& rhs) = delete; 44 AWSHttpResourceClient& operator =(const AWSHttpResourceClient&& rhs) = delete; 45 AWSHttpResourceClient(const AWSHttpResourceClient&& rhs) = delete; 46 47 virtual ~AWSHttpResourceClient(); 48 49 /** 50 * Connects to an HTTP endpoint to read the specified resource and returns the text contents. 51 * The resource URI = endpoint + resourcePath (e.g:http://domain/path/to/res) 52 * @param endpoint The HTTP resource to connect to. 53 * @param resourcePath A path appended to the endpoint to form the final URI. 54 * @param authToken An optional authorization token that will be passed as the value of the HTTP 55 * header 'Authorization'. 56 * @return The response from the HTTP endpoint as a string. 57 */ 58 virtual Aws::String GetResource(const char* endpoint, const char* resourcePath, const char* authToken) const; 59 60 /** 61 * Connects to an HTTP endpoint to read the specified resource and returns the text contents. 62 * The resource URI = endpoint + resourcePath (e.g:http://domain/path/to/res) 63 * @param endpoint The HTTP resource to connect to. 64 * @param resourcePath A path appended to the endpoint to form the final URI. 65 * @param authToken An optional authorization token that will be passed as the value of the HTTP 66 * header 'Authorization'. 67 * @return The response from the HTTP endpoint as a string, together with the http response code. 68 */ 69 virtual AmazonWebServiceResult<Aws::String> GetResourceWithAWSWebServiceResult(const char *endpoint, const char *resourcePath, const char *authToken) const; 70 71 /** 72 * Above Function: Aws::String GetResource(const char* endpoint, const char* resourcePath, const char* authToken) const; 73 * is limited to HTTP GET method and caller can't add wanted HTTP headers as well. 74 * This overload gives caller the flexibility to manipulate the request, as well returns the HttpResponseCode of the last attempt. 75 */ 76 virtual AmazonWebServiceResult<Aws::String> GetResourceWithAWSWebServiceResult(const std::shared_ptr<Http::HttpRequest> &httpRequest) const; 77 78 /** 79 * Set an error marshaller so as to marshall error type from http response body if any. 80 * So that it can work with retry strategy to decide if a request should retry or not. 81 */ SetErrorMarshaller(Aws::UniquePtr<Client::AWSErrorMarshaller> errorMarshaller)82 void SetErrorMarshaller(Aws::UniquePtr<Client::AWSErrorMarshaller> errorMarshaller) { m_errorMarshaller = std::move(errorMarshaller); } GetErrorMarshaller()83 const Client::AWSErrorMarshaller* GetErrorMarshaller() const { return m_errorMarshaller.get(); } 84 85 protected: 86 Aws::String m_logtag; 87 88 private: 89 std::shared_ptr<Client::RetryStrategy> m_retryStrategy; 90 std::shared_ptr<Http::HttpClient> m_httpClient; 91 Aws::UniquePtr<Client::AWSErrorMarshaller> m_errorMarshaller; 92 }; 93 94 /** 95 * Derived class to support retrieving of EC2 Metadata 96 */ 97 class AWS_CORE_API EC2MetadataClient : public AWSHttpResourceClient 98 { 99 public: 100 /** 101 * Build an instance with default EC2 Metadata service endpoint 102 */ 103 EC2MetadataClient(const char* endpoint = "http://169.254.169.254"); 104 EC2MetadataClient(const Client::ClientConfiguration& clientConfiguration, const char* endpoint = "http://169.254.169.254"); 105 106 EC2MetadataClient& operator =(const EC2MetadataClient& rhs) = delete; 107 EC2MetadataClient(const EC2MetadataClient& rhs) = delete; 108 EC2MetadataClient& operator =(const EC2MetadataClient&& rhs) = delete; 109 EC2MetadataClient(const EC2MetadataClient&& rhs) = delete; 110 111 virtual ~EC2MetadataClient(); 112 113 using AWSHttpResourceClient::GetResource; 114 115 /** 116 * Connects to the metadata service to read the specified resource and 117 * returns the text contents. The resource URI = m_endpoint + resourcePath. 118 */ 119 virtual Aws::String GetResource(const char* resourcePath) const; 120 121 /** 122 * Connects to the Amazon EC2 Instance Metadata Service to retrieve the 123 * default credential information (if any). 124 */ 125 virtual Aws::String GetDefaultCredentials() const; 126 127 /** 128 * Connects to the Amazon EC2 Instance Metadata Service to retrieve the 129 * credential information (if any) in a more secure way. 130 */ 131 virtual Aws::String GetDefaultCredentialsSecurely() const; 132 133 /** 134 * connects to the Amazon EC2 Instance metadata Service to retrieve the region 135 * the current EC2 instance is running in. 136 */ 137 virtual Aws::String GetCurrentRegion() const; 138 139 /** 140 * Sets endpoint used to connect to the EC2 Instance metadata Service 141 */ 142 virtual void SetEndpoint(const Aws::String& endpoint); 143 144 /** 145 * Gets endpoint used to connect to the EC2 Instance metadata Service 146 */ 147 virtual Aws::String GetEndpoint() const; 148 149 private: 150 Aws::String m_endpoint; 151 mutable std::recursive_mutex m_tokenMutex; 152 mutable Aws::String m_token; 153 mutable bool m_tokenRequired; 154 mutable Aws::String m_region; 155 }; 156 157 void AWS_CORE_API InitEC2MetadataClient(); 158 void AWS_CORE_API CleanupEC2MetadataClient(); 159 std::shared_ptr<EC2MetadataClient> AWS_CORE_API GetEC2MetadataClient(); 160 161 /** 162 * Derived class to support retrieving of ECS Credentials 163 */ 164 class AWS_CORE_API ECSCredentialsClient : public AWSHttpResourceClient 165 { 166 public: 167 /** 168 * Build an instance with default ECS service endpoint 169 * @param resourcePath The path part of the metadata URL 170 * @param endpoint The URL authority to hit. Default is the IP address of the Task metadata service endpoint. 171 */ 172 ECSCredentialsClient(const char* resourcePath, const char* endpoint = "http://169.254.170.2", 173 const char* authToken = ""); 174 ECSCredentialsClient(const Client::ClientConfiguration& clientConfiguration, 175 const char* resourcePath, const char* endpoint = "http://169.254.170.2", 176 const char* authToken = ""); 177 178 ECSCredentialsClient& operator =(ECSCredentialsClient& rhs) = delete; 179 ECSCredentialsClient(const ECSCredentialsClient& rhs) = delete; 180 ECSCredentialsClient& operator =(ECSCredentialsClient&& rhs) = delete; 181 ECSCredentialsClient(const ECSCredentialsClient&& rhs) = delete; 182 183 /** 184 * Connects to the Amazon ECS service to retrieve the credential 185 */ GetECSCredentials()186 virtual Aws::String GetECSCredentials() const 187 { 188 return GetResource(m_endpoint.c_str(), m_resourcePath.c_str(), m_token.c_str()); 189 } 190 191 private: 192 Aws::String m_resourcePath; 193 Aws::String m_endpoint; 194 Aws::String m_token; 195 }; 196 197 /** 198 * To support retrieving credentials from STS. 199 * Note that STS accepts request with protocol of queryxml. Calling GetResource() will trigger 200 * a query request using AWSHttpResourceClient under the hood. 201 */ 202 class AWS_CORE_API STSCredentialsClient : public AWSHttpResourceClient 203 { 204 public: 205 /** 206 * Initializes the provider to retrieve credentials from STS when it expires. 207 */ 208 STSCredentialsClient(const Client::ClientConfiguration& clientConfiguration); 209 210 STSCredentialsClient& operator =(STSCredentialsClient& rhs) = delete; 211 STSCredentialsClient(const STSCredentialsClient& rhs) = delete; 212 STSCredentialsClient& operator =(STSCredentialsClient&& rhs) = delete; 213 STSCredentialsClient(const STSCredentialsClient&& rhs) = delete; 214 215 // If you want to make an AssumeRoleWithWebIdentity call to sts. use these classes to pass data to and get info from STSCredentialsClient client. 216 // If you want to make an AssumeRole call to sts, define the request/result members class/struct like this. 217 struct STSAssumeRoleWithWebIdentityRequest 218 { 219 Aws::String roleSessionName; 220 Aws::String roleArn; 221 Aws::String webIdentityToken; 222 }; 223 224 struct STSAssumeRoleWithWebIdentityResult 225 { 226 Aws::Auth::AWSCredentials creds; 227 }; 228 229 STSAssumeRoleWithWebIdentityResult GetAssumeRoleWithWebIdentityCredentials(const STSAssumeRoleWithWebIdentityRequest& request); 230 231 private: 232 Aws::String m_endpoint; 233 }; 234 235 /** 236 * To support retrieving credentials from SSO. 237 */ 238 class AWS_CORE_API SSOCredentialsClient : public AWSHttpResourceClient 239 { 240 public: 241 SSOCredentialsClient(const Client::ClientConfiguration& clientConfiguration); 242 243 SSOCredentialsClient& operator =(SSOCredentialsClient& rhs) = delete; 244 SSOCredentialsClient(const SSOCredentialsClient& rhs) = delete; 245 SSOCredentialsClient& operator =(SSOCredentialsClient&& rhs) = delete; 246 SSOCredentialsClient(SSOCredentialsClient&& rhs) = delete; 247 248 struct SSOGetRoleCredentialsRequest 249 { 250 Aws::String m_ssoAccountId; 251 Aws::String m_ssoRoleName; 252 Aws::String m_accessToken; 253 }; 254 255 struct SSOGetRoleCredentialsResult 256 { 257 Aws::Auth::AWSCredentials creds; 258 }; 259 260 SSOGetRoleCredentialsResult GetSSOCredentials(const SSOGetRoleCredentialsRequest& request); 261 262 private: 263 Aws::String m_endpoint; 264 }; 265 } // namespace Internal 266 } // namespace Aws 267