HttpProxyStrategy.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/crt/http/HttpProxyStrategy.h>
  6. #include <aws/common/string.h>
  7. #include <aws/crt/http/HttpConnection.h>
  8. #include <aws/http/proxy.h>
  9. namespace Aws
  10. {
  11. namespace Crt
  12. {
  13. namespace Http
  14. {
  15. HttpProxyStrategy::HttpProxyStrategy(struct aws_http_proxy_strategy *strategy) : m_strategy(strategy) {}
  16. HttpProxyStrategy::~HttpProxyStrategy() { aws_http_proxy_strategy_release(m_strategy); }
  17. HttpProxyStrategyBasicAuthConfig::HttpProxyStrategyBasicAuthConfig()
  18. : ConnectionType(AwsHttpProxyConnectionType::Legacy), Username(), Password()
  19. {
  20. }
  21. std::shared_ptr<HttpProxyStrategy> HttpProxyStrategy::CreateBasicHttpProxyStrategy(
  22. const HttpProxyStrategyBasicAuthConfig &config,
  23. Allocator *allocator)
  24. {
  25. struct aws_http_proxy_strategy_basic_auth_options basicConfig;
  26. AWS_ZERO_STRUCT(basicConfig);
  27. basicConfig.proxy_connection_type = (enum aws_http_proxy_connection_type)config.ConnectionType;
  28. basicConfig.user_name = aws_byte_cursor_from_c_str(config.Username.c_str());
  29. basicConfig.password = aws_byte_cursor_from_c_str(config.Password.c_str());
  30. struct aws_http_proxy_strategy *strategy =
  31. aws_http_proxy_strategy_new_basic_auth(allocator, &basicConfig);
  32. if (strategy == NULL)
  33. {
  34. return NULL;
  35. }
  36. return Aws::Crt::MakeShared<HttpProxyStrategy>(allocator, strategy);
  37. }
  38. class AdaptiveHttpProxyStrategy : public HttpProxyStrategy
  39. {
  40. public:
  41. AdaptiveHttpProxyStrategy(
  42. Allocator *allocator,
  43. const KerberosGetTokenFunction &kerberosGetToken,
  44. const KerberosGetTokenFunction &ntlmGetCredential,
  45. const NtlmGetTokenFunction &ntlmGetToken)
  46. : HttpProxyStrategy(nullptr), m_Allocator(allocator), m_KerberosGetToken(kerberosGetToken),
  47. m_NtlmGetCredential(ntlmGetCredential), m_NtlmGetToken(ntlmGetToken)
  48. {
  49. }
  50. void SetStrategy(struct aws_http_proxy_strategy *strategy)
  51. {
  52. aws_http_proxy_strategy_release(m_strategy);
  53. m_strategy = strategy;
  54. }
  55. static struct aws_string *NtlmGetCredential(void *user_data, int *error_code)
  56. {
  57. AdaptiveHttpProxyStrategy *strategy = reinterpret_cast<AdaptiveHttpProxyStrategy *>(user_data);
  58. String ntlmCredential;
  59. if (strategy->m_NtlmGetCredential(ntlmCredential))
  60. {
  61. struct aws_string *token =
  62. aws_string_new_from_c_str(strategy->m_Allocator, ntlmCredential.c_str());
  63. if (token != NULL)
  64. {
  65. return token;
  66. }
  67. *error_code = aws_last_error();
  68. }
  69. else
  70. {
  71. *error_code = AWS_ERROR_HTTP_PROXY_STRATEGY_TOKEN_RETRIEVAL_FAILURE;
  72. }
  73. return NULL;
  74. }
  75. static struct aws_string *KerberosGetToken(void *user_data, int *error_code)
  76. {
  77. AdaptiveHttpProxyStrategy *strategy = reinterpret_cast<AdaptiveHttpProxyStrategy *>(user_data);
  78. String kerberosToken;
  79. if (strategy->m_KerberosGetToken(kerberosToken))
  80. {
  81. struct aws_string *token =
  82. aws_string_new_from_c_str(strategy->m_Allocator, kerberosToken.c_str());
  83. if (token != NULL)
  84. {
  85. return token;
  86. }
  87. *error_code = aws_last_error();
  88. }
  89. else
  90. {
  91. *error_code = AWS_ERROR_HTTP_PROXY_STRATEGY_TOKEN_RETRIEVAL_FAILURE;
  92. }
  93. return NULL;
  94. }
  95. static struct aws_string *NtlmGetToken(
  96. void *user_data,
  97. const struct aws_byte_cursor *challenge_cursor,
  98. int *error_code)
  99. {
  100. AdaptiveHttpProxyStrategy *strategy = reinterpret_cast<AdaptiveHttpProxyStrategy *>(user_data);
  101. String ntlmToken;
  102. String challengeToken((const char *)challenge_cursor->ptr, challenge_cursor->len);
  103. if (strategy->m_NtlmGetToken(challengeToken, ntlmToken))
  104. {
  105. struct aws_string *token = aws_string_new_from_c_str(strategy->m_Allocator, ntlmToken.c_str());
  106. if (token != NULL)
  107. {
  108. return token;
  109. }
  110. *error_code = aws_last_error();
  111. }
  112. else
  113. {
  114. *error_code = AWS_ERROR_HTTP_PROXY_STRATEGY_TOKEN_RETRIEVAL_FAILURE;
  115. }
  116. return NULL;
  117. }
  118. private:
  119. Allocator *m_Allocator;
  120. KerberosGetTokenFunction m_KerberosGetToken;
  121. KerberosGetTokenFunction m_NtlmGetCredential;
  122. NtlmGetTokenFunction m_NtlmGetToken;
  123. };
  124. std::shared_ptr<HttpProxyStrategy> HttpProxyStrategy::CreateAdaptiveHttpProxyStrategy(
  125. const HttpProxyStrategyAdaptiveConfig &config,
  126. Allocator *allocator)
  127. {
  128. std::shared_ptr<AdaptiveHttpProxyStrategy> adaptiveStrategy =
  129. Aws::Crt::MakeShared<AdaptiveHttpProxyStrategy>(
  130. allocator, allocator, config.KerberosGetToken, config.NtlmGetCredential, config.NtlmGetToken);
  131. struct aws_http_proxy_strategy_tunneling_kerberos_options kerberosConfig;
  132. AWS_ZERO_STRUCT(kerberosConfig);
  133. kerberosConfig.get_token = AdaptiveHttpProxyStrategy::KerberosGetToken;
  134. kerberosConfig.get_token_user_data = adaptiveStrategy.get();
  135. struct aws_http_proxy_strategy_tunneling_ntlm_options ntlmConfig;
  136. AWS_ZERO_STRUCT(ntlmConfig);
  137. ntlmConfig.get_challenge_token = AdaptiveHttpProxyStrategy::NtlmGetToken;
  138. ntlmConfig.get_token = AdaptiveHttpProxyStrategy::NtlmGetCredential;
  139. ntlmConfig.get_challenge_token_user_data = adaptiveStrategy.get();
  140. struct aws_http_proxy_strategy_tunneling_adaptive_options adaptiveConfig;
  141. AWS_ZERO_STRUCT(adaptiveConfig);
  142. if (config.KerberosGetToken)
  143. {
  144. adaptiveConfig.kerberos_options = &kerberosConfig;
  145. }
  146. if (config.NtlmGetToken)
  147. {
  148. adaptiveConfig.ntlm_options = &ntlmConfig;
  149. }
  150. struct aws_http_proxy_strategy *strategy =
  151. aws_http_proxy_strategy_new_tunneling_adaptive(allocator, &adaptiveConfig);
  152. if (strategy == NULL)
  153. {
  154. return NULL;
  155. }
  156. adaptiveStrategy->SetStrategy(strategy);
  157. return adaptiveStrategy;
  158. }
  159. } // namespace Http
  160. } // namespace Crt
  161. } // namespace Aws