grpc 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (459) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +29456 -0
  3. data/Rakefile +13 -8
  4. data/etc/roots.pem +5114 -0
  5. data/include/grpc/byte_buffer.h +120 -0
  6. data/include/grpc/byte_buffer_reader.h +58 -0
  7. data/include/grpc/census.h +488 -0
  8. data/include/grpc/compression.h +106 -0
  9. data/include/grpc/grpc.h +732 -0
  10. data/include/grpc/grpc_security.h +374 -0
  11. data/include/grpc/grpc_zookeeper.h +59 -0
  12. data/include/grpc/status.h +163 -0
  13. data/include/grpc/support/alloc.h +72 -0
  14. data/include/grpc/support/atm.h +92 -0
  15. data/include/grpc/support/atm_gcc_atomic.h +72 -0
  16. data/include/grpc/support/atm_gcc_sync.h +87 -0
  17. data/include/grpc/support/atm_win32.h +125 -0
  18. data/include/grpc/support/avl.h +91 -0
  19. data/include/grpc/support/cmdline.h +101 -0
  20. data/include/grpc/support/cpu.h +57 -0
  21. data/include/grpc/support/histogram.h +76 -0
  22. data/include/grpc/support/host_port.h +64 -0
  23. data/include/grpc/support/log.h +108 -0
  24. data/include/grpc/support/log_win32.h +51 -0
  25. data/include/grpc/support/port_platform.h +356 -0
  26. data/include/grpc/support/slice.h +182 -0
  27. data/include/grpc/support/slice_buffer.h +102 -0
  28. data/include/grpc/support/string_util.h +61 -0
  29. data/include/grpc/support/subprocess.h +57 -0
  30. data/include/grpc/support/sync.h +315 -0
  31. data/include/grpc/support/sync_generic.h +55 -0
  32. data/include/grpc/support/sync_posix.h +47 -0
  33. data/include/grpc/support/sync_win32.h +49 -0
  34. data/include/grpc/support/thd.h +91 -0
  35. data/include/grpc/support/time.h +128 -0
  36. data/include/grpc/support/tls.h +77 -0
  37. data/include/grpc/support/tls_gcc.h +56 -0
  38. data/include/grpc/support/tls_msvc.h +56 -0
  39. data/include/grpc/support/tls_pthread.h +60 -0
  40. data/include/grpc/support/useful.h +75 -0
  41. data/src/core/census/aggregation.h +66 -0
  42. data/src/core/census/context.c +46 -0
  43. data/src/core/census/context.h +47 -0
  44. data/src/core/census/grpc_context.c +53 -0
  45. data/src/core/census/grpc_filter.c +184 -0
  46. data/src/core/census/grpc_filter.h +44 -0
  47. data/src/core/census/initialize.c +57 -0
  48. data/src/core/census/operation.c +63 -0
  49. data/src/core/census/rpc_metric_id.h +51 -0
  50. data/src/core/census/tracing.c +45 -0
  51. data/src/core/channel/channel_args.c +209 -0
  52. data/src/core/channel/channel_args.h +88 -0
  53. data/src/core/channel/channel_stack.c +262 -0
  54. data/src/core/channel/channel_stack.h +260 -0
  55. data/src/core/channel/client_channel.c +524 -0
  56. data/src/core/channel/client_channel.h +63 -0
  57. data/src/core/channel/client_uchannel.c +243 -0
  58. data/src/core/channel/client_uchannel.h +60 -0
  59. data/src/core/channel/compress_filter.c +297 -0
  60. data/src/core/channel/compress_filter.h +65 -0
  61. data/src/core/channel/connected_channel.c +167 -0
  62. data/src/core/channel/connected_channel.h +51 -0
  63. data/src/core/channel/context.h +49 -0
  64. data/src/core/channel/http_client_filter.c +248 -0
  65. data/src/core/channel/http_client_filter.h +44 -0
  66. data/src/core/channel/http_server_filter.c +233 -0
  67. data/src/core/channel/http_server_filter.h +42 -0
  68. data/src/core/channel/subchannel_call_holder.c +259 -0
  69. data/src/core/channel/subchannel_call_holder.h +98 -0
  70. data/src/core/client_config/client_config.c +72 -0
  71. data/src/core/client_config/client_config.h +53 -0
  72. data/src/core/client_config/connector.c +54 -0
  73. data/src/core/client_config/connector.h +95 -0
  74. data/src/core/client_config/default_initial_connect_string.c +39 -0
  75. data/src/core/client_config/initial_connect_string.c +53 -0
  76. data/src/core/client_config/initial_connect_string.h +50 -0
  77. data/src/core/client_config/lb_policies/pick_first.c +398 -0
  78. data/src/core/client_config/lb_policies/pick_first.h +43 -0
  79. data/src/core/client_config/lb_policies/round_robin.c +537 -0
  80. data/src/core/client_config/lb_policies/round_robin.h +46 -0
  81. data/src/core/client_config/lb_policy.c +134 -0
  82. data/src/core/client_config/lb_policy.h +143 -0
  83. data/src/core/client_config/lb_policy_factory.c +48 -0
  84. data/src/core/client_config/lb_policy_factory.h +73 -0
  85. data/src/core/client_config/lb_policy_registry.c +88 -0
  86. data/src/core/client_config/lb_policy_registry.h +54 -0
  87. data/src/core/client_config/resolver.c +82 -0
  88. data/src/core/client_config/resolver.h +94 -0
  89. data/src/core/client_config/resolver_factory.c +55 -0
  90. data/src/core/client_config/resolver_factory.h +82 -0
  91. data/src/core/client_config/resolver_registry.c +137 -0
  92. data/src/core/client_config/resolver_registry.h +65 -0
  93. data/src/core/client_config/resolvers/dns_resolver.c +257 -0
  94. data/src/core/client_config/resolvers/dns_resolver.h +42 -0
  95. data/src/core/client_config/resolvers/sockaddr_resolver.c +391 -0
  96. data/src/core/client_config/resolvers/sockaddr_resolver.h +50 -0
  97. data/src/core/client_config/subchannel.c +697 -0
  98. data/src/core/client_config/subchannel.h +165 -0
  99. data/src/core/client_config/subchannel_factory.c +49 -0
  100. data/src/core/client_config/subchannel_factory.h +66 -0
  101. data/src/core/client_config/uri_parser.c +242 -0
  102. data/src/core/client_config/uri_parser.h +51 -0
  103. data/src/core/compression/algorithm.c +166 -0
  104. data/src/core/compression/algorithm_metadata.h +53 -0
  105. data/src/core/compression/message_compress.c +198 -0
  106. data/src/core/compression/message_compress.h +52 -0
  107. data/src/core/debug/trace.c +136 -0
  108. data/src/core/debug/trace.h +43 -0
  109. data/src/core/httpcli/format_request.c +120 -0
  110. data/src/core/httpcli/format_request.h +45 -0
  111. data/src/core/httpcli/httpcli.c +286 -0
  112. data/src/core/httpcli/httpcli.h +162 -0
  113. data/src/core/httpcli/httpcli_security_connector.c +189 -0
  114. data/src/core/httpcli/parser.c +211 -0
  115. data/src/core/httpcli/parser.h +64 -0
  116. data/src/core/iomgr/closure.c +98 -0
  117. data/src/core/iomgr/closure.h +97 -0
  118. data/src/core/iomgr/endpoint.c +67 -0
  119. data/src/core/iomgr/endpoint.h +102 -0
  120. data/src/core/iomgr/endpoint_pair.h +47 -0
  121. data/src/core/iomgr/endpoint_pair_posix.c +82 -0
  122. data/src/core/iomgr/endpoint_pair_windows.c +97 -0
  123. data/src/core/iomgr/exec_ctx.c +72 -0
  124. data/src/core/iomgr/exec_ctx.h +78 -0
  125. data/src/core/iomgr/executor.c +143 -0
  126. data/src/core/iomgr/executor.h +53 -0
  127. data/src/core/iomgr/fd_posix.c +438 -0
  128. data/src/core/iomgr/fd_posix.h +189 -0
  129. data/src/core/iomgr/iocp_windows.c +206 -0
  130. data/src/core/iomgr/iocp_windows.h +56 -0
  131. data/src/core/iomgr/iomgr.c +156 -0
  132. data/src/core/iomgr/iomgr.h +43 -0
  133. data/src/core/iomgr/iomgr_internal.h +58 -0
  134. data/src/core/iomgr/iomgr_posix.c +52 -0
  135. data/src/core/iomgr/iomgr_posix.h +39 -0
  136. data/src/core/iomgr/iomgr_windows.c +73 -0
  137. data/src/core/iomgr/pollset.h +95 -0
  138. data/src/core/iomgr/pollset_multipoller_with_epoll.c +258 -0
  139. data/src/core/iomgr/pollset_multipoller_with_poll_posix.c +227 -0
  140. data/src/core/iomgr/pollset_posix.c +638 -0
  141. data/src/core/iomgr/pollset_posix.h +147 -0
  142. data/src/core/iomgr/pollset_set.h +67 -0
  143. data/src/core/iomgr/pollset_set_posix.c +182 -0
  144. data/src/core/iomgr/pollset_set_posix.h +61 -0
  145. data/src/core/iomgr/pollset_set_windows.c +60 -0
  146. data/src/core/iomgr/pollset_set_windows.h +39 -0
  147. data/src/core/iomgr/pollset_windows.c +248 -0
  148. data/src/core/iomgr/pollset_windows.h +79 -0
  149. data/src/core/iomgr/resolve_address.h +72 -0
  150. data/src/core/iomgr/resolve_address_posix.c +183 -0
  151. data/src/core/iomgr/resolve_address_windows.c +166 -0
  152. data/src/core/iomgr/sockaddr.h +47 -0
  153. data/src/core/iomgr/sockaddr_posix.h +44 -0
  154. data/src/core/iomgr/sockaddr_utils.c +234 -0
  155. data/src/core/iomgr/sockaddr_utils.h +89 -0
  156. data/src/core/iomgr/sockaddr_win32.h +46 -0
  157. data/src/core/iomgr/socket_utils_common_posix.c +208 -0
  158. data/src/core/iomgr/socket_utils_linux.c +51 -0
  159. data/src/core/iomgr/socket_utils_posix.c +70 -0
  160. data/src/core/iomgr/socket_utils_posix.h +113 -0
  161. data/src/core/iomgr/socket_windows.c +98 -0
  162. data/src/core/iomgr/socket_windows.h +111 -0
  163. data/src/core/iomgr/tcp_client.h +53 -0
  164. data/src/core/iomgr/tcp_client_posix.c +304 -0
  165. data/src/core/iomgr/tcp_client_windows.c +221 -0
  166. data/src/core/iomgr/tcp_posix.c +485 -0
  167. data/src/core/iomgr/tcp_posix.h +65 -0
  168. data/src/core/iomgr/tcp_server.h +83 -0
  169. data/src/core/iomgr/tcp_server_posix.c +562 -0
  170. data/src/core/iomgr/tcp_server_windows.c +509 -0
  171. data/src/core/iomgr/tcp_windows.c +406 -0
  172. data/src/core/iomgr/tcp_windows.h +57 -0
  173. data/src/core/iomgr/time_averaged_stats.c +77 -0
  174. data/src/core/iomgr/time_averaged_stats.h +88 -0
  175. data/src/core/iomgr/timer.c +345 -0
  176. data/src/core/iomgr/timer.h +89 -0
  177. data/src/core/iomgr/timer_heap.c +148 -0
  178. data/src/core/iomgr/timer_heap.h +57 -0
  179. data/src/core/iomgr/timer_internal.h +61 -0
  180. data/src/core/iomgr/udp_server.c +439 -0
  181. data/src/core/iomgr/udp_server.h +83 -0
  182. data/src/core/iomgr/wakeup_fd_eventfd.c +85 -0
  183. data/src/core/iomgr/wakeup_fd_nospecial.c +51 -0
  184. data/src/core/iomgr/wakeup_fd_pipe.c +97 -0
  185. data/src/core/iomgr/wakeup_fd_pipe.h +41 -0
  186. data/src/core/iomgr/wakeup_fd_posix.c +72 -0
  187. data/src/core/iomgr/wakeup_fd_posix.h +101 -0
  188. data/src/core/iomgr/workqueue.h +85 -0
  189. data/src/core/iomgr/workqueue_posix.c +143 -0
  190. data/src/core/iomgr/workqueue_posix.h +51 -0
  191. data/src/core/iomgr/workqueue_windows.c +40 -0
  192. data/src/core/iomgr/workqueue_windows.h +37 -0
  193. data/src/core/json/json.c +64 -0
  194. data/src/core/json/json.h +88 -0
  195. data/src/core/json/json_common.h +49 -0
  196. data/src/core/json/json_reader.c +660 -0
  197. data/src/core/json/json_reader.h +160 -0
  198. data/src/core/json/json_string.c +379 -0
  199. data/src/core/json/json_writer.c +260 -0
  200. data/src/core/json/json_writer.h +97 -0
  201. data/src/core/profiling/basic_timers.c +274 -0
  202. data/src/core/profiling/stap_timers.c +65 -0
  203. data/src/core/profiling/timers.h +119 -0
  204. data/src/core/security/auth_filters.h +42 -0
  205. data/src/core/security/base64.c +233 -0
  206. data/src/core/security/base64.h +52 -0
  207. data/src/core/security/client_auth_filter.c +337 -0
  208. data/src/core/security/credentials.c +1273 -0
  209. data/src/core/security/credentials.h +376 -0
  210. data/src/core/security/credentials_metadata.c +101 -0
  211. data/src/core/security/credentials_posix.c +61 -0
  212. data/src/core/security/credentials_win32.c +61 -0
  213. data/src/core/security/google_default_credentials.c +260 -0
  214. data/src/core/security/handshake.c +327 -0
  215. data/src/core/security/handshake.h +50 -0
  216. data/src/core/security/json_token.c +405 -0
  217. data/src/core/security/json_token.h +118 -0
  218. data/src/core/security/jwt_verifier.c +842 -0
  219. data/src/core/security/jwt_verifier.h +136 -0
  220. data/src/core/security/secure_endpoint.c +383 -0
  221. data/src/core/security/secure_endpoint.h +49 -0
  222. data/src/core/security/security_connector.c +756 -0
  223. data/src/core/security/security_connector.h +246 -0
  224. data/src/core/security/security_context.c +342 -0
  225. data/src/core/security/security_context.h +114 -0
  226. data/src/core/security/server_auth_filter.c +264 -0
  227. data/src/core/security/server_secure_chttp2.c +268 -0
  228. data/src/core/statistics/census_interface.h +76 -0
  229. data/src/core/statistics/census_rpc_stats.h +101 -0
  230. data/src/core/support/alloc.c +90 -0
  231. data/src/core/support/avl.c +288 -0
  232. data/src/core/support/block_annotate.h +48 -0
  233. data/src/core/support/cmdline.c +347 -0
  234. data/src/core/support/cpu_iphone.c +49 -0
  235. data/src/core/support/cpu_linux.c +78 -0
  236. data/src/core/support/cpu_posix.c +77 -0
  237. data/src/core/support/cpu_windows.c +47 -0
  238. data/src/core/support/env.h +60 -0
  239. data/src/core/support/env_linux.c +62 -0
  240. data/src/core/support/env_posix.c +57 -0
  241. data/src/core/support/env_win32.c +65 -0
  242. data/src/core/support/file.c +91 -0
  243. data/src/core/support/file.h +63 -0
  244. data/src/core/support/file_posix.c +85 -0
  245. data/src/core/support/file_win32.c +84 -0
  246. data/src/core/support/histogram.c +244 -0
  247. data/src/core/support/host_port.c +110 -0
  248. data/src/core/support/log.c +66 -0
  249. data/src/core/support/log_android.c +87 -0
  250. data/src/core/support/log_linux.c +105 -0
  251. data/src/core/support/log_posix.c +102 -0
  252. data/src/core/support/log_win32.c +125 -0
  253. data/src/core/support/murmur_hash.c +96 -0
  254. data/src/core/support/murmur_hash.h +44 -0
  255. data/src/core/support/slice.c +343 -0
  256. data/src/core/support/slice_buffer.c +282 -0
  257. data/src/core/support/stack_lockfree.c +175 -0
  258. data/src/core/support/stack_lockfree.h +53 -0
  259. data/src/core/support/string.c +296 -0
  260. data/src/core/support/string.h +121 -0
  261. data/src/core/support/string_posix.c +86 -0
  262. data/src/core/support/string_win32.c +109 -0
  263. data/src/core/support/string_win32.h +47 -0
  264. data/src/core/support/subprocess_posix.c +112 -0
  265. data/src/core/support/sync.c +122 -0
  266. data/src/core/support/sync_posix.c +104 -0
  267. data/src/core/support/sync_win32.c +128 -0
  268. data/src/core/support/thd.c +64 -0
  269. data/src/core/support/thd_internal.h +39 -0
  270. data/src/core/support/thd_posix.c +94 -0
  271. data/src/core/support/thd_win32.c +117 -0
  272. data/src/core/support/time.c +304 -0
  273. data/src/core/support/time_posix.c +161 -0
  274. data/src/core/support/time_precise.c +89 -0
  275. data/src/core/support/time_precise.h +42 -0
  276. data/src/core/support/time_win32.c +101 -0
  277. data/src/core/support/tls_pthread.c +45 -0
  278. data/src/core/surface/api_trace.c +36 -0
  279. data/src/core/surface/api_trace.h +65 -0
  280. data/src/core/surface/byte_buffer.c +97 -0
  281. data/src/core/surface/byte_buffer_reader.c +123 -0
  282. data/src/core/surface/call.c +1424 -0
  283. data/src/core/surface/call.h +109 -0
  284. data/src/core/surface/call_details.c +50 -0
  285. data/src/core/surface/call_log_batch.c +118 -0
  286. data/src/core/surface/call_test_only.h +64 -0
  287. data/src/core/surface/channel.c +327 -0
  288. data/src/core/surface/channel.h +74 -0
  289. data/src/core/surface/channel_connectivity.c +220 -0
  290. data/src/core/surface/channel_create.c +235 -0
  291. data/src/core/surface/channel_ping.c +79 -0
  292. data/src/core/surface/completion_queue.c +481 -0
  293. data/src/core/surface/completion_queue.h +91 -0
  294. data/src/core/surface/event_string.c +81 -0
  295. data/src/core/surface/event_string.h +42 -0
  296. data/src/core/surface/init.c +168 -0
  297. data/src/core/surface/init.h +40 -0
  298. data/src/core/surface/init_secure.c +42 -0
  299. data/src/core/surface/lame_client.c +149 -0
  300. data/src/core/surface/metadata_array.c +49 -0
  301. data/src/core/surface/secure_channel_create.c +336 -0
  302. data/src/core/surface/server.c +1343 -0
  303. data/src/core/surface/server.h +67 -0
  304. data/src/core/surface/server_chttp2.c +149 -0
  305. data/src/core/surface/server_create.c +51 -0
  306. data/src/core/surface/surface_trace.h +48 -0
  307. data/src/core/surface/validate_metadata.c +73 -0
  308. data/src/core/surface/version.c +39 -0
  309. data/src/core/transport/byte_stream.c +76 -0
  310. data/src/core/transport/byte_stream.h +88 -0
  311. data/src/core/transport/chttp2/alpn.c +56 -0
  312. data/src/core/transport/chttp2/alpn.h +49 -0
  313. data/src/core/transport/chttp2/bin_encoder.c +285 -0
  314. data/src/core/transport/chttp2/bin_encoder.h +54 -0
  315. data/src/core/transport/chttp2/frame.h +69 -0
  316. data/src/core/transport/chttp2/frame_data.c +245 -0
  317. data/src/core/transport/chttp2/frame_data.h +101 -0
  318. data/src/core/transport/chttp2/frame_goaway.c +193 -0
  319. data/src/core/transport/chttp2/frame_goaway.h +77 -0
  320. data/src/core/transport/chttp2/frame_ping.c +97 -0
  321. data/src/core/transport/chttp2/frame_ping.h +56 -0
  322. data/src/core/transport/chttp2/frame_rst_stream.c +100 -0
  323. data/src/core/transport/chttp2/frame_rst_stream.h +55 -0
  324. data/src/core/transport/chttp2/frame_settings.c +259 -0
  325. data/src/core/transport/chttp2/frame_settings.h +103 -0
  326. data/src/core/transport/chttp2/frame_window_update.c +114 -0
  327. data/src/core/transport/chttp2/frame_window_update.h +58 -0
  328. data/src/core/transport/chttp2/hpack_encoder.c +572 -0
  329. data/src/core/transport/chttp2/hpack_encoder.h +95 -0
  330. data/src/core/transport/chttp2/hpack_parser.c +1449 -0
  331. data/src/core/transport/chttp2/hpack_parser.h +116 -0
  332. data/src/core/transport/chttp2/hpack_table.c +361 -0
  333. data/src/core/transport/chttp2/hpack_table.h +108 -0
  334. data/src/core/transport/chttp2/http2_errors.h +56 -0
  335. data/src/core/transport/chttp2/huffsyms.c +297 -0
  336. data/src/core/transport/chttp2/huffsyms.h +48 -0
  337. data/src/core/transport/chttp2/incoming_metadata.c +96 -0
  338. data/src/core/transport/chttp2/incoming_metadata.h +60 -0
  339. data/src/core/transport/chttp2/internal.h +757 -0
  340. data/src/core/transport/chttp2/parsing.c +866 -0
  341. data/src/core/transport/chttp2/status_conversion.c +109 -0
  342. data/src/core/transport/chttp2/status_conversion.h +50 -0
  343. data/src/core/transport/chttp2/stream_lists.c +401 -0
  344. data/src/core/transport/chttp2/stream_map.c +198 -0
  345. data/src/core/transport/chttp2/stream_map.h +85 -0
  346. data/src/core/transport/chttp2/timeout_encoding.c +185 -0
  347. data/src/core/transport/chttp2/timeout_encoding.h +47 -0
  348. data/src/core/transport/chttp2/varint.c +66 -0
  349. data/src/core/transport/chttp2/varint.h +76 -0
  350. data/src/core/transport/chttp2/writing.c +356 -0
  351. data/src/core/transport/chttp2_transport.c +1692 -0
  352. data/src/core/transport/chttp2_transport.h +51 -0
  353. data/src/core/transport/connectivity_state.c +164 -0
  354. data/src/core/transport/connectivity_state.h +85 -0
  355. data/src/core/transport/metadata.c +690 -0
  356. data/src/core/transport/metadata.h +156 -0
  357. data/src/core/transport/metadata_batch.c +194 -0
  358. data/src/core/transport/metadata_batch.h +125 -0
  359. data/src/core/transport/static_metadata.c +90 -0
  360. data/src/core/transport/static_metadata.h +408 -0
  361. data/src/core/transport/transport.c +183 -0
  362. data/src/core/transport/transport.h +222 -0
  363. data/src/core/transport/transport_impl.h +78 -0
  364. data/src/core/transport/transport_op_string.c +140 -0
  365. data/src/core/tsi/fake_transport_security.c +525 -0
  366. data/src/core/tsi/fake_transport_security.h +61 -0
  367. data/src/core/tsi/ssl_transport_security.c +1467 -0
  368. data/src/core/tsi/ssl_transport_security.h +173 -0
  369. data/src/core/tsi/transport_security.c +284 -0
  370. data/src/core/tsi/transport_security.h +111 -0
  371. data/src/core/tsi/transport_security_interface.h +344 -0
  372. data/{bin → src/ruby/bin}/apis/google/protobuf/empty.rb +0 -0
  373. data/{bin → src/ruby/bin}/apis/pubsub_demo.rb +7 -15
  374. data/{bin → src/ruby/bin}/apis/tech/pubsub/proto/pubsub.rb +0 -0
  375. data/{bin → src/ruby/bin}/apis/tech/pubsub/proto/pubsub_services.rb +0 -0
  376. data/{bin → src/ruby/bin}/grpc_ruby_interop_client +0 -0
  377. data/{bin → src/ruby/bin}/grpc_ruby_interop_server +0 -0
  378. data/{bin → src/ruby/bin}/interop/interop_client.rb +0 -0
  379. data/{bin → src/ruby/bin}/interop/interop_server.rb +0 -0
  380. data/src/ruby/bin/math.rb +32 -0
  381. data/{bin → src/ruby/bin}/math_client.rb +1 -1
  382. data/{bin → src/ruby/bin}/math_server.rb +1 -1
  383. data/src/ruby/bin/math_services.rb +27 -0
  384. data/{bin → src/ruby/bin}/noproto_client.rb +1 -1
  385. data/{bin → src/ruby/bin}/noproto_server.rb +1 -1
  386. data/{ext → src/ruby/ext}/grpc/extconf.rb +24 -40
  387. data/{ext → src/ruby/ext}/grpc/rb_byte_buffer.c +0 -0
  388. data/{ext → src/ruby/ext}/grpc/rb_byte_buffer.h +0 -0
  389. data/{ext → src/ruby/ext}/grpc/rb_call.c +80 -18
  390. data/{ext → src/ruby/ext}/grpc/rb_call.h +6 -0
  391. data/src/ruby/ext/grpc/rb_call_credentials.c +315 -0
  392. data/src/ruby/ext/grpc/rb_call_credentials.h +46 -0
  393. data/{ext → src/ruby/ext}/grpc/rb_channel.c +19 -7
  394. data/{ext → src/ruby/ext}/grpc/rb_channel.h +0 -0
  395. data/{ext → src/ruby/ext}/grpc/rb_channel_args.c +2 -0
  396. data/{ext → src/ruby/ext}/grpc/rb_channel_args.h +0 -0
  397. data/src/ruby/ext/grpc/rb_channel_credentials.c +266 -0
  398. data/{ext/grpc/rb_credentials.h → src/ruby/ext/grpc/rb_channel_credentials.h} +3 -3
  399. data/{ext → src/ruby/ext}/grpc/rb_completion_queue.c +3 -1
  400. data/{ext → src/ruby/ext}/grpc/rb_completion_queue.h +0 -0
  401. data/src/ruby/ext/grpc/rb_event_thread.c +153 -0
  402. data/src/ruby/ext/grpc/rb_event_thread.h +37 -0
  403. data/{ext → src/ruby/ext}/grpc/rb_grpc.c +25 -5
  404. data/{ext → src/ruby/ext}/grpc/rb_grpc.h +0 -0
  405. data/{ext → src/ruby/ext}/grpc/rb_server.c +4 -1
  406. data/{ext → src/ruby/ext}/grpc/rb_server.h +0 -0
  407. data/{ext → src/ruby/ext}/grpc/rb_server_credentials.c +2 -0
  408. data/{ext → src/ruby/ext}/grpc/rb_server_credentials.h +0 -0
  409. data/{lib → src/ruby/lib}/grpc.rb +6 -1
  410. data/{lib → src/ruby/lib}/grpc/core/time_consts.rb +0 -0
  411. data/{lib → src/ruby/lib}/grpc/errors.rb +0 -0
  412. data/{lib → src/ruby/lib}/grpc/generic/active_call.rb +4 -6
  413. data/{lib → src/ruby/lib}/grpc/generic/bidi_call.rb +16 -4
  414. data/{lib → src/ruby/lib}/grpc/generic/client_stub.rb +42 -52
  415. data/{lib → src/ruby/lib}/grpc/generic/rpc_desc.rb +0 -0
  416. data/{lib → src/ruby/lib}/grpc/generic/rpc_server.rb +15 -8
  417. data/{lib → src/ruby/lib}/grpc/generic/service.rb +4 -2
  418. data/src/ruby/lib/grpc/grpc.so +0 -0
  419. data/{lib → src/ruby/lib}/grpc/logconfig.rb +0 -0
  420. data/{lib → src/ruby/lib}/grpc/notifier.rb +0 -0
  421. data/{lib → src/ruby/lib}/grpc/version.rb +2 -2
  422. data/src/ruby/pb/README.md +42 -0
  423. data/src/ruby/pb/generate_proto_ruby.sh +51 -0
  424. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  425. data/src/ruby/pb/grpc/health/v1alpha/health.rb +29 -0
  426. data/src/ruby/pb/grpc/health/v1alpha/health_services.rb +28 -0
  427. data/src/ruby/pb/test/client.rb +469 -0
  428. data/src/ruby/pb/test/proto/empty.rb +15 -0
  429. data/src/ruby/pb/test/proto/messages.rb +80 -0
  430. data/src/ruby/pb/test/proto/test.rb +14 -0
  431. data/src/ruby/pb/test/proto/test_services.rb +64 -0
  432. data/src/ruby/pb/test/server.rb +253 -0
  433. data/{bin/math_services.rb → src/ruby/spec/call_credentials_spec.rb} +19 -18
  434. data/{spec → src/ruby/spec}/call_spec.rb +10 -1
  435. data/{spec/credentials_spec.rb → src/ruby/spec/channel_credentials_spec.rb} +38 -12
  436. data/{spec → src/ruby/spec}/channel_spec.rb +14 -9
  437. data/{spec → src/ruby/spec}/client_server_spec.rb +31 -2
  438. data/{spec → src/ruby/spec}/completion_queue_spec.rb +0 -0
  439. data/{spec → src/ruby/spec}/generic/active_call_spec.rb +2 -1
  440. data/{spec → src/ruby/spec}/generic/client_stub_spec.rb +27 -67
  441. data/{spec → src/ruby/spec}/generic/rpc_desc_spec.rb +0 -0
  442. data/{spec → src/ruby/spec}/generic/rpc_server_pool_spec.rb +0 -0
  443. data/{spec → src/ruby/spec}/generic/rpc_server_spec.rb +12 -46
  444. data/{spec → src/ruby/spec}/generic/service_spec.rb +6 -3
  445. data/{spec → src/ruby/spec}/pb/health/checker_spec.rb +8 -8
  446. data/{spec → src/ruby/spec}/server_credentials_spec.rb +0 -0
  447. data/{spec → src/ruby/spec}/server_spec.rb +0 -0
  448. data/{spec → src/ruby/spec}/spec_helper.rb +0 -0
  449. data/{spec → src/ruby/spec}/testdata/README +0 -0
  450. data/{spec → src/ruby/spec}/testdata/ca.pem +0 -0
  451. data/{spec → src/ruby/spec}/testdata/server1.key +0 -0
  452. data/src/ruby/spec/testdata/server1.pem +16 -0
  453. data/{spec → src/ruby/spec}/time_consts_spec.rb +0 -0
  454. metadata +496 -97
  455. data/bin/math.proto +0 -80
  456. data/bin/math.rb +0 -61
  457. data/ext/grpc/rb_credentials.c +0 -294
  458. data/lib/grpc/grpc.so +0 -0
  459. data/spec/testdata/server1.pem +0 -16
@@ -0,0 +1,52 @@
1
+ /*
2
+ *
3
+ * Copyright 2015, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #ifndef GRPC_INTERNAL_CORE_SECURITY_BASE64_H
35
+ #define GRPC_INTERNAL_CORE_SECURITY_BASE64_H
36
+
37
+ #include <grpc/support/slice.h>
38
+
39
+ /* Encodes data using base64. It is the caller's responsability to free
40
+ the returned char * using gpr_free. Returns NULL on NULL input. */
41
+ char *grpc_base64_encode(const void *data, size_t data_size, int url_safe,
42
+ int multiline);
43
+
44
+ /* Decodes data according to the base64 specification. Returns an empty
45
+ slice in case of failure. */
46
+ gpr_slice grpc_base64_decode(const char *b64, int url_safe);
47
+
48
+ /* Same as above except that the length is provided by the caller. */
49
+ gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
50
+ int url_safe);
51
+
52
+ #endif /* GRPC_INTERNAL_CORE_SECURITY_BASE64_H */
@@ -0,0 +1,337 @@
1
+ /*
2
+ *
3
+ * Copyright 2015, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #include "src/core/security/auth_filters.h"
35
+
36
+ #include <string.h>
37
+
38
+ #include <grpc/support/alloc.h>
39
+ #include <grpc/support/log.h>
40
+ #include <grpc/support/string_util.h>
41
+
42
+ #include "src/core/channel/channel_stack.h"
43
+ #include "src/core/security/credentials.h"
44
+ #include "src/core/security/security_connector.h"
45
+ #include "src/core/security/security_context.h"
46
+ #include "src/core/support/string.h"
47
+ #include "src/core/surface/call.h"
48
+ #include "src/core/transport/static_metadata.h"
49
+
50
+ #define MAX_CREDENTIALS_METADATA_COUNT 4
51
+
52
+ /* We can have a per-call credentials. */
53
+ typedef struct {
54
+ grpc_call_credentials *creds;
55
+ grpc_mdstr *host;
56
+ grpc_mdstr *method;
57
+ /* pollset bound to this call; if we need to make external
58
+ network requests, they should be done under this pollset
59
+ so that work can progress when this call wants work to
60
+ progress */
61
+ grpc_pollset *pollset;
62
+ grpc_transport_stream_op op;
63
+ gpr_uint8 security_context_set;
64
+ grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
65
+ grpc_auth_metadata_context auth_md_context;
66
+ } call_data;
67
+
68
+ /* We can have a per-channel credentials. */
69
+ typedef struct {
70
+ grpc_channel_security_connector *security_connector;
71
+ grpc_auth_context *auth_context;
72
+ } channel_data;
73
+
74
+ static void reset_auth_metadata_context(
75
+ grpc_auth_metadata_context *auth_md_context) {
76
+ if (auth_md_context->service_url != NULL) {
77
+ gpr_free((char *)auth_md_context->service_url);
78
+ auth_md_context->service_url = NULL;
79
+ }
80
+ if (auth_md_context->method_name != NULL) {
81
+ gpr_free((char *)auth_md_context->method_name);
82
+ auth_md_context->method_name = NULL;
83
+ }
84
+ GRPC_AUTH_CONTEXT_UNREF(
85
+ (grpc_auth_context *)auth_md_context->channel_auth_context,
86
+ "grpc_auth_metadata_context");
87
+ auth_md_context->channel_auth_context = NULL;
88
+ }
89
+
90
+ static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
91
+ grpc_status_code status, const char *error_msg) {
92
+ call_data *calld = elem->call_data;
93
+ gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg);
94
+ grpc_transport_stream_op_add_cancellation(&calld->op, status);
95
+ grpc_call_next_op(exec_ctx, elem, &calld->op);
96
+ }
97
+
98
+ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
99
+ grpc_credentials_md *md_elems,
100
+ size_t num_md,
101
+ grpc_credentials_status status) {
102
+ grpc_call_element *elem = (grpc_call_element *)user_data;
103
+ call_data *calld = elem->call_data;
104
+ grpc_transport_stream_op *op = &calld->op;
105
+ grpc_metadata_batch *mdb;
106
+ size_t i;
107
+ reset_auth_metadata_context(&calld->auth_md_context);
108
+ if (status != GRPC_CREDENTIALS_OK) {
109
+ bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
110
+ "Credentials failed to get metadata.");
111
+ return;
112
+ }
113
+ GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
114
+ GPR_ASSERT(op->send_initial_metadata != NULL);
115
+ mdb = op->send_initial_metadata;
116
+ for (i = 0; i < num_md; i++) {
117
+ grpc_metadata_batch_add_tail(
118
+ mdb, &calld->md_links[i],
119
+ grpc_mdelem_from_slices(gpr_slice_ref(md_elems[i].key),
120
+ gpr_slice_ref(md_elems[i].value)));
121
+ }
122
+ grpc_call_next_op(exec_ctx, elem, op);
123
+ }
124
+
125
+ void build_auth_metadata_context(grpc_security_connector *sc,
126
+ grpc_auth_context *auth_context,
127
+ call_data *calld) {
128
+ char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method));
129
+ char *last_slash = strrchr(service, '/');
130
+ char *method_name = NULL;
131
+ char *service_url = NULL;
132
+ reset_auth_metadata_context(&calld->auth_md_context);
133
+ if (last_slash == NULL) {
134
+ gpr_log(GPR_ERROR, "No '/' found in fully qualified method name");
135
+ service[0] = '\0';
136
+ } else if (last_slash == service) {
137
+ /* No service part in fully qualified method name: will just be "/". */
138
+ service[1] = '\0';
139
+ } else {
140
+ *last_slash = '\0';
141
+ method_name = gpr_strdup(last_slash + 1);
142
+ }
143
+ if (method_name == NULL) method_name = gpr_strdup("");
144
+ gpr_asprintf(&service_url, "%s://%s%s",
145
+ sc->url_scheme == NULL ? "" : sc->url_scheme,
146
+ grpc_mdstr_as_c_string(calld->host), service);
147
+ calld->auth_md_context.service_url = service_url;
148
+ calld->auth_md_context.method_name = method_name;
149
+ calld->auth_md_context.channel_auth_context =
150
+ GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context");
151
+ gpr_free(service);
152
+ }
153
+
154
+ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
155
+ grpc_call_element *elem,
156
+ grpc_transport_stream_op *op) {
157
+ call_data *calld = elem->call_data;
158
+ channel_data *chand = elem->channel_data;
159
+ grpc_client_security_context *ctx =
160
+ (grpc_client_security_context *)op->context[GRPC_CONTEXT_SECURITY].value;
161
+ grpc_call_credentials *channel_call_creds =
162
+ chand->security_connector->request_metadata_creds;
163
+ int call_creds_has_md = (ctx != NULL) && (ctx->creds != NULL);
164
+
165
+ if (channel_call_creds == NULL && !call_creds_has_md) {
166
+ /* Skip sending metadata altogether. */
167
+ grpc_call_next_op(exec_ctx, elem, op);
168
+ return;
169
+ }
170
+
171
+ if (channel_call_creds != NULL && call_creds_has_md) {
172
+ calld->creds = grpc_composite_call_credentials_create(channel_call_creds,
173
+ ctx->creds, NULL);
174
+ if (calld->creds == NULL) {
175
+ bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT,
176
+ "Incompatible credentials set on channel and call.");
177
+ return;
178
+ }
179
+ } else {
180
+ calld->creds = grpc_call_credentials_ref(
181
+ call_creds_has_md ? ctx->creds : channel_call_creds);
182
+ }
183
+
184
+ build_auth_metadata_context(&chand->security_connector->base,
185
+ chand->auth_context, calld);
186
+ calld->op = *op; /* Copy op (originates from the caller's stack). */
187
+ GPR_ASSERT(calld->pollset);
188
+ grpc_call_credentials_get_request_metadata(
189
+ exec_ctx, calld->creds, calld->pollset, calld->auth_md_context,
190
+ on_credentials_metadata, elem);
191
+ }
192
+
193
+ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
194
+ grpc_security_status status) {
195
+ grpc_call_element *elem = (grpc_call_element *)user_data;
196
+ call_data *calld = elem->call_data;
197
+
198
+ if (status == GRPC_SECURITY_OK) {
199
+ send_security_metadata(exec_ctx, elem, &calld->op);
200
+ } else {
201
+ char *error_msg;
202
+ gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
203
+ grpc_mdstr_as_c_string(calld->host));
204
+ bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT, error_msg);
205
+ gpr_free(error_msg);
206
+ }
207
+ }
208
+
209
+ /* Called either:
210
+ - in response to an API call (or similar) from above, to send something
211
+ - a network event (or similar) from below, to receive something
212
+ op contains type and call direction information, in addition to the data
213
+ that is being sent or received. */
214
+ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
215
+ grpc_call_element *elem,
216
+ grpc_transport_stream_op *op) {
217
+ /* grab pointers to our data from the call element */
218
+ call_data *calld = elem->call_data;
219
+ channel_data *chand = elem->channel_data;
220
+ grpc_linked_mdelem *l;
221
+ grpc_client_security_context *sec_ctx = NULL;
222
+
223
+ if (calld->security_context_set == 0 &&
224
+ op->cancel_with_status == GRPC_STATUS_OK) {
225
+ calld->security_context_set = 1;
226
+ GPR_ASSERT(op->context);
227
+ if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) {
228
+ op->context[GRPC_CONTEXT_SECURITY].value =
229
+ grpc_client_security_context_create();
230
+ op->context[GRPC_CONTEXT_SECURITY].destroy =
231
+ grpc_client_security_context_destroy;
232
+ }
233
+ sec_ctx = op->context[GRPC_CONTEXT_SECURITY].value;
234
+ GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
235
+ sec_ctx->auth_context = GRPC_AUTH_CONTEXT_REF(
236
+ chand->auth_context, "client_auth_filter");
237
+ }
238
+
239
+ if (op->send_initial_metadata != NULL) {
240
+ for (l = op->send_initial_metadata->list.head; l != NULL; l = l->next) {
241
+ grpc_mdelem *md = l->md;
242
+ /* Pointer comparison is OK for md_elems created from the same context.
243
+ */
244
+ if (md->key == GRPC_MDSTR_AUTHORITY) {
245
+ if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host);
246
+ calld->host = GRPC_MDSTR_REF(md->value);
247
+ } else if (md->key == GRPC_MDSTR_PATH) {
248
+ if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method);
249
+ calld->method = GRPC_MDSTR_REF(md->value);
250
+ }
251
+ }
252
+ if (calld->host != NULL) {
253
+ const char *call_host = grpc_mdstr_as_c_string(calld->host);
254
+ calld->op = *op; /* Copy op (originates from the caller's stack). */
255
+ grpc_channel_security_connector_check_call_host(
256
+ exec_ctx, chand->security_connector, call_host, chand->auth_context,
257
+ on_host_checked, elem);
258
+ return; /* early exit */
259
+ }
260
+ }
261
+
262
+ /* pass control down the stack */
263
+ grpc_call_next_op(exec_ctx, elem, op);
264
+ }
265
+
266
+ /* Constructor for call_data */
267
+ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
268
+ grpc_call_element_args *args) {
269
+ call_data *calld = elem->call_data;
270
+ memset(calld, 0, sizeof(*calld));
271
+ }
272
+
273
+ static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
274
+ grpc_pollset *pollset) {
275
+ call_data *calld = elem->call_data;
276
+ calld->pollset = pollset;
277
+ }
278
+
279
+ /* Destructor for call_data */
280
+ static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
281
+ grpc_call_element *elem) {
282
+ call_data *calld = elem->call_data;
283
+ grpc_call_credentials_unref(calld->creds);
284
+ if (calld->host != NULL) {
285
+ GRPC_MDSTR_UNREF(calld->host);
286
+ }
287
+ if (calld->method != NULL) {
288
+ GRPC_MDSTR_UNREF(calld->method);
289
+ }
290
+ reset_auth_metadata_context(&calld->auth_md_context);
291
+ }
292
+
293
+ /* Constructor for channel_data */
294
+ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
295
+ grpc_channel_element *elem,
296
+ grpc_channel_element_args *args) {
297
+ grpc_security_connector *sc =
298
+ grpc_find_security_connector_in_args(args->channel_args);
299
+ grpc_auth_context *auth_context =
300
+ grpc_find_auth_context_in_args(args->channel_args);
301
+
302
+ /* grab pointers to our data from the channel element */
303
+ channel_data *chand = elem->channel_data;
304
+
305
+ /* The first and the last filters tend to be implemented differently to
306
+ handle the case that there's no 'next' filter to call on the up or down
307
+ path */
308
+ GPR_ASSERT(!args->is_last);
309
+ GPR_ASSERT(sc != NULL);
310
+ GPR_ASSERT(auth_context != NULL);
311
+
312
+ /* initialize members */
313
+ GPR_ASSERT(sc->is_client_side);
314
+ chand->security_connector =
315
+ (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(
316
+ sc, "client_auth_filter");
317
+ chand->auth_context =
318
+ GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter");
319
+ }
320
+
321
+ /* Destructor for channel data */
322
+ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
323
+ grpc_channel_element *elem) {
324
+ /* grab pointers to our data from the channel element */
325
+ channel_data *chand = elem->channel_data;
326
+ grpc_channel_security_connector *sc = chand->security_connector;
327
+ if (sc != NULL) {
328
+ GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter");
329
+ }
330
+ GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter");
331
+ }
332
+
333
+ const grpc_channel_filter grpc_client_auth_filter = {
334
+ auth_start_transport_op, grpc_channel_next_op, sizeof(call_data),
335
+ init_call_elem, set_pollset, destroy_call_elem, sizeof(channel_data),
336
+ init_channel_elem, destroy_channel_elem, grpc_call_next_get_peer,
337
+ "client-auth"};
@@ -0,0 +1,1273 @@
1
+ /*
2
+ *
3
+ * Copyright 2015, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #include "src/core/security/credentials.h"
35
+
36
+ #include <stdio.h>
37
+ #include <string.h>
38
+
39
+ #include "src/core/channel/channel_args.h"
40
+ #include "src/core/channel/http_client_filter.h"
41
+ #include "src/core/httpcli/httpcli.h"
42
+ #include "src/core/iomgr/executor.h"
43
+ #include "src/core/json/json.h"
44
+ #include "src/core/support/string.h"
45
+ #include "src/core/surface/api_trace.h"
46
+
47
+ #include <grpc/support/alloc.h>
48
+ #include <grpc/support/log.h>
49
+ #include <grpc/support/string_util.h>
50
+ #include <grpc/support/sync.h>
51
+ #include <grpc/support/time.h>
52
+
53
+ /* -- Common. -- */
54
+
55
+ struct grpc_credentials_metadata_request {
56
+ grpc_call_credentials *creds;
57
+ grpc_credentials_metadata_cb cb;
58
+ void *user_data;
59
+ };
60
+
61
+ static grpc_credentials_metadata_request *
62
+ grpc_credentials_metadata_request_create(grpc_call_credentials *creds,
63
+ grpc_credentials_metadata_cb cb,
64
+ void *user_data) {
65
+ grpc_credentials_metadata_request *r =
66
+ gpr_malloc(sizeof(grpc_credentials_metadata_request));
67
+ r->creds = grpc_call_credentials_ref(creds);
68
+ r->cb = cb;
69
+ r->user_data = user_data;
70
+ return r;
71
+ }
72
+
73
+ static void grpc_credentials_metadata_request_destroy(
74
+ grpc_credentials_metadata_request *r) {
75
+ grpc_call_credentials_unref(r->creds);
76
+ gpr_free(r);
77
+ }
78
+
79
+ grpc_channel_credentials *grpc_channel_credentials_ref(
80
+ grpc_channel_credentials *creds) {
81
+ if (creds == NULL) return NULL;
82
+ gpr_ref(&creds->refcount);
83
+ return creds;
84
+ }
85
+
86
+ void grpc_channel_credentials_unref(grpc_channel_credentials *creds) {
87
+ if (creds == NULL) return;
88
+ if (gpr_unref(&creds->refcount)) {
89
+ if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
90
+ gpr_free(creds);
91
+ }
92
+ }
93
+
94
+ void grpc_channel_credentials_release(grpc_channel_credentials *creds) {
95
+ GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds));
96
+ grpc_channel_credentials_unref(creds);
97
+ }
98
+
99
+ grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) {
100
+ if (creds == NULL) return NULL;
101
+ gpr_ref(&creds->refcount);
102
+ return creds;
103
+ }
104
+
105
+ void grpc_call_credentials_unref(grpc_call_credentials *creds) {
106
+ if (creds == NULL) return;
107
+ if (gpr_unref(&creds->refcount)) {
108
+ if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
109
+ gpr_free(creds);
110
+ }
111
+ }
112
+
113
+ void grpc_call_credentials_release(grpc_call_credentials *creds) {
114
+ GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds));
115
+ grpc_call_credentials_unref(creds);
116
+ }
117
+
118
+ void grpc_call_credentials_get_request_metadata(
119
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
120
+ grpc_pollset *pollset, grpc_auth_metadata_context context,
121
+ grpc_credentials_metadata_cb cb, void *user_data) {
122
+ if (creds == NULL || creds->vtable->get_request_metadata == NULL) {
123
+ if (cb != NULL) {
124
+ cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
125
+ }
126
+ return;
127
+ }
128
+ creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb,
129
+ user_data);
130
+ }
131
+
132
+ grpc_security_status grpc_channel_credentials_create_security_connector(
133
+ grpc_channel_credentials *channel_creds, const char *target,
134
+ const grpc_channel_args *args, grpc_channel_security_connector **sc,
135
+ grpc_channel_args **new_args) {
136
+ *new_args = NULL;
137
+ if (channel_creds == NULL) {
138
+ return GRPC_SECURITY_ERROR;
139
+ }
140
+ GPR_ASSERT(channel_creds->vtable->create_security_connector != NULL);
141
+ return channel_creds->vtable->create_security_connector(
142
+ channel_creds, NULL, target, args, sc, new_args);
143
+ }
144
+
145
+ grpc_server_credentials *grpc_server_credentials_ref(
146
+ grpc_server_credentials *creds) {
147
+ if (creds == NULL) return NULL;
148
+ gpr_ref(&creds->refcount);
149
+ return creds;
150
+ }
151
+
152
+ void grpc_server_credentials_unref(grpc_server_credentials *creds) {
153
+ if (creds == NULL) return;
154
+ if (gpr_unref(&creds->refcount)) {
155
+ if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
156
+ if (creds->processor.destroy != NULL && creds->processor.state != NULL) {
157
+ creds->processor.destroy(creds->processor.state);
158
+ }
159
+ gpr_free(creds);
160
+ }
161
+ }
162
+
163
+ void grpc_server_credentials_release(grpc_server_credentials *creds) {
164
+ GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds));
165
+ grpc_server_credentials_unref(creds);
166
+ }
167
+
168
+ grpc_security_status grpc_server_credentials_create_security_connector(
169
+ grpc_server_credentials *creds, grpc_security_connector **sc) {
170
+ if (creds == NULL || creds->vtable->create_security_connector == NULL) {
171
+ gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
172
+ return GRPC_SECURITY_ERROR;
173
+ }
174
+ return creds->vtable->create_security_connector(creds, sc);
175
+ }
176
+
177
+ void grpc_server_credentials_set_auth_metadata_processor(
178
+ grpc_server_credentials *creds, grpc_auth_metadata_processor processor) {
179
+ GRPC_API_TRACE(
180
+ "grpc_server_credentials_set_auth_metadata_processor("
181
+ "creds=%p, "
182
+ "processor=grpc_auth_metadata_processor { process: %lx, state: %p })",
183
+ 3, (creds, (unsigned long)processor.process, processor.state));
184
+ if (creds == NULL) return;
185
+ if (creds->processor.destroy != NULL && creds->processor.state != NULL) {
186
+ creds->processor.destroy(creds->processor.state);
187
+ }
188
+ creds->processor = processor;
189
+ }
190
+
191
+ static void server_credentials_pointer_arg_destroy(void *p) {
192
+ grpc_server_credentials_unref(p);
193
+ }
194
+
195
+ static void *server_credentials_pointer_arg_copy(void *p) {
196
+ return grpc_server_credentials_ref(p);
197
+ }
198
+
199
+ grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) {
200
+ grpc_arg arg;
201
+ memset(&arg, 0, sizeof(grpc_arg));
202
+ arg.type = GRPC_ARG_POINTER;
203
+ arg.key = GRPC_SERVER_CREDENTIALS_ARG;
204
+ arg.value.pointer.p = p;
205
+ arg.value.pointer.copy = server_credentials_pointer_arg_copy;
206
+ arg.value.pointer.destroy = server_credentials_pointer_arg_destroy;
207
+ return arg;
208
+ }
209
+
210
+ grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg) {
211
+ if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL;
212
+ if (arg->type != GRPC_ARG_POINTER) {
213
+ gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
214
+ GRPC_SERVER_CREDENTIALS_ARG);
215
+ return NULL;
216
+ }
217
+ return arg->value.pointer.p;
218
+ }
219
+
220
+ grpc_server_credentials *grpc_find_server_credentials_in_args(
221
+ const grpc_channel_args *args) {
222
+ size_t i;
223
+ if (args == NULL) return NULL;
224
+ for (i = 0; i < args->num_args; i++) {
225
+ grpc_server_credentials *p =
226
+ grpc_server_credentials_from_arg(&args->args[i]);
227
+ if (p != NULL) return p;
228
+ }
229
+ return NULL;
230
+ }
231
+
232
+ /* -- Ssl credentials. -- */
233
+
234
+ static void ssl_destruct(grpc_channel_credentials *creds) {
235
+ grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
236
+ if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
237
+ if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
238
+ if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain);
239
+ }
240
+
241
+ static void ssl_server_destruct(grpc_server_credentials *creds) {
242
+ grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
243
+ size_t i;
244
+ for (i = 0; i < c->config.num_key_cert_pairs; i++) {
245
+ if (c->config.pem_private_keys[i] != NULL) {
246
+ gpr_free(c->config.pem_private_keys[i]);
247
+ }
248
+ if (c->config.pem_cert_chains[i] != NULL) {
249
+ gpr_free(c->config.pem_cert_chains[i]);
250
+ }
251
+ }
252
+ if (c->config.pem_private_keys != NULL) gpr_free(c->config.pem_private_keys);
253
+ if (c->config.pem_private_keys_sizes != NULL) {
254
+ gpr_free(c->config.pem_private_keys_sizes);
255
+ }
256
+ if (c->config.pem_cert_chains != NULL) gpr_free(c->config.pem_cert_chains);
257
+ if (c->config.pem_cert_chains_sizes != NULL) {
258
+ gpr_free(c->config.pem_cert_chains_sizes);
259
+ }
260
+ if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
261
+ }
262
+
263
+ static grpc_security_status ssl_create_security_connector(
264
+ grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
265
+ const char *target, const grpc_channel_args *args,
266
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
267
+ grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
268
+ grpc_security_status status = GRPC_SECURITY_OK;
269
+ size_t i = 0;
270
+ const char *overridden_target_name = NULL;
271
+ grpc_arg new_arg;
272
+
273
+ for (i = 0; args && i < args->num_args; i++) {
274
+ grpc_arg *arg = &args->args[i];
275
+ if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
276
+ arg->type == GRPC_ARG_STRING) {
277
+ overridden_target_name = arg->value.string;
278
+ break;
279
+ }
280
+ }
281
+ status = grpc_ssl_channel_security_connector_create(
282
+ call_creds, &c->config, target, overridden_target_name, sc);
283
+ if (status != GRPC_SECURITY_OK) {
284
+ return status;
285
+ }
286
+ new_arg.type = GRPC_ARG_STRING;
287
+ new_arg.key = GRPC_ARG_HTTP2_SCHEME;
288
+ new_arg.value.string = "https";
289
+ *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
290
+ return status;
291
+ }
292
+
293
+ static grpc_security_status ssl_server_create_security_connector(
294
+ grpc_server_credentials *creds, grpc_security_connector **sc) {
295
+ grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
296
+ return grpc_ssl_server_security_connector_create(&c->config, sc);
297
+ }
298
+
299
+ static grpc_channel_credentials_vtable ssl_vtable = {
300
+ ssl_destruct, ssl_create_security_connector};
301
+
302
+ static grpc_server_credentials_vtable ssl_server_vtable = {
303
+ ssl_server_destruct, ssl_server_create_security_connector};
304
+
305
+ static void ssl_copy_key_material(const char *input, unsigned char **output,
306
+ size_t *output_size) {
307
+ *output_size = strlen(input);
308
+ *output = gpr_malloc(*output_size);
309
+ memcpy(*output, input, *output_size);
310
+ }
311
+
312
+ static void ssl_build_config(const char *pem_root_certs,
313
+ grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
314
+ grpc_ssl_config *config) {
315
+ if (pem_root_certs != NULL) {
316
+ ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
317
+ &config->pem_root_certs_size);
318
+ }
319
+ if (pem_key_cert_pair != NULL) {
320
+ GPR_ASSERT(pem_key_cert_pair->private_key != NULL);
321
+ GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL);
322
+ ssl_copy_key_material(pem_key_cert_pair->private_key,
323
+ &config->pem_private_key,
324
+ &config->pem_private_key_size);
325
+ ssl_copy_key_material(pem_key_cert_pair->cert_chain,
326
+ &config->pem_cert_chain,
327
+ &config->pem_cert_chain_size);
328
+ }
329
+ }
330
+
331
+ static void ssl_build_server_config(
332
+ const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
333
+ size_t num_key_cert_pairs, int force_client_auth,
334
+ grpc_ssl_server_config *config) {
335
+ size_t i;
336
+ config->force_client_auth = force_client_auth;
337
+ if (pem_root_certs != NULL) {
338
+ ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
339
+ &config->pem_root_certs_size);
340
+ }
341
+ if (num_key_cert_pairs > 0) {
342
+ GPR_ASSERT(pem_key_cert_pairs != NULL);
343
+ config->pem_private_keys =
344
+ gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
345
+ config->pem_cert_chains =
346
+ gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
347
+ config->pem_private_keys_sizes =
348
+ gpr_malloc(num_key_cert_pairs * sizeof(size_t));
349
+ config->pem_cert_chains_sizes =
350
+ gpr_malloc(num_key_cert_pairs * sizeof(size_t));
351
+ }
352
+ config->num_key_cert_pairs = num_key_cert_pairs;
353
+ for (i = 0; i < num_key_cert_pairs; i++) {
354
+ GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
355
+ GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
356
+ ssl_copy_key_material(pem_key_cert_pairs[i].private_key,
357
+ &config->pem_private_keys[i],
358
+ &config->pem_private_keys_sizes[i]);
359
+ ssl_copy_key_material(pem_key_cert_pairs[i].cert_chain,
360
+ &config->pem_cert_chains[i],
361
+ &config->pem_cert_chains_sizes[i]);
362
+ }
363
+ }
364
+
365
+ grpc_channel_credentials *grpc_ssl_credentials_create(
366
+ const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
367
+ void *reserved) {
368
+ grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials));
369
+ GRPC_API_TRACE(
370
+ "grpc_ssl_credentials_create(pem_root_certs=%s, "
371
+ "pem_key_cert_pair=%p, "
372
+ "reserved=%p)",
373
+ 3, (pem_root_certs, pem_key_cert_pair, reserved));
374
+ GPR_ASSERT(reserved == NULL);
375
+ memset(c, 0, sizeof(grpc_ssl_credentials));
376
+ c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
377
+ c->base.vtable = &ssl_vtable;
378
+ gpr_ref_init(&c->base.refcount, 1);
379
+ ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config);
380
+ return &c->base;
381
+ }
382
+
383
+ grpc_server_credentials *grpc_ssl_server_credentials_create(
384
+ const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
385
+ size_t num_key_cert_pairs, int force_client_auth, void *reserved) {
386
+ grpc_ssl_server_credentials *c =
387
+ gpr_malloc(sizeof(grpc_ssl_server_credentials));
388
+ GRPC_API_TRACE(
389
+ "grpc_ssl_server_credentials_create("
390
+ "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, "
391
+ "force_client_auth=%d, reserved=%p)",
392
+ 5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs,
393
+ force_client_auth, reserved));
394
+ GPR_ASSERT(reserved == NULL);
395
+ memset(c, 0, sizeof(grpc_ssl_server_credentials));
396
+ c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
397
+ gpr_ref_init(&c->base.refcount, 1);
398
+ c->base.vtable = &ssl_server_vtable;
399
+ ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
400
+ num_key_cert_pairs, force_client_auth, &c->config);
401
+ return &c->base;
402
+ }
403
+
404
+ /* -- Jwt credentials -- */
405
+
406
+ static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) {
407
+ if (c->cached.jwt_md != NULL) {
408
+ grpc_credentials_md_store_unref(c->cached.jwt_md);
409
+ c->cached.jwt_md = NULL;
410
+ }
411
+ if (c->cached.service_url != NULL) {
412
+ gpr_free(c->cached.service_url);
413
+ c->cached.service_url = NULL;
414
+ }
415
+ c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
416
+ }
417
+
418
+ static void jwt_destruct(grpc_call_credentials *creds) {
419
+ grpc_service_account_jwt_access_credentials *c =
420
+ (grpc_service_account_jwt_access_credentials *)creds;
421
+ grpc_auth_json_key_destruct(&c->key);
422
+ jwt_reset_cache(c);
423
+ gpr_mu_destroy(&c->cache_mu);
424
+ }
425
+
426
+ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
427
+ grpc_call_credentials *creds,
428
+ grpc_pollset *pollset,
429
+ grpc_auth_metadata_context context,
430
+ grpc_credentials_metadata_cb cb,
431
+ void *user_data) {
432
+ grpc_service_account_jwt_access_credentials *c =
433
+ (grpc_service_account_jwt_access_credentials *)creds;
434
+ gpr_timespec refresh_threshold = gpr_time_from_seconds(
435
+ GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN);
436
+
437
+ /* See if we can return a cached jwt. */
438
+ grpc_credentials_md_store *jwt_md = NULL;
439
+ {
440
+ gpr_mu_lock(&c->cache_mu);
441
+ if (c->cached.service_url != NULL &&
442
+ strcmp(c->cached.service_url, context.service_url) == 0 &&
443
+ c->cached.jwt_md != NULL &&
444
+ (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration,
445
+ gpr_now(GPR_CLOCK_REALTIME)),
446
+ refresh_threshold) > 0)) {
447
+ jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md);
448
+ }
449
+ gpr_mu_unlock(&c->cache_mu);
450
+ }
451
+
452
+ if (jwt_md == NULL) {
453
+ char *jwt = NULL;
454
+ /* Generate a new jwt. */
455
+ gpr_mu_lock(&c->cache_mu);
456
+ jwt_reset_cache(c);
457
+ jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url,
458
+ c->jwt_lifetime, NULL);
459
+ if (jwt != NULL) {
460
+ char *md_value;
461
+ gpr_asprintf(&md_value, "Bearer %s", jwt);
462
+ gpr_free(jwt);
463
+ c->cached.jwt_expiration =
464
+ gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime);
465
+ c->cached.service_url = gpr_strdup(context.service_url);
466
+ c->cached.jwt_md = grpc_credentials_md_store_create(1);
467
+ grpc_credentials_md_store_add_cstrings(
468
+ c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value);
469
+ gpr_free(md_value);
470
+ jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md);
471
+ }
472
+ gpr_mu_unlock(&c->cache_mu);
473
+ }
474
+
475
+ if (jwt_md != NULL) {
476
+ cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries,
477
+ GRPC_CREDENTIALS_OK);
478
+ grpc_credentials_md_store_unref(jwt_md);
479
+ } else {
480
+ cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
481
+ }
482
+ }
483
+
484
+ static grpc_call_credentials_vtable jwt_vtable = {jwt_destruct,
485
+ jwt_get_request_metadata};
486
+
487
+ grpc_call_credentials *
488
+ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
489
+ grpc_auth_json_key key, gpr_timespec token_lifetime) {
490
+ grpc_service_account_jwt_access_credentials *c;
491
+ if (!grpc_auth_json_key_is_valid(&key)) {
492
+ gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
493
+ return NULL;
494
+ }
495
+ c = gpr_malloc(sizeof(grpc_service_account_jwt_access_credentials));
496
+ memset(c, 0, sizeof(grpc_service_account_jwt_access_credentials));
497
+ c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT;
498
+ gpr_ref_init(&c->base.refcount, 1);
499
+ c->base.vtable = &jwt_vtable;
500
+ c->key = key;
501
+ c->jwt_lifetime = token_lifetime;
502
+ gpr_mu_init(&c->cache_mu);
503
+ jwt_reset_cache(c);
504
+ return &c->base;
505
+ }
506
+
507
+ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
508
+ const char *json_key, gpr_timespec token_lifetime, void *reserved) {
509
+ GRPC_API_TRACE(
510
+ "grpc_service_account_jwt_access_credentials_create("
511
+ "json_key=%s, "
512
+ "token_lifetime="
513
+ "gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
514
+ "reserved=%p)",
515
+ 5,
516
+ (json_key, (long long)token_lifetime.tv_sec, (int)token_lifetime.tv_nsec,
517
+ (int)token_lifetime.clock_type, reserved));
518
+ GPR_ASSERT(reserved == NULL);
519
+ return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
520
+ grpc_auth_json_key_create_from_string(json_key), token_lifetime);
521
+ }
522
+
523
+ /* -- Oauth2TokenFetcher credentials -- */
524
+
525
+ static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) {
526
+ grpc_oauth2_token_fetcher_credentials *c =
527
+ (grpc_oauth2_token_fetcher_credentials *)creds;
528
+ grpc_credentials_md_store_unref(c->access_token_md);
529
+ gpr_mu_destroy(&c->mu);
530
+ grpc_httpcli_context_destroy(&c->httpcli_context);
531
+ }
532
+
533
+ grpc_credentials_status
534
+ grpc_oauth2_token_fetcher_credentials_parse_server_response(
535
+ const grpc_httpcli_response *response, grpc_credentials_md_store **token_md,
536
+ gpr_timespec *token_lifetime) {
537
+ char *null_terminated_body = NULL;
538
+ char *new_access_token = NULL;
539
+ grpc_credentials_status status = GRPC_CREDENTIALS_OK;
540
+ grpc_json *json = NULL;
541
+
542
+ if (response == NULL) {
543
+ gpr_log(GPR_ERROR, "Received NULL response.");
544
+ status = GRPC_CREDENTIALS_ERROR;
545
+ goto end;
546
+ }
547
+
548
+ if (response->body_length > 0) {
549
+ null_terminated_body = gpr_malloc(response->body_length + 1);
550
+ null_terminated_body[response->body_length] = '\0';
551
+ memcpy(null_terminated_body, response->body, response->body_length);
552
+ }
553
+
554
+ if (response->status != 200) {
555
+ gpr_log(GPR_ERROR, "Call to http server ended with error %d [%s].",
556
+ response->status,
557
+ null_terminated_body != NULL ? null_terminated_body : "");
558
+ status = GRPC_CREDENTIALS_ERROR;
559
+ goto end;
560
+ } else {
561
+ grpc_json *access_token = NULL;
562
+ grpc_json *token_type = NULL;
563
+ grpc_json *expires_in = NULL;
564
+ grpc_json *ptr;
565
+ json = grpc_json_parse_string(null_terminated_body);
566
+ if (json == NULL) {
567
+ gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body);
568
+ status = GRPC_CREDENTIALS_ERROR;
569
+ goto end;
570
+ }
571
+ if (json->type != GRPC_JSON_OBJECT) {
572
+ gpr_log(GPR_ERROR, "Response should be a JSON object");
573
+ status = GRPC_CREDENTIALS_ERROR;
574
+ goto end;
575
+ }
576
+ for (ptr = json->child; ptr; ptr = ptr->next) {
577
+ if (strcmp(ptr->key, "access_token") == 0) {
578
+ access_token = ptr;
579
+ } else if (strcmp(ptr->key, "token_type") == 0) {
580
+ token_type = ptr;
581
+ } else if (strcmp(ptr->key, "expires_in") == 0) {
582
+ expires_in = ptr;
583
+ }
584
+ }
585
+ if (access_token == NULL || access_token->type != GRPC_JSON_STRING) {
586
+ gpr_log(GPR_ERROR, "Missing or invalid access_token in JSON.");
587
+ status = GRPC_CREDENTIALS_ERROR;
588
+ goto end;
589
+ }
590
+ if (token_type == NULL || token_type->type != GRPC_JSON_STRING) {
591
+ gpr_log(GPR_ERROR, "Missing or invalid token_type in JSON.");
592
+ status = GRPC_CREDENTIALS_ERROR;
593
+ goto end;
594
+ }
595
+ if (expires_in == NULL || expires_in->type != GRPC_JSON_NUMBER) {
596
+ gpr_log(GPR_ERROR, "Missing or invalid expires_in in JSON.");
597
+ status = GRPC_CREDENTIALS_ERROR;
598
+ goto end;
599
+ }
600
+ gpr_asprintf(&new_access_token, "%s %s", token_type->value,
601
+ access_token->value);
602
+ token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10);
603
+ token_lifetime->tv_nsec = 0;
604
+ token_lifetime->clock_type = GPR_TIMESPAN;
605
+ if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md);
606
+ *token_md = grpc_credentials_md_store_create(1);
607
+ grpc_credentials_md_store_add_cstrings(
608
+ *token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token);
609
+ status = GRPC_CREDENTIALS_OK;
610
+ }
611
+
612
+ end:
613
+ if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) {
614
+ grpc_credentials_md_store_unref(*token_md);
615
+ *token_md = NULL;
616
+ }
617
+ if (null_terminated_body != NULL) gpr_free(null_terminated_body);
618
+ if (new_access_token != NULL) gpr_free(new_access_token);
619
+ if (json != NULL) grpc_json_destroy(json);
620
+ return status;
621
+ }
622
+
623
+ static void on_oauth2_token_fetcher_http_response(
624
+ grpc_exec_ctx *exec_ctx, void *user_data,
625
+ const grpc_httpcli_response *response) {
626
+ grpc_credentials_metadata_request *r =
627
+ (grpc_credentials_metadata_request *)user_data;
628
+ grpc_oauth2_token_fetcher_credentials *c =
629
+ (grpc_oauth2_token_fetcher_credentials *)r->creds;
630
+ gpr_timespec token_lifetime;
631
+ grpc_credentials_status status;
632
+
633
+ gpr_mu_lock(&c->mu);
634
+ status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
635
+ response, &c->access_token_md, &token_lifetime);
636
+ if (status == GRPC_CREDENTIALS_OK) {
637
+ c->token_expiration =
638
+ gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
639
+ r->cb(exec_ctx, r->user_data, c->access_token_md->entries,
640
+ c->access_token_md->num_entries, status);
641
+ } else {
642
+ c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
643
+ r->cb(exec_ctx, r->user_data, NULL, 0, status);
644
+ }
645
+ gpr_mu_unlock(&c->mu);
646
+ grpc_credentials_metadata_request_destroy(r);
647
+ }
648
+
649
+ static void oauth2_token_fetcher_get_request_metadata(
650
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
651
+ grpc_pollset *pollset, grpc_auth_metadata_context context,
652
+ grpc_credentials_metadata_cb cb, void *user_data) {
653
+ grpc_oauth2_token_fetcher_credentials *c =
654
+ (grpc_oauth2_token_fetcher_credentials *)creds;
655
+ gpr_timespec refresh_threshold = gpr_time_from_seconds(
656
+ GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN);
657
+ grpc_credentials_md_store *cached_access_token_md = NULL;
658
+ {
659
+ gpr_mu_lock(&c->mu);
660
+ if (c->access_token_md != NULL &&
661
+ (gpr_time_cmp(
662
+ gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_REALTIME)),
663
+ refresh_threshold) > 0)) {
664
+ cached_access_token_md =
665
+ grpc_credentials_md_store_ref(c->access_token_md);
666
+ }
667
+ gpr_mu_unlock(&c->mu);
668
+ }
669
+ if (cached_access_token_md != NULL) {
670
+ cb(exec_ctx, user_data, cached_access_token_md->entries,
671
+ cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK);
672
+ grpc_credentials_md_store_unref(cached_access_token_md);
673
+ } else {
674
+ c->fetch_func(
675
+ exec_ctx,
676
+ grpc_credentials_metadata_request_create(creds, cb, user_data),
677
+ &c->httpcli_context, pollset, on_oauth2_token_fetcher_http_response,
678
+ gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
679
+ }
680
+ }
681
+
682
+ static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c,
683
+ grpc_fetch_oauth2_func fetch_func) {
684
+ memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials));
685
+ c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
686
+ gpr_ref_init(&c->base.refcount, 1);
687
+ gpr_mu_init(&c->mu);
688
+ c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
689
+ c->fetch_func = fetch_func;
690
+ grpc_httpcli_context_init(&c->httpcli_context);
691
+ }
692
+
693
+ /* -- GoogleComputeEngine credentials. -- */
694
+
695
+ static grpc_call_credentials_vtable compute_engine_vtable = {
696
+ oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata};
697
+
698
+ static void compute_engine_fetch_oauth2(
699
+ grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
700
+ grpc_httpcli_context *httpcli_context, grpc_pollset *pollset,
701
+ grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
702
+ grpc_httpcli_header header = {"Metadata-Flavor", "Google"};
703
+ grpc_httpcli_request request;
704
+ memset(&request, 0, sizeof(grpc_httpcli_request));
705
+ request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
706
+ request.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
707
+ request.hdr_count = 1;
708
+ request.hdrs = &header;
709
+ grpc_httpcli_get(exec_ctx, httpcli_context, pollset, &request, deadline,
710
+ response_cb, metadata_req);
711
+ }
712
+
713
+ grpc_call_credentials *grpc_google_compute_engine_credentials_create(
714
+ void *reserved) {
715
+ grpc_oauth2_token_fetcher_credentials *c =
716
+ gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials));
717
+ GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1,
718
+ (reserved));
719
+ GPR_ASSERT(reserved == NULL);
720
+ init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2);
721
+ c->base.vtable = &compute_engine_vtable;
722
+ return &c->base;
723
+ }
724
+
725
+ /* -- GoogleRefreshToken credentials. -- */
726
+
727
+ static void refresh_token_destruct(grpc_call_credentials *creds) {
728
+ grpc_google_refresh_token_credentials *c =
729
+ (grpc_google_refresh_token_credentials *)creds;
730
+ grpc_auth_refresh_token_destruct(&c->refresh_token);
731
+ oauth2_token_fetcher_destruct(&c->base.base);
732
+ }
733
+
734
+ static grpc_call_credentials_vtable refresh_token_vtable = {
735
+ refresh_token_destruct, oauth2_token_fetcher_get_request_metadata};
736
+
737
+ static void refresh_token_fetch_oauth2(
738
+ grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
739
+ grpc_httpcli_context *httpcli_context, grpc_pollset *pollset,
740
+ grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
741
+ grpc_google_refresh_token_credentials *c =
742
+ (grpc_google_refresh_token_credentials *)metadata_req->creds;
743
+ grpc_httpcli_header header = {"Content-Type",
744
+ "application/x-www-form-urlencoded"};
745
+ grpc_httpcli_request request;
746
+ char *body = NULL;
747
+ gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
748
+ c->refresh_token.client_id, c->refresh_token.client_secret,
749
+ c->refresh_token.refresh_token);
750
+ memset(&request, 0, sizeof(grpc_httpcli_request));
751
+ request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
752
+ request.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
753
+ request.hdr_count = 1;
754
+ request.hdrs = &header;
755
+ request.handshaker = &grpc_httpcli_ssl;
756
+ grpc_httpcli_post(exec_ctx, httpcli_context, pollset, &request, body,
757
+ strlen(body), deadline, response_cb, metadata_req);
758
+ gpr_free(body);
759
+ }
760
+
761
+ grpc_call_credentials *
762
+ grpc_refresh_token_credentials_create_from_auth_refresh_token(
763
+ grpc_auth_refresh_token refresh_token) {
764
+ grpc_google_refresh_token_credentials *c;
765
+ if (!grpc_auth_refresh_token_is_valid(&refresh_token)) {
766
+ gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation");
767
+ return NULL;
768
+ }
769
+ c = gpr_malloc(sizeof(grpc_google_refresh_token_credentials));
770
+ memset(c, 0, sizeof(grpc_google_refresh_token_credentials));
771
+ init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2);
772
+ c->base.base.vtable = &refresh_token_vtable;
773
+ c->refresh_token = refresh_token;
774
+ return &c->base.base;
775
+ }
776
+
777
+ grpc_call_credentials *grpc_google_refresh_token_credentials_create(
778
+ const char *json_refresh_token, void *reserved) {
779
+ GRPC_API_TRACE(
780
+ "grpc_refresh_token_credentials_create(json_refresh_token=%s, "
781
+ "reserved=%p)",
782
+ 2, (json_refresh_token, reserved));
783
+ GPR_ASSERT(reserved == NULL);
784
+ return grpc_refresh_token_credentials_create_from_auth_refresh_token(
785
+ grpc_auth_refresh_token_create_from_string(json_refresh_token));
786
+ }
787
+
788
+ /* -- Metadata-only credentials. -- */
789
+
790
+ static void md_only_test_destruct(grpc_call_credentials *creds) {
791
+ grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
792
+ grpc_credentials_md_store_unref(c->md_store);
793
+ }
794
+
795
+ static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
796
+ void *user_data, int success) {
797
+ grpc_credentials_metadata_request *r =
798
+ (grpc_credentials_metadata_request *)user_data;
799
+ grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds;
800
+ r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries,
801
+ GRPC_CREDENTIALS_OK);
802
+ grpc_credentials_metadata_request_destroy(r);
803
+ }
804
+
805
+ static void md_only_test_get_request_metadata(
806
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
807
+ grpc_pollset *pollset, grpc_auth_metadata_context context,
808
+ grpc_credentials_metadata_cb cb, void *user_data) {
809
+ grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
810
+
811
+ if (c->is_async) {
812
+ grpc_credentials_metadata_request *cb_arg =
813
+ grpc_credentials_metadata_request_create(creds, cb, user_data);
814
+ grpc_executor_enqueue(
815
+ grpc_closure_create(on_simulated_token_fetch_done, cb_arg), 1);
816
+ } else {
817
+ cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK);
818
+ }
819
+ }
820
+
821
+ static grpc_call_credentials_vtable md_only_test_vtable = {
822
+ md_only_test_destruct, md_only_test_get_request_metadata};
823
+
824
+ grpc_call_credentials *grpc_md_only_test_credentials_create(
825
+ const char *md_key, const char *md_value, int is_async) {
826
+ grpc_md_only_test_credentials *c =
827
+ gpr_malloc(sizeof(grpc_md_only_test_credentials));
828
+ memset(c, 0, sizeof(grpc_md_only_test_credentials));
829
+ c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
830
+ c->base.vtable = &md_only_test_vtable;
831
+ gpr_ref_init(&c->base.refcount, 1);
832
+ c->md_store = grpc_credentials_md_store_create(1);
833
+ grpc_credentials_md_store_add_cstrings(c->md_store, md_key, md_value);
834
+ c->is_async = is_async;
835
+ return &c->base;
836
+ }
837
+
838
+ /* -- Oauth2 Access Token credentials. -- */
839
+
840
+ static void access_token_destruct(grpc_call_credentials *creds) {
841
+ grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
842
+ grpc_credentials_md_store_unref(c->access_token_md);
843
+ }
844
+
845
+ static void access_token_get_request_metadata(
846
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
847
+ grpc_pollset *pollset, grpc_auth_metadata_context context,
848
+ grpc_credentials_metadata_cb cb, void *user_data) {
849
+ grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
850
+ cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
851
+ }
852
+
853
+ static grpc_call_credentials_vtable access_token_vtable = {
854
+ access_token_destruct, access_token_get_request_metadata};
855
+
856
+ grpc_call_credentials *grpc_access_token_credentials_create(
857
+ const char *access_token, void *reserved) {
858
+ grpc_access_token_credentials *c =
859
+ gpr_malloc(sizeof(grpc_access_token_credentials));
860
+ char *token_md_value;
861
+ GRPC_API_TRACE(
862
+ "grpc_access_token_credentials_create(access_token=%s, "
863
+ "reserved=%p)",
864
+ 2, (access_token, reserved));
865
+ GPR_ASSERT(reserved == NULL);
866
+ memset(c, 0, sizeof(grpc_access_token_credentials));
867
+ c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
868
+ c->base.vtable = &access_token_vtable;
869
+ gpr_ref_init(&c->base.refcount, 1);
870
+ c->access_token_md = grpc_credentials_md_store_create(1);
871
+ gpr_asprintf(&token_md_value, "Bearer %s", access_token);
872
+ grpc_credentials_md_store_add_cstrings(
873
+ c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value);
874
+ gpr_free(token_md_value);
875
+ return &c->base;
876
+ }
877
+
878
+ /* -- Fake transport security credentials. -- */
879
+
880
+ static grpc_security_status fake_transport_security_create_security_connector(
881
+ grpc_channel_credentials *c, grpc_call_credentials *call_creds,
882
+ const char *target, const grpc_channel_args *args,
883
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
884
+ *sc = grpc_fake_channel_security_connector_create(call_creds);
885
+ return GRPC_SECURITY_OK;
886
+ }
887
+
888
+ static grpc_security_status
889
+ fake_transport_security_server_create_security_connector(
890
+ grpc_server_credentials *c, grpc_security_connector **sc) {
891
+ *sc = grpc_fake_server_security_connector_create();
892
+ return GRPC_SECURITY_OK;
893
+ }
894
+
895
+ static grpc_channel_credentials_vtable
896
+ fake_transport_security_credentials_vtable = {
897
+ NULL, fake_transport_security_create_security_connector};
898
+
899
+ static grpc_server_credentials_vtable
900
+ fake_transport_security_server_credentials_vtable = {
901
+ NULL, fake_transport_security_server_create_security_connector};
902
+
903
+ grpc_channel_credentials *grpc_fake_transport_security_credentials_create(
904
+ void) {
905
+ grpc_channel_credentials *c = gpr_malloc(sizeof(grpc_channel_credentials));
906
+ memset(c, 0, sizeof(grpc_channel_credentials));
907
+ c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
908
+ c->vtable = &fake_transport_security_credentials_vtable;
909
+ gpr_ref_init(&c->refcount, 1);
910
+ return c;
911
+ }
912
+
913
+ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
914
+ void) {
915
+ grpc_server_credentials *c = gpr_malloc(sizeof(grpc_server_credentials));
916
+ memset(c, 0, sizeof(grpc_server_credentials));
917
+ c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
918
+ gpr_ref_init(&c->refcount, 1);
919
+ c->vtable = &fake_transport_security_server_credentials_vtable;
920
+ return c;
921
+ }
922
+
923
+ /* -- Composite call credentials. -- */
924
+
925
+ typedef struct {
926
+ grpc_composite_call_credentials *composite_creds;
927
+ size_t creds_index;
928
+ grpc_credentials_md_store *md_elems;
929
+ grpc_auth_metadata_context auth_md_context;
930
+ void *user_data;
931
+ grpc_pollset *pollset;
932
+ grpc_credentials_metadata_cb cb;
933
+ } grpc_composite_call_credentials_metadata_context;
934
+
935
+ static void composite_call_destruct(grpc_call_credentials *creds) {
936
+ grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
937
+ size_t i;
938
+ for (i = 0; i < c->inner.num_creds; i++) {
939
+ grpc_call_credentials_unref(c->inner.creds_array[i]);
940
+ }
941
+ gpr_free(c->inner.creds_array);
942
+ }
943
+
944
+ static void composite_call_md_context_destroy(
945
+ grpc_composite_call_credentials_metadata_context *ctx) {
946
+ grpc_credentials_md_store_unref(ctx->md_elems);
947
+ gpr_free(ctx);
948
+ }
949
+
950
+ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
951
+ grpc_credentials_md *md_elems,
952
+ size_t num_md,
953
+ grpc_credentials_status status) {
954
+ grpc_composite_call_credentials_metadata_context *ctx =
955
+ (grpc_composite_call_credentials_metadata_context *)user_data;
956
+ if (status != GRPC_CREDENTIALS_OK) {
957
+ ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status);
958
+ return;
959
+ }
960
+
961
+ /* Copy the metadata in the context. */
962
+ if (num_md > 0) {
963
+ size_t i;
964
+ for (i = 0; i < num_md; i++) {
965
+ grpc_credentials_md_store_add(ctx->md_elems, md_elems[i].key,
966
+ md_elems[i].value);
967
+ }
968
+ }
969
+
970
+ /* See if we need to get some more metadata. */
971
+ if (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
972
+ grpc_call_credentials *inner_creds =
973
+ ctx->composite_creds->inner.creds_array[ctx->creds_index++];
974
+ grpc_call_credentials_get_request_metadata(
975
+ exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context,
976
+ composite_call_metadata_cb, ctx);
977
+ return;
978
+ }
979
+
980
+ /* We're done!. */
981
+ ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries,
982
+ ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK);
983
+ composite_call_md_context_destroy(ctx);
984
+ }
985
+
986
+ static void composite_call_get_request_metadata(
987
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
988
+ grpc_pollset *pollset, grpc_auth_metadata_context auth_md_context,
989
+ grpc_credentials_metadata_cb cb, void *user_data) {
990
+ grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
991
+ grpc_composite_call_credentials_metadata_context *ctx;
992
+
993
+ ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context));
994
+ memset(ctx, 0, sizeof(grpc_composite_call_credentials_metadata_context));
995
+ ctx->auth_md_context = auth_md_context;
996
+ ctx->user_data = user_data;
997
+ ctx->cb = cb;
998
+ ctx->composite_creds = c;
999
+ ctx->pollset = pollset;
1000
+ ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds);
1001
+ grpc_call_credentials_get_request_metadata(
1002
+ exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset,
1003
+ auth_md_context, composite_call_metadata_cb, ctx);
1004
+ }
1005
+
1006
+ static grpc_call_credentials_vtable composite_call_credentials_vtable = {
1007
+ composite_call_destruct, composite_call_get_request_metadata};
1008
+
1009
+ static grpc_call_credentials_array get_creds_array(
1010
+ grpc_call_credentials **creds_addr) {
1011
+ grpc_call_credentials_array result;
1012
+ grpc_call_credentials *creds = *creds_addr;
1013
+ result.creds_array = creds_addr;
1014
+ result.num_creds = 1;
1015
+ if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) {
1016
+ result = *grpc_composite_call_credentials_get_credentials(creds);
1017
+ }
1018
+ return result;
1019
+ }
1020
+
1021
+ grpc_call_credentials *grpc_composite_call_credentials_create(
1022
+ grpc_call_credentials *creds1, grpc_call_credentials *creds2,
1023
+ void *reserved) {
1024
+ size_t i;
1025
+ size_t creds_array_byte_size;
1026
+ grpc_call_credentials_array creds1_array;
1027
+ grpc_call_credentials_array creds2_array;
1028
+ grpc_composite_call_credentials *c;
1029
+ GRPC_API_TRACE(
1030
+ "grpc_composite_call_credentials_create(creds1=%p, creds2=%p, "
1031
+ "reserved=%p)",
1032
+ 3, (creds1, creds2, reserved));
1033
+ GPR_ASSERT(reserved == NULL);
1034
+ GPR_ASSERT(creds1 != NULL);
1035
+ GPR_ASSERT(creds2 != NULL);
1036
+ c = gpr_malloc(sizeof(grpc_composite_call_credentials));
1037
+ memset(c, 0, sizeof(grpc_composite_call_credentials));
1038
+ c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE;
1039
+ c->base.vtable = &composite_call_credentials_vtable;
1040
+ gpr_ref_init(&c->base.refcount, 1);
1041
+ creds1_array = get_creds_array(&creds1);
1042
+ creds2_array = get_creds_array(&creds2);
1043
+ c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds;
1044
+ creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials *);
1045
+ c->inner.creds_array = gpr_malloc(creds_array_byte_size);
1046
+ memset(c->inner.creds_array, 0, creds_array_byte_size);
1047
+ for (i = 0; i < creds1_array.num_creds; i++) {
1048
+ grpc_call_credentials *cur_creds = creds1_array.creds_array[i];
1049
+ c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds);
1050
+ }
1051
+ for (i = 0; i < creds2_array.num_creds; i++) {
1052
+ grpc_call_credentials *cur_creds = creds2_array.creds_array[i];
1053
+ c->inner.creds_array[i + creds1_array.num_creds] =
1054
+ grpc_call_credentials_ref(cur_creds);
1055
+ }
1056
+ return &c->base;
1057
+ }
1058
+
1059
+ const grpc_call_credentials_array *
1060
+ grpc_composite_call_credentials_get_credentials(grpc_call_credentials *creds) {
1061
+ const grpc_composite_call_credentials *c =
1062
+ (const grpc_composite_call_credentials *)creds;
1063
+ GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
1064
+ return &c->inner;
1065
+ }
1066
+
1067
+ grpc_call_credentials *grpc_credentials_contains_type(
1068
+ grpc_call_credentials *creds, const char *type,
1069
+ grpc_call_credentials **composite_creds) {
1070
+ size_t i;
1071
+ if (strcmp(creds->type, type) == 0) {
1072
+ if (composite_creds != NULL) *composite_creds = NULL;
1073
+ return creds;
1074
+ } else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) {
1075
+ const grpc_call_credentials_array *inner_creds_array =
1076
+ grpc_composite_call_credentials_get_credentials(creds);
1077
+ for (i = 0; i < inner_creds_array->num_creds; i++) {
1078
+ if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) {
1079
+ if (composite_creds != NULL) *composite_creds = creds;
1080
+ return inner_creds_array->creds_array[i];
1081
+ }
1082
+ }
1083
+ }
1084
+ return NULL;
1085
+ }
1086
+
1087
+ /* -- IAM credentials. -- */
1088
+
1089
+ static void iam_destruct(grpc_call_credentials *creds) {
1090
+ grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
1091
+ grpc_credentials_md_store_unref(c->iam_md);
1092
+ }
1093
+
1094
+ static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
1095
+ grpc_call_credentials *creds,
1096
+ grpc_pollset *pollset,
1097
+ grpc_auth_metadata_context context,
1098
+ grpc_credentials_metadata_cb cb,
1099
+ void *user_data) {
1100
+ grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
1101
+ cb(exec_ctx, user_data, c->iam_md->entries, c->iam_md->num_entries,
1102
+ GRPC_CREDENTIALS_OK);
1103
+ }
1104
+
1105
+ static grpc_call_credentials_vtable iam_vtable = {iam_destruct,
1106
+ iam_get_request_metadata};
1107
+
1108
+ grpc_call_credentials *grpc_google_iam_credentials_create(
1109
+ const char *token, const char *authority_selector, void *reserved) {
1110
+ grpc_google_iam_credentials *c;
1111
+ GRPC_API_TRACE(
1112
+ "grpc_iam_credentials_create(token=%s, authority_selector=%s, "
1113
+ "reserved=%p)",
1114
+ 3, (token, authority_selector, reserved));
1115
+ GPR_ASSERT(reserved == NULL);
1116
+ GPR_ASSERT(token != NULL);
1117
+ GPR_ASSERT(authority_selector != NULL);
1118
+ c = gpr_malloc(sizeof(grpc_google_iam_credentials));
1119
+ memset(c, 0, sizeof(grpc_google_iam_credentials));
1120
+ c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM;
1121
+ c->base.vtable = &iam_vtable;
1122
+ gpr_ref_init(&c->base.refcount, 1);
1123
+ c->iam_md = grpc_credentials_md_store_create(2);
1124
+ grpc_credentials_md_store_add_cstrings(
1125
+ c->iam_md, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, token);
1126
+ grpc_credentials_md_store_add_cstrings(
1127
+ c->iam_md, GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, authority_selector);
1128
+ return &c->base;
1129
+ }
1130
+
1131
+ /* -- Plugin credentials. -- */
1132
+
1133
+ typedef struct {
1134
+ void *user_data;
1135
+ grpc_credentials_metadata_cb cb;
1136
+ } grpc_metadata_plugin_request;
1137
+
1138
+ static void plugin_destruct(grpc_call_credentials *creds) {
1139
+ grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
1140
+ if (c->plugin.state != NULL && c->plugin.destroy != NULL) {
1141
+ c->plugin.destroy(c->plugin.state);
1142
+ }
1143
+ }
1144
+
1145
+ static void plugin_md_request_metadata_ready(void *request,
1146
+ const grpc_metadata *md,
1147
+ size_t num_md,
1148
+ grpc_status_code status,
1149
+ const char *error_details) {
1150
+ /* called from application code */
1151
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
1152
+ grpc_metadata_plugin_request *r = (grpc_metadata_plugin_request *)request;
1153
+ if (status != GRPC_STATUS_OK) {
1154
+ if (error_details != NULL) {
1155
+ gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s",
1156
+ error_details);
1157
+ }
1158
+ r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
1159
+ } else {
1160
+ size_t i;
1161
+ grpc_credentials_md *md_array = NULL;
1162
+ if (num_md > 0) {
1163
+ md_array = gpr_malloc(num_md * sizeof(grpc_credentials_md));
1164
+ for (i = 0; i < num_md; i++) {
1165
+ md_array[i].key = gpr_slice_from_copied_string(md[i].key);
1166
+ md_array[i].value =
1167
+ gpr_slice_from_copied_buffer(md[i].value, md[i].value_length);
1168
+ }
1169
+ }
1170
+ r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK);
1171
+ if (md_array != NULL) {
1172
+ for (i = 0; i < num_md; i++) {
1173
+ gpr_slice_unref(md_array[i].key);
1174
+ gpr_slice_unref(md_array[i].value);
1175
+ }
1176
+ gpr_free(md_array);
1177
+ }
1178
+ }
1179
+ gpr_free(r);
1180
+ grpc_exec_ctx_finish(&exec_ctx);
1181
+ }
1182
+
1183
+ static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
1184
+ grpc_call_credentials *creds,
1185
+ grpc_pollset *pollset,
1186
+ grpc_auth_metadata_context context,
1187
+ grpc_credentials_metadata_cb cb,
1188
+ void *user_data) {
1189
+ grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
1190
+ if (c->plugin.get_metadata != NULL) {
1191
+ grpc_metadata_plugin_request *request = gpr_malloc(sizeof(*request));
1192
+ memset(request, 0, sizeof(*request));
1193
+ request->user_data = user_data;
1194
+ request->cb = cb;
1195
+ c->plugin.get_metadata(c->plugin.state, context,
1196
+ plugin_md_request_metadata_ready, request);
1197
+ } else {
1198
+ cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
1199
+ }
1200
+ }
1201
+
1202
+ static grpc_call_credentials_vtable plugin_vtable = {
1203
+ plugin_destruct, plugin_get_request_metadata};
1204
+
1205
+ grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
1206
+ grpc_metadata_credentials_plugin plugin, void *reserved) {
1207
+ grpc_plugin_credentials *c = gpr_malloc(sizeof(*c));
1208
+ GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1,
1209
+ (reserved));
1210
+ GPR_ASSERT(reserved == NULL);
1211
+ memset(c, 0, sizeof(*c));
1212
+ c->base.type = plugin.type;
1213
+ c->base.vtable = &plugin_vtable;
1214
+ gpr_ref_init(&c->base.refcount, 1);
1215
+ c->plugin = plugin;
1216
+ return &c->base;
1217
+ }
1218
+
1219
+ /* -- Composite channel credentials. -- */
1220
+
1221
+ static void composite_channel_destruct(grpc_channel_credentials *creds) {
1222
+ grpc_composite_channel_credentials *c =
1223
+ (grpc_composite_channel_credentials *)creds;
1224
+ grpc_channel_credentials_unref(c->inner_creds);
1225
+ grpc_call_credentials_unref(c->call_creds);
1226
+ }
1227
+
1228
+ static grpc_security_status composite_channel_create_security_connector(
1229
+ grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
1230
+ const char *target, const grpc_channel_args *args,
1231
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
1232
+ grpc_composite_channel_credentials *c =
1233
+ (grpc_composite_channel_credentials *)creds;
1234
+ grpc_security_status status = GRPC_SECURITY_ERROR;
1235
+
1236
+ GPR_ASSERT(c->inner_creds != NULL && c->call_creds != NULL &&
1237
+ c->inner_creds->vtable != NULL &&
1238
+ c->inner_creds->vtable->create_security_connector != NULL);
1239
+ /* If we are passed a call_creds, create a call composite to pass it
1240
+ downstream. */
1241
+ if (call_creds != NULL) {
1242
+ grpc_call_credentials *composite_call_creds =
1243
+ grpc_composite_call_credentials_create(c->call_creds, call_creds, NULL);
1244
+ status = c->inner_creds->vtable->create_security_connector(
1245
+ c->inner_creds, composite_call_creds, target, args, sc, new_args);
1246
+ grpc_call_credentials_unref(composite_call_creds);
1247
+ } else {
1248
+ status = c->inner_creds->vtable->create_security_connector(
1249
+ c->inner_creds, c->call_creds, target, args, sc, new_args);
1250
+ }
1251
+ return status;
1252
+ }
1253
+
1254
+ static grpc_channel_credentials_vtable composite_channel_credentials_vtable = {
1255
+ composite_channel_destruct, composite_channel_create_security_connector};
1256
+
1257
+ grpc_channel_credentials *grpc_composite_channel_credentials_create(
1258
+ grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds,
1259
+ void *reserved) {
1260
+ grpc_composite_channel_credentials *c = gpr_malloc(sizeof(*c));
1261
+ memset(c, 0, sizeof(*c));
1262
+ GPR_ASSERT(channel_creds != NULL && call_creds != NULL && reserved == NULL);
1263
+ GRPC_API_TRACE(
1264
+ "grpc_composite_channel_credentials_create(channel_creds=%p, "
1265
+ "call_creds=%p, reserved=%p)",
1266
+ 3, (channel_creds, call_creds, reserved));
1267
+ c->base.type = channel_creds->type;
1268
+ c->base.vtable = &composite_channel_credentials_vtable;
1269
+ gpr_ref_init(&c->base.refcount, 1);
1270
+ c->inner_creds = grpc_channel_credentials_ref(channel_creds);
1271
+ c->call_creds = grpc_call_credentials_ref(call_creds);
1272
+ return &c->base;
1273
+ }