Example #1
0
static void on_host_checked(void *user_data, grpc_security_status status) {
  grpc_call_element *elem = (grpc_call_element *)user_data;
  call_data *calld = elem->call_data;

  if (status == GRPC_SECURITY_OK) {
    send_security_metadata(elem, &calld->op);
  } else {
    char *error_msg;
    gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
                 grpc_mdstr_as_c_string(calld->host));
    bubble_up_error(elem, GRPC_STATUS_INVALID_ARGUMENT, error_msg);
    gpr_free(error_msg);
  }
}
Example #2
0
static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
                            grpc_security_status status) {
  grpc_call_element *elem = (grpc_call_element *)user_data;
  call_data *calld = elem->call_data;

  if (status == GRPC_SECURITY_OK) {
    send_security_metadata(exec_ctx, elem, &calld->op);
  } else {
    char *error_msg;
    char *host = grpc_slice_to_c_string(calld->host);
    gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
                 host);
    gpr_free(host);
    grpc_call_element_signal_error(
        exec_ctx, elem, grpc_error_set_int(GRPC_ERROR_CREATE(error_msg),
                                           GRPC_ERROR_INT_GRPC_STATUS,
                                           GRPC_STATUS_UNAUTHENTICATED));
    gpr_free(error_msg);
  }
}
Example #3
0
static void on_host_checked(grpc_exec_ctx *exec_ctx, void *arg,
                            grpc_error *error) {
  grpc_transport_stream_op_batch *batch = (grpc_transport_stream_op_batch *)arg;
  grpc_call_element *elem = batch->handler_private.extra_arg;
  call_data *calld = elem->call_data;

  if (error == GRPC_ERROR_NONE) {
    send_security_metadata(exec_ctx, elem, batch);
  } else {
    char *error_msg;
    char *host = grpc_slice_to_c_string(calld->host);
    gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
                 host);
    gpr_free(host);
    grpc_transport_stream_op_batch_finish_with_failure(
        exec_ctx, batch,
        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg),
                           GRPC_ERROR_INT_GRPC_STATUS,
                           GRPC_STATUS_UNAUTHENTICATED));
    gpr_free(error_msg);
  }
}
Example #4
0
/* Called either:
     - in response to an API call (or similar) from above, to send something
     - a network event (or similar) from below, to receive something
   op contains type and call direction information, in addition to the data
   that is being sent or received. */
static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
                                    grpc_call_element *elem,
                                    grpc_transport_stream_op *op) {
  /* grab pointers to our data from the call element */
  call_data *calld = elem->call_data;
  channel_data *chand = elem->channel_data;
  grpc_linked_mdelem *l;
  size_t i;
  grpc_client_security_context *sec_ctx = NULL;

  if (calld->security_context_set == 0 &&
      op->cancel_with_status == GRPC_STATUS_OK) {
    calld->security_context_set = 1;
    GPR_ASSERT(op->context);
    if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) {
      op->context[GRPC_CONTEXT_SECURITY].value =
          grpc_client_security_context_create();
      op->context[GRPC_CONTEXT_SECURITY].destroy =
          grpc_client_security_context_destroy;
    }
    sec_ctx = op->context[GRPC_CONTEXT_SECURITY].value;
    GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
    sec_ctx->auth_context = GRPC_AUTH_CONTEXT_REF(
        chand->security_connector->base.auth_context, "client_auth_filter");
  }

  if (op->bind_pollset != NULL) {
    calld->pollset = op->bind_pollset;
  }

  if (op->send_ops != NULL && !calld->sent_initial_metadata) {
    size_t nops = op->send_ops->nops;
    grpc_stream_op *ops = op->send_ops->ops;
    for (i = 0; i < nops; i++) {
      grpc_stream_op *sop = &ops[i];
      if (sop->type != GRPC_OP_METADATA) continue;
      calld->op_md_idx = i;
      calld->sent_initial_metadata = 1;
      for (l = sop->data.metadata.list.head; l != NULL; l = l->next) {
        grpc_mdelem *md = l->md;
        /* Pointer comparison is OK for md_elems created from the same context.
         */
        if (md->key == chand->authority_string) {
          if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host);
          calld->host = GRPC_MDSTR_REF(md->value);
        } else if (md->key == chand->path_string) {
          if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method);
          calld->method = GRPC_MDSTR_REF(md->value);
        }
      }
      if (calld->host != NULL) {
        grpc_security_status status;
        const char *call_host = grpc_mdstr_as_c_string(calld->host);
        calld->op = *op; /* Copy op (originates from the caller's stack). */
        status = grpc_channel_security_connector_check_call_host(
            exec_ctx, chand->security_connector, call_host, on_host_checked,
            elem);
        if (status != GRPC_SECURITY_OK) {
          if (status == GRPC_SECURITY_ERROR) {
            char *error_msg;
            gpr_asprintf(&error_msg,
                         "Invalid host %s set in :authority metadata.",
                         call_host);
            bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT,
                            error_msg);
            gpr_free(error_msg);
          }
          return; /* early exit */
        }
      }
      send_security_metadata(exec_ctx, elem, op);
      return; /* early exit */
    }
  }

  /* pass control down the stack */
  grpc_call_next_op(exec_ctx, elem, op);
}