static void composite_get_request_metadata(grpc_credentials *creds, grpc_pollset *pollset, const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { grpc_composite_credentials *c = (grpc_composite_credentials *)creds; grpc_composite_credentials_metadata_context *ctx; if (!grpc_credentials_has_request_metadata(creds)) { cb(user_data, NULL, 0, GRPC_CREDENTIALS_OK); return; } ctx = gpr_malloc(sizeof(grpc_composite_credentials_metadata_context)); memset(ctx, 0, sizeof(grpc_composite_credentials_metadata_context)); ctx->service_url = gpr_strdup(service_url); ctx->user_data = user_data; ctx->cb = cb; ctx->composite_creds = c; ctx->pollset = pollset; ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds); while (ctx->creds_index < c->inner.num_creds) { grpc_credentials *inner_creds = c->inner.creds_array[ctx->creds_index++]; if (grpc_credentials_has_request_metadata(inner_creds)) { grpc_credentials_get_request_metadata(inner_creds, pollset, service_url, composite_metadata_cb, ctx); return; } } GPR_ASSERT(0); /* Should have exited before. */ }
static void test_empty_preallocated_md_store(void) { grpc_credentials_md_store *store = grpc_credentials_md_store_create(4); GPR_ASSERT(store->num_entries == 0); GPR_ASSERT(store->allocated == 4); GPR_ASSERT(store->entries != NULL); grpc_credentials_md_store_unref(store); }
static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_polling_entity *pollent, grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_service_account_jwt_access_credentials *c = (grpc_service_account_jwt_access_credentials *)creds; gpr_timespec refresh_threshold = gpr_time_from_seconds( GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); /* See if we can return a cached jwt. */ grpc_credentials_md_store *jwt_md = NULL; { gpr_mu_lock(&c->cache_mu); if (c->cached.service_url != NULL && strcmp(c->cached.service_url, context.service_url) == 0 && c->cached.jwt_md != NULL && (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)), refresh_threshold) > 0)) { jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md); } gpr_mu_unlock(&c->cache_mu); } if (jwt_md == NULL) { char *jwt = NULL; /* Generate a new jwt. */ gpr_mu_lock(&c->cache_mu); jwt_reset_cache(exec_ctx, c); jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url, c->jwt_lifetime, NULL); if (jwt != NULL) { char *md_value; gpr_asprintf(&md_value, "Bearer %s", jwt); gpr_free(jwt); c->cached.jwt_expiration = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); c->cached.service_url = gpr_strdup(context.service_url); c->cached.jwt_md = grpc_credentials_md_store_create(1); grpc_credentials_md_store_add_cstrings( c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value); gpr_free(md_value); jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md); } gpr_mu_unlock(&c->cache_mu); } if (jwt_md != NULL) { cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries, GRPC_CREDENTIALS_OK, NULL); grpc_credentials_md_store_unref(exec_ctx, jwt_md); } else { cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR, "Could not generate JWT."); } }
static void test_add_cstrings_to_empty_md_store(void) { grpc_credentials_md_store *store = grpc_credentials_md_store_create(0); const char *key_str = "hello"; const char *value_str = "there blah blah blah blah blah blah blah"; grpc_credentials_md_store_add_cstrings(store, key_str, value_str); GPR_ASSERT(store->num_entries == 1); GPR_ASSERT(gpr_slice_str_cmp(store->entries[0].key, key_str) == 0); GPR_ASSERT(gpr_slice_str_cmp(store->entries[0].value, value_str) == 0); grpc_credentials_md_store_unref(store); }
static void test_ref_unref_empty_md_store(void) { grpc_credentials_md_store *store = grpc_credentials_md_store_create(0); grpc_credentials_md_store_ref(store); grpc_credentials_md_store_ref(store); GPR_ASSERT(store->num_entries == 0); GPR_ASSERT(store->allocated == 0); grpc_credentials_md_store_unref(store); grpc_credentials_md_store_unref(store); grpc_credentials_md_store_unref(store); }
static void jwt_get_request_metadata(grpc_credentials *creds, grpc_pollset *pollset, const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { grpc_jwt_credentials *c = (grpc_jwt_credentials *)creds; gpr_timespec refresh_threshold = {GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, 0}; /* See if we can return a cached jwt. */ grpc_credentials_md_store *jwt_md = NULL; { gpr_mu_lock(&c->cache_mu); if (c->cached.service_url != NULL && strcmp(c->cached.service_url, service_url) == 0 && c->cached.jwt_md != NULL && (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)), refresh_threshold) > 0)) { jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md); } gpr_mu_unlock(&c->cache_mu); } if (jwt_md == NULL) { char *jwt = NULL; /* Generate a new jwt. */ gpr_mu_lock(&c->cache_mu); jwt_reset_cache(c); jwt = grpc_jwt_encode_and_sign(&c->key, service_url, c->jwt_lifetime, NULL); if (jwt != NULL) { char *md_value; gpr_asprintf(&md_value, "Bearer %s", jwt); gpr_free(jwt); c->cached.jwt_expiration = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); c->cached.service_url = gpr_strdup(service_url); c->cached.jwt_md = grpc_credentials_md_store_create(1); grpc_credentials_md_store_add_cstrings( c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value); gpr_free(md_value); jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md); } gpr_mu_unlock(&c->cache_mu); } if (jwt_md != NULL) { cb(user_data, jwt_md->entries, jwt_md->num_entries, GRPC_CREDENTIALS_OK); grpc_credentials_md_store_unref(jwt_md); } else { cb(user_data, NULL, 0, GRPC_CREDENTIALS_ERROR); } }
grpc_call_credentials *grpc_md_only_test_credentials_create( const char *md_key, const char *md_value, int is_async) { grpc_md_only_test_credentials *c = gpr_zalloc(sizeof(grpc_md_only_test_credentials)); c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; c->base.vtable = &md_only_test_vtable; gpr_ref_init(&c->base.refcount, 1); c->md_store = grpc_credentials_md_store_create(1); grpc_credentials_md_store_add_cstrings(c->md_store, md_key, md_value); c->is_async = is_async; return &c->base; }
grpc_credentials *grpc_fake_oauth2_credentials_create( const char *token_md_value, int is_async) { grpc_fake_oauth2_credentials *c = gpr_malloc(sizeof(grpc_fake_oauth2_credentials)); memset(c, 0, sizeof(grpc_fake_oauth2_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2; c->base.vtable = &fake_oauth2_vtable; gpr_ref_init(&c->base.refcount, 1); c->access_token_md = grpc_credentials_md_store_create(1); grpc_credentials_md_store_add_cstrings( c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value); c->is_async = is_async; return &c->base; }
static void test_add_to_empty_md_store(void) { grpc_credentials_md_store *store = grpc_credentials_md_store_create(0); const char *key_str = "hello"; const char *value_str = "there blah blah blah blah blah blah blah"; gpr_slice key = gpr_slice_from_copied_string(key_str); gpr_slice value = gpr_slice_from_copied_string(value_str); grpc_credentials_md_store_add(store, key, value); GPR_ASSERT(store->num_entries == 1); GPR_ASSERT(gpr_slice_cmp(key, store->entries[0].key) == 0); GPR_ASSERT(gpr_slice_cmp(value, store->entries[0].value) == 0); gpr_slice_unref(key); gpr_slice_unref(value); grpc_credentials_md_store_unref(store); }
static void test_add_abunch_to_md_store(void) { grpc_credentials_md_store *store = grpc_credentials_md_store_create(4); size_t num_entries = 1000; const char *key_str = "hello"; const char *value_str = "there blah blah blah blah blah blah blah"; size_t i; for (i = 0; i < num_entries; i++) { grpc_credentials_md_store_add_cstrings(store, key_str, value_str); } for (i = 0; i < num_entries; i++) { GPR_ASSERT(gpr_slice_str_cmp(store->entries[i].key, key_str) == 0); GPR_ASSERT(gpr_slice_str_cmp(store->entries[i].value, value_str) == 0); } grpc_credentials_md_store_unref(store); }
grpc_credentials *grpc_access_token_credentials_create( const char *access_token) { grpc_access_token_credentials *c = gpr_malloc(sizeof(grpc_access_token_credentials)); char *token_md_value; memset(c, 0, sizeof(grpc_access_token_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2; c->base.vtable = &access_token_vtable; gpr_ref_init(&c->base.refcount, 1); c->access_token_md = grpc_credentials_md_store_create(1); gpr_asprintf(&token_md_value, "Bearer %s", access_token); grpc_credentials_md_store_add_cstrings( c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value); gpr_free(token_md_value); return &c->base; }
grpc_credentials *grpc_iam_credentials_create(const char *token, const char *authority_selector) { grpc_iam_credentials *c; GPR_ASSERT(token != NULL); GPR_ASSERT(authority_selector != NULL); c = gpr_malloc(sizeof(grpc_iam_credentials)); memset(c, 0, sizeof(grpc_iam_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_IAM; c->base.vtable = &iam_vtable; gpr_ref_init(&c->base.refcount, 1); c->iam_md = grpc_credentials_md_store_create(2); grpc_credentials_md_store_add_cstrings( c->iam_md, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, token); grpc_credentials_md_store_add_cstrings( c->iam_md, GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, authority_selector); return &c->base; }
static void composite_call_get_request_metadata( grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_polling_entity *pollent, grpc_auth_metadata_context auth_md_context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds; grpc_composite_call_credentials_metadata_context *ctx; ctx = gpr_zalloc(sizeof(grpc_composite_call_credentials_metadata_context)); ctx->auth_md_context = auth_md_context; ctx->user_data = user_data; ctx->cb = cb; ctx->composite_creds = c; ctx->pollent = pollent; ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds); grpc_call_credentials_get_request_metadata( exec_ctx, c->inner.creds_array[ctx->creds_index++], ctx->pollent, auth_md_context, composite_call_metadata_cb, ctx); }
grpc_credentials *grpc_access_token_credentials_create(const char *access_token, void *reserved) { grpc_access_token_credentials *c = gpr_malloc(sizeof(grpc_access_token_credentials)); char *token_md_value; GRPC_API_TRACE( "grpc_access_token_credentials_create(access_token=%s, " "reserved=%p)", 2, (access_token, reserved)); GPR_ASSERT(reserved == NULL); memset(c, 0, sizeof(grpc_access_token_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2; c->base.vtable = &access_token_vtable; gpr_ref_init(&c->base.refcount, 1); c->access_token_md = grpc_credentials_md_store_create(1); gpr_asprintf(&token_md_value, "Bearer %s", access_token); grpc_credentials_md_store_add_cstrings( c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value); gpr_free(token_md_value); return &c->base; }
grpc_credentials_status grpc_oauth2_token_fetcher_credentials_parse_server_response( const grpc_httpcli_response *response, grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime) { char *null_terminated_body = NULL; char *new_access_token = NULL; grpc_credentials_status status = GRPC_CREDENTIALS_OK; grpc_json *json = NULL; if (response == NULL) { gpr_log(GPR_ERROR, "Received NULL response."); status = GRPC_CREDENTIALS_ERROR; goto end; } if (response->body_length > 0) { null_terminated_body = gpr_malloc(response->body_length + 1); null_terminated_body[response->body_length] = '\0'; memcpy(null_terminated_body, response->body, response->body_length); } if (response->status != 200) { gpr_log(GPR_ERROR, "Call to http server ended with error %d [%s].", response->status, null_terminated_body != NULL ? null_terminated_body : ""); status = GRPC_CREDENTIALS_ERROR; goto end; } else { grpc_json *access_token = NULL; grpc_json *token_type = NULL; grpc_json *expires_in = NULL; grpc_json *ptr; json = grpc_json_parse_string(null_terminated_body); if (json == NULL) { gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body); status = GRPC_CREDENTIALS_ERROR; goto end; } if (json->type != GRPC_JSON_OBJECT) { gpr_log(GPR_ERROR, "Response should be a JSON object"); status = GRPC_CREDENTIALS_ERROR; goto end; } for (ptr = json->child; ptr; ptr = ptr->next) { if (strcmp(ptr->key, "access_token") == 0) { access_token = ptr; } else if (strcmp(ptr->key, "token_type") == 0) { token_type = ptr; } else if (strcmp(ptr->key, "expires_in") == 0) { expires_in = ptr; } } if (access_token == NULL || access_token->type != GRPC_JSON_STRING) { gpr_log(GPR_ERROR, "Missing or invalid access_token in JSON."); status = GRPC_CREDENTIALS_ERROR; goto end; } if (token_type == NULL || token_type->type != GRPC_JSON_STRING) { gpr_log(GPR_ERROR, "Missing or invalid token_type in JSON."); status = GRPC_CREDENTIALS_ERROR; goto end; } if (expires_in == NULL || expires_in->type != GRPC_JSON_NUMBER) { gpr_log(GPR_ERROR, "Missing or invalid expires_in in JSON."); status = GRPC_CREDENTIALS_ERROR; goto end; } gpr_asprintf(&new_access_token, "%s %s", token_type->value, access_token->value); token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10); token_lifetime->tv_nsec = 0; if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md); *token_md = grpc_credentials_md_store_create(1); grpc_credentials_md_store_add_cstrings( *token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token); status = GRPC_CREDENTIALS_OK; } end: if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) { grpc_credentials_md_store_unref(*token_md); *token_md = NULL; } if (null_terminated_body != NULL) gpr_free(null_terminated_body); if (new_access_token != NULL) gpr_free(new_access_token); if (json != NULL) grpc_json_destroy(json); return status; }