grpc 0.14.1 → 0.15.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 (277) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1398 -817
  3. data/include/grpc/compression.h +2 -1
  4. data/include/grpc/grpc.h +10 -1
  5. data/include/grpc/grpc_cronet.h +51 -0
  6. data/include/grpc/grpc_posix.h +70 -0
  7. data/include/grpc/impl/codegen/atm.h +2 -2
  8. data/include/grpc/impl/codegen/{atm_win32.h → atm_windows.h} +3 -3
  9. data/include/grpc/impl/codegen/compression_types.h +39 -5
  10. data/include/grpc/impl/codegen/connectivity_state.h +1 -1
  11. data/include/grpc/impl/codegen/grpc_types.h +10 -0
  12. data/include/grpc/impl/codegen/log.h +2 -1
  13. data/include/grpc/impl/codegen/port_platform.h +30 -12
  14. data/include/grpc/impl/codegen/slice_buffer.h +2 -3
  15. data/include/grpc/impl/codegen/sync.h +2 -2
  16. data/include/grpc/impl/codegen/{sync_win32.h → sync_windows.h} +3 -3
  17. data/include/grpc/support/{sync_win32.h → atm_windows.h} +4 -4
  18. data/include/grpc/support/avl.h +5 -0
  19. data/include/grpc/support/{log_win32.h → log_windows.h} +3 -3
  20. data/include/grpc/support/string_util.h +2 -1
  21. data/include/grpc/support/{atm_win32.h → sync_windows.h} +4 -4
  22. data/src/core/ext/census/gen/census.pb.c +179 -0
  23. data/src/core/ext/census/gen/census.pb.h +294 -0
  24. data/src/core/ext/census/grpc_filter.c +11 -7
  25. data/src/core/ext/client_config/channel_connectivity.c +28 -14
  26. data/src/core/ext/client_config/client_channel.c +77 -53
  27. data/src/core/ext/client_config/connector.h +1 -1
  28. data/src/core/ext/client_config/lb_policy.c +9 -6
  29. data/src/core/ext/client_config/lb_policy.h +9 -5
  30. data/src/core/ext/client_config/subchannel.c +58 -39
  31. data/src/core/ext/client_config/subchannel.h +3 -2
  32. data/src/core/ext/client_config/subchannel_call_holder.c +34 -19
  33. data/src/core/ext/client_config/subchannel_call_holder.h +2 -1
  34. data/src/core/ext/client_config/subchannel_index.c +20 -9
  35. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +7 -7
  36. data/src/core/ext/lb_policy/grpclb/load_balancer_api.h +5 -5
  37. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/{v0 → v1}/load_balancer.pb.c +29 -30
  38. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +178 -0
  39. data/src/core/ext/lb_policy/pick_first/pick_first.c +65 -45
  40. data/src/core/ext/lb_policy/round_robin/round_robin.c +84 -43
  41. data/src/core/ext/load_reporting/load_reporting.c +133 -0
  42. data/src/core/ext/load_reporting/load_reporting.h +75 -0
  43. data/src/core/ext/load_reporting/load_reporting_filter.c +151 -0
  44. data/src/core/ext/load_reporting/load_reporting_filter.h +41 -0
  45. data/src/core/ext/resolver/dns/native/dns_resolver.c +22 -8
  46. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +2 -2
  47. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +4 -4
  48. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +95 -0
  49. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +14 -18
  50. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +49 -24
  51. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +82 -0
  52. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +104 -60
  53. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +232 -0
  54. data/src/{ruby/ext/grpc/rb_signal.c → core/ext/transport/chttp2/transport/bin_decoder.h} +27 -31
  55. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +481 -260
  56. data/src/core/ext/transport/chttp2/transport/frame.h +1 -7
  57. data/src/core/ext/transport/chttp2/transport/frame_data.c +44 -27
  58. data/src/core/ext/transport/chttp2/transport/frame_data.h +6 -5
  59. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +23 -17
  60. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +2 -2
  61. data/src/core/ext/transport/chttp2/transport/frame_ping.c +12 -7
  62. data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -3
  63. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +25 -12
  64. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +2 -2
  65. data/src/core/ext/transport/chttp2/transport/frame_settings.c +23 -21
  66. data/src/core/ext/transport/chttp2/transport/frame_settings.h +2 -2
  67. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +17 -9
  68. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +2 -2
  69. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +365 -287
  70. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -6
  71. data/src/core/ext/transport/chttp2/transport/hpack_table.c +24 -20
  72. data/src/core/ext/transport/chttp2/transport/hpack_table.h +5 -4
  73. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +1 -0
  74. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +1 -0
  75. data/src/core/ext/transport/chttp2/transport/internal.h +34 -32
  76. data/src/core/ext/transport/chttp2/transport/parsing.c +296 -212
  77. data/src/core/ext/transport/chttp2/transport/writing.c +12 -9
  78. data/src/core/lib/channel/channel_args.c +26 -12
  79. data/src/core/lib/channel/channel_args.h +1 -1
  80. data/src/core/lib/channel/channel_stack.c +12 -8
  81. data/src/core/lib/channel/channel_stack.h +27 -11
  82. data/src/core/lib/channel/channel_stack_builder.c +2 -2
  83. data/src/core/lib/channel/compress_filter.c +26 -31
  84. data/src/core/lib/channel/compress_filter.h +4 -4
  85. data/src/core/lib/channel/connected_channel.c +7 -5
  86. data/src/core/lib/channel/http_client_filter.c +34 -8
  87. data/src/core/lib/channel/http_client_filter.h +1 -1
  88. data/src/core/lib/channel/http_server_filter.c +21 -12
  89. data/src/core/lib/compression/{compression_algorithm.c → compression.c} +22 -21
  90. data/src/core/lib/http/httpcli.c +81 -59
  91. data/src/core/lib/http/httpcli.h +11 -15
  92. data/src/core/lib/http/httpcli_security_connector.c +5 -3
  93. data/src/core/lib/http/parser.c +127 -118
  94. data/src/core/lib/http/parser.h +11 -6
  95. data/src/core/lib/iomgr/closure.c +20 -16
  96. data/src/core/lib/iomgr/closure.h +19 -15
  97. data/src/core/lib/iomgr/endpoint.h +1 -1
  98. data/src/core/lib/iomgr/endpoint_pair_posix.c +2 -2
  99. data/src/core/lib/iomgr/error.c +535 -0
  100. data/src/core/lib/iomgr/error.h +192 -0
  101. data/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +190 -83
  102. data/src/core/lib/iomgr/ev_poll_posix.c +1267 -0
  103. data/src/{ruby/ext/grpc/rb_signal.h → core/lib/iomgr/ev_poll_posix.h} +7 -5
  104. data/src/core/lib/iomgr/ev_posix.c +104 -14
  105. data/src/core/lib/iomgr/ev_posix.h +17 -7
  106. data/src/core/lib/iomgr/exec_ctx.c +25 -7
  107. data/src/core/lib/iomgr/exec_ctx.h +27 -8
  108. data/src/core/lib/iomgr/executor.c +2 -2
  109. data/src/core/lib/iomgr/executor.h +1 -1
  110. data/src/core/lib/iomgr/iocp_windows.c +2 -41
  111. data/src/core/lib/iomgr/iocp_windows.h +0 -8
  112. data/src/core/lib/iomgr/iomgr.c +5 -4
  113. data/src/core/lib/iomgr/iomgr_posix.c +5 -1
  114. data/src/core/lib/iomgr/iomgr_windows.c +1 -1
  115. data/src/core/lib/{support → iomgr}/load_file.c +15 -17
  116. data/src/core/lib/{support → iomgr}/load_file.h +8 -7
  117. data/src/core/lib/iomgr/polling_entity.c +104 -0
  118. data/src/core/lib/iomgr/polling_entity.h +81 -0
  119. data/src/core/lib/iomgr/pollset.h +6 -5
  120. data/src/core/lib/iomgr/pollset_set_windows.c +4 -1
  121. data/src/core/lib/iomgr/pollset_windows.c +10 -6
  122. data/src/core/lib/iomgr/resolve_address.h +5 -9
  123. data/src/core/lib/iomgr/resolve_address_posix.c +55 -38
  124. data/src/core/lib/iomgr/resolve_address_windows.c +51 -37
  125. data/src/core/lib/iomgr/sockaddr.h +2 -2
  126. data/src/core/lib/iomgr/{sockaddr_win32.h → sockaddr_windows.h} +3 -3
  127. data/src/core/lib/iomgr/socket_utils_common_posix.c +92 -45
  128. data/src/core/lib/iomgr/socket_utils_posix.h +19 -12
  129. data/src/core/lib/iomgr/socket_windows.c +61 -2
  130. data/src/core/lib/iomgr/socket_windows.h +13 -0
  131. data/src/core/lib/iomgr/tcp_client_posix.c +54 -39
  132. data/src/core/lib/iomgr/tcp_client_windows.c +34 -34
  133. data/src/core/lib/iomgr/tcp_posix.c +43 -39
  134. data/src/core/lib/iomgr/tcp_server.h +5 -3
  135. data/src/core/lib/iomgr/tcp_server_posix.c +103 -64
  136. data/src/core/lib/iomgr/tcp_server_windows.c +114 -101
  137. data/src/core/lib/iomgr/tcp_windows.c +45 -50
  138. data/src/core/lib/iomgr/tcp_windows.h +1 -1
  139. data/src/core/lib/iomgr/timer.c +26 -13
  140. data/src/core/lib/iomgr/udp_server.c +28 -4
  141. data/src/core/lib/iomgr/udp_server.h +5 -1
  142. data/src/core/lib/iomgr/unix_sockets_posix.c +8 -7
  143. data/src/core/lib/iomgr/unix_sockets_posix.h +2 -1
  144. data/src/core/lib/iomgr/unix_sockets_posix_noop.c +4 -2
  145. data/src/core/lib/iomgr/wakeup_fd_eventfd.c +15 -5
  146. data/src/core/lib/iomgr/wakeup_fd_pipe.c +13 -9
  147. data/src/core/lib/iomgr/wakeup_fd_posix.c +6 -6
  148. data/src/core/lib/iomgr/wakeup_fd_posix.h +9 -6
  149. data/src/core/lib/iomgr/workqueue.h +5 -4
  150. data/src/core/lib/iomgr/workqueue_posix.c +40 -26
  151. data/src/core/lib/iomgr/workqueue_windows.c +2 -2
  152. data/src/core/lib/profiling/basic_timers.c +2 -2
  153. data/src/core/lib/security/{security_context.c → context/security_context.c} +1 -1
  154. data/src/core/lib/security/{security_context.h → context/security_context.h} +4 -4
  155. data/src/core/lib/security/credentials/composite/composite_credentials.c +263 -0
  156. data/src/core/lib/security/credentials/composite/composite_credentials.h +72 -0
  157. data/src/core/lib/security/credentials/credentials.c +233 -0
  158. data/src/core/lib/security/{credentials.h → credentials/credentials.h} +19 -157
  159. data/src/core/lib/security/{credentials_metadata.c → credentials/credentials_metadata.c} +1 -1
  160. data/src/core/lib/security/credentials/fake/fake_credentials.c +139 -0
  161. data/src/core/lib/security/credentials/fake/fake_credentials.h +56 -0
  162. data/src/core/lib/security/{credentials_posix.c → credentials/google_default/credentials_posix.c} +1 -1
  163. data/src/core/lib/security/{credentials_win32.c → credentials/google_default/credentials_windows.c} +3 -3
  164. data/src/core/lib/security/{google_default_credentials.c → credentials/google_default/google_default_credentials.c} +93 -35
  165. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +46 -0
  166. data/src/core/lib/security/credentials/iam/iam_credentials.c +85 -0
  167. data/src/core/lib/security/credentials/iam/iam_credentials.h +44 -0
  168. data/src/core/lib/security/{json_token.c → credentials/jwt/json_token.c} +10 -101
  169. data/src/core/lib/security/{json_token.h → credentials/jwt/json_token.h} +3 -33
  170. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +160 -0
  171. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +62 -0
  172. data/src/core/lib/security/{jwt_verifier.c → credentials/jwt/jwt_verifier.c} +35 -15
  173. data/src/core/lib/security/{jwt_verifier.h → credentials/jwt/jwt_verifier.h} +3 -3
  174. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +433 -0
  175. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +109 -0
  176. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +129 -0
  177. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +45 -0
  178. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +240 -0
  179. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +48 -0
  180. data/src/core/lib/security/{auth_filters.h → transport/auth_filters.h} +3 -3
  181. data/src/core/lib/security/{client_auth_filter.c → transport/client_auth_filter.c} +27 -20
  182. data/src/core/lib/security/{handshake.c → transport/handshake.c} +77 -45
  183. data/src/core/lib/security/{handshake.h → transport/handshake.h} +9 -11
  184. data/src/core/lib/security/{secure_endpoint.c → transport/secure_endpoint.c} +19 -12
  185. data/src/core/lib/security/{secure_endpoint.h → transport/secure_endpoint.h} +3 -3
  186. data/src/core/lib/security/{security_connector.c → transport/security_connector.c} +26 -17
  187. data/src/core/lib/security/{security_connector.h → transport/security_connector.h} +8 -8
  188. data/src/core/lib/security/{server_auth_filter.c → transport/server_auth_filter.c} +24 -16
  189. data/src/core/lib/security/transport/tsi_error.c +40 -0
  190. data/src/core/lib/security/transport/tsi_error.h +42 -0
  191. data/src/core/lib/security/{b64.c → util/b64.c} +1 -1
  192. data/src/core/lib/security/{b64.h → util/b64.h} +3 -3
  193. data/src/core/lib/security/util/json_util.c +61 -0
  194. data/src/core/lib/security/util/json_util.h +55 -0
  195. data/src/core/lib/support/avl.c +11 -0
  196. data/src/core/lib/support/cpu_windows.c +2 -2
  197. data/src/core/lib/support/{env_win32.c → env_windows.c} +3 -3
  198. data/src/core/lib/support/log.c +3 -1
  199. data/src/core/lib/support/log_linux.c +2 -2
  200. data/src/core/lib/support/{log_win32.c → log_windows.c} +4 -4
  201. data/src/core/lib/support/murmur_hash.c +3 -5
  202. data/src/core/lib/support/string.c +10 -0
  203. data/src/core/lib/support/string.h +4 -0
  204. data/src/core/lib/support/{string_util_win32.c → string_util_windows.c} +3 -3
  205. data/src/core/lib/support/{string_win32.c → string_windows.c} +2 -2
  206. data/src/core/lib/support/{string_win32.h → string_windows.h} +5 -5
  207. data/src/core/lib/support/subprocess_windows.c +1 -1
  208. data/src/core/lib/support/{sync_win32.c → sync_windows.c} +2 -2
  209. data/src/core/lib/support/{thd_win32.c → thd_windows.c} +2 -2
  210. data/src/core/lib/support/{time_win32.c → time_windows.c} +2 -2
  211. data/src/core/lib/support/tmpfile_msys.c +1 -1
  212. data/src/core/lib/support/{tmpfile_win32.c → tmpfile_windows.c} +3 -3
  213. data/src/core/lib/surface/alarm.c +2 -2
  214. data/src/core/lib/surface/byte_buffer_reader.c +13 -6
  215. data/src/core/lib/surface/call.c +323 -123
  216. data/src/core/lib/surface/call.h +2 -0
  217. data/src/core/lib/surface/call_log_batch.c +1 -1
  218. data/src/core/lib/surface/channel.c +64 -15
  219. data/src/core/lib/surface/channel.h +9 -0
  220. data/src/core/lib/surface/channel_ping.c +3 -3
  221. data/src/core/lib/surface/completion_queue.c +75 -19
  222. data/src/core/lib/surface/completion_queue.h +7 -2
  223. data/src/core/lib/surface/init.c +2 -1
  224. data/src/core/lib/surface/init_secure.c +4 -4
  225. data/src/core/lib/surface/lame_client.c +12 -8
  226. data/src/core/lib/surface/server.c +213 -120
  227. data/src/core/lib/surface/server.h +1 -0
  228. data/src/core/lib/surface/version.c +1 -1
  229. data/src/core/lib/transport/connectivity_state.c +40 -18
  230. data/src/core/lib/transport/connectivity_state.h +4 -1
  231. data/src/core/lib/transport/metadata.c +23 -23
  232. data/src/core/lib/transport/metadata.h +4 -0
  233. data/src/core/lib/transport/metadata_batch.c +9 -0
  234. data/src/core/lib/transport/metadata_batch.h +3 -0
  235. data/src/core/lib/transport/static_metadata.c +6 -5
  236. data/src/core/lib/transport/static_metadata.h +64 -60
  237. data/src/core/lib/transport/transport.c +24 -12
  238. data/src/core/lib/transport/transport.h +6 -5
  239. data/src/core/lib/transport/transport_impl.h +4 -0
  240. data/src/core/lib/transport/transport_op_string.c +2 -2
  241. data/src/core/plugin_registry/grpc_plugin_registry.c +4 -0
  242. data/src/ruby/bin/math_services.rb +41 -2
  243. data/src/ruby/ext/grpc/rb_call.c +42 -40
  244. data/src/ruby/ext/grpc/rb_channel.c +1 -1
  245. data/src/ruby/ext/grpc/rb_completion_queue.c +59 -6
  246. data/src/ruby/ext/grpc/rb_completion_queue.h +1 -1
  247. data/src/ruby/ext/grpc/rb_grpc.c +1 -3
  248. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -2
  249. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +21 -5
  250. data/src/ruby/ext/grpc/rb_loader.c +1 -1
  251. data/src/ruby/ext/grpc/rb_server.c +5 -3
  252. data/src/ruby/lib/grpc.rb +0 -3
  253. data/src/ruby/lib/grpc/errors.rb +3 -2
  254. data/src/ruby/lib/grpc/generic/active_call.rb +32 -42
  255. data/src/ruby/lib/grpc/generic/bidi_call.rb +20 -0
  256. data/src/ruby/lib/grpc/generic/client_stub.rb +31 -54
  257. data/src/ruby/lib/grpc/generic/rpc_desc.rb +4 -4
  258. data/src/ruby/lib/grpc/generic/rpc_server.rb +12 -23
  259. data/src/ruby/lib/grpc/generic/service.rb +8 -8
  260. data/src/ruby/lib/grpc/version.rb +1 -1
  261. data/src/ruby/pb/grpc/health/v1/health_services.rb +30 -2
  262. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb +34 -4
  263. data/src/ruby/pb/grpc/testing/metrics_services.rb +39 -2
  264. data/src/ruby/pb/src/proto/grpc/testing/empty.rb +15 -0
  265. data/src/ruby/pb/src/proto/grpc/testing/messages.rb +84 -0
  266. data/src/ruby/pb/src/proto/grpc/testing/test.rb +14 -0
  267. data/src/ruby/pb/src/proto/grpc/testing/test_services.rb +110 -0
  268. data/src/ruby/pb/test/client.rb +5 -2
  269. data/src/ruby/spec/generic/active_call_spec.rb +3 -2
  270. data/src/ruby/spec/generic/client_stub_spec.rb +27 -24
  271. data/src/ruby/spec/generic/rpc_desc_spec.rb +11 -11
  272. data/src/ruby/spec/generic/rpc_server_spec.rb +42 -61
  273. data/src/ruby/spec/pb/health/checker_spec.rb +3 -5
  274. metadata +86 -48
  275. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h +0 -182
  276. data/src/core/lib/security/credentials.c +0 -1296
  277. data/src/ruby/lib/grpc/signals.rb +0 -69
@@ -0,0 +1,62 @@
1
+ /*
2
+ *
3
+ * Copyright 2016, 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_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H
35
+ #define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H
36
+
37
+ #include "src/core/lib/security/credentials/credentials.h"
38
+ #include "src/core/lib/security/credentials/jwt/json_token.h"
39
+
40
+ typedef struct {
41
+ grpc_call_credentials base;
42
+
43
+ // Have a simple cache for now with just 1 entry. We could have a map based on
44
+ // the service_url for a more sophisticated one.
45
+ gpr_mu cache_mu;
46
+ struct {
47
+ grpc_credentials_md_store *jwt_md;
48
+ char *service_url;
49
+ gpr_timespec jwt_expiration;
50
+ } cached;
51
+
52
+ grpc_auth_json_key key;
53
+ gpr_timespec jwt_lifetime;
54
+ } grpc_service_account_jwt_access_credentials;
55
+
56
+ // Private constructor for jwt credentials from an already parsed json key.
57
+ // Takes ownership of the key.
58
+ grpc_call_credentials *
59
+ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
60
+ grpc_auth_json_key key, gpr_timespec token_lifetime);
61
+
62
+ #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H */
@@ -31,19 +31,21 @@
31
31
  *
32
32
  */
33
33
 
34
- #include "src/core/lib/security/jwt_verifier.h"
34
+ #include "src/core/lib/security/credentials/jwt/jwt_verifier.h"
35
35
 
36
36
  #include <limits.h>
37
37
  #include <string.h>
38
38
 
39
39
  #include "src/core/lib/http/httpcli.h"
40
- #include "src/core/lib/security/b64.h"
40
+ #include "src/core/lib/iomgr/polling_entity.h"
41
+ #include "src/core/lib/security/util/b64.h"
41
42
  #include "src/core/lib/tsi/ssl_types.h"
42
43
 
43
44
  #include <grpc/support/alloc.h>
44
45
  #include <grpc/support/log.h>
45
46
  #include <grpc/support/string_util.h>
46
47
  #include <grpc/support/sync.h>
48
+ #include <grpc/support/useful.h>
47
49
  #include <openssl/pem.h>
48
50
 
49
51
  /* --- Utils. --- */
@@ -319,9 +321,15 @@ grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
319
321
 
320
322
  /* --- verifier_cb_ctx object. --- */
321
323
 
324
+ typedef enum {
325
+ HTTP_RESPONSE_OPENID = 0,
326
+ HTTP_RESPONSE_KEYS,
327
+ HTTP_RESPONSE_COUNT /* must be last */
328
+ } http_response_index;
329
+
322
330
  typedef struct {
323
331
  grpc_jwt_verifier *verifier;
324
- grpc_pollset *pollset;
332
+ grpc_polling_entity pollent;
325
333
  jose_header *header;
326
334
  grpc_jwt_claims *claims;
327
335
  char *audience;
@@ -329,6 +337,7 @@ typedef struct {
329
337
  gpr_slice signed_data;
330
338
  void *user_data;
331
339
  grpc_jwt_verification_done_cb user_cb;
340
+ grpc_http_response responses[HTTP_RESPONSE_COUNT];
332
341
  } verifier_cb_ctx;
333
342
 
334
343
  /* Takes ownership of the header, claims and signature. */
@@ -337,10 +346,11 @@ static verifier_cb_ctx *verifier_cb_ctx_create(
337
346
  grpc_jwt_claims *claims, const char *audience, gpr_slice signature,
338
347
  const char *signed_jwt, size_t signed_jwt_len, void *user_data,
339
348
  grpc_jwt_verification_done_cb cb) {
349
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
340
350
  verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx));
341
351
  memset(ctx, 0, sizeof(verifier_cb_ctx));
342
352
  ctx->verifier = verifier;
343
- ctx->pollset = pollset;
353
+ ctx->pollent = grpc_polling_entity_create_from_pollset(pollset);
344
354
  ctx->header = header;
345
355
  ctx->audience = gpr_strdup(audience);
346
356
  ctx->claims = claims;
@@ -348,6 +358,7 @@ static verifier_cb_ctx *verifier_cb_ctx_create(
348
358
  ctx->signed_data = gpr_slice_from_copied_buffer(signed_jwt, signed_jwt_len);
349
359
  ctx->user_data = user_data;
350
360
  ctx->user_cb = cb;
361
+ grpc_exec_ctx_finish(&exec_ctx);
351
362
  return ctx;
352
363
  }
353
364
 
@@ -357,6 +368,9 @@ void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) {
357
368
  gpr_slice_unref(ctx->signature);
358
369
  gpr_slice_unref(ctx->signed_data);
359
370
  jose_header_destroy(ctx->header);
371
+ for (size_t i = 0; i < HTTP_RESPONSE_COUNT; i++) {
372
+ grpc_http_response_destroy(&ctx->responses[i]);
373
+ }
360
374
  /* TODO: see what to do with claims... */
361
375
  gpr_free(ctx);
362
376
  }
@@ -571,9 +585,9 @@ end:
571
585
  }
572
586
 
573
587
  static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
574
- const grpc_httpcli_response *response) {
575
- grpc_json *json = json_from_http(response);
588
+ grpc_error *error) {
576
589
  verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data;
590
+ grpc_json *json = json_from_http(&ctx->responses[HTTP_RESPONSE_KEYS]);
577
591
  EVP_PKEY *verification_key = NULL;
578
592
  grpc_jwt_verifier_status status = GRPC_JWT_VERIFIER_GENERIC_ERROR;
579
593
  grpc_jwt_claims *claims = NULL;
@@ -612,10 +626,11 @@ end:
612
626
  }
613
627
 
614
628
  static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
615
- const grpc_httpcli_response *response) {
629
+ grpc_error *error) {
616
630
  const grpc_json *cur;
617
- grpc_json *json = json_from_http(response);
618
631
  verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data;
632
+ const grpc_http_response *response = &ctx->responses[HTTP_RESPONSE_OPENID];
633
+ grpc_json *json = json_from_http(response);
619
634
  grpc_httpcli_request req;
620
635
  const char *jwks_uri;
621
636
 
@@ -641,10 +656,12 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
641
656
  } else {
642
657
  *(req.host + (req.http.path - jwks_uri)) = '\0';
643
658
  }
659
+
644
660
  grpc_httpcli_get(
645
- exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req,
661
+ exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, &req,
646
662
  gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
647
- on_keys_retrieved, ctx);
663
+ grpc_closure_create(on_keys_retrieved, ctx),
664
+ &ctx->responses[HTTP_RESPONSE_KEYS]);
648
665
  grpc_json_destroy(json);
649
666
  gpr_free(req.host);
650
667
  return;
@@ -686,12 +703,13 @@ static void verifier_put_mapping(grpc_jwt_verifier *v, const char *email_domain,
686
703
  static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
687
704
  verifier_cb_ctx *ctx) {
688
705
  const char *at_sign;
689
- grpc_httpcli_response_cb http_cb;
706
+ grpc_closure *http_cb;
690
707
  char *path_prefix = NULL;
691
708
  const char *iss;
692
709
  grpc_httpcli_request req;
693
710
  memset(&req, 0, sizeof(grpc_httpcli_request));
694
711
  req.handshaker = &grpc_httpcli_ssl;
712
+ http_response_index rsp_idx;
695
713
 
696
714
  GPR_ASSERT(ctx != NULL && ctx->header != NULL && ctx->claims != NULL);
697
715
  iss = ctx->claims->iss;
@@ -730,7 +748,8 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
730
748
  *(path_prefix++) = '\0';
731
749
  gpr_asprintf(&req.http.path, "/%s/%s", path_prefix, iss);
732
750
  }
733
- http_cb = on_keys_retrieved;
751
+ http_cb = grpc_closure_create(on_keys_retrieved, ctx);
752
+ rsp_idx = HTTP_RESPONSE_KEYS;
734
753
  } else {
735
754
  req.host = gpr_strdup(strstr(iss, "https://") == iss ? iss + 8 : iss);
736
755
  path_prefix = strchr(req.host, '/');
@@ -741,13 +760,14 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
741
760
  gpr_asprintf(&req.http.path, "/%s%s", path_prefix,
742
761
  GRPC_OPENID_CONFIG_URL_SUFFIX);
743
762
  }
744
- http_cb = on_openid_config_retrieved;
763
+ http_cb = grpc_closure_create(on_openid_config_retrieved, ctx);
764
+ rsp_idx = HTTP_RESPONSE_OPENID;
745
765
  }
746
766
 
747
767
  grpc_httpcli_get(
748
- exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req,
768
+ exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, &req,
749
769
  gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
750
- http_cb, ctx);
770
+ http_cb, &ctx->responses[rsp_idx]);
751
771
  gpr_free(req.host);
752
772
  gpr_free(req.http.path);
753
773
  return;
@@ -31,8 +31,8 @@
31
31
  *
32
32
  */
33
33
 
34
- #ifndef GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H
35
- #define GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H
34
+ #ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H
35
+ #define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H
36
36
 
37
37
  #include "src/core/lib/iomgr/pollset.h"
38
38
  #include "src/core/lib/json/json.h"
@@ -133,4 +133,4 @@ grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, gpr_slice buffer);
133
133
  grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
134
134
  const char *audience);
135
135
 
136
- #endif /* GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H */
136
+ #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H */
@@ -0,0 +1,433 @@
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/lib/security/credentials/oauth2/oauth2_credentials.h"
35
+
36
+ #include <string.h>
37
+
38
+ #include "src/core/lib/security/util/json_util.h"
39
+ #include "src/core/lib/surface/api_trace.h"
40
+
41
+ #include <grpc/support/alloc.h>
42
+ #include <grpc/support/log.h>
43
+ #include <grpc/support/string_util.h>
44
+
45
+ //
46
+ // Auth Refresh Token.
47
+ //
48
+
49
+ int grpc_auth_refresh_token_is_valid(
50
+ const grpc_auth_refresh_token *refresh_token) {
51
+ return (refresh_token != NULL) &&
52
+ strcmp(refresh_token->type, GRPC_AUTH_JSON_TYPE_INVALID);
53
+ }
54
+
55
+ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
56
+ const grpc_json *json) {
57
+ grpc_auth_refresh_token result;
58
+ const char *prop_value;
59
+ int success = 0;
60
+
61
+ memset(&result, 0, sizeof(grpc_auth_refresh_token));
62
+ result.type = GRPC_AUTH_JSON_TYPE_INVALID;
63
+ if (json == NULL) {
64
+ gpr_log(GPR_ERROR, "Invalid json.");
65
+ goto end;
66
+ }
67
+
68
+ prop_value = grpc_json_get_string_property(json, "type");
69
+ if (prop_value == NULL ||
70
+ strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) {
71
+ goto end;
72
+ }
73
+ result.type = GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER;
74
+
75
+ if (!grpc_copy_json_string_property(json, "client_secret",
76
+ &result.client_secret) ||
77
+ !grpc_copy_json_string_property(json, "client_id", &result.client_id) ||
78
+ !grpc_copy_json_string_property(json, "refresh_token",
79
+ &result.refresh_token)) {
80
+ goto end;
81
+ }
82
+ success = 1;
83
+
84
+ end:
85
+ if (!success) grpc_auth_refresh_token_destruct(&result);
86
+ return result;
87
+ }
88
+
89
+ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string(
90
+ const char *json_string) {
91
+ char *scratchpad = gpr_strdup(json_string);
92
+ grpc_json *json = grpc_json_parse_string(scratchpad);
93
+ grpc_auth_refresh_token result =
94
+ grpc_auth_refresh_token_create_from_json(json);
95
+ if (json != NULL) grpc_json_destroy(json);
96
+ gpr_free(scratchpad);
97
+ return result;
98
+ }
99
+
100
+ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) {
101
+ if (refresh_token == NULL) return;
102
+ refresh_token->type = GRPC_AUTH_JSON_TYPE_INVALID;
103
+ if (refresh_token->client_id != NULL) {
104
+ gpr_free(refresh_token->client_id);
105
+ refresh_token->client_id = NULL;
106
+ }
107
+ if (refresh_token->client_secret != NULL) {
108
+ gpr_free(refresh_token->client_secret);
109
+ refresh_token->client_secret = NULL;
110
+ }
111
+ if (refresh_token->refresh_token != NULL) {
112
+ gpr_free(refresh_token->refresh_token);
113
+ refresh_token->refresh_token = NULL;
114
+ }
115
+ }
116
+
117
+ //
118
+ // Oauth2 Token Fetcher credentials.
119
+ //
120
+
121
+ static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) {
122
+ grpc_oauth2_token_fetcher_credentials *c =
123
+ (grpc_oauth2_token_fetcher_credentials *)creds;
124
+ grpc_credentials_md_store_unref(c->access_token_md);
125
+ gpr_mu_destroy(&c->mu);
126
+ grpc_httpcli_context_destroy(&c->httpcli_context);
127
+ }
128
+
129
+ grpc_credentials_status
130
+ grpc_oauth2_token_fetcher_credentials_parse_server_response(
131
+ const grpc_http_response *response, grpc_credentials_md_store **token_md,
132
+ gpr_timespec *token_lifetime) {
133
+ char *null_terminated_body = NULL;
134
+ char *new_access_token = NULL;
135
+ grpc_credentials_status status = GRPC_CREDENTIALS_OK;
136
+ grpc_json *json = NULL;
137
+
138
+ if (response == NULL) {
139
+ gpr_log(GPR_ERROR, "Received NULL response.");
140
+ status = GRPC_CREDENTIALS_ERROR;
141
+ goto end;
142
+ }
143
+
144
+ if (response->body_length > 0) {
145
+ null_terminated_body = gpr_malloc(response->body_length + 1);
146
+ null_terminated_body[response->body_length] = '\0';
147
+ memcpy(null_terminated_body, response->body, response->body_length);
148
+ }
149
+
150
+ if (response->status != 200) {
151
+ gpr_log(GPR_ERROR, "Call to http server ended with error %d [%s].",
152
+ response->status,
153
+ null_terminated_body != NULL ? null_terminated_body : "");
154
+ status = GRPC_CREDENTIALS_ERROR;
155
+ goto end;
156
+ } else {
157
+ grpc_json *access_token = NULL;
158
+ grpc_json *token_type = NULL;
159
+ grpc_json *expires_in = NULL;
160
+ grpc_json *ptr;
161
+ json = grpc_json_parse_string(null_terminated_body);
162
+ if (json == NULL) {
163
+ gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body);
164
+ status = GRPC_CREDENTIALS_ERROR;
165
+ goto end;
166
+ }
167
+ if (json->type != GRPC_JSON_OBJECT) {
168
+ gpr_log(GPR_ERROR, "Response should be a JSON object");
169
+ status = GRPC_CREDENTIALS_ERROR;
170
+ goto end;
171
+ }
172
+ for (ptr = json->child; ptr; ptr = ptr->next) {
173
+ if (strcmp(ptr->key, "access_token") == 0) {
174
+ access_token = ptr;
175
+ } else if (strcmp(ptr->key, "token_type") == 0) {
176
+ token_type = ptr;
177
+ } else if (strcmp(ptr->key, "expires_in") == 0) {
178
+ expires_in = ptr;
179
+ }
180
+ }
181
+ if (access_token == NULL || access_token->type != GRPC_JSON_STRING) {
182
+ gpr_log(GPR_ERROR, "Missing or invalid access_token in JSON.");
183
+ status = GRPC_CREDENTIALS_ERROR;
184
+ goto end;
185
+ }
186
+ if (token_type == NULL || token_type->type != GRPC_JSON_STRING) {
187
+ gpr_log(GPR_ERROR, "Missing or invalid token_type in JSON.");
188
+ status = GRPC_CREDENTIALS_ERROR;
189
+ goto end;
190
+ }
191
+ if (expires_in == NULL || expires_in->type != GRPC_JSON_NUMBER) {
192
+ gpr_log(GPR_ERROR, "Missing or invalid expires_in in JSON.");
193
+ status = GRPC_CREDENTIALS_ERROR;
194
+ goto end;
195
+ }
196
+ gpr_asprintf(&new_access_token, "%s %s", token_type->value,
197
+ access_token->value);
198
+ token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10);
199
+ token_lifetime->tv_nsec = 0;
200
+ token_lifetime->clock_type = GPR_TIMESPAN;
201
+ if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md);
202
+ *token_md = grpc_credentials_md_store_create(1);
203
+ grpc_credentials_md_store_add_cstrings(
204
+ *token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token);
205
+ status = GRPC_CREDENTIALS_OK;
206
+ }
207
+
208
+ end:
209
+ if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) {
210
+ grpc_credentials_md_store_unref(*token_md);
211
+ *token_md = NULL;
212
+ }
213
+ if (null_terminated_body != NULL) gpr_free(null_terminated_body);
214
+ if (new_access_token != NULL) gpr_free(new_access_token);
215
+ if (json != NULL) grpc_json_destroy(json);
216
+ return status;
217
+ }
218
+
219
+ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
220
+ void *user_data,
221
+ grpc_error *error) {
222
+ grpc_credentials_metadata_request *r =
223
+ (grpc_credentials_metadata_request *)user_data;
224
+ grpc_oauth2_token_fetcher_credentials *c =
225
+ (grpc_oauth2_token_fetcher_credentials *)r->creds;
226
+ gpr_timespec token_lifetime;
227
+ grpc_credentials_status status;
228
+
229
+ GRPC_LOG_IF_ERROR("oauth_fetch", GRPC_ERROR_REF(error));
230
+
231
+ gpr_mu_lock(&c->mu);
232
+ status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
233
+ &r->response, &c->access_token_md, &token_lifetime);
234
+ if (status == GRPC_CREDENTIALS_OK) {
235
+ c->token_expiration =
236
+ gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
237
+ r->cb(exec_ctx, r->user_data, c->access_token_md->entries,
238
+ c->access_token_md->num_entries, status);
239
+ } else {
240
+ c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
241
+ r->cb(exec_ctx, r->user_data, NULL, 0, status);
242
+ }
243
+ gpr_mu_unlock(&c->mu);
244
+ grpc_credentials_metadata_request_destroy(r);
245
+ }
246
+
247
+ static void oauth2_token_fetcher_get_request_metadata(
248
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
249
+ grpc_polling_entity *pollent, grpc_auth_metadata_context context,
250
+ grpc_credentials_metadata_cb cb, void *user_data) {
251
+ grpc_oauth2_token_fetcher_credentials *c =
252
+ (grpc_oauth2_token_fetcher_credentials *)creds;
253
+ gpr_timespec refresh_threshold = gpr_time_from_seconds(
254
+ GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN);
255
+ grpc_credentials_md_store *cached_access_token_md = NULL;
256
+ {
257
+ gpr_mu_lock(&c->mu);
258
+ if (c->access_token_md != NULL &&
259
+ (gpr_time_cmp(
260
+ gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_REALTIME)),
261
+ refresh_threshold) > 0)) {
262
+ cached_access_token_md =
263
+ grpc_credentials_md_store_ref(c->access_token_md);
264
+ }
265
+ gpr_mu_unlock(&c->mu);
266
+ }
267
+ if (cached_access_token_md != NULL) {
268
+ cb(exec_ctx, user_data, cached_access_token_md->entries,
269
+ cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK);
270
+ grpc_credentials_md_store_unref(cached_access_token_md);
271
+ } else {
272
+ c->fetch_func(
273
+ exec_ctx,
274
+ grpc_credentials_metadata_request_create(creds, cb, user_data),
275
+ &c->httpcli_context, pollent, on_oauth2_token_fetcher_http_response,
276
+ gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
277
+ }
278
+ }
279
+
280
+ static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c,
281
+ grpc_fetch_oauth2_func fetch_func) {
282
+ memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials));
283
+ c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
284
+ gpr_ref_init(&c->base.refcount, 1);
285
+ gpr_mu_init(&c->mu);
286
+ c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
287
+ c->fetch_func = fetch_func;
288
+ grpc_httpcli_context_init(&c->httpcli_context);
289
+ }
290
+
291
+ //
292
+ // Google Compute Engine credentials.
293
+ //
294
+
295
+ static grpc_call_credentials_vtable compute_engine_vtable = {
296
+ oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata};
297
+
298
+ static void compute_engine_fetch_oauth2(
299
+ grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
300
+ grpc_httpcli_context *httpcli_context, grpc_polling_entity *pollent,
301
+ grpc_iomgr_cb_func response_cb, gpr_timespec deadline) {
302
+ grpc_http_header header = {"Metadata-Flavor", "Google"};
303
+ grpc_httpcli_request request;
304
+ memset(&request, 0, sizeof(grpc_httpcli_request));
305
+ request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
306
+ request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
307
+ request.http.hdr_count = 1;
308
+ request.http.hdrs = &header;
309
+ grpc_httpcli_get(exec_ctx, httpcli_context, pollent, &request, deadline,
310
+ grpc_closure_create(response_cb, metadata_req),
311
+ &metadata_req->response);
312
+ }
313
+
314
+ grpc_call_credentials *grpc_google_compute_engine_credentials_create(
315
+ void *reserved) {
316
+ grpc_oauth2_token_fetcher_credentials *c =
317
+ gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials));
318
+ GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1,
319
+ (reserved));
320
+ GPR_ASSERT(reserved == NULL);
321
+ init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2);
322
+ c->base.vtable = &compute_engine_vtable;
323
+ return &c->base;
324
+ }
325
+
326
+ //
327
+ // Google Refresh Token credentials.
328
+ //
329
+
330
+ static void refresh_token_destruct(grpc_call_credentials *creds) {
331
+ grpc_google_refresh_token_credentials *c =
332
+ (grpc_google_refresh_token_credentials *)creds;
333
+ grpc_auth_refresh_token_destruct(&c->refresh_token);
334
+ oauth2_token_fetcher_destruct(&c->base.base);
335
+ }
336
+
337
+ static grpc_call_credentials_vtable refresh_token_vtable = {
338
+ refresh_token_destruct, oauth2_token_fetcher_get_request_metadata};
339
+
340
+ static void refresh_token_fetch_oauth2(
341
+ grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
342
+ grpc_httpcli_context *httpcli_context, grpc_polling_entity *pollent,
343
+ grpc_iomgr_cb_func response_cb, gpr_timespec deadline) {
344
+ grpc_google_refresh_token_credentials *c =
345
+ (grpc_google_refresh_token_credentials *)metadata_req->creds;
346
+ grpc_http_header header = {"Content-Type",
347
+ "application/x-www-form-urlencoded"};
348
+ grpc_httpcli_request request;
349
+ char *body = NULL;
350
+ gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
351
+ c->refresh_token.client_id, c->refresh_token.client_secret,
352
+ c->refresh_token.refresh_token);
353
+ memset(&request, 0, sizeof(grpc_httpcli_request));
354
+ request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
355
+ request.http.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
356
+ request.http.hdr_count = 1;
357
+ request.http.hdrs = &header;
358
+ request.handshaker = &grpc_httpcli_ssl;
359
+ grpc_httpcli_post(exec_ctx, httpcli_context, pollent, &request, body,
360
+ strlen(body), deadline,
361
+ grpc_closure_create(response_cb, metadata_req),
362
+ &metadata_req->response);
363
+ gpr_free(body);
364
+ }
365
+
366
+ grpc_call_credentials *
367
+ grpc_refresh_token_credentials_create_from_auth_refresh_token(
368
+ grpc_auth_refresh_token refresh_token) {
369
+ grpc_google_refresh_token_credentials *c;
370
+ if (!grpc_auth_refresh_token_is_valid(&refresh_token)) {
371
+ gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation");
372
+ return NULL;
373
+ }
374
+ c = gpr_malloc(sizeof(grpc_google_refresh_token_credentials));
375
+ memset(c, 0, sizeof(grpc_google_refresh_token_credentials));
376
+ init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2);
377
+ c->base.base.vtable = &refresh_token_vtable;
378
+ c->refresh_token = refresh_token;
379
+ return &c->base.base;
380
+ }
381
+
382
+ grpc_call_credentials *grpc_google_refresh_token_credentials_create(
383
+ const char *json_refresh_token, void *reserved) {
384
+ GRPC_API_TRACE(
385
+ "grpc_refresh_token_credentials_create(json_refresh_token=%s, "
386
+ "reserved=%p)",
387
+ 2, (json_refresh_token, reserved));
388
+ GPR_ASSERT(reserved == NULL);
389
+ return grpc_refresh_token_credentials_create_from_auth_refresh_token(
390
+ grpc_auth_refresh_token_create_from_string(json_refresh_token));
391
+ }
392
+
393
+ //
394
+ // Oauth2 Access Token credentials.
395
+ //
396
+
397
+ static void access_token_destruct(grpc_call_credentials *creds) {
398
+ grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
399
+ grpc_credentials_md_store_unref(c->access_token_md);
400
+ }
401
+
402
+ static void access_token_get_request_metadata(
403
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
404
+ grpc_polling_entity *pollent, grpc_auth_metadata_context context,
405
+ grpc_credentials_metadata_cb cb, void *user_data) {
406
+ grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
407
+ cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
408
+ }
409
+
410
+ static grpc_call_credentials_vtable access_token_vtable = {
411
+ access_token_destruct, access_token_get_request_metadata};
412
+
413
+ grpc_call_credentials *grpc_access_token_credentials_create(
414
+ const char *access_token, void *reserved) {
415
+ grpc_access_token_credentials *c =
416
+ gpr_malloc(sizeof(grpc_access_token_credentials));
417
+ char *token_md_value;
418
+ GRPC_API_TRACE(
419
+ "grpc_access_token_credentials_create(access_token=%s, "
420
+ "reserved=%p)",
421
+ 2, (access_token, reserved));
422
+ GPR_ASSERT(reserved == NULL);
423
+ memset(c, 0, sizeof(grpc_access_token_credentials));
424
+ c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
425
+ c->base.vtable = &access_token_vtable;
426
+ gpr_ref_init(&c->base.refcount, 1);
427
+ c->access_token_md = grpc_credentials_md_store_create(1);
428
+ gpr_asprintf(&token_md_value, "Bearer %s", access_token);
429
+ grpc_credentials_md_store_add_cstrings(
430
+ c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value);
431
+ gpr_free(token_md_value);
432
+ return &c->base;
433
+ }