Credentials.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/crt/auth/Credentials.h>
  6. #include <aws/crt/http/HttpConnection.h>
  7. #include <aws/crt/http/HttpProxyStrategy.h>
  8. #include <aws/auth/credentials.h>
  9. #include <aws/common/string.h>
  10. #include <algorithm>
  11. #include <aws/http/connection.h>
  12. #include <aws/crt/Api.h>
  13. namespace Aws
  14. {
  15. namespace Crt
  16. {
  17. namespace Auth
  18. {
  19. Credentials::Credentials(const aws_credentials *credentials) noexcept : m_credentials(credentials)
  20. {
  21. if (credentials != nullptr)
  22. {
  23. aws_credentials_acquire(credentials);
  24. }
  25. }
  26. Credentials::Credentials(
  27. ByteCursor access_key_id,
  28. ByteCursor secret_access_key,
  29. ByteCursor session_token,
  30. uint64_t expiration_timepoint_in_seconds,
  31. Allocator *allocator) noexcept
  32. : m_credentials(aws_credentials_new(
  33. allocator,
  34. access_key_id,
  35. secret_access_key,
  36. session_token,
  37. expiration_timepoint_in_seconds))
  38. {
  39. }
  40. Credentials::Credentials(Allocator *allocator) noexcept
  41. : m_credentials(aws_credentials_new_anonymous(allocator))
  42. {
  43. }
  44. Credentials::~Credentials()
  45. {
  46. aws_credentials_release(m_credentials);
  47. m_credentials = nullptr;
  48. }
  49. ByteCursor Credentials::GetAccessKeyId() const noexcept
  50. {
  51. if (m_credentials)
  52. {
  53. return aws_credentials_get_access_key_id(m_credentials);
  54. }
  55. else
  56. {
  57. return ByteCursor{0, nullptr};
  58. }
  59. }
  60. ByteCursor Credentials::GetSecretAccessKey() const noexcept
  61. {
  62. if (m_credentials)
  63. {
  64. return aws_credentials_get_secret_access_key(m_credentials);
  65. }
  66. else
  67. {
  68. return ByteCursor{0, nullptr};
  69. }
  70. }
  71. ByteCursor Credentials::GetSessionToken() const noexcept
  72. {
  73. if (m_credentials)
  74. {
  75. return aws_credentials_get_session_token(m_credentials);
  76. }
  77. else
  78. {
  79. return ByteCursor{0, nullptr};
  80. }
  81. }
  82. uint64_t Credentials::GetExpirationTimepointInSeconds() const noexcept
  83. {
  84. if (m_credentials)
  85. {
  86. return aws_credentials_get_expiration_timepoint_seconds(m_credentials);
  87. }
  88. else
  89. {
  90. return 0;
  91. }
  92. }
  93. Credentials::operator bool() const noexcept { return m_credentials != nullptr; }
  94. CredentialsProvider::CredentialsProvider(aws_credentials_provider *provider, Allocator *allocator) noexcept
  95. : m_allocator(allocator), m_provider(provider)
  96. {
  97. }
  98. CredentialsProvider::~CredentialsProvider()
  99. {
  100. if (m_provider)
  101. {
  102. aws_credentials_provider_release(m_provider);
  103. m_provider = nullptr;
  104. }
  105. }
  106. struct CredentialsProviderCallbackArgs
  107. {
  108. CredentialsProviderCallbackArgs() = default;
  109. OnCredentialsResolved m_onCredentialsResolved;
  110. std::shared_ptr<const CredentialsProvider> m_provider;
  111. };
  112. void CredentialsProvider::s_onCredentialsResolved(
  113. aws_credentials *credentials,
  114. int error_code,
  115. void *user_data)
  116. {
  117. CredentialsProviderCallbackArgs *callbackArgs =
  118. static_cast<CredentialsProviderCallbackArgs *>(user_data);
  119. auto credentialsPtr =
  120. Aws::Crt::MakeShared<Credentials>(callbackArgs->m_provider->m_allocator, credentials);
  121. callbackArgs->m_onCredentialsResolved(credentialsPtr, error_code);
  122. Aws::Crt::Delete(callbackArgs, callbackArgs->m_provider->m_allocator);
  123. }
  124. bool CredentialsProvider::GetCredentials(const OnCredentialsResolved &onCredentialsResolved) const
  125. {
  126. if (m_provider == nullptr)
  127. {
  128. return false;
  129. }
  130. auto callbackArgs = Aws::Crt::New<CredentialsProviderCallbackArgs>(m_allocator);
  131. if (callbackArgs == nullptr)
  132. {
  133. return false;
  134. }
  135. callbackArgs->m_provider = std::static_pointer_cast<const CredentialsProvider>(shared_from_this());
  136. callbackArgs->m_onCredentialsResolved = onCredentialsResolved;
  137. aws_credentials_provider_get_credentials(m_provider, s_onCredentialsResolved, callbackArgs);
  138. return true;
  139. }
  140. static std::shared_ptr<ICredentialsProvider> s_CreateWrappedProvider(
  141. struct aws_credentials_provider *raw_provider,
  142. Allocator *allocator)
  143. {
  144. if (raw_provider == nullptr)
  145. {
  146. return nullptr;
  147. }
  148. /* Switch to some kind of make_shared/allocate_shared when allocator support improves */
  149. auto provider = Aws::Crt::MakeShared<CredentialsProvider>(allocator, raw_provider, allocator);
  150. return std::static_pointer_cast<ICredentialsProvider>(provider);
  151. }
  152. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderStatic(
  153. const CredentialsProviderStaticConfig &config,
  154. Allocator *allocator)
  155. {
  156. aws_credentials_provider_static_options staticOptions;
  157. AWS_ZERO_STRUCT(staticOptions);
  158. staticOptions.access_key_id = config.AccessKeyId;
  159. staticOptions.secret_access_key = config.SecretAccessKey;
  160. staticOptions.session_token = config.SessionToken;
  161. return s_CreateWrappedProvider(
  162. aws_credentials_provider_new_static(allocator, &staticOptions), allocator);
  163. }
  164. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderAnonymous(
  165. Allocator *allocator)
  166. {
  167. aws_credentials_provider_shutdown_options shutdown_options;
  168. AWS_ZERO_STRUCT(shutdown_options);
  169. return s_CreateWrappedProvider(
  170. aws_credentials_provider_new_anonymous(allocator, &shutdown_options), allocator);
  171. }
  172. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderEnvironment(
  173. Allocator *allocator)
  174. {
  175. aws_credentials_provider_environment_options environmentOptions;
  176. AWS_ZERO_STRUCT(environmentOptions);
  177. return s_CreateWrappedProvider(
  178. aws_credentials_provider_new_environment(allocator, &environmentOptions), allocator);
  179. }
  180. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderProfile(
  181. const CredentialsProviderProfileConfig &config,
  182. Allocator *allocator)
  183. {
  184. struct aws_credentials_provider_profile_options raw_config;
  185. AWS_ZERO_STRUCT(raw_config);
  186. raw_config.config_file_name_override = config.ConfigFileNameOverride;
  187. raw_config.credentials_file_name_override = config.CredentialsFileNameOverride;
  188. raw_config.profile_name_override = config.ProfileNameOverride;
  189. raw_config.bootstrap = config.Bootstrap ? config.Bootstrap->GetUnderlyingHandle() : nullptr;
  190. raw_config.tls_ctx = config.TlsContext ? config.TlsContext->GetUnderlyingHandle() : nullptr;
  191. return s_CreateWrappedProvider(aws_credentials_provider_new_profile(allocator, &raw_config), allocator);
  192. }
  193. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderImds(
  194. const CredentialsProviderImdsConfig &config,
  195. Allocator *allocator)
  196. {
  197. struct aws_credentials_provider_imds_options raw_config;
  198. AWS_ZERO_STRUCT(raw_config);
  199. if (config.Bootstrap != nullptr)
  200. {
  201. raw_config.bootstrap = config.Bootstrap->GetUnderlyingHandle();
  202. }
  203. else
  204. {
  205. raw_config.bootstrap = ApiHandle::GetOrCreateStaticDefaultClientBootstrap()->GetUnderlyingHandle();
  206. }
  207. return s_CreateWrappedProvider(aws_credentials_provider_new_imds(allocator, &raw_config), allocator);
  208. }
  209. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderChain(
  210. const CredentialsProviderChainConfig &config,
  211. Allocator *allocator)
  212. {
  213. Vector<aws_credentials_provider *> providers;
  214. providers.reserve(config.Providers.size());
  215. std::for_each(
  216. config.Providers.begin(),
  217. config.Providers.end(),
  218. [&](const std::shared_ptr<ICredentialsProvider> &provider) {
  219. providers.push_back(provider->GetUnderlyingHandle());
  220. });
  221. struct aws_credentials_provider_chain_options raw_config;
  222. AWS_ZERO_STRUCT(raw_config);
  223. raw_config.providers = providers.data();
  224. raw_config.provider_count = config.Providers.size();
  225. return s_CreateWrappedProvider(aws_credentials_provider_new_chain(allocator, &raw_config), allocator);
  226. }
  227. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderCached(
  228. const CredentialsProviderCachedConfig &config,
  229. Allocator *allocator)
  230. {
  231. struct aws_credentials_provider_cached_options raw_config;
  232. AWS_ZERO_STRUCT(raw_config);
  233. raw_config.source = config.Provider->GetUnderlyingHandle();
  234. raw_config.refresh_time_in_milliseconds = config.CachedCredentialTTL.count();
  235. return s_CreateWrappedProvider(aws_credentials_provider_new_cached(allocator, &raw_config), allocator);
  236. }
  237. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderChainDefault(
  238. const CredentialsProviderChainDefaultConfig &config,
  239. Allocator *allocator)
  240. {
  241. struct aws_credentials_provider_chain_default_options raw_config;
  242. AWS_ZERO_STRUCT(raw_config);
  243. raw_config.bootstrap =
  244. config.Bootstrap ? config.Bootstrap->GetUnderlyingHandle()
  245. : ApiHandle::GetOrCreateStaticDefaultClientBootstrap()->GetUnderlyingHandle();
  246. raw_config.tls_ctx = config.TlsContext ? config.TlsContext->GetUnderlyingHandle() : nullptr;
  247. return s_CreateWrappedProvider(
  248. aws_credentials_provider_new_chain_default(allocator, &raw_config), allocator);
  249. }
  250. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderX509(
  251. const CredentialsProviderX509Config &config,
  252. Allocator *allocator)
  253. {
  254. struct aws_credentials_provider_x509_options raw_config;
  255. AWS_ZERO_STRUCT(raw_config);
  256. raw_config.bootstrap =
  257. config.Bootstrap ? config.Bootstrap->GetUnderlyingHandle()
  258. : ApiHandle::GetOrCreateStaticDefaultClientBootstrap()->GetUnderlyingHandle();
  259. raw_config.tls_connection_options = config.TlsOptions.GetUnderlyingHandle();
  260. raw_config.thing_name = aws_byte_cursor_from_c_str(config.ThingName.c_str());
  261. raw_config.role_alias = aws_byte_cursor_from_c_str(config.RoleAlias.c_str());
  262. raw_config.endpoint = aws_byte_cursor_from_c_str(config.Endpoint.c_str());
  263. struct aws_http_proxy_options proxy_options;
  264. AWS_ZERO_STRUCT(proxy_options);
  265. if (config.ProxyOptions.has_value())
  266. {
  267. const Http::HttpClientConnectionProxyOptions &proxy_config = config.ProxyOptions.value();
  268. proxy_config.InitializeRawProxyOptions(proxy_options);
  269. raw_config.proxy_options = &proxy_options;
  270. }
  271. return s_CreateWrappedProvider(aws_credentials_provider_new_x509(allocator, &raw_config), allocator);
  272. }
  273. struct DelegateCredentialsProviderCallbackArgs
  274. {
  275. DelegateCredentialsProviderCallbackArgs() = default;
  276. Allocator *allocator;
  277. GetCredentialsHandler m_Handler;
  278. };
  279. static int s_onDelegateGetCredentials(
  280. void *delegate_user_data,
  281. aws_on_get_credentials_callback_fn callback,
  282. void *callback_user_data)
  283. {
  284. auto args = static_cast<DelegateCredentialsProviderCallbackArgs *>(delegate_user_data);
  285. auto creds = args->m_Handler();
  286. struct aws_credentials *m_credentials = (struct aws_credentials *)(void *)creds->GetUnderlyingHandle();
  287. callback(m_credentials, AWS_ERROR_SUCCESS, callback_user_data);
  288. return AWS_OP_SUCCESS;
  289. }
  290. static void s_onDelegateShutdownComplete(void *user_data)
  291. {
  292. auto args = static_cast<DelegateCredentialsProviderCallbackArgs *>(user_data);
  293. Aws::Crt::Delete(args, args->allocator);
  294. }
  295. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderDelegate(
  296. const CredentialsProviderDelegateConfig &config,
  297. Allocator *allocator)
  298. {
  299. struct aws_credentials_provider_delegate_options raw_config;
  300. AWS_ZERO_STRUCT(raw_config);
  301. auto delegateCallbackArgs = Aws::Crt::New<DelegateCredentialsProviderCallbackArgs>(allocator);
  302. delegateCallbackArgs->allocator = allocator;
  303. delegateCallbackArgs->m_Handler = config.Handler;
  304. raw_config.delegate_user_data = delegateCallbackArgs;
  305. raw_config.get_credentials = s_onDelegateGetCredentials;
  306. aws_credentials_provider_shutdown_options options;
  307. options.shutdown_callback = s_onDelegateShutdownComplete;
  308. options.shutdown_user_data = delegateCallbackArgs;
  309. raw_config.shutdown_options = options;
  310. return s_CreateWrappedProvider(
  311. aws_credentials_provider_new_delegate(allocator, &raw_config), allocator);
  312. }
  313. CredentialsProviderCognitoConfig::CredentialsProviderCognitoConfig() : Bootstrap(nullptr) {}
  314. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderCognito(
  315. const CredentialsProviderCognitoConfig &config,
  316. Allocator *allocator)
  317. {
  318. struct aws_credentials_provider_cognito_options raw_config;
  319. AWS_ZERO_STRUCT(raw_config);
  320. raw_config.endpoint = aws_byte_cursor_from_c_str(config.Endpoint.c_str());
  321. raw_config.identity = aws_byte_cursor_from_c_str(config.Identity.c_str());
  322. struct aws_byte_cursor custom_role_arn_cursor;
  323. AWS_ZERO_STRUCT(custom_role_arn_cursor);
  324. if (config.CustomRoleArn.has_value())
  325. {
  326. custom_role_arn_cursor = aws_byte_cursor_from_c_str(config.CustomRoleArn.value().c_str());
  327. raw_config.custom_role_arn = &custom_role_arn_cursor;
  328. }
  329. Vector<struct aws_cognito_identity_provider_token_pair> logins;
  330. if (config.Logins.has_value())
  331. {
  332. for (const auto &login_pair : config.Logins.value())
  333. {
  334. struct aws_cognito_identity_provider_token_pair cursor_login_pair;
  335. AWS_ZERO_STRUCT(cursor_login_pair);
  336. cursor_login_pair.identity_provider_name =
  337. aws_byte_cursor_from_c_str(login_pair.IdentityProviderName.c_str());
  338. cursor_login_pair.identity_provider_token =
  339. aws_byte_cursor_from_c_str(login_pair.IdentityProviderToken.c_str());
  340. logins.push_back(cursor_login_pair);
  341. }
  342. raw_config.login_count = logins.size();
  343. raw_config.logins = logins.data();
  344. }
  345. raw_config.bootstrap =
  346. config.Bootstrap ? config.Bootstrap->GetUnderlyingHandle()
  347. : ApiHandle::GetOrCreateStaticDefaultClientBootstrap()->GetUnderlyingHandle();
  348. raw_config.tls_ctx = config.TlsCtx.GetUnderlyingHandle();
  349. struct aws_http_proxy_options proxy_options;
  350. AWS_ZERO_STRUCT(proxy_options);
  351. if (config.ProxyOptions.has_value())
  352. {
  353. const Http::HttpClientConnectionProxyOptions &proxy_config = config.ProxyOptions.value();
  354. proxy_config.InitializeRawProxyOptions(proxy_options);
  355. raw_config.http_proxy_options = &proxy_options;
  356. }
  357. return s_CreateWrappedProvider(
  358. aws_credentials_provider_new_cognito_caching(allocator, &raw_config), allocator);
  359. }
  360. CredentialsProviderSTSConfig::CredentialsProviderSTSConfig() : Bootstrap(nullptr) {}
  361. std::shared_ptr<ICredentialsProvider> CredentialsProvider::CreateCredentialsProviderSTS(
  362. const CredentialsProviderSTSConfig &config,
  363. Allocator *allocator)
  364. {
  365. if (config.Provider == nullptr)
  366. {
  367. AWS_LOGF_ERROR(
  368. AWS_LS_AUTH_CREDENTIALS_PROVIDER,
  369. "Failed to build STS credentials provider - missing required 'Provider' configuration "
  370. "parameter");
  371. return nullptr;
  372. }
  373. struct aws_credentials_provider_sts_options raw_config;
  374. AWS_ZERO_STRUCT(raw_config);
  375. raw_config.creds_provider = config.Provider->GetUnderlyingHandle();
  376. raw_config.role_arn = aws_byte_cursor_from_c_str(config.RoleArn.c_str());
  377. raw_config.session_name = aws_byte_cursor_from_c_str(config.SessionName.c_str());
  378. raw_config.duration_seconds = config.DurationSeconds;
  379. raw_config.bootstrap =
  380. config.Bootstrap ? config.Bootstrap->GetUnderlyingHandle()
  381. : ApiHandle::GetOrCreateStaticDefaultClientBootstrap()->GetUnderlyingHandle();
  382. raw_config.tls_ctx = config.TlsCtx.GetUnderlyingHandle();
  383. struct aws_http_proxy_options proxy_options;
  384. AWS_ZERO_STRUCT(proxy_options);
  385. if (config.ProxyOptions.has_value())
  386. {
  387. const Http::HttpClientConnectionProxyOptions &proxy_config = config.ProxyOptions.value();
  388. proxy_config.InitializeRawProxyOptions(proxy_options);
  389. raw_config.http_proxy_options = &proxy_options;
  390. }
  391. return s_CreateWrappedProvider(aws_credentials_provider_new_sts(allocator, &raw_config), allocator);
  392. }
  393. } // namespace Auth
  394. } // namespace Crt
  395. } // namespace Aws