rb_call_credentials.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <ruby/ruby.h>
20 
21 #include "rb_call_credentials.h"
22 
23 #include <ruby/thread.h>
24 
25 #include "rb_call.h"
26 #include "rb_event_thread.h"
27 #include "rb_grpc.h"
29 
30 #include <grpc/grpc.h>
31 #include <grpc/grpc_security.h>
32 #include <grpc/support/alloc.h>
33 #include <grpc/support/log.h>
34 
35 /* grpc_rb_cCallCredentials is the ruby class that proxies
36  * grpc_call_credentials */
37 static VALUE grpc_rb_cCallCredentials = Qnil;
38 
39 /* grpc_rb_call_credentials wraps a grpc_call_credentials. It provides a mark
40  * object that is used to hold references to any objects used to create the
41  * credentials. */
42 typedef struct grpc_rb_call_credentials {
43  /* Holder of ruby objects involved in contructing the credentials */
44  VALUE mark;
45 
46  /* The actual credentials */
49 
50 typedef struct callback_params {
51  VALUE get_metadata;
53  void* user_data;
56 
58  VALUE result = rb_hash_new();
59  VALUE callback_func = rb_ary_entry(args, 0);
60  VALUE callback_args = rb_ary_entry(args, 1);
61  VALUE md_ary_obj = rb_ary_entry(args, 2);
63  VALUE callback_func_str = rb_funcall(callback_func, rb_intern("to_s"), 0);
64  VALUE callback_args_str = rb_funcall(callback_args, rb_intern("to_s"), 0);
65  VALUE callback_source_info =
66  rb_funcall(callback_func, rb_intern("source_location"), 0);
67  if (callback_source_info != Qnil) {
68  VALUE source_filename = rb_ary_entry(callback_source_info, 0);
69  VALUE source_line_number = rb_funcall(
70  rb_ary_entry(callback_source_info, 1), rb_intern("to_s"), 0);
72  "GRPC_RUBY: grpc_rb_call_credentials invoking user callback:|%s| "
73  "source_filename:%s line_number:%s with arguments:|%s|",
74  StringValueCStr(callback_func_str),
75  StringValueCStr(source_filename),
76  StringValueCStr(source_line_number),
77  StringValueCStr(callback_args_str));
78  } else {
80  "GRPC_RUBY: grpc_rb_call_credentials invoking user callback:|%s| "
81  "(failed to get source filename and line) with arguments:|%s|",
82  StringValueCStr(callback_func_str),
83  StringValueCStr(callback_args_str));
84  }
85  }
86  VALUE metadata =
87  rb_funcall(callback_func, rb_intern("call"), 1, callback_args);
88  grpc_metadata_array* md_ary = NULL;
89  TypedData_Get_Struct(md_ary_obj, grpc_metadata_array,
90  &grpc_rb_md_ary_data_type, md_ary);
92  rb_hash_aset(result, rb_str_new2("metadata"), metadata);
93  rb_hash_aset(result, rb_str_new2("status"), INT2NUM(GRPC_STATUS_OK));
94  rb_hash_aset(result, rb_str_new2("details"), rb_str_new2(""));
95  return result;
96 }
97 
99  VALUE exception_object) {
100  VALUE result = rb_hash_new();
101  VALUE backtrace = rb_funcall(exception_object, rb_intern("backtrace"), 0);
102  VALUE backtrace_str;
103  if (backtrace != Qnil) {
104  backtrace_str =
105  rb_funcall(backtrace, rb_intern("join"), 1, rb_str_new2("\n\tfrom "));
106  } else {
107  backtrace_str = rb_str_new2(
108  "failed to get backtrace, this exception was likely thrown from native "
109  "code");
110  }
111  VALUE rb_exception_info =
112  rb_funcall(exception_object, rb_intern("inspect"), 0);
113  (void)args;
115  "GRPC_RUBY call credentials callback failed, exception inspect:|%s| "
116  "backtrace:|%s|",
117  StringValueCStr(rb_exception_info), StringValueCStr(backtrace_str));
118  rb_hash_aset(result, rb_str_new2("metadata"), Qnil);
119  rb_hash_aset(result, rb_str_new2("status"),
120  INT2NUM(GRPC_STATUS_UNAUTHENTICATED));
121  rb_hash_aset(result, rb_str_new2("details"), rb_exception_info);
122  return result;
123 }
124 
126  callback_params* const params = (callback_params*)param;
127  VALUE auth_uri = rb_str_new_cstr(params->context.service_url);
128  /* Pass the arguments to the proc in a hash, which currently only has they key
129  'auth_uri' */
130  VALUE callback_args = rb_ary_new();
131  VALUE args = rb_hash_new();
132  VALUE result;
133  grpc_metadata_array md_ary;
135  VALUE details;
136  char* error_details;
137  grpc_metadata_array_init(&md_ary);
138  rb_hash_aset(args, ID2SYM(rb_intern("jwt_aud_uri")), auth_uri);
139  rb_ary_push(callback_args, params->get_metadata);
140  rb_ary_push(callback_args, args);
141  // Wrap up the grpc_metadata_array into a ruby object and do the conversion
142  // from hash to grpc_metadata_array within the rescue block, because the
143  // conversion can throw exceptions.
144  rb_ary_push(callback_args,
145  TypedData_Wrap_Struct(grpc_rb_cMdAry, &grpc_rb_md_ary_data_type,
146  &md_ary));
147  result = rb_rescue(grpc_rb_call_credentials_callback, callback_args,
149  // Both callbacks return a hash, so result should be a hash
150  status = NUM2INT(rb_hash_aref(result, rb_str_new2("status")));
151  details = rb_hash_aref(result, rb_str_new2("details"));
152  error_details = StringValueCStr(details);
153  params->callback(params->user_data, md_ary.metadata, md_ary.count, status,
154  error_details);
157  gpr_free(params);
158 }
159 
162  grpc_credentials_plugin_metadata_cb cb, void* user_data,
164  size_t* num_creds_md, grpc_status_code* status,
165  const char** error_details) {
166  callback_params* params = gpr_zalloc(sizeof(callback_params));
167  params->get_metadata = (VALUE)state;
169  params->user_data = user_data;
170  params->callback = cb;
171 
173  (void*)(params));
174  return 0; // Async return.
175 }
176 
178  (void)state;
179  // Not sure what needs to be done here
180 }
181 
184  if (p == NULL) {
185  return;
186  }
189  wrapper->wrapped = NULL;
190  xfree(p);
191 }
192 
193 /* Destroys the credentials instances. */
194 static void grpc_rb_call_credentials_free(void* p) {
197 }
198 
199 /* Protects the mark object from GC */
200 static void grpc_rb_call_credentials_mark(void* p) {
202  if (p == NULL) {
203  return;
204  }
206  if (wrapper->mark != Qnil) {
207  rb_gc_mark(wrapper->mark);
208  }
209 }
210 
211 static rb_data_type_t grpc_rb_call_credentials_data_type = {
212  "grpc_call_credentials",
216  {NULL, NULL}},
217  NULL,
218  NULL,
219 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
220  RUBY_TYPED_FREE_IMMEDIATELY
221 #endif
222 };
223 
224 /* Allocates CallCredentials instances.
225  Provides safe initial defaults for the instance fields. */
226 static VALUE grpc_rb_call_credentials_alloc(VALUE cls) {
227  grpc_ruby_init();
229  wrapper->wrapped = NULL;
230  wrapper->mark = Qnil;
231  return TypedData_Wrap_Struct(cls, &grpc_rb_call_credentials_data_type,
232  wrapper);
233 }
234 
235 /* Creates a wrapping object for a given call credentials. This should only be
236  * called with grpc_call_credentials objects that are not already associated
237  * with any Ruby object */
239  VALUE rb_wrapper;
241  if (c == NULL) {
242  return Qnil;
243  }
245  TypedData_Get_Struct(rb_wrapper, grpc_rb_call_credentials,
247  wrapper->wrapped = c;
248  wrapper->mark = mark;
249  return rb_wrapper;
250 }
251 
252 /* The attribute used on the mark object to hold the callback */
253 static ID id_callback;
254 
255 /*
256  call-seq:
257  creds = Credentials.new auth_proc
258  proc: (required) Proc that generates auth metadata
259  Initializes CallCredential instances. */
260 static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) {
262  grpc_call_credentials* creds = NULL;
264 
265  TypedData_Get_Struct(self, grpc_rb_call_credentials,
267 
270  if (!rb_obj_is_proc(proc)) {
271  rb_raise(rb_eTypeError, "Argument to CallCredentials#new must be a proc");
272  return Qnil;
273  }
274  plugin.state = (void*)proc;
275  plugin.type = "";
276 
277  // TODO(yihuazhang): Expose min_security_level via the Ruby API so that
278  // applications can decide what minimum security level their plugins require.
280  plugin, GRPC_PRIVACY_AND_INTEGRITY, NULL);
281  if (creds == NULL) {
282  rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
283  return Qnil;
284  }
285 
286  wrapper->mark = proc;
287  wrapper->wrapped = creds;
288  rb_ivar_set(self, id_callback, proc);
289 
290  return self;
291 }
292 
293 static VALUE grpc_rb_call_credentials_compose(int argc, VALUE* argv,
294  VALUE self) {
295  grpc_call_credentials* creds;
296  grpc_call_credentials* other;
297  grpc_call_credentials* prev = NULL;
298  VALUE mark;
299  if (argc == 0) {
300  return self;
301  }
302  mark = rb_ary_new();
304  for (int i = 0; i < argc; i++) {
305  rb_ary_push(mark, argv[i]);
307  creds = grpc_composite_call_credentials_create(creds, other, NULL);
308  if (prev != NULL) {
310  }
311  prev = creds;
312  }
313  return grpc_rb_wrap_call_credentials(creds, mark);
314 }
315 
318  rb_define_class_under(grpc_rb_mGrpcCore, "CallCredentials", rb_cObject);
319 
320  /* Allocates an object managed by the ruby runtime */
321  rb_define_alloc_func(grpc_rb_cCallCredentials,
323 
324  /* Provides a ruby constructor and support for dup/clone. */
325  rb_define_method(grpc_rb_cCallCredentials, "initialize",
327  rb_define_method(grpc_rb_cCallCredentials, "initialize_copy",
329  rb_define_method(grpc_rb_cCallCredentials, "compose",
331 
332  id_callback = rb_intern("__callback");
333 }
334 
335 /* Gets the wrapped grpc_call_credentials from the ruby wrapper */
338  TypedData_Get_Struct(v, grpc_rb_call_credentials,
340  return wrapper->wrapped;
341 }
grpc_rb_call_credentials_callback
static VALUE grpc_rb_call_credentials_callback(VALUE args)
Definition: rb_call_credentials.c:57
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX
#define GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX
Definition: grpc_security.h:417
grpc_credentials_plugin_metadata_cb
void(* grpc_credentials_plugin_metadata_cb)(void *user_data, const grpc_metadata *creds_md, size_t num_creds_md, grpc_status_code status, const char *error_details)
Definition: grpc_security.h:385
grpc_metadata_array::metadata
grpc_metadata * metadata
Definition: grpc_types.h:582
log.h
rb_grpc_imports.generated.h
metadata
Definition: cq_verifier.cc:48
GRPC_STATUS_UNAUTHENTICATED
@ GRPC_STATUS_UNAUTHENTICATED
Definition: include/grpc/impl/codegen/status.h:72
GRPC_RB_MEMSIZE_UNAVAILABLE
#define GRPC_RB_MEMSIZE_UNAVAILABLE
Definition: rb_grpc.h:57
grpc_ruby_shutdown
void grpc_ruby_shutdown()
Definition: rb_grpc.c:296
gpr_should_log
GPRAPI void GPRAPI int gpr_should_log(gpr_log_severity severity)
Definition: log.cc:67
grpc_metadata_array
Definition: grpc_types.h:579
grpc_rb_cMdAry
VALUE grpc_rb_cMdAry
Definition: rb_call.c:51
grpc_metadata_credentials_plugin::state
void * state
Definition: grpc_security.h:458
grpc_auth_metadata_context::service_url
const char * service_url
Definition: grpc_security.h:393
callback_params::context
grpc_auth_metadata_context context
Definition: rb_call_credentials.c:52
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
grpc_status_code
grpc_status_code
Definition: include/grpc/impl/codegen/status.h:28
grpc_rb_call_credentials_data_type
static rb_data_type_t grpc_rb_call_credentials_data_type
Definition: rb_call_credentials.c:211
grpc_metadata_credentials_create_from_plugin
GRPCAPI grpc_call_credentials * grpc_metadata_credentials_create_from_plugin(grpc_metadata_credentials_plugin plugin, grpc_security_level min_security_level, void *reserved)
Definition: plugin_credentials.cc:208
grpc_rb_call_credentials_compose
static VALUE grpc_rb_call_credentials_compose(int argc, VALUE *argv, VALUE self)
Definition: rb_call_credentials.c:293
grpc_call_credentials
Definition: src/core/lib/security/credentials/credentials.h:189
status
absl::Status status
Definition: rls.cc:251
grpc_call_credentials_release
GRPCAPI void grpc_call_credentials_release(grpc_call_credentials *creds)
Definition: credentials.cc:42
callback_params::callback
grpc_credentials_plugin_metadata_cb callback
Definition: rb_call_credentials.c:54
grpc_composite_call_credentials_create
GRPCAPI grpc_call_credentials * grpc_composite_call_credentials_create(grpc_call_credentials *creds1, grpc_call_credentials *creds2, void *reserved)
Definition: composite_credentials.cc:129
grpc_metadata_array::count
size_t count
Definition: grpc_types.h:580
xds_manager.p
p
Definition: xds_manager.py:60
grpc_security.h
grpc_auth_metadata_context_reset
GRPCAPI void grpc_auth_metadata_context_reset(grpc_auth_metadata_context *context)
Definition: client_auth_filter.cc:71
GPR_LOG_SEVERITY_DEBUG
@ GPR_LOG_SEVERITY_DEBUG
Definition: include/grpc/impl/codegen/log.h:46
_grpc_channel_wrapper::wrapped
grpc_channel * wrapped
Definition: src/php/ext/grpc/channel.h:35
grpc_rb_metadata_array_destroy_including_entries
void grpc_rb_metadata_array_destroy_including_entries(grpc_metadata_array *array)
Definition: rb_call.c:642
grpc_rb_call_credentials_mark
static void grpc_rb_call_credentials_mark(void *p)
Definition: rb_call_credentials.c:200
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
callback_params::get_metadata
VALUE get_metadata
Definition: rb_call_credentials.c:51
callback_params
Definition: rb_call_credentials.c:50
callback_params::user_data
void * user_data
Definition: rb_call_credentials.c:53
grpc_metadata
Definition: grpc_types.h:537
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
GRPC_STATUS_OK
@ GRPC_STATUS_OK
Definition: include/grpc/impl/codegen/status.h:30
grpc_rb_get_wrapped_call_credentials
grpc_call_credentials * grpc_rb_get_wrapped_call_credentials(VALUE v)
Definition: rb_call_credentials.c:336
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
grpc_rb_call_credentials_callback_with_gil
static void grpc_rb_call_credentials_callback_with_gil(void *param)
Definition: rb_call_credentials.c:125
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
grpc.h
grpc_rb_call_credentials_plugin_destroy
static void grpc_rb_call_credentials_plugin_destroy(void *state)
Definition: rb_call_credentials.c:177
grpc_metadata_credentials_plugin
Definition: grpc_security.h:424
wrapper
grpc_channel_wrapper * wrapper
Definition: src/php/ext/grpc/channel.h:48
grpc_rb_wrap_call_credentials
VALUE grpc_rb_wrap_call_credentials(grpc_call_credentials *c, VALUE mark)
Definition: rb_call_credentials.c:238
grpc_rb_call_credentials
Definition: rb_call_credentials.c:42
grpc_rb_md_ary_data_type
const rb_data_type_t grpc_rb_md_ary_data_type
Definition: rb_call.c:106
grpc_rb_event_queue_enqueue
void grpc_rb_event_queue_enqueue(void(*callback)(void *), void *argument)
Definition: rb_event_thread.c:55
rb_call_credentials.h
details
static grpc_slice details
Definition: test/core/fling/client.cc:46
grpc_rb_call_credentials::wrapped
grpc_call_credentials * wrapped
Definition: rb_call_credentials.c:47
grpc_rb_call_credentials_alloc
static VALUE grpc_rb_call_credentials_alloc(VALUE cls)
Definition: rb_call_credentials.c:226
rb_grpc.h
grpc_rb_call_credentials_free_internal
static void grpc_rb_call_credentials_free_internal(void *p)
Definition: rb_call_credentials.c:182
grpc_rb_call_credentials_callback_rescue
static VALUE grpc_rb_call_credentials_callback_rescue(VALUE args, VALUE exception_object)
Definition: rb_call_credentials.c:98
grpc_rb_mGrpcCore
VALUE grpc_rb_mGrpcCore
Definition: rb_grpc.c:252
grpc_metadata_credentials_plugin::type
const char * type
Definition: grpc_security.h:461
grpc_metadata_credentials_plugin::get_metadata
int(* get_metadata)(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data, grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t *num_creds_md, grpc_status_code *status, const char **error_details)
Definition: grpc_security.h:443
grpc_rb_call_credentials
struct grpc_rb_call_credentials grpc_rb_call_credentials
ALLOC
#define ALLOC(class_name)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1486
grpc_rb_cannot_init_copy
VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self)
Definition: rb_grpc.c:80
id_callback
static ID id_callback
Definition: rb_call_credentials.c:253
alloc.h
callback_params
struct callback_params callback_params
Init_grpc_call_credentials
void Init_grpc_call_credentials()
Definition: rb_call_credentials.c:316
rb_call.h
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
GRPC_PRIVACY_AND_INTEGRITY
@ GRPC_PRIVACY_AND_INTEGRITY
Definition: grpc_security_constants.h:135
grpc_rb_cCallCredentials
static VALUE grpc_rb_cCallCredentials
Definition: rb_call_credentials.c:37
grpc_auth_metadata_context_copy
GRPCAPI void grpc_auth_metadata_context_copy(grpc_auth_metadata_context *from, grpc_auth_metadata_context *to)
Definition: client_auth_filter.cc:58
GPR_DEBUG
#define GPR_DEBUG
Definition: include/grpc/impl/codegen/log.h:55
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
grpc_rb_call_credentials_free
static void grpc_rb_call_credentials_free(void *p)
Definition: rb_call_credentials.c:194
grpc_rb_call_credentials_init
static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc)
Definition: rb_call_credentials.c:260
grpc_rb_call_credentials_plugin_get_metadata
static int grpc_rb_call_credentials_plugin_get_metadata(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data, grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t *num_creds_md, grpc_status_code *status, const char **error_details)
Definition: rb_call_credentials.c:160
rb_event_thread.h
grpc_auth_metadata_context
Definition: grpc_security.h:391
grpc_metadata_credentials_plugin::destroy
void(* destroy)(void *state)
Definition: grpc_security.h:455
cb
OPENSSL_EXPORT pem_password_cb * cb
Definition: pem.h:351
grpc_ruby_init
void grpc_ruby_init()
Definition: rb_grpc.c:286
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
grpc_rb_md_ary_convert
void grpc_rb_md_ary_convert(VALUE md_ary_hash, grpc_metadata_array *md_ary)
Definition: rb_call.c:494
grpc_metadata_array_init
GRPCAPI void grpc_metadata_array_init(grpc_metadata_array *array)
Definition: metadata_array.cc:30
grpc_rb_call_credentials::mark
VALUE mark
Definition: rb_call_credentials.c:44


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:59