예제 #1
0
파일: credentials.c 프로젝트: KyoheiG3/grpc
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. */
}
예제 #2
0
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.");
  }
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
파일: credentials.c 프로젝트: KyoheiG3/grpc
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);
  }
}
예제 #7
0
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;
}
예제 #8
0
파일: credentials.c 프로젝트: KyoheiG3/grpc
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;
}
예제 #9
0
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);
}
예제 #10
0
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);
}
예제 #11
0
파일: credentials.c 프로젝트: KyoheiG3/grpc
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;
}
예제 #12
0
파일: credentials.c 프로젝트: KyoheiG3/grpc
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;
}
예제 #13
0
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);
}
예제 #14
0
파일: credentials.c 프로젝트: bjori/grpc
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;
}
예제 #15
0
파일: credentials.c 프로젝트: KyoheiG3/grpc
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;
}