Add Session Token to AWS IMDSv2 Metadata requests (#29296)

* Add AWS Session Token to AWS IMDS Metadata Requests

* Formatted code

* rename header method, remove unused code

* formatted code

* minor fixes

* fix duplicate param in test function header

* fixing build failures
pull/29410/head
sai-sunder-s 3 years ago committed by GitHub
parent 7fb4998029
commit 387dbb92bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 29
      src/core/lib/http/format_request.cc
  2. 2
      src/core/lib/http/format_request.h
  3. 29
      src/core/lib/http/httpcli.cc
  4. 33
      src/core/lib/http/httpcli.h
  5. 79
      src/core/lib/security/credentials/external/aws_external_account_credentials.cc
  6. 8
      src/core/lib/security/credentials/external/aws_external_account_credentials.h
  7. 294
      test/core/security/credentials_test.cc
  8. 47
      test/core/security/jwt_verifier_test.cc

@ -95,6 +95,35 @@ grpc_slice grpc_httpcli_format_post_request(const grpc_http_request* request,
return grpc_slice_from_copied_buffer(req.data(), req.size());
}
grpc_slice grpc_httpcli_format_put_request(const grpc_http_request* request,
const char* host, const char* path) {
std::vector<std::string> out;
out.push_back("PUT ");
fill_common_header(request, host, path, true, &out);
if (request->body != nullptr) {
bool has_content_type = false;
for (size_t i = 0; i < request->hdr_count; i++) {
if (strcmp(request->hdrs[i].key, "Content-Type") == 0) {
has_content_type = true;
break;
}
}
if (!has_content_type) {
out.push_back("Content-Type: text/plain\r\n");
}
out.push_back(
absl::StrFormat("Content-Length: %lu\r\n",
static_cast<unsigned long>(request->body_length)));
}
out.push_back("\r\n");
std::string req = absl::StrJoin(out, "");
if (request->body != nullptr) {
absl::StrAppend(&req,
absl::string_view(request->body, request->body_length));
}
return grpc_slice_from_copied_buffer(req.data(), req.size());
}
grpc_slice grpc_httpcli_format_connect_request(const grpc_http_request* request,
const char* host,
const char* path) {

@ -29,6 +29,8 @@ grpc_slice grpc_httpcli_format_get_request(const grpc_http_request* request,
const char* host, const char* path);
grpc_slice grpc_httpcli_format_post_request(const grpc_http_request* request,
const char* host, const char* path);
grpc_slice grpc_httpcli_format_put_request(const grpc_http_request* request,
const char* host, const char* path);
grpc_slice grpc_httpcli_format_connect_request(const grpc_http_request* request,
const char* host,
const char* path);

@ -53,6 +53,7 @@ namespace {
grpc_httpcli_get_override g_get_override;
grpc_httpcli_post_override g_post_override;
grpc_httpcli_put_override g_put_override;
void (*g_test_only_on_handshake_done_intercept)(HttpRequest* req);
} // namespace
@ -107,10 +108,36 @@ OrphanablePtr<HttpRequest> HttpRequest::Post(
std::move(channel_creds));
}
OrphanablePtr<HttpRequest> HttpRequest::Put(
URI uri, const grpc_channel_args* channel_args,
grpc_polling_entity* pollent, const grpc_http_request* request,
Timestamp deadline, grpc_closure* on_done, grpc_http_response* response,
RefCountedPtr<grpc_channel_credentials> channel_creds) {
absl::optional<std::function<void()>> test_only_generate_response;
if (g_put_override != nullptr) {
test_only_generate_response = [request, uri, deadline, on_done,
response]() {
g_put_override(request, uri.authority().c_str(), uri.path().c_str(),
request->body, request->body_length, deadline, on_done,
response);
};
}
std::string name =
absl::StrFormat("HTTP:PUT:%s:%s", uri.authority(), uri.path());
const grpc_slice request_text = grpc_httpcli_format_put_request(
request, uri.authority().c_str(), uri.path().c_str());
return MakeOrphanable<HttpRequest>(
std::move(uri), request_text, response, deadline, channel_args, on_done,
pollent, name.c_str(), std::move(test_only_generate_response),
std::move(channel_creds));
}
void HttpRequest::SetOverride(grpc_httpcli_get_override get,
grpc_httpcli_post_override post) {
grpc_httpcli_post_override post,
grpc_httpcli_put_override put) {
g_get_override = get;
g_post_override = post;
g_put_override = put;
}
void HttpRequest::TestOnlySetOnHandshakeDoneIntercept(

@ -50,6 +50,10 @@ typedef int (*grpc_httpcli_post_override)(
const grpc_http_request* request, const char* host, const char* path,
const char* body_bytes, size_t body_size, grpc_core::Timestamp deadline,
grpc_closure* on_complete, grpc_http_response* response);
typedef int (*grpc_httpcli_put_override)(
const grpc_http_request* request, const char* host, const char* path,
const char* body_bytes, size_t body_size, grpc_core::Timestamp deadline,
grpc_closure* on_complete, grpc_http_response* response);
namespace grpc_core {
@ -112,6 +116,32 @@ class HttpRequest : public InternallyRefCounted<HttpRequest> {
RefCountedPtr<grpc_channel_credentials> channel_creds)
GRPC_MUST_USE_RESULT;
// Asynchronously perform a HTTP PUT.
// 'uri' is the target to make the request to. The scheme field is used to
// determine the port number. The authority field is the target host. The
// path field determines the path of the request. No other fields are used.
// 'args' are optional channel args for the request.
// 'pollent' indicates a grpc_polling_entity that is interested in the result
// of the post - work on this entity may be used to progress the post
// operation
// 'request' contains request parameters - these are caller owned and can be
// destroyed once the call returns
// 'deadline' contains a deadline for the request (or gpr_inf_future)
// 'on_done' is a callback to report results to
// 'channel_creds' are used to configurably secure the connection.
// For insecure requests, use grpc_insecure_credentials_create.
// For secure requests, use CreateHttpRequestSSLCredentials().
// nullptr is treated as insecure credentials.
// TODO(apolcyn): disallow nullptr as a value after unsecure builds
// are removed.
// Does not support ?var1=val1&var2=val2 in the path.
static OrphanablePtr<HttpRequest> Put(
URI uri, const grpc_channel_args* args, grpc_polling_entity* pollent,
const grpc_http_request* request, Timestamp deadline,
grpc_closure* on_done, grpc_http_response* response,
RefCountedPtr<grpc_channel_credentials> channel_creds)
GRPC_MUST_USE_RESULT;
HttpRequest(URI uri, const grpc_slice& request_text,
grpc_http_response* response, Timestamp deadline,
const grpc_channel_args* channel_args, grpc_closure* on_done,
@ -126,7 +156,8 @@ class HttpRequest : public InternallyRefCounted<HttpRequest> {
void Orphan() override;
static void SetOverride(grpc_httpcli_get_override get,
grpc_httpcli_post_override post);
grpc_httpcli_post_override post,
grpc_httpcli_put_override put);
static void TestOnlySetOnHandshakeDoneIntercept(
void (*intercept)(HttpRequest* req));

@ -119,6 +119,12 @@ AwsExternalAccountCredentials::AwsExternalAccountCredentials(
return;
}
regional_cred_verification_url_ = it->second.string_value();
it =
options.credential_source.object_value().find("imdsv2_session_token_url");
if (it != options.credential_source.object_value().end() &&
it->second.type() == Json::Type::STRING) {
imdsv2_session_token_url_ = it->second.string_value();
}
}
void AwsExternalAccountCredentials::RetrieveSubjectToken(
@ -133,6 +139,62 @@ void AwsExternalAccountCredentials::RetrieveSubjectToken(
}
ctx_ = ctx;
cb_ = cb;
if (!imdsv2_session_token_url_.empty()) {
RetrieveImdsV2SessionToken();
} else if (signer_ != nullptr) {
BuildSubjectToken();
} else {
RetrieveRegion();
}
}
void AwsExternalAccountCredentials::RetrieveImdsV2SessionToken() {
absl::StatusOr<URI> uri = URI::Parse(imdsv2_session_token_url_);
if (!uri.ok()) {
return;
}
grpc_http_header* headers =
static_cast<grpc_http_header*>(gpr_malloc(sizeof(grpc_http_header)));
headers[0].key = gpr_strdup("x-aws-ec2-metadata-token-ttl-seconds");
headers[0].value = gpr_strdup("300");
grpc_http_request request;
memset(&request, 0, sizeof(grpc_http_request));
request.hdr_count = 1;
request.hdrs = headers;
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveImdsV2SessionToken, this,
nullptr);
RefCountedPtr<grpc_channel_credentials> http_request_creds;
if (uri->scheme() == "http") {
http_request_creds = RefCountedPtr<grpc_channel_credentials>(
grpc_insecure_credentials_create());
} else {
http_request_creds = CreateHttpRequestSSLCredentials();
}
http_request_ =
HttpRequest::Put(std::move(*uri), nullptr /* channel args */,
ctx_->pollent, &request, ctx_->deadline, &ctx_->closure,
&ctx_->response, std::move(http_request_creds));
http_request_->Start();
grpc_http_request_destroy(&request);
}
void AwsExternalAccountCredentials::OnRetrieveImdsV2SessionToken(
void* arg, grpc_error_handle error) {
AwsExternalAccountCredentials* self =
static_cast<AwsExternalAccountCredentials*>(arg);
self->OnRetrieveImdsV2SessionTokenInternal(GRPC_ERROR_REF(error));
}
void AwsExternalAccountCredentials::OnRetrieveImdsV2SessionTokenInternal(
grpc_error_handle error) {
if (error != GRPC_ERROR_NONE) {
FinishRetrieveSubjectToken("", error);
return;
}
imdsv2_session_token_ =
std::string(ctx_->response.body, ctx_->response.body_length);
if (signer_ != nullptr) {
BuildSubjectToken();
} else {
@ -140,6 +202,20 @@ void AwsExternalAccountCredentials::RetrieveSubjectToken(
}
}
void AwsExternalAccountCredentials::AddMetadataRequestHeaders(
grpc_http_request* request) {
if (!imdsv2_session_token_.empty()) {
GPR_ASSERT(request->hdr_count == 0);
GPR_ASSERT(request->hdrs == nullptr);
grpc_http_header* headers =
static_cast<grpc_http_header*>(gpr_malloc(sizeof(grpc_http_header)));
headers[0].key = gpr_strdup("x-aws-ec2-metadata-token");
headers[0].value = gpr_strdup(imdsv2_session_token_.c_str());
request->hdr_count = 1;
request->hdrs = headers;
}
}
void AwsExternalAccountCredentials::RetrieveRegion() {
UniquePtr<char> region_from_env(gpr_getenv(kRegionEnvVar));
if (region_from_env == nullptr) {
@ -165,6 +241,7 @@ void AwsExternalAccountCredentials::RetrieveRegion() {
memset(&request, 0, sizeof(grpc_http_request));
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
AddMetadataRequestHeaders(&request);
GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveRegion, this, nullptr);
RefCountedPtr<grpc_channel_credentials> http_request_creds;
if (uri->scheme() == "http") {
@ -217,6 +294,7 @@ void AwsExternalAccountCredentials::RetrieveRoleName() {
memset(&request, 0, sizeof(grpc_http_request));
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
AddMetadataRequestHeaders(&request);
GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveRoleName, this, nullptr);
// TODO(ctiller): use the caller's resource quota.
RefCountedPtr<grpc_channel_credentials> http_request_creds;
@ -282,6 +360,7 @@ void AwsExternalAccountCredentials::RetrieveSigningKeys() {
memset(&request, 0, sizeof(grpc_http_request));
grpc_http_response_destroy(&ctx_->response);
ctx_->response = {};
AddMetadataRequestHeaders(&request);
GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveSigningKeys, this, nullptr);
// TODO(ctiller): use the caller's resource quota.
RefCountedPtr<grpc_channel_credentials> http_request_creds;

@ -43,6 +43,10 @@ class AwsExternalAccountCredentials final : public ExternalAccountCredentials {
static void OnRetrieveRegion(void* arg, grpc_error_handle error);
void OnRetrieveRegionInternal(grpc_error_handle error);
void RetrieveImdsV2SessionToken();
static void OnRetrieveImdsV2SessionToken(void* arg, grpc_error_handle error);
void OnRetrieveImdsV2SessionTokenInternal(grpc_error_handle error);
void RetrieveRoleName();
static void OnRetrieveRoleName(void* arg, grpc_error_handle error);
void OnRetrieveRoleNameInternal(grpc_error_handle error);
@ -55,6 +59,8 @@ class AwsExternalAccountCredentials final : public ExternalAccountCredentials {
void FinishRetrieveSubjectToken(std::string subject_token,
grpc_error_handle error);
void AddMetadataRequestHeaders(grpc_http_request* request);
std::string audience_;
OrphanablePtr<HttpRequest> http_request_;
@ -62,6 +68,7 @@ class AwsExternalAccountCredentials final : public ExternalAccountCredentials {
std::string region_url_;
std::string url_;
std::string regional_cred_verification_url_;
std::string imdsv2_session_token_url_;
// Information required by request signer
std::string region_;
@ -69,6 +76,7 @@ class AwsExternalAccountCredentials final : public ExternalAccountCredentials {
std::string access_key_id_;
std::string secret_access_key_;
std::string token_;
std::string imdsv2_session_token_;
std::unique_ptr<AwsRequestSigner> signer_;
std::string cred_verification_url_;

@ -247,6 +247,8 @@ const char valid_aws_external_account_creds_retrieve_signing_keys_response[] =
"{\"AccessKeyId\":\"test_access_key_id\",\"SecretAccessKey\":"
"\"test_secret_access_key\",\"Token\":\"test_token\"}";
const char aws_imdsv2_session_token[] = "imdsv2_session_token";
const char valid_aws_external_account_creds_options_credential_source[] =
"{\"environment_id\":\"aws1\","
"\"region_url\":\"https://foo.com:5555/region_url\","
@ -254,6 +256,15 @@ const char valid_aws_external_account_creds_options_credential_source[] =
"\"regional_cred_verification_url\":\"https://foo.com:5555/"
"regional_cred_verification_url_{region}\"}";
const char valid_aws_imdsv2_external_account_creds_options_credential_source[] =
"{\"environment_id\":\"aws1\","
"\"region_url\":\"https://foo.com:5555/region_url\","
"\"url\":\"https://foo.com:5555/url\","
"\"imdsv2_session_token_url\":\"https://foo.com:5555/"
"imdsv2_session_token_url\","
"\"regional_cred_verification_url\":\"https://foo.com:5555/"
"regional_cred_verification_url_{region}\"}";
const char
invalid_aws_external_account_creds_options_credential_source_unmatched_environment_id
[] = "{\"environment_id\":\"unsupported_aws_version\","
@ -761,6 +772,17 @@ int httpcli_get_should_not_be_called(const grpc_http_request* /*request*/,
return 1;
}
int httpcli_put_should_not_be_called(const grpc_http_request* /*request*/,
const char* /*host*/, const char* /*path*/,
const char* /*body_bytes*/,
size_t /*body_size*/,
Timestamp /*deadline*/,
grpc_closure* /*on_done*/,
grpc_http_response* /*response*/) {
GPR_ASSERT("HTTP PUT should not be called" == nullptr);
return 1;
}
TEST(CredentialsTest, TestComputeEngineCredsSuccess) {
ExecCtx exec_ctx;
std::string emd = "authorization: Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_";
@ -775,7 +797,8 @@ TEST(CredentialsTest, TestComputeEngineCredsSuccess) {
/* First request: http get should be called. */
auto state = RequestMetadataState::NewInstance(GRPC_ERROR_NONE, emd);
HttpRequest::SetOverride(compute_engine_httpcli_get_success_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -783,7 +806,8 @@ TEST(CredentialsTest, TestComputeEngineCredsSuccess) {
/* Second request: the cached token should be served directly. */
state = RequestMetadataState::NewInstance(GRPC_ERROR_NONE, emd);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -791,7 +815,7 @@ TEST(CredentialsTest, TestComputeEngineCredsSuccess) {
GPR_ASSERT(
strcmp(creds->debug_string().c_str(), expected_creds_debug_string) == 0);
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestComputeEngineCredsFailure) {
@ -806,13 +830,14 @@ TEST(CredentialsTest, TestComputeEngineCredsFailure) {
grpc_call_credentials* creds =
grpc_google_compute_engine_credentials_create(nullptr);
HttpRequest::SetOverride(compute_engine_httpcli_get_failure_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
GPR_ASSERT(
strcmp(creds->debug_string().c_str(), expected_creds_debug_string) == 0);
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
void validate_refresh_token_http_request(const grpc_http_request* request,
@ -872,7 +897,8 @@ TEST(CredentialsTest, TestRefreshTokenCredsSuccess) {
/* First request: http put should be called. */
auto state = RequestMetadataState::NewInstance(GRPC_ERROR_NONE, emd);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
refresh_token_httpcli_post_success);
refresh_token_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -880,7 +906,8 @@ TEST(CredentialsTest, TestRefreshTokenCredsSuccess) {
/* Second request: the cached token should be served directly. */
state = RequestMetadataState::NewInstance(GRPC_ERROR_NONE, emd);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -888,7 +915,7 @@ TEST(CredentialsTest, TestRefreshTokenCredsSuccess) {
strcmp(creds->debug_string().c_str(), expected_creds_debug_string) == 0);
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestRefreshTokenCredsFailure) {
@ -903,14 +930,15 @@ TEST(CredentialsTest, TestRefreshTokenCredsFailure) {
grpc_call_credentials* creds = grpc_google_refresh_token_credentials_create(
test_refresh_token_str, nullptr);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
token_httpcli_post_failure);
token_httpcli_post_failure,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
GPR_ASSERT(
strcmp(creds->debug_string().c_str(), expected_creds_debug_string) == 0);
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestValidStsCredsOptions) {
@ -1120,7 +1148,8 @@ TEST(CredentialsTest, TestStsCredsSuccess) {
/* First request: http put should be called. */
auto state = RequestMetadataState::NewInstance(GRPC_ERROR_NONE, emd);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
sts_token_httpcli_post_success);
sts_token_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -1128,7 +1157,8 @@ TEST(CredentialsTest, TestStsCredsSuccess) {
/* Second request: the cached token should be served directly. */
state = RequestMetadataState::NewInstance(GRPC_ERROR_NONE, emd);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -1136,7 +1166,7 @@ TEST(CredentialsTest, TestStsCredsSuccess) {
strcmp(creds->debug_string().c_str(), expected_creds_debug_string) == 0);
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_free(subject_token_path);
gpr_free(actor_token_path);
}
@ -1165,14 +1195,15 @@ TEST(CredentialsTest, TestStsCredsTokenFileNotFound) {
"Error occurred when fetching oauth2 token."),
{});
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
/* Cleanup. */
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestStsCredsNoActorTokenSuccess) {
@ -1202,7 +1233,8 @@ TEST(CredentialsTest, TestStsCredsNoActorTokenSuccess) {
/* First request: http put should be called. */
auto state = RequestMetadataState::NewInstance(GRPC_ERROR_NONE, emd);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
sts_token_httpcli_post_success_no_actor_token);
sts_token_httpcli_post_success_no_actor_token,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -1210,7 +1242,8 @@ TEST(CredentialsTest, TestStsCredsNoActorTokenSuccess) {
/* Second request: the cached token should be served directly. */
state = RequestMetadataState::NewInstance(GRPC_ERROR_NONE, emd);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -1218,7 +1251,7 @@ TEST(CredentialsTest, TestStsCredsNoActorTokenSuccess) {
strcmp(creds->debug_string().c_str(), expected_creds_debug_string) == 0);
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_free(subject_token_path);
}
@ -1245,14 +1278,15 @@ TEST(CredentialsTest, TestStsCredsLoadTokenFailure) {
};
grpc_call_credentials* creds = grpc_sts_credentials_create(&options, nullptr);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
GPR_ASSERT(
strcmp(creds->debug_string().c_str(), expected_creds_debug_string) == 0);
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_free(test_signed_jwt_path);
}
@ -1280,13 +1314,14 @@ TEST(CredentialsTest, TestStsCredsHttpFailure) {
grpc_call_credentials* creds =
grpc_sts_credentials_create(&valid_options, nullptr);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
token_httpcli_post_failure);
token_httpcli_post_failure,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds, kTestUrlScheme, kTestAuthority,
kTestPath);
GPR_ASSERT(
strcmp(creds->debug_string().c_str(), expected_creds_debug_string) == 0);
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_free(test_signed_jwt_path);
}
@ -1655,7 +1690,8 @@ TEST(CredentialsTest, TestGoogleDefaultCredsGce) {
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(creds->call_creds() != nullptr);
HttpRequest::SetOverride(compute_engine_httpcli_get_success_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds->mutable_call_creds(), kTestUrlScheme,
kTestAuthority, kTestPath);
ExecCtx::Get()->Flush();
@ -1664,7 +1700,7 @@ TEST(CredentialsTest, TestGoogleDefaultCredsGce) {
/* Cleanup. */
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
grpc_override_well_known_credentials_path_getter(nullptr);
}
@ -1683,7 +1719,7 @@ TEST(CredentialsTest, TestGoogleDefaultCredsNonGce) {
/* Simulate a successful detection of metadata server. */
HttpRequest::SetOverride(
default_creds_metadata_server_detection_httpcli_get_success_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called, httpcli_put_should_not_be_called);
grpc_composite_channel_credentials* creds =
reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create(nullptr));
@ -1691,14 +1727,15 @@ TEST(CredentialsTest, TestGoogleDefaultCredsNonGce) {
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(creds->call_creds() != nullptr);
HttpRequest::SetOverride(compute_engine_httpcli_get_success_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds->mutable_call_creds(), kTestUrlScheme,
kTestAuthority, kTestPath);
ExecCtx::Get()->Flush();
GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
/* Cleanup. */
creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
grpc_override_well_known_credentials_path_getter(nullptr);
}
@ -1724,7 +1761,7 @@ TEST(CredentialsTest, TestNoGoogleDefaultCreds) {
g_test_is_on_gce = false;
HttpRequest::SetOverride(
default_creds_gce_detection_httpcli_get_failure_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called, httpcli_put_should_not_be_called);
/* Simulate a successful detection of GCE. */
GPR_ASSERT(grpc_google_default_credentials_create(nullptr) == nullptr);
/* Try a second one. GCE detection should occur again. */
@ -1733,7 +1770,7 @@ TEST(CredentialsTest, TestNoGoogleDefaultCreds) {
GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
/* Cleanup. */
grpc_override_well_known_credentials_path_getter(nullptr);
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestGoogleDefaultCredsCallCredsSpecified) {
@ -1749,7 +1786,7 @@ TEST(CredentialsTest, TestGoogleDefaultCredsCallCredsSpecified) {
g_test_is_on_gce = true;
HttpRequest::SetOverride(
default_creds_metadata_server_detection_httpcli_get_success_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called, httpcli_put_should_not_be_called);
grpc_composite_channel_credentials* channel_creds =
reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create(call_creds));
@ -1757,12 +1794,13 @@ TEST(CredentialsTest, TestGoogleDefaultCredsCallCredsSpecified) {
GPR_ASSERT(channel_creds != nullptr);
GPR_ASSERT(channel_creds->call_creds() != nullptr);
HttpRequest::SetOverride(compute_engine_httpcli_get_success_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(channel_creds->mutable_call_creds(),
kTestUrlScheme, kTestAuthority, kTestPath);
ExecCtx::Get()->Flush();
channel_creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
struct fake_call_creds : public grpc_call_credentials {
@ -1795,7 +1833,7 @@ TEST(CredentialsTest, TestGoogleDefaultCredsNotDefault) {
g_test_is_on_gce = true;
HttpRequest::SetOverride(
default_creds_metadata_server_detection_httpcli_get_success_override,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called, httpcli_put_should_not_be_called);
grpc_composite_channel_credentials* channel_creds =
reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create(call_creds.release()));
@ -1806,7 +1844,7 @@ TEST(CredentialsTest, TestGoogleDefaultCredsNotDefault) {
kTestUrlScheme, kTestAuthority, kTestPath);
ExecCtx::Get()->Flush();
channel_creds->Unref();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
typedef enum {
@ -2315,6 +2353,30 @@ int aws_external_account_creds_httpcli_get_success(
return 1;
}
int aws_imdsv2_external_account_creds_httpcli_get_success(
const grpc_http_request* request, const char* host, const char* path,
Timestamp deadline, grpc_closure* on_done, grpc_http_response* response) {
GPR_ASSERT(request->hdr_count == 1);
GPR_ASSERT(strcmp(request->hdrs[0].key, "x-aws-ec2-metadata-token") == 0);
GPR_ASSERT(strcmp(request->hdrs[0].value, aws_imdsv2_session_token) == 0);
return aws_external_account_creds_httpcli_get_success(
request, host, path, deadline, on_done, response);
}
int aws_imdsv2_external_account_creds_httpcli_put_success(
const grpc_http_request* request, const char* /*host*/, const char* path,
const char* /*body*/, size_t /*body_size*/, Timestamp /*deadline*/,
grpc_closure* on_done, grpc_http_response* response) {
GPR_ASSERT(request->hdr_count == 1);
GPR_ASSERT(strcmp(request->hdrs[0].key,
"x-aws-ec2-metadata-token-ttl-seconds") == 0);
GPR_ASSERT(strcmp(request->hdrs[0].value, "300") == 0);
GPR_ASSERT(strcmp(path, "/imdsv2_session_token_url") == 0);
*response = http_response(200, aws_imdsv2_session_token);
ExecCtx::Run(DEBUG_LOCATION, on_done, GRPC_ERROR_NONE);
return 1;
}
int aws_external_account_creds_httpcli_post_success(
const grpc_http_request* request, const char* host, const char* path,
const char* body, size_t body_size, Timestamp /*deadline*/,
@ -2369,7 +2431,8 @@ TEST(CredentialsTest, TestExternalAccountCredsSuccess) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(&creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
@ -2377,11 +2440,12 @@ TEST(CredentialsTest, TestExternalAccountCredsSuccess) {
state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(&creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestExternalAccountCredsSuccessWithUrlEncode) {
@ -2406,11 +2470,12 @@ TEST(CredentialsTest, TestExternalAccountCredsSuccessWithUrlEncode) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(&creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest,
@ -2438,11 +2503,12 @@ TEST(CredentialsTest,
GRPC_ERROR_NONE,
"authorization: Bearer service_account_impersonation_access_token");
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(&creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestExternalAccountCredsFailureInvalidTokenUrl) {
@ -2463,7 +2529,8 @@ TEST(CredentialsTest, TestExternalAccountCredsFailureInvalidTokenUrl) {
};
TestExternalAccountCredentials creds(options, {});
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
grpc_error_handle error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid token url: invalid_token_url.");
grpc_error_handle expected_error =
@ -2474,7 +2541,7 @@ TEST(CredentialsTest, TestExternalAccountCredsFailureInvalidTokenUrl) {
kTestPath);
GRPC_ERROR_UNREF(error);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest,
@ -2496,7 +2563,8 @@ TEST(CredentialsTest,
};
TestExternalAccountCredentials creds(options, {});
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
grpc_error_handle error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid service account impersonation url: "
"invalid_service_account_impersonation_url.");
@ -2508,7 +2576,7 @@ TEST(CredentialsTest,
kTestPath);
GRPC_ERROR_UNREF(error);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest,
@ -2531,7 +2599,8 @@ TEST(CredentialsTest,
TestExternalAccountCredentials creds(options, {});
HttpRequest::SetOverride(
httpcli_get_should_not_be_called,
external_account_creds_httpcli_post_failure_token_exchange_response_missing_access_token);
external_account_creds_httpcli_post_failure_token_exchange_response_missing_access_token,
httpcli_put_should_not_be_called);
grpc_error_handle error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Missing or invalid access_token in "
"{\"not_access_token\":\"not_access_token\",\"expires_in\":3599,\"token_"
@ -2544,7 +2613,7 @@ TEST(CredentialsTest,
kTestPath);
GRPC_ERROR_UNREF(error);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestUrlExternalAccountCredsSuccessFormatText) {
@ -2574,11 +2643,12 @@ TEST(CredentialsTest, TestUrlExternalAccountCredsSuccessFormatText) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(url_external_account_creds_httpcli_get_success,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest,
@ -2611,11 +2681,12 @@ TEST(CredentialsTest,
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(url_external_account_creds_httpcli_get_success,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestUrlExternalAccountCredsSuccessFormatJson) {
@ -2645,11 +2716,12 @@ TEST(CredentialsTest, TestUrlExternalAccountCredsSuccessFormatJson) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(url_external_account_creds_httpcli_get_success,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest,
@ -2710,11 +2782,12 @@ TEST(CredentialsTest, TestFileExternalAccountCredsSuccessFormatText) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
GRPC_ERROR_UNREF(error);
gpr_free(subject_token_path);
}
@ -2757,11 +2830,12 @@ TEST(CredentialsTest, TestFileExternalAccountCredsSuccessFormatJson) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
external_account_creds_httpcli_post_success);
external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
GRPC_ERROR_UNREF(error);
gpr_free(subject_token_path);
}
@ -2789,7 +2863,8 @@ TEST(CredentialsTest, TestFileExternalAccountCredsFailureFileNotFound) {
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(error == GRPC_ERROR_NONE);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to load file");
grpc_error_handle expected_error =
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
@ -2798,7 +2873,7 @@ TEST(CredentialsTest, TestFileExternalAccountCredsFailureFileNotFound) {
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
GRPC_ERROR_UNREF(error);
}
@ -2836,7 +2911,8 @@ TEST(CredentialsTest, TestFileExternalAccountCredsFailureInvalidJsonContent) {
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(error == GRPC_ERROR_NONE);
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"The content of the file is not a valid json object.");
grpc_error_handle expected_error =
@ -2846,7 +2922,7 @@ TEST(CredentialsTest, TestFileExternalAccountCredsFailureInvalidJsonContent) {
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
GRPC_ERROR_UNREF(error);
gpr_free(subject_token_path);
}
@ -2877,11 +2953,48 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccess) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestAwsImdsv2ExternalAccountCredsSuccess) {
ExecCtx exec_ctx;
grpc_error_handle error = GRPC_ERROR_NONE;
Json credential_source = Json::Parse(
valid_aws_imdsv2_external_account_creds_options_credential_source,
&error);
GPR_ASSERT(error == GRPC_ERROR_NONE);
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
};
auto creds = AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(error == GRPC_ERROR_NONE);
GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(
aws_imdsv2_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success,
aws_imdsv2_external_account_creds_httpcli_put_success);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(CredentialsTest, TestAwsExternalAccountCredsSuccessPathRegionEnvKeysUrl) {
@ -2911,11 +3024,12 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccessPathRegionEnvKeysUrl) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_unsetenv("AWS_REGION");
}
@ -2947,11 +3061,12 @@ TEST(CredentialsTest,
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_unsetenv("AWS_DEFAULT_REGION");
}
@ -2985,11 +3100,12 @@ TEST(CredentialsTest,
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_unsetenv("AWS_REGION");
gpr_unsetenv("AWS_DEFAULT_REGION");
}
@ -3023,11 +3139,12 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccessPathRegionUrlKeysEnv) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_unsetenv("AWS_ACCESS_KEY_ID");
gpr_unsetenv("AWS_SECRET_ACCESS_KEY");
gpr_unsetenv("AWS_SESSION_TOKEN");
@ -3063,11 +3180,12 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccessPathRegionEnvKeysEnv) {
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_unsetenv("AWS_REGION");
gpr_unsetenv("AWS_ACCESS_KEY_ID");
gpr_unsetenv("AWS_SECRET_ACCESS_KEY");
@ -3107,11 +3225,12 @@ TEST(CredentialsTest,
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_unsetenv("AWS_DEFAULT_REGION");
gpr_unsetenv("AWS_ACCESS_KEY_ID");
gpr_unsetenv("AWS_SECRET_ACCESS_KEY");
@ -3151,11 +3270,12 @@ TEST(CredentialsTest,
auto state = RequestMetadataState::NewInstance(
GRPC_ERROR_NONE, "authorization: Bearer token_exchange_access_token");
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
gpr_unsetenv("AWS_REGION");
gpr_unsetenv("AWS_DEFAULT_REGION");
gpr_unsetenv("AWS_ACCESS_KEY_ID");
@ -3224,11 +3344,12 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsFailureInvalidRegionUrl) {
"Error occurred when fetching oauth2 token.", &error, 1);
auto state = RequestMetadataState::NewInstance(expected_error, {});
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
GRPC_ERROR_UNREF(error);
}
@ -3262,11 +3383,12 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsFailureInvalidUrl) {
"Error occurred when fetching oauth2 token.", &error, 1);
auto state = RequestMetadataState::NewInstance(expected_error, {});
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
GRPC_ERROR_UNREF(error);
}
@ -3301,11 +3423,12 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsFailureMissingRoleName) {
"Error occurred when fetching oauth2 token.", &error, 1);
auto state = RequestMetadataState::NewInstance(expected_error, {});
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
GRPC_ERROR_UNREF(error);
}
@ -3341,11 +3464,12 @@ TEST(CredentialsTest,
"Error occurred when fetching oauth2 token.", &error, 1);
auto state = RequestMetadataState::NewInstance(expected_error, {});
HttpRequest::SetOverride(aws_external_account_creds_httpcli_get_success,
aws_external_account_creds_httpcli_post_success);
aws_external_account_creds_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr);
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
GRPC_ERROR_UNREF(error);
}

@ -348,6 +348,15 @@ static int httpcli_post_should_not_be_called(
return 1;
}
static int httpcli_put_should_not_be_called(
const grpc_http_request* /*request*/, const char* /*host*/,
const char* /*path*/, const char* /*body_bytes*/, size_t /*body_size*/,
grpc_core::Timestamp /*deadline*/, grpc_closure* /*on_done*/,
grpc_http_response* /*response*/) {
GPR_ASSERT("HTTP PUT should not be called" == nullptr);
return 1;
}
static int httpcli_get_google_keys_for_email(
const grpc_http_request* /*request*/, const char* host, const char* path,
grpc_core::Timestamp /*deadline*/, grpc_closure* on_done,
@ -381,7 +390,8 @@ static void test_jwt_verifier_google_email_issuer_success(void) {
gpr_free(key_str);
GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
grpc_core::HttpRequest::SetOverride(httpcli_get_google_keys_for_email,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
nullptr);
grpc_auth_json_key_destruct(&key);
@ -392,7 +402,7 @@ static void test_jwt_verifier_google_email_issuer_success(void) {
grpc_jwt_verifier_destroy(verifier);
grpc_core::ExecCtx::Get()->Flush();
gpr_free(jwt);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
static int httpcli_get_custom_keys_for_email(
@ -415,7 +425,8 @@ static void test_jwt_verifier_custom_email_issuer_success(void) {
gpr_free(key_str);
GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
grpc_core::HttpRequest::SetOverride(httpcli_get_custom_keys_for_email,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
nullptr);
grpc_auth_json_key_destruct(&key);
@ -426,7 +437,7 @@ static void test_jwt_verifier_custom_email_issuer_success(void) {
grpc_jwt_verifier_destroy(verifier);
grpc_core::ExecCtx::Get()->Flush();
gpr_free(jwt);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
static int httpcli_get_jwk_set(const grpc_http_request* /*request*/,
@ -450,7 +461,8 @@ static int httpcli_get_openid_config(const grpc_http_request* /*request*/,
GPR_ASSERT(strcmp(host, "accounts.google.com") == 0);
GPR_ASSERT(strcmp(path, GRPC_OPENID_CONFIG_URL_SUFFIX) == 0);
grpc_core::HttpRequest::SetOverride(httpcli_get_jwk_set,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_done, GRPC_ERROR_NONE);
return 1;
}
@ -464,7 +476,8 @@ static void test_jwt_verifier_url_issuer_success(void) {
gpr_free(key_str);
GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
grpc_core::HttpRequest::SetOverride(httpcli_get_openid_config,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
nullptr);
grpc_auth_json_key_destruct(&key);
@ -475,7 +488,7 @@ static void test_jwt_verifier_url_issuer_success(void) {
grpc_jwt_verifier_destroy(verifier);
grpc_core::ExecCtx::Get()->Flush();
gpr_free(jwt);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
static void on_verification_key_retrieval_error(void* user_data,
@ -505,7 +518,8 @@ static void test_jwt_verifier_url_issuer_bad_config(void) {
gpr_free(key_str);
GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
grpc_core::HttpRequest::SetOverride(httpcli_get_bad_json,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
nullptr);
grpc_auth_json_key_destruct(&key);
@ -516,7 +530,7 @@ static void test_jwt_verifier_url_issuer_bad_config(void) {
grpc_jwt_verifier_destroy(verifier);
grpc_core::ExecCtx::Get()->Flush();
gpr_free(jwt);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
static void test_jwt_verifier_bad_json_key(void) {
@ -528,7 +542,8 @@ static void test_jwt_verifier_bad_json_key(void) {
gpr_free(key_str);
GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
grpc_core::HttpRequest::SetOverride(httpcli_get_bad_json,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
nullptr);
grpc_auth_json_key_destruct(&key);
@ -539,7 +554,7 @@ static void test_jwt_verifier_bad_json_key(void) {
grpc_jwt_verifier_destroy(verifier);
grpc_core::ExecCtx::Get()->Flush();
gpr_free(jwt);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
static void corrupt_jwt_sig(char* jwt) {
@ -579,7 +594,8 @@ static void test_jwt_verifier_bad_signature(void) {
gpr_free(key_str);
GPR_ASSERT(grpc_auth_json_key_is_valid(&key));
grpc_core::HttpRequest::SetOverride(httpcli_get_openid_config,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
jwt = grpc_jwt_encode_and_sign(&key, expected_audience, expected_lifetime,
nullptr);
grpc_auth_json_key_destruct(&key);
@ -591,7 +607,7 @@ static void test_jwt_verifier_bad_signature(void) {
gpr_free(jwt);
grpc_jwt_verifier_destroy(verifier);
grpc_core::ExecCtx::Get()->Flush();
grpc_core::HttpRequest::SetOverride(nullptr, nullptr);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
static int httpcli_get_should_not_be_called(
@ -614,13 +630,14 @@ static void test_jwt_verifier_bad_format(void) {
grpc_core::ExecCtx exec_ctx;
grpc_jwt_verifier* verifier = grpc_jwt_verifier_create(nullptr, 0);
grpc_core::HttpRequest::SetOverride(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called);
httpcli_post_should_not_be_called,
httpcli_put_should_not_be_called);
grpc_jwt_verifier_verify(verifier, nullptr, "bad jwt", expected_audience,
on_verification_bad_format,
const_cast<char*>(expected_user_data));
grpc_jwt_verifier_destroy(verifier);
grpc_core::ExecCtx::Get()->Flush();
grpc_core::HttpRequest::SetOverride(nullptr, nullptr);
grpc_core::HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
/* find verification key: bad jks, cannot find key in jks */

Loading…
Cancel
Save