Adding support for service account credentials.
- Tested end to end with a JSON key I generated for my account using the
fetch_oauth2 binary.
- The same fetch_oauth2 binary can get a token from the GCE metadata service on a VM in cloud.
Change on 2014/12/19 by jboeuf <jboeuf@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=82548689
diff --git a/Makefile b/Makefile
index 049d1f8..cbf1f23 100644
--- a/Makefile
+++ b/Makefile
@@ -622,7 +622,7 @@
$(Q) ./bins/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
-tools: privatelibs bins/gen_hpack_tables
+tools: privatelibs bins/gen_hpack_tables bins/grpc_fetch_oauth2
protoc_plugins: bins/cpp_plugin bins/ruby_plugin
@@ -731,7 +731,7 @@
dep_c: deps_libgpr deps_libgrpc deps_libgrpc_test_util deps_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request deps_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs deps_libgrpc_unsecure
-bins_dep_c: deps_gen_hpack_tables deps_grpc_byte_buffer_reader_test deps_gpr_cancellable_test deps_gpr_log_test deps_gpr_useful_test deps_gpr_cmdline_test deps_gpr_histogram_test deps_gpr_host_port_test deps_gpr_slice_buffer_test deps_gpr_slice_test deps_gpr_string_test deps_gpr_sync_test deps_gpr_thd_test deps_gpr_time_test deps_murmur_hash_test deps_grpc_stream_op_test deps_alpn_test deps_time_averaged_stats_test deps_chttp2_stream_encoder_test deps_hpack_table_test deps_chttp2_stream_map_test deps_hpack_parser_test deps_transport_metadata_test deps_chttp2_status_conversion_test deps_chttp2_transport_end2end_test deps_tcp_posix_test deps_dualstack_socket_test deps_no_server_test deps_resolve_address_test deps_sockaddr_utils_test deps_tcp_server_posix_test deps_tcp_client_posix_test deps_grpc_channel_stack_test deps_metadata_buffer_test deps_grpc_completion_queue_test deps_grpc_completion_queue_benchmark deps_census_window_stats_test deps_census_statistics_quick_test deps_census_statistics_small_log_test deps_census_statistics_performance_test deps_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test deps_census_hash_table_test deps_fling_server deps_fling_client deps_fling_test deps_echo_server deps_echo_client deps_echo_test deps_low_level_ping_pong_benchmark deps_message_compress_test deps_bin_encoder_test deps_secure_endpoint_test deps_httpcli_format_request_test deps_httpcli_parser_test deps_httpcli_test deps_grpc_credentials_test deps_grpc_base64_test deps_grpc_json_token_test deps_timeout_encoding_test deps_fd_posix_test deps_fling_stream_test deps_lame_client_test deps_alarm_test deps_time_test deps_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+bins_dep_c: deps_gen_hpack_tables deps_grpc_byte_buffer_reader_test deps_gpr_cancellable_test deps_gpr_log_test deps_gpr_useful_test deps_gpr_cmdline_test deps_gpr_histogram_test deps_gpr_host_port_test deps_gpr_slice_buffer_test deps_gpr_slice_test deps_gpr_string_test deps_gpr_sync_test deps_gpr_thd_test deps_gpr_time_test deps_murmur_hash_test deps_grpc_stream_op_test deps_alpn_test deps_time_averaged_stats_test deps_chttp2_stream_encoder_test deps_hpack_table_test deps_chttp2_stream_map_test deps_hpack_parser_test deps_transport_metadata_test deps_chttp2_status_conversion_test deps_chttp2_transport_end2end_test deps_tcp_posix_test deps_dualstack_socket_test deps_no_server_test deps_resolve_address_test deps_sockaddr_utils_test deps_tcp_server_posix_test deps_tcp_client_posix_test deps_grpc_channel_stack_test deps_metadata_buffer_test deps_grpc_completion_queue_test deps_grpc_completion_queue_benchmark deps_census_window_stats_test deps_census_statistics_quick_test deps_census_statistics_small_log_test deps_census_statistics_performance_test deps_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test deps_census_hash_table_test deps_fling_server deps_fling_client deps_fling_test deps_echo_server deps_echo_client deps_echo_test deps_low_level_ping_pong_benchmark deps_message_compress_test deps_bin_encoder_test deps_secure_endpoint_test deps_httpcli_format_request_test deps_httpcli_parser_test deps_httpcli_test deps_grpc_credentials_test deps_grpc_fetch_oauth2 deps_grpc_base64_test deps_grpc_json_token_test deps_timeout_encoding_test deps_fd_posix_test deps_fling_stream_test deps_lame_client_test deps_alarm_test deps_time_test deps_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
dep_cxx: deps_libgrpc++ deps_libgrpc++_test_util
@@ -779,7 +779,7 @@
$(E) "[INSTALL] Installing libgrpc++.so"
$(Q) $(INSTALL) libs/libgrpc++.so.$(VERSION) $(prefix)/lib/libgrpc++.so.$(VERSION)
-clean: clean_libgpr clean_libgrpc clean_libgrpc_test_util clean_libgrpc++ clean_libgrpc++_test_util clean_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_disappearing_server clean_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_invoke_large_request clean_libend2end_test_max_concurrent_streams clean_libend2end_test_no_op clean_libend2end_test_ping_pong_streaming clean_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_simple_delayed_request clean_libend2end_test_simple_request clean_libend2end_test_thread_stress clean_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_certs clean_libgrpc_unsecure clean_gen_hpack_tables clean_cpp_plugin clean_ruby_plugin clean_grpc_byte_buffer_reader_test clean_gpr_cancellable_test clean_gpr_log_test clean_gpr_useful_test clean_gpr_cmdline_test clean_gpr_histogram_test clean_gpr_host_port_test clean_gpr_slice_buffer_test clean_gpr_slice_test clean_gpr_string_test clean_gpr_sync_test clean_gpr_thd_test clean_gpr_time_test clean_murmur_hash_test clean_grpc_stream_op_test clean_alpn_test clean_time_averaged_stats_test clean_chttp2_stream_encoder_test clean_hpack_table_test clean_chttp2_stream_map_test clean_hpack_parser_test clean_transport_metadata_test clean_chttp2_status_conversion_test clean_chttp2_transport_end2end_test clean_tcp_posix_test clean_dualstack_socket_test clean_no_server_test clean_resolve_address_test clean_sockaddr_utils_test clean_tcp_server_posix_test clean_tcp_client_posix_test clean_grpc_channel_stack_test clean_metadata_buffer_test clean_grpc_completion_queue_test clean_grpc_completion_queue_benchmark clean_census_window_stats_test clean_census_statistics_quick_test clean_census_statistics_small_log_test clean_census_statistics_performance_test clean_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_circular_buffer_test clean_census_stub_test clean_census_hash_table_test clean_fling_server clean_fling_client clean_fling_test clean_echo_server clean_echo_client clean_echo_test clean_low_level_ping_pong_benchmark clean_message_compress_test clean_bin_encoder_test clean_secure_endpoint_test clean_httpcli_format_request_test clean_httpcli_parser_test clean_httpcli_test clean_grpc_credentials_test clean_grpc_base64_test clean_grpc_json_token_test clean_timeout_encoding_test clean_fd_posix_test clean_fling_stream_test clean_lame_client_test clean_thread_pool_test clean_status_test clean_sync_client_async_server_test clean_qps_client clean_qps_server clean_interop_server clean_interop_client clean_end2end_test clean_channel_arguments_test clean_alarm_test clean_time_test clean_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_no_op_test clean_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_no_op_test clean_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+clean: clean_libgpr clean_libgrpc clean_libgrpc_test_util clean_libgrpc++ clean_libgrpc++_test_util clean_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_disappearing_server clean_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_invoke_large_request clean_libend2end_test_max_concurrent_streams clean_libend2end_test_no_op clean_libend2end_test_ping_pong_streaming clean_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_simple_delayed_request clean_libend2end_test_simple_request clean_libend2end_test_thread_stress clean_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_certs clean_libgrpc_unsecure clean_gen_hpack_tables clean_cpp_plugin clean_ruby_plugin clean_grpc_byte_buffer_reader_test clean_gpr_cancellable_test clean_gpr_log_test clean_gpr_useful_test clean_gpr_cmdline_test clean_gpr_histogram_test clean_gpr_host_port_test clean_gpr_slice_buffer_test clean_gpr_slice_test clean_gpr_string_test clean_gpr_sync_test clean_gpr_thd_test clean_gpr_time_test clean_murmur_hash_test clean_grpc_stream_op_test clean_alpn_test clean_time_averaged_stats_test clean_chttp2_stream_encoder_test clean_hpack_table_test clean_chttp2_stream_map_test clean_hpack_parser_test clean_transport_metadata_test clean_chttp2_status_conversion_test clean_chttp2_transport_end2end_test clean_tcp_posix_test clean_dualstack_socket_test clean_no_server_test clean_resolve_address_test clean_sockaddr_utils_test clean_tcp_server_posix_test clean_tcp_client_posix_test clean_grpc_channel_stack_test clean_metadata_buffer_test clean_grpc_completion_queue_test clean_grpc_completion_queue_benchmark clean_census_window_stats_test clean_census_statistics_quick_test clean_census_statistics_small_log_test clean_census_statistics_performance_test clean_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_circular_buffer_test clean_census_stub_test clean_census_hash_table_test clean_fling_server clean_fling_client clean_fling_test clean_echo_server clean_echo_client clean_echo_test clean_low_level_ping_pong_benchmark clean_message_compress_test clean_bin_encoder_test clean_secure_endpoint_test clean_httpcli_format_request_test clean_httpcli_parser_test clean_httpcli_test clean_grpc_credentials_test clean_grpc_fetch_oauth2 clean_grpc_base64_test clean_grpc_json_token_test clean_timeout_encoding_test clean_fd_posix_test clean_fling_stream_test clean_lame_client_test clean_thread_pool_test clean_status_test clean_sync_client_async_server_test clean_qps_client clean_qps_server clean_interop_server clean_interop_client clean_end2end_test clean_channel_arguments_test clean_alarm_test clean_time_test clean_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_no_op_test clean_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_no_op_test clean_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
$(Q) $(RM) -r deps objs libs bins gens
@@ -4137,6 +4137,40 @@
$(Q) $(RM) bins/grpc_credentials_test
+GRPC_FETCH_OAUTH2_SRC = \
+ test/core/security/fetch_oauth2.c \
+
+GRPC_FETCH_OAUTH2_OBJS = $(addprefix objs/, $(addsuffix .o, $(basename $(GRPC_FETCH_OAUTH2_SRC))))
+GRPC_FETCH_OAUTH2_DEPS = $(addprefix deps/, $(addsuffix .dep, $(basename $(GRPC_FETCH_OAUTH2_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/grpc_fetch_oauth2: openssl_dep_error
+
+else
+
+bins/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) libs/libgrpc_test_util.a libs/libgrpc.a libs/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) -Llibs -lgrpc_test_util -lgrpc -lgpr $(LDLIBS) $(LDLIBS_SECURE) -o bins/grpc_fetch_oauth2
+
+endif
+
+deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_FETCH_OAUTH2_DEPS)
+endif
+endif
+
+clean_grpc_fetch_oauth2:
+ $(E) "[CLEAN] Cleaning grpc_fetch_oauth2 files"
+ $(Q) $(RM) $(GRPC_FETCH_OAUTH2_OBJS)
+ $(Q) $(RM) $(GRPC_FETCH_OAUTH2_DEPS)
+ $(Q) $(RM) bins/grpc_fetch_oauth2
+
+
GRPC_BASE64_TEST_SRC = \
test/core/security/base64_test.c \
@@ -8691,4 +8725,4 @@
-.PHONY: all strip tools dep_error openssl_dep_error openssl_dep_message git_update stop buildtests buildtests_c buildtests_cxx test test_c test_cxx install install_c install_cxx install-headers install-headers_c install-headers_cxx install-shared install-shared_c install-shared_cxx install-static install-static_c install-static_cxx strip strip-shared strip-static strip_c strip-shared_c strip-static_c strip_cxx strip-shared_cxx strip-static_cxx clean dep_c dep_cxx bins_dep_c bins_dep_cxx deps_libgpr clean_libgpr deps_libgrpc clean_libgrpc deps_libgrpc_test_util clean_libgrpc_test_util deps_libgrpc++ clean_libgrpc++ deps_libgrpc++_test_util clean_libgrpc++_test_util deps_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_disappearing_server clean_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request clean_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams clean_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op clean_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming clean_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request clean_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request clean_libend2end_test_simple_request deps_libend2end_test_thread_stress clean_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs clean_libend2end_certs deps_libgrpc_unsecure clean_libgrpc_unsecure deps_gen_hpack_tables clean_gen_hpack_tables deps_cpp_plugin clean_cpp_plugin deps_ruby_plugin clean_ruby_plugin deps_grpc_byte_buffer_reader_test clean_grpc_byte_buffer_reader_test deps_gpr_cancellable_test clean_gpr_cancellable_test deps_gpr_log_test clean_gpr_log_test deps_gpr_useful_test clean_gpr_useful_test deps_gpr_cmdline_test clean_gpr_cmdline_test deps_gpr_histogram_test clean_gpr_histogram_test deps_gpr_host_port_test clean_gpr_host_port_test deps_gpr_slice_buffer_test clean_gpr_slice_buffer_test deps_gpr_slice_test clean_gpr_slice_test deps_gpr_string_test clean_gpr_string_test deps_gpr_sync_test clean_gpr_sync_test deps_gpr_thd_test clean_gpr_thd_test deps_gpr_time_test clean_gpr_time_test deps_murmur_hash_test clean_murmur_hash_test deps_grpc_stream_op_test clean_grpc_stream_op_test deps_alpn_test clean_alpn_test deps_time_averaged_stats_test clean_time_averaged_stats_test deps_chttp2_stream_encoder_test clean_chttp2_stream_encoder_test deps_hpack_table_test clean_hpack_table_test deps_chttp2_stream_map_test clean_chttp2_stream_map_test deps_hpack_parser_test clean_hpack_parser_test deps_transport_metadata_test clean_transport_metadata_test deps_chttp2_status_conversion_test clean_chttp2_status_conversion_test deps_chttp2_transport_end2end_test clean_chttp2_transport_end2end_test deps_tcp_posix_test clean_tcp_posix_test deps_dualstack_socket_test clean_dualstack_socket_test deps_no_server_test clean_no_server_test deps_resolve_address_test clean_resolve_address_test deps_sockaddr_utils_test clean_sockaddr_utils_test deps_tcp_server_posix_test clean_tcp_server_posix_test deps_tcp_client_posix_test clean_tcp_client_posix_test deps_grpc_channel_stack_test clean_grpc_channel_stack_test deps_metadata_buffer_test clean_metadata_buffer_test deps_grpc_completion_queue_test clean_grpc_completion_queue_test deps_grpc_completion_queue_benchmark clean_grpc_completion_queue_benchmark deps_census_window_stats_test clean_census_window_stats_test deps_census_statistics_quick_test clean_census_statistics_quick_test deps_census_statistics_small_log_test clean_census_statistics_small_log_test deps_census_statistics_performance_test clean_census_statistics_performance_test deps_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test clean_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test clean_census_stub_test deps_census_hash_table_test clean_census_hash_table_test deps_fling_server clean_fling_server deps_fling_client clean_fling_client deps_fling_test clean_fling_test deps_echo_server clean_echo_server deps_echo_client clean_echo_client deps_echo_test clean_echo_test deps_low_level_ping_pong_benchmark clean_low_level_ping_pong_benchmark deps_message_compress_test clean_message_compress_test deps_bin_encoder_test clean_bin_encoder_test deps_secure_endpoint_test clean_secure_endpoint_test deps_httpcli_format_request_test clean_httpcli_format_request_test deps_httpcli_parser_test clean_httpcli_parser_test deps_httpcli_test clean_httpcli_test deps_grpc_credentials_test clean_grpc_credentials_test deps_grpc_base64_test clean_grpc_base64_test deps_grpc_json_token_test clean_grpc_json_token_test deps_timeout_encoding_test clean_timeout_encoding_test deps_fd_posix_test clean_fd_posix_test deps_fling_stream_test clean_fling_stream_test deps_lame_client_test clean_lame_client_test deps_thread_pool_test clean_thread_pool_test deps_status_test clean_status_test deps_sync_client_async_server_test clean_sync_client_async_server_test deps_qps_client clean_qps_client deps_qps_server clean_qps_server deps_interop_server clean_interop_server deps_interop_client clean_interop_client deps_end2end_test clean_end2end_test deps_channel_arguments_test clean_channel_arguments_test deps_alarm_test clean_alarm_test deps_time_test clean_time_test deps_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test clean_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test clean_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+.PHONY: all strip tools dep_error openssl_dep_error openssl_dep_message git_update stop buildtests buildtests_c buildtests_cxx test test_c test_cxx install install_c install_cxx install-headers install-headers_c install-headers_cxx install-shared install-shared_c install-shared_cxx install-static install-static_c install-static_cxx strip strip-shared strip-static strip_c strip-shared_c strip-static_c strip_cxx strip-shared_cxx strip-static_cxx clean dep_c dep_cxx bins_dep_c bins_dep_cxx deps_libgpr clean_libgpr deps_libgrpc clean_libgrpc deps_libgrpc_test_util clean_libgrpc_test_util deps_libgrpc++ clean_libgrpc++ deps_libgrpc++_test_util clean_libgrpc++_test_util deps_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_disappearing_server clean_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request clean_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams clean_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op clean_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming clean_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request clean_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request clean_libend2end_test_simple_request deps_libend2end_test_thread_stress clean_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs clean_libend2end_certs deps_libgrpc_unsecure clean_libgrpc_unsecure deps_gen_hpack_tables clean_gen_hpack_tables deps_cpp_plugin clean_cpp_plugin deps_ruby_plugin clean_ruby_plugin deps_grpc_byte_buffer_reader_test clean_grpc_byte_buffer_reader_test deps_gpr_cancellable_test clean_gpr_cancellable_test deps_gpr_log_test clean_gpr_log_test deps_gpr_useful_test clean_gpr_useful_test deps_gpr_cmdline_test clean_gpr_cmdline_test deps_gpr_histogram_test clean_gpr_histogram_test deps_gpr_host_port_test clean_gpr_host_port_test deps_gpr_slice_buffer_test clean_gpr_slice_buffer_test deps_gpr_slice_test clean_gpr_slice_test deps_gpr_string_test clean_gpr_string_test deps_gpr_sync_test clean_gpr_sync_test deps_gpr_thd_test clean_gpr_thd_test deps_gpr_time_test clean_gpr_time_test deps_murmur_hash_test clean_murmur_hash_test deps_grpc_stream_op_test clean_grpc_stream_op_test deps_alpn_test clean_alpn_test deps_time_averaged_stats_test clean_time_averaged_stats_test deps_chttp2_stream_encoder_test clean_chttp2_stream_encoder_test deps_hpack_table_test clean_hpack_table_test deps_chttp2_stream_map_test clean_chttp2_stream_map_test deps_hpack_parser_test clean_hpack_parser_test deps_transport_metadata_test clean_transport_metadata_test deps_chttp2_status_conversion_test clean_chttp2_status_conversion_test deps_chttp2_transport_end2end_test clean_chttp2_transport_end2end_test deps_tcp_posix_test clean_tcp_posix_test deps_dualstack_socket_test clean_dualstack_socket_test deps_no_server_test clean_no_server_test deps_resolve_address_test clean_resolve_address_test deps_sockaddr_utils_test clean_sockaddr_utils_test deps_tcp_server_posix_test clean_tcp_server_posix_test deps_tcp_client_posix_test clean_tcp_client_posix_test deps_grpc_channel_stack_test clean_grpc_channel_stack_test deps_metadata_buffer_test clean_metadata_buffer_test deps_grpc_completion_queue_test clean_grpc_completion_queue_test deps_grpc_completion_queue_benchmark clean_grpc_completion_queue_benchmark deps_census_window_stats_test clean_census_window_stats_test deps_census_statistics_quick_test clean_census_statistics_quick_test deps_census_statistics_small_log_test clean_census_statistics_small_log_test deps_census_statistics_performance_test clean_census_statistics_performance_test deps_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test clean_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test clean_census_stub_test deps_census_hash_table_test clean_census_hash_table_test deps_fling_server clean_fling_server deps_fling_client clean_fling_client deps_fling_test clean_fling_test deps_echo_server clean_echo_server deps_echo_client clean_echo_client deps_echo_test clean_echo_test deps_low_level_ping_pong_benchmark clean_low_level_ping_pong_benchmark deps_message_compress_test clean_message_compress_test deps_bin_encoder_test clean_bin_encoder_test deps_secure_endpoint_test clean_secure_endpoint_test deps_httpcli_format_request_test clean_httpcli_format_request_test deps_httpcli_parser_test clean_httpcli_parser_test deps_httpcli_test clean_httpcli_test deps_grpc_credentials_test clean_grpc_credentials_test deps_grpc_fetch_oauth2 clean_grpc_fetch_oauth2 deps_grpc_base64_test clean_grpc_base64_test deps_grpc_json_token_test clean_grpc_json_token_test deps_timeout_encoding_test clean_timeout_encoding_test deps_fd_posix_test clean_fd_posix_test deps_fling_stream_test clean_fling_stream_test deps_lame_client_test clean_lame_client_test deps_thread_pool_test clean_thread_pool_test deps_status_test clean_status_test deps_sync_client_async_server_test clean_sync_client_async_server_test deps_qps_client clean_qps_client deps_qps_server clean_qps_server deps_interop_server clean_interop_server deps_interop_client clean_interop_client deps_end2end_test clean_end2end_test deps_channel_arguments_test clean_channel_arguments_test deps_alarm_test clean_alarm_test deps_time_test clean_time_test deps_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test clean_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test clean_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
diff --git a/build.json b/build.json
index dc64378..50f3ca3 100644
--- a/build.json
+++ b/build.json
@@ -1088,6 +1088,18 @@
]
},
{
+ "name": "grpc_fetch_oauth2",
+ "build": "tool",
+ "src": [
+ "test/core/security/fetch_oauth2.c"
+ ],
+ "deps": [
+ "grpc_test_util",
+ "grpc",
+ "gpr"
+ ]
+ },
+ {
"name": "grpc_base64_test",
"build": "test",
"src": [
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index bfc2e33..442d2fa 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -35,6 +35,7 @@
#include "src/core/httpcli/httpcli.h"
#include "src/core/iomgr/iomgr.h"
+#include "src/core/security/json_token.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string.h>
@@ -47,10 +48,18 @@
#include <stdio.h>
/* -- Constants. -- */
-#define GRPC_COMPUTE_ENGINE_TOKEN_REFRESH_THRESHOLD_SECS 60
+
+#define GRPC_OAUTH2_TOKEN_REFRESH_THRESHOLD_SECS 60
+
#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata"
#define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
- "computeMetadata/v1/instance/service-accounts/default/token"
+ "/computeMetadata/v1/instance/service-accounts/default/token"
+
+#define GRPC_SERVICE_ACCOUNT_HOST "www.googleapis.com"
+#define GRPC_SERVICE_ACCOUNT_TOKEN_PATH "/oauth2/v3/token"
+#define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \
+ "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \
+ "assertion="
/* -- Common. -- */
@@ -234,7 +243,14 @@
return &c->base;
}
-/* -- ComputeEngine credentials. -- */
+/* -- Oauth2TokenFetcher credentials -- */
+
+/* This object is a base for credentials that need to acquire an oauth2 token
+ from an http service. */
+
+typedef void (*grpc_fetch_oauth2_func)(grpc_credentials_metadata_request *req,
+ grpc_httpcli_response_cb response_cb,
+ gpr_timespec deadline);
typedef struct {
grpc_credentials base;
@@ -242,10 +258,12 @@
grpc_mdctx *md_ctx;
grpc_mdelem *access_token_md;
gpr_timespec token_expiration;
-} grpc_compute_engine_credentials;
+ grpc_fetch_oauth2_func fetch_func;
+} grpc_oauth2_token_fetcher_credentials;
-static void compute_engine_destroy(grpc_credentials *creds) {
- grpc_compute_engine_credentials *c = (grpc_compute_engine_credentials *)creds;
+static void oauth2_token_fetcher_destroy(grpc_credentials *creds) {
+ grpc_oauth2_token_fetcher_credentials *c =
+ (grpc_oauth2_token_fetcher_credentials *)creds;
if (c->access_token_md != NULL) {
grpc_mdelem_unref(c->access_token_md);
}
@@ -254,16 +272,18 @@
gpr_free(c);
}
-static int compute_engine_has_request_metadata(const grpc_credentials *creds) {
- return 1;
-}
-
-static int compute_engine_has_request_metadata_only(
+static int oauth2_token_fetcher_has_request_metadata(
const grpc_credentials *creds) {
return 1;
}
-grpc_credentials_status grpc_compute_engine_credentials_parse_server_response(
+static int oauth2_token_fetcher_has_request_metadata_only(
+ const grpc_credentials *creds) {
+ return 1;
+}
+
+grpc_credentials_status
+grpc_oauth2_token_fetcher_credentials_parse_server_response(
const grpc_httpcli_response *response, grpc_mdctx *ctx,
grpc_mdelem **token_elem, gpr_timespec *token_lifetime) {
char *null_terminated_body = NULL;
@@ -271,9 +291,16 @@
grpc_credentials_status status = GRPC_CREDENTIALS_OK;
cJSON *json = NULL;
+ if (response->body_length > 0) {
+ null_terminated_body = gpr_malloc(response->body_length + 1);
+ null_terminated_body[response->body_length] = '\0';
+ memcpy(null_terminated_body, response->body, response->body_length);
+ }
+
if (response->status != 200) {
- gpr_log(GPR_ERROR, "Call to metadata server ended with error %d",
- response->status);
+ gpr_log(GPR_ERROR, "Call to http server ended with error %d [%s].",
+ response->status,
+ null_terminated_body != NULL ? null_terminated_body : "");
status = GRPC_CREDENTIALS_ERROR;
goto end;
} else {
@@ -281,9 +308,6 @@
cJSON *token_type = NULL;
cJSON *expires_in = NULL;
size_t new_access_token_size = 0;
- null_terminated_body = gpr_malloc(response->body_length + 1);
- null_terminated_body[response->body_length] = '\0';
- memcpy(null_terminated_body, response->body, response->body_length);
json = cJSON_Parse(null_terminated_body);
if (json == NULL) {
gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body);
@@ -338,17 +362,17 @@
return status;
}
-static void on_compute_engine_token_response(
+static void on_oauth2_token_fetcher_http_response(
void *user_data, const grpc_httpcli_response *response) {
grpc_credentials_metadata_request *r =
(grpc_credentials_metadata_request *)user_data;
- grpc_compute_engine_credentials *c =
- (grpc_compute_engine_credentials *)r->creds;
+ grpc_oauth2_token_fetcher_credentials *c =
+ (grpc_oauth2_token_fetcher_credentials *)r->creds;
gpr_timespec token_lifetime;
grpc_credentials_status status;
gpr_mu_lock(&c->mu);
- status = grpc_compute_engine_credentials_parse_server_response(
+ status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
response, c->md_ctx, &c->access_token_md, &token_lifetime);
if (status == GRPC_CREDENTIALS_OK) {
c->token_expiration = gpr_time_add(gpr_now(), token_lifetime);
@@ -361,51 +385,149 @@
grpc_credentials_metadata_request_destroy(r);
}
-static void compute_engine_get_request_metadata(grpc_credentials *creds,
- grpc_credentials_metadata_cb cb,
- void *user_data) {
- grpc_compute_engine_credentials *c = (grpc_compute_engine_credentials *)creds;
- gpr_timespec refresh_threshold = {
- GRPC_COMPUTE_ENGINE_TOKEN_REFRESH_THRESHOLD_SECS, 0};
-
- gpr_mu_lock(&c->mu);
- if (c->access_token_md == NULL ||
- (gpr_time_cmp(gpr_time_sub(gpr_now(), c->token_expiration),
- refresh_threshold) < 0)) {
- grpc_httpcli_header header = {"Metadata-Flavor", "Google"};
- grpc_httpcli_request request;
- request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
- request.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
- request.hdr_count = 1;
- request.hdrs = &header;
- grpc_httpcli_get(
- &request, gpr_time_add(gpr_now(), refresh_threshold),
- on_compute_engine_token_response,
- grpc_credentials_metadata_request_create(creds, cb, user_data));
- } else {
- cb(user_data, &c->access_token_md, 1, GRPC_CREDENTIALS_OK);
+static void oauth2_token_fetcher_get_request_metadata(
+ grpc_credentials *creds, grpc_credentials_metadata_cb cb, void *user_data) {
+ grpc_oauth2_token_fetcher_credentials *c =
+ (grpc_oauth2_token_fetcher_credentials *)creds;
+ gpr_timespec refresh_threshold = {GRPC_OAUTH2_TOKEN_REFRESH_THRESHOLD_SECS,
+ 0};
+ grpc_mdelem *cached_access_token_md = NULL;
+ {
+ gpr_mu_lock(&c->mu);
+ if (c->access_token_md != NULL &&
+ (gpr_time_cmp(gpr_time_sub(c->token_expiration, gpr_now()),
+ refresh_threshold) > 0)) {
+ cached_access_token_md = grpc_mdelem_ref(c->access_token_md);
+ }
+ gpr_mu_unlock(&c->mu);
}
- gpr_mu_unlock(&c->mu);
+ if (cached_access_token_md != NULL) {
+ cb(user_data, &cached_access_token_md, 1, GRPC_CREDENTIALS_OK);
+ grpc_mdelem_unref(cached_access_token_md);
+ } else {
+ c->fetch_func(
+ grpc_credentials_metadata_request_create(creds, cb, user_data),
+ on_oauth2_token_fetcher_http_response,
+ gpr_time_add(gpr_now(), refresh_threshold));
+ }
}
-static grpc_credentials_vtable compute_engine_vtable = {
- compute_engine_destroy, compute_engine_has_request_metadata,
- compute_engine_has_request_metadata_only,
- compute_engine_get_request_metadata};
-
-grpc_credentials *grpc_compute_engine_credentials_create(void) {
- grpc_compute_engine_credentials *c =
- gpr_malloc(sizeof(grpc_compute_engine_credentials));
- memset(c, 0, sizeof(grpc_compute_engine_credentials));
+static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c,
+ grpc_fetch_oauth2_func fetch_func) {
+ memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials));
c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
- c->base.vtable = &compute_engine_vtable;
gpr_ref_init(&c->base.refcount, 1);
gpr_mu_init(&c->mu);
c->md_ctx = grpc_mdctx_create();
c->token_expiration = gpr_inf_past;
+ c->fetch_func = fetch_func;
+}
+
+/* -- ComputeEngine credentials. -- */
+
+static grpc_credentials_vtable compute_engine_vtable = {
+ oauth2_token_fetcher_destroy, oauth2_token_fetcher_has_request_metadata,
+ oauth2_token_fetcher_has_request_metadata_only,
+ oauth2_token_fetcher_get_request_metadata};
+
+static void compute_engine_fetch_oauth2(
+ grpc_credentials_metadata_request *metadata_req,
+ grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
+ grpc_httpcli_header header = {"Metadata-Flavor", "Google"};
+ grpc_httpcli_request request;
+ memset(&request, 0, sizeof(grpc_httpcli_request));
+ request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
+ request.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
+ request.hdr_count = 1;
+ request.hdrs = &header;
+ grpc_httpcli_get(&request, deadline, response_cb, metadata_req);
+}
+
+grpc_credentials *grpc_compute_engine_credentials_create(void) {
+ grpc_oauth2_token_fetcher_credentials *c =
+ gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials));
+ init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2);
+ c->base.vtable = &compute_engine_vtable;
return &c->base;
}
+/* -- ServiceAccount credentials. -- */
+
+typedef struct {
+ grpc_oauth2_token_fetcher_credentials base;
+ grpc_auth_json_key key;
+ char *scope;
+ gpr_timespec token_lifetime;
+} grpc_service_account_credentials;
+
+static void service_account_destroy(grpc_credentials *creds) {
+ grpc_service_account_credentials *c =
+ (grpc_service_account_credentials *)creds;
+ if (c->scope != NULL) gpr_free(c->scope);
+ grpc_auth_json_key_destruct(&c->key);
+ oauth2_token_fetcher_destroy(&c->base.base);
+}
+
+static grpc_credentials_vtable service_account_vtable = {
+ service_account_destroy, oauth2_token_fetcher_has_request_metadata,
+ oauth2_token_fetcher_has_request_metadata_only,
+ oauth2_token_fetcher_get_request_metadata};
+
+static void service_account_fetch_oauth2(
+ grpc_credentials_metadata_request *metadata_req,
+ grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
+ grpc_service_account_credentials *c =
+ (grpc_service_account_credentials *)metadata_req->creds;
+ grpc_httpcli_header header = {"Content-Type",
+ "application/x-www-form-urlencoded"};
+ grpc_httpcli_request request;
+ char *body = NULL;
+ char *jwt = grpc_jwt_encode_and_sign(&c->key, c->scope, c->token_lifetime);
+ if (jwt == NULL) {
+ grpc_httpcli_response response;
+ memset(&response, 0, sizeof(grpc_httpcli_response));
+ response.status = 400; /* Invalid request. */
+ gpr_log(GPR_ERROR, "Could not create signed jwt.");
+ /* Do not even send the request, just call the response callback. */
+ response_cb(metadata_req, &response);
+ return;
+ }
+ body = gpr_malloc(strlen(GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX) +
+ strlen(jwt) + 1);
+ sprintf(body, "%s%s", GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX, jwt);
+ memset(&request, 0, sizeof(grpc_httpcli_request));
+ request.host = GRPC_SERVICE_ACCOUNT_HOST;
+ request.path = GRPC_SERVICE_ACCOUNT_TOKEN_PATH;
+ request.hdr_count = 1;
+ request.hdrs = &header;
+ request.use_ssl = 1;
+ grpc_httpcli_post(&request, body, strlen(body), deadline, response_cb,
+ metadata_req);
+ gpr_free(body);
+ gpr_free(jwt);
+}
+
+grpc_credentials *grpc_service_account_credentials_create(
+ const char *json_key, const char *scope, gpr_timespec token_lifetime) {
+ grpc_service_account_credentials *c;
+ grpc_auth_json_key key = grpc_auth_json_key_create_from_string(json_key);
+
+ if (scope == NULL || (strlen(scope) == 0) ||
+ !grpc_auth_json_key_is_valid(&key)) {
+ gpr_log(GPR_ERROR,
+ "Invalid input for service account credentials creation");
+ return NULL;
+ }
+ c = gpr_malloc(sizeof(grpc_service_account_credentials));
+ memset(c, 0, sizeof(grpc_service_account_credentials));
+ init_oauth2_token_fetcher(&c->base, service_account_fetch_oauth2);
+ c->base.base.vtable = &service_account_vtable;
+ c->scope = gpr_strdup(scope);
+ c->key = key;
+ c->token_lifetime = token_lifetime;
+ return &c->base.base;
+}
+
/* -- Fake Oauth2 credentials. -- */
typedef struct {
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 9fb82e1..036a444 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -109,7 +109,8 @@
grpc_credentials *composite_creds);
/* Exposed for testing only. */
-grpc_credentials_status grpc_compute_engine_credentials_parse_server_response(
+grpc_credentials_status
+grpc_oauth2_token_fetcher_credentials_parse_server_response(
const struct grpc_httpcli_response *response, grpc_mdctx *ctx,
grpc_mdelem **token_elem, gpr_timespec *token_lifetime);
diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c
index 440dd8a..14ee758 100644
--- a/src/core/security/json_token.c
+++ b/src/core/security/json_token.c
@@ -58,6 +58,10 @@
#define GRPC_JWT_RSA_SHA256_ALGORITHM "RS256"
#define GRPC_JWT_TYPE "JWT"
+/* --- Override for testing. --- */
+
+static grpc_jwt_encode_and_sign_override g_jwt_encode_and_sign_override = NULL;
+
/* --- grpc_auth_json_key. --- */
static const char *json_get_string_property(cJSON *json,
@@ -79,7 +83,7 @@
return 1;
}
-int grpc_auth_json_key_is_valid(grpc_auth_json_key *json_key) {
+int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key) {
return (json_key != NULL) &&
strcmp(json_key->type, GRPC_AUTH_JSON_KEY_TYPE_INVALID);
}
@@ -277,14 +281,23 @@
char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key,
const char *scope, gpr_timespec token_lifetime) {
- const char *sig_algo = GRPC_JWT_RSA_SHA256_ALGORITHM;
- char *to_sign = dot_concat_and_free_strings(
- encoded_jwt_header(sig_algo),
- encoded_jwt_claim(json_key, scope, token_lifetime));
- char *sig = compute_and_encode_signature(json_key, sig_algo, to_sign);
- if (sig == NULL) {
- gpr_free(to_sign);
- return NULL;
+ if (g_jwt_encode_and_sign_override != NULL) {
+ return g_jwt_encode_and_sign_override(json_key, scope, token_lifetime);
+ } else {
+ const char *sig_algo = GRPC_JWT_RSA_SHA256_ALGORITHM;
+ char *to_sign = dot_concat_and_free_strings(
+ encoded_jwt_header(sig_algo),
+ encoded_jwt_claim(json_key, scope, token_lifetime));
+ char *sig = compute_and_encode_signature(json_key, sig_algo, to_sign);
+ if (sig == NULL) {
+ gpr_free(to_sign);
+ return NULL;
+ }
+ return dot_concat_and_free_strings(to_sign, sig);
}
- return dot_concat_and_free_strings(to_sign, sig);
+}
+
+void grpc_jwt_encode_and_sign_set_override(
+ grpc_jwt_encode_and_sign_override func) {
+ g_jwt_encode_and_sign_override = func;
}
diff --git a/src/core/security/json_token.h b/src/core/security/json_token.h
index 2a1f825..3ef9f1b 100644
--- a/src/core/security/json_token.h
+++ b/src/core/security/json_token.h
@@ -37,7 +37,7 @@
#include <grpc/support/slice.h>
#include <openssl/rsa.h>
-/* --- auth_json_key parsing. Exposed for testing only. --- */
+/* --- auth_json_key parsing. --- */
typedef struct {
char *type;
@@ -48,7 +48,7 @@
} grpc_auth_json_key;
/* Returns 1 if the object is valid, 0 otherwise. */
-int grpc_auth_json_key_is_valid(grpc_auth_json_key *json_key);
+int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key);
/* Creates a json_key object from string. Returns an invalid object if a parsing
error has been encountered. */
@@ -65,4 +65,13 @@
char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key,
const char *scope, gpr_timespec token_lifetime);
+/* Override encode_and_sign function for testing. */
+typedef char *(*grpc_jwt_encode_and_sign_override)(
+ const grpc_auth_json_key *json_key, const char *scope,
+ gpr_timespec token_lifetime);
+
+/* Set a custom encode_and_sign override for testing. */
+void grpc_jwt_encode_and_sign_set_override(
+ grpc_jwt_encode_and_sign_override func);
+
#endif /* __GRPC_INTERNAL_SECURITY_JSON_TOKEN_H_ */
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 7eca844..619f093 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -33,12 +33,16 @@
#include "src/core/security/credentials.h"
+#include <string.h>
+
#include "src/core/httpcli/httpcli.h"
+#include "src/core/security/json_token.h"
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/string.h>
#include <grpc/support/time.h>
#include "test/core/util/test_config.h"
-
-#include <string.h>
+#include <openssl/rsa.h>
static const char test_iam_authorization_token[] = "blahblahblhahb";
static const char test_iam_authority_selector[] = "respectmyauthoritah";
@@ -46,30 +50,86 @@
"Bearer blaaslkdjfaslkdfasdsfasf";
static const unsigned char test_root_cert[] = {0xDE, 0xAD, 0xBE, 0xEF};
+/* This JSON key was generated with the GCE console and revoked immediately.
+ The identifiers have been changed as well.
+ Maximum size for a string literal is 509 chars in C89, yay! */
+static const char test_json_key_str_part1[] =
+ "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
+ "\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\n7mJEqg"
+ "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\nyjSeg/"
+ "rWBQvS4hle4LfijkP3J5BG+"
+ "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\nOnVF6N7dL3nTYZg+"
+ "uQrNsMTz9UxVAgMBAAECgYEAzbLewe1xe9vy+2GoSsfib+28\nDZgSE6Bu/"
+ "zuFoPrRc6qL9p2SsnV7txrunTyJkkOnPLND9ABAXybRTlcVKP/sGgza\n/"
+ "8HpCqFYM9V8f34SBWfD4fRFT+n/"
+ "73cfRUtGXdXpseva2lh8RilIQfPhNZAncenU\ngqXjDvpkypEusgXAykECQQD+";
+static const char test_json_key_str_part2[] =
+ "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\nCslxoHQM8s+"
+ "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\nEkoy2L/"
+ "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\nAARh2QJBAMKeDAG"
+ "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\n8FZi5c8idxiwC36kbAL6HzA"
+ "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\n6z8RJm0+"
+ "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
+ "5nZ68ECQQDvYuI3\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZY"
+ "Ap6LI9W\nIqv4vr6y38N79TTC\n-----END PRIVATE KEY-----\n\", ";
+static const char test_json_key_str_part3[] =
+ "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
+ "\"client_email\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
+ "com\", \"client_id\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
+ "com\", \"type\": \"service_account\" }";
+
+static const char valid_oauth2_json_response[] =
+ "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
+ " \"expires_in\":3599, "
+ " \"token_type\":\"Bearer\"}";
+
+static const char test_user_data[] = "user data";
+
+static const char test_scope[] = "perm1 perm2";
+
+static const char test_signed_jwt[] = "signed jwt";
+
+static const char expected_service_account_http_body_prefix[] =
+ "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&"
+ "assertion=";
+
+static char *test_json_key_str(void) {
+ size_t result_len = strlen(test_json_key_str_part1) +
+ strlen(test_json_key_str_part2) +
+ strlen(test_json_key_str_part3);
+ char *result = gpr_malloc(result_len + 1);
+ char *current = result;
+ strcpy(result, test_json_key_str_part1);
+ current += strlen(test_json_key_str_part1);
+ strcpy(current, test_json_key_str_part2);
+ current += strlen(test_json_key_str_part2);
+ strcpy(current, test_json_key_str_part3);
+ return result;
+}
+
typedef struct {
const char *key;
const char *value;
} expected_md;
-static grpc_httpcli_response http_response(int status, char *body) {
+static grpc_httpcli_response http_response(int status, const char *body) {
grpc_httpcli_response response;
memset(&response, 0, sizeof(grpc_httpcli_response));
response.status = status;
- response.body = body;
+ response.body = (char *)body;
response.body_length = strlen(body);
return response;
}
-static void test_compute_engine_creds_parsing_ok(void) {
+static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
grpc_mdctx *ctx = grpc_mdctx_create();
grpc_mdelem *token_elem = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response =
- http_response(200,
- "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
- " \"expires_in\":3599, "
- " \"token_type\":\"Bearer\"}");
- GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+ http_response(200, valid_oauth2_json_response);
+ GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
&response, ctx, &token_elem, &token_lifetime) ==
GRPC_CREDENTIALS_OK);
GPR_ASSERT(token_lifetime.tv_sec == 3599);
@@ -81,33 +141,30 @@
grpc_mdctx_orphan(ctx);
}
-static void test_compute_engine_creds_parsing_bad_http_status(void) {
+static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
grpc_mdctx *ctx = grpc_mdctx_create();
grpc_mdelem *token_elem = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response =
- http_response(401,
- "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
- " \"expires_in\":3599, "
- " \"token_type\":\"Bearer\"}");
- GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+ http_response(401, valid_oauth2_json_response);
+ GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
&response, ctx, &token_elem, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_mdctx_orphan(ctx);
}
-static void test_compute_engine_creds_parsing_empty_http_body(void) {
+static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
grpc_mdctx *ctx = grpc_mdctx_create();
grpc_mdelem *token_elem = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response = http_response(200, "");
- GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+ GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
&response, ctx, &token_elem, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_mdctx_orphan(ctx);
}
-static void test_compute_engine_creds_parsing_invalid_json(void) {
+static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
grpc_mdctx *ctx = grpc_mdctx_create();
grpc_mdelem *token_elem = NULL;
gpr_timespec token_lifetime;
@@ -116,13 +173,13 @@
"{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
" \"expires_in\":3599, "
" \"token_type\":\"Bearer\"");
- GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+ GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
&response, ctx, &token_elem, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_mdctx_orphan(ctx);
}
-static void test_compute_engine_creds_parsing_missing_token(void) {
+static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
grpc_mdctx *ctx = grpc_mdctx_create();
grpc_mdelem *token_elem = NULL;
gpr_timespec token_lifetime;
@@ -130,13 +187,13 @@
"{"
" \"expires_in\":3599, "
" \"token_type\":\"Bearer\"}");
- GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+ GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
&response, ctx, &token_elem, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_mdctx_orphan(ctx);
}
-static void test_compute_engine_creds_parsing_missing_token_type(void) {
+static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
grpc_mdctx *ctx = grpc_mdctx_create();
grpc_mdelem *token_elem = NULL;
gpr_timespec token_lifetime;
@@ -145,13 +202,14 @@
"{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
" \"expires_in\":3599, "
"}");
- GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+ GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
&response, ctx, &token_elem, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_mdctx_orphan(ctx);
}
-static void test_compute_engine_creds_parsing_missing_token_lifetime(void) {
+static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
+ void) {
grpc_mdctx *ctx = grpc_mdctx_create();
grpc_mdelem *token_elem = NULL;
gpr_timespec token_lifetime;
@@ -159,7 +217,7 @@
http_response(200,
"{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
" \"token_type\":\"Bearer\"}");
- GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+ GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
&response, ctx, &token_elem, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_mdctx_orphan(ctx);
@@ -285,17 +343,285 @@
composite_creds);
}
+static void on_oauth2_creds_get_metadata_success(
+ void *user_data, grpc_mdelem **md_elems, size_t num_md,
+ grpc_credentials_status status) {
+ GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
+ GPR_ASSERT(num_md == 1);
+ GPR_ASSERT(
+ !strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), "Authorization"));
+ GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
+ "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"));
+ GPR_ASSERT(user_data != NULL);
+ GPR_ASSERT(!strcmp((const char *)user_data, test_user_data));
+}
+
+static void on_oauth2_creds_get_metadata_failure(
+ void *user_data, grpc_mdelem **md_elems, size_t num_md,
+ grpc_credentials_status status) {
+ GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
+ GPR_ASSERT(num_md == 0);
+ GPR_ASSERT(user_data != NULL);
+ GPR_ASSERT(!strcmp((const char *)user_data, test_user_data));
+}
+
+static void validate_compute_engine_http_request(
+ const grpc_httpcli_request *request) {
+ GPR_ASSERT(!request->use_ssl);
+ GPR_ASSERT(!strcmp(request->host, "metadata"));
+ GPR_ASSERT(
+ !strcmp(request->path,
+ "/computeMetadata/v1/instance/service-accounts/default/token"));
+ GPR_ASSERT(request->hdr_count == 1);
+ GPR_ASSERT(!strcmp(request->hdrs[0].key, "Metadata-Flavor"));
+ GPR_ASSERT(!strcmp(request->hdrs[0].value, "Google"));
+}
+
+static int compute_engine_httpcli_get_success_override(
+ const grpc_httpcli_request *request, gpr_timespec deadline,
+ grpc_httpcli_response_cb on_response, void *user_data) {
+ grpc_httpcli_response response =
+ http_response(200, valid_oauth2_json_response);
+ validate_compute_engine_http_request(request);
+ on_response(user_data, &response);
+ return 1;
+}
+
+static int compute_engine_httpcli_get_failure_override(
+ const grpc_httpcli_request *request, gpr_timespec deadline,
+ grpc_httpcli_response_cb on_response, void *user_data) {
+ grpc_httpcli_response response = http_response(403, "Not Authorized.");
+ validate_compute_engine_http_request(request);
+ on_response(user_data, &response);
+ return 1;
+}
+
+static int httpcli_post_should_not_be_called(
+ const grpc_httpcli_request *request, const char *body_bytes,
+ size_t body_size, gpr_timespec deadline,
+ grpc_httpcli_response_cb on_response, void *user_data) {
+ GPR_ASSERT("HTTP POST should not be called" == NULL);
+ return 1;
+}
+
+static int httpcli_get_should_not_be_called(
+ const grpc_httpcli_request *request, gpr_timespec deadline,
+ grpc_httpcli_response_cb on_response, void *user_data) {
+ GPR_ASSERT("HTTP GET should not be called" == NULL);
+ return 1;
+}
+
+static void test_compute_engine_creds_success(void) {
+ grpc_credentials *compute_engine_creds =
+ grpc_compute_engine_credentials_create();
+ GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
+ GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
+
+ /* First request: http get should be called. */
+ grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
+ httpcli_post_should_not_be_called);
+ grpc_credentials_get_request_metadata(compute_engine_creds,
+ on_oauth2_creds_get_metadata_success,
+ (void *)test_user_data);
+
+ /* Second request: the cached token should be served directly. */
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ httpcli_post_should_not_be_called);
+ grpc_credentials_get_request_metadata(compute_engine_creds,
+ on_oauth2_creds_get_metadata_success,
+ (void *)test_user_data);
+
+ grpc_credentials_unref(compute_engine_creds);
+ grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void test_compute_engine_creds_failure(void) {
+ grpc_credentials *compute_engine_creds =
+ grpc_compute_engine_credentials_create();
+ grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
+ httpcli_post_should_not_be_called);
+ GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
+ GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
+ grpc_credentials_get_request_metadata(compute_engine_creds,
+ on_oauth2_creds_get_metadata_failure,
+ (void *)test_user_data);
+ grpc_credentials_unref(compute_engine_creds);
+ grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void validate_jwt_encode_and_sign_params(
+ const grpc_auth_json_key *json_key, const char *scope,
+ gpr_timespec token_lifetime) {
+ GPR_ASSERT(grpc_auth_json_key_is_valid(json_key));
+ GPR_ASSERT(json_key->private_key != NULL);
+ GPR_ASSERT(RSA_check_key(json_key->private_key));
+ GPR_ASSERT(json_key->type != NULL &&
+ !(strcmp(json_key->type, "service_account")));
+ GPR_ASSERT(json_key->private_key_id != NULL &&
+ !strcmp(json_key->private_key_id,
+ "e6b5137873db8d2ef81e06a47289e6434ec8a165"));
+ GPR_ASSERT(json_key->client_id != NULL &&
+ !strcmp(json_key->client_id,
+ "777-abaslkan11hlb6nmim3bpspl31ud.apps."
+ "googleusercontent.com"));
+ GPR_ASSERT(json_key->client_email != NULL &&
+ !strcmp(json_key->client_email,
+ "777-abaslkan11hlb6nmim3bpspl31ud@developer."
+ "gserviceaccount.com"));
+ GPR_ASSERT(!strcmp(scope, test_scope));
+ GPR_ASSERT(!gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime));
+}
+
+static char *encode_and_sign_jwt_success(const grpc_auth_json_key *json_key,
+ const char *scope,
+ gpr_timespec token_lifetime) {
+ validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
+ return gpr_strdup(test_signed_jwt);
+}
+
+static char *encode_and_sign_jwt_failure(const grpc_auth_json_key *json_key,
+ const char *scope,
+ gpr_timespec token_lifetime) {
+ validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
+ return NULL;
+}
+
+static char *encode_and_sign_jwt_should_not_be_called(
+ const grpc_auth_json_key *json_key, const char *scope,
+ gpr_timespec token_lifetime) {
+ GPR_ASSERT("grpc_jwt_encode_and_sign should not be called" == NULL);
+}
+
+static void validate_service_account_http_request(
+ const grpc_httpcli_request *request, const char *body, size_t body_size) {
+ /* The content of the assertion is tested extensively in json_token_test. */
+ char *expected_body = NULL;
+ GPR_ASSERT(body != NULL);
+ GPR_ASSERT(body_size != 0);
+ expected_body = gpr_malloc(strlen(expected_service_account_http_body_prefix) +
+ strlen(test_signed_jwt) + 1);
+ sprintf(expected_body, "%s%s", expected_service_account_http_body_prefix,
+ test_signed_jwt);
+ GPR_ASSERT(strlen(expected_body) == body_size);
+ GPR_ASSERT(!memcmp(expected_body, body, body_size));
+ gpr_free(expected_body);
+ GPR_ASSERT(request->use_ssl);
+ GPR_ASSERT(!strcmp(request->host, "www.googleapis.com"));
+ GPR_ASSERT(!strcmp(request->path, "/oauth2/v3/token"));
+ GPR_ASSERT(request->hdr_count == 1);
+ GPR_ASSERT(!strcmp(request->hdrs[0].key, "Content-Type"));
+ GPR_ASSERT(
+ !strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded"));
+}
+
+static int service_account_httpcli_post_success(
+ const grpc_httpcli_request *request, const char *body, size_t body_size,
+ gpr_timespec deadline, grpc_httpcli_response_cb on_response,
+ void *user_data) {
+ grpc_httpcli_response response =
+ http_response(200, valid_oauth2_json_response);
+ validate_service_account_http_request(request, body, body_size);
+ on_response(user_data, &response);
+ return 1;
+}
+
+static int service_account_httpcli_post_failure(
+ const grpc_httpcli_request *request, const char *body, size_t body_size,
+ gpr_timespec deadline, grpc_httpcli_response_cb on_response,
+ void *user_data) {
+ grpc_httpcli_response response = http_response(403, "Not Authorized.");
+ validate_service_account_http_request(request, body, body_size);
+ on_response(user_data, &response);
+ return 1;
+}
+
+static void test_service_accounts_creds_success(void) {
+ char *json_key_string = test_json_key_str();
+ grpc_credentials *service_account_creds =
+ grpc_service_account_credentials_create(json_key_string, test_scope,
+ grpc_max_auth_token_lifetime);
+ GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
+ GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
+
+ /* First request: http get should be called. */
+ grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ service_account_httpcli_post_success);
+ grpc_credentials_get_request_metadata(service_account_creds,
+ on_oauth2_creds_get_metadata_success,
+ (void *)test_user_data);
+
+ /* Second request: the cached token should be served directly. */
+ grpc_jwt_encode_and_sign_set_override(
+ encode_and_sign_jwt_should_not_be_called);
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ httpcli_post_should_not_be_called);
+ grpc_credentials_get_request_metadata(service_account_creds,
+ on_oauth2_creds_get_metadata_success,
+ (void *)test_user_data);
+
+ gpr_free(json_key_string);
+ grpc_credentials_unref(service_account_creds);
+ grpc_jwt_encode_and_sign_set_override(NULL);
+ grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void test_service_accounts_creds_http_failure(void) {
+ char *json_key_string = test_json_key_str();
+ grpc_credentials *service_account_creds =
+ grpc_service_account_credentials_create(json_key_string, test_scope,
+ grpc_max_auth_token_lifetime);
+ GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
+ GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
+
+ grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ service_account_httpcli_post_failure);
+ grpc_credentials_get_request_metadata(service_account_creds,
+ on_oauth2_creds_get_metadata_failure,
+ (void *)test_user_data);
+
+ gpr_free(json_key_string);
+ grpc_credentials_unref(service_account_creds);
+ grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void test_service_accounts_creds_signing_failure(void) {
+ char *json_key_string = test_json_key_str();
+ grpc_credentials *service_account_creds =
+ grpc_service_account_credentials_create(json_key_string, test_scope,
+ grpc_max_auth_token_lifetime);
+ GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
+ GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
+
+ grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure);
+ grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+ httpcli_post_should_not_be_called);
+ grpc_credentials_get_request_metadata(service_account_creds,
+ on_oauth2_creds_get_metadata_failure,
+ (void *)test_user_data);
+
+ gpr_free(json_key_string);
+ grpc_credentials_unref(service_account_creds);
+ grpc_httpcli_set_override(NULL, NULL);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
- test_compute_engine_creds_parsing_ok();
- test_compute_engine_creds_parsing_bad_http_status();
- test_compute_engine_creds_parsing_empty_http_body();
- test_compute_engine_creds_parsing_invalid_json();
- test_compute_engine_creds_parsing_missing_token();
- test_compute_engine_creds_parsing_missing_token_type();
- test_compute_engine_creds_parsing_missing_token_lifetime();
+ test_oauth2_token_fetcher_creds_parsing_ok();
+ test_oauth2_token_fetcher_creds_parsing_bad_http_status();
+ test_oauth2_token_fetcher_creds_parsing_empty_http_body();
+ test_oauth2_token_fetcher_creds_parsing_invalid_json();
+ test_oauth2_token_fetcher_creds_parsing_missing_token();
+ test_oauth2_token_fetcher_creds_parsing_missing_token_type();
+ test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime();
test_iam_creds();
test_ssl_oauth2_composite_creds();
test_ssl_oauth2_iam_composite_creds();
+ test_compute_engine_creds_success();
+ test_compute_engine_creds_failure();
+ test_service_accounts_creds_success();
+ test_service_accounts_creds_http_failure();
+ test_service_accounts_creds_signing_failure();
return 0;
}
diff --git a/test/core/security/fetch_oauth2.c b/test/core/security/fetch_oauth2.c
new file mode 100644
index 0000000..c5cc3ad
--- /dev/null
+++ b/test/core/security/fetch_oauth2.c
@@ -0,0 +1,177 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "src/core/security/credentials.h"
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/cmdline.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/sync.h>
+
+typedef struct {
+ gpr_cv cv;
+ gpr_mu mu;
+ int is_done;
+} synchronizer;
+
+static void on_oauth2_response(void *user_data, grpc_mdelem **md_elems,
+ size_t num_md, grpc_credentials_status status) {
+ synchronizer *sync = user_data;
+ char *token;
+ gpr_slice token_slice;
+ if (status == GRPC_CREDENTIALS_ERROR) {
+ gpr_log(GPR_ERROR, "Fetching token failed.");
+ } else {
+ GPR_ASSERT(num_md == 1);
+ token_slice = md_elems[0]->value->slice;
+ token = gpr_malloc(GPR_SLICE_LENGTH(token_slice) + 1);
+ memcpy(token, GPR_SLICE_START_PTR(token_slice),
+ GPR_SLICE_LENGTH(token_slice));
+ token[GPR_SLICE_LENGTH(token_slice)] = '\0';
+ printf("Got token: %s.\n", token);
+ gpr_free(token);
+ }
+ gpr_mu_lock(&sync->mu);
+ sync->is_done = 1;
+ gpr_mu_unlock(&sync->mu);
+ gpr_cv_signal(&sync->cv);
+}
+
+static grpc_credentials *create_service_account_creds(
+ const char *json_key_file_path, const char *scope) {
+ char json_key[8192]; /* Should be plenty. */
+ char *current = json_key;
+ FILE *json_key_file = fopen(json_key_file_path, "r");
+ if (json_key_file == NULL) {
+ gpr_log(GPR_ERROR, "Invalid path for json key file: %s.",
+ json_key_file_path);
+ exit(1);
+ }
+
+ do {
+ size_t bytes_read = fread(
+ current, 1, sizeof(json_key) - (current - json_key), json_key_file);
+ if (bytes_read == 0) {
+ if (!feof(json_key_file)) {
+ gpr_log(GPR_ERROR, "Error occured while reading %s.",
+ json_key_file_path);
+ exit(1);
+ }
+ break;
+ }
+ current += bytes_read;
+ } while (sizeof(json_key) > (current - json_key));
+
+ if ((current - json_key) == sizeof(json_key)) {
+ gpr_log(GPR_ERROR, "Json key file %s exceeds size limit (%d bytes).",
+ json_key_file_path, (int)sizeof(json_key));
+ exit(1);
+ }
+ fclose(json_key_file);
+
+ return grpc_service_account_credentials_create(json_key, scope,
+ grpc_max_auth_token_lifetime);
+}
+
+int main(int argc, char **argv) {
+ synchronizer sync;
+ grpc_credentials *creds = NULL;
+ char *json_key_file_path = NULL;
+ int use_gce = 0;
+ char *scope = NULL;
+ gpr_cmdline *cl = gpr_cmdline_create("fetch_oauth2");
+ gpr_cmdline_add_string(cl, "json_key", "File path of the json key.",
+ &json_key_file_path);
+ gpr_cmdline_add_string(cl, "scope", "Space delimited permissions.", &scope);
+ gpr_cmdline_add_flag(
+ cl, "gce",
+ "Get a token from the GCE metadata server (only works in GCE).",
+ &use_gce);
+ gpr_cmdline_parse(cl, argc, argv);
+
+ grpc_init();
+
+ if (use_gce) {
+ if (json_key_file_path != NULL || scope != NULL) {
+ gpr_log(GPR_INFO,
+ "Ignoring json key and scope to get a token from the GCE "
+ "metadata server.");
+ }
+ creds = grpc_compute_engine_credentials_create();
+ if (creds == NULL) {
+ gpr_log(GPR_ERROR, "Could not create gce credentials.");
+ exit(1);
+ }
+ } else {
+ if (json_key_file_path == NULL) {
+ gpr_log(GPR_ERROR, "missing --json_key option.");
+ exit(1);
+ }
+ if (scope == NULL) {
+ gpr_log(GPR_ERROR, "Missing --scope option.");
+ exit(1);
+ }
+
+ creds = create_service_account_creds(json_key_file_path, scope);
+ if (creds == NULL) {
+ gpr_log(GPR_ERROR,
+ "Could not create service account creds. %s does probably not "
+ "contain a valid json key.",
+ json_key_file_path);
+ exit(1);
+ }
+ }
+ GPR_ASSERT(creds != NULL);
+
+ gpr_mu_init(&sync.mu);
+ gpr_cv_init(&sync.cv);
+ sync.is_done = 0;
+
+ grpc_credentials_get_request_metadata(creds, on_oauth2_response, &sync);
+
+ gpr_mu_lock(&sync.mu);
+ while (!sync.is_done) gpr_cv_wait(&sync.cv, &sync.mu, gpr_inf_future);
+ gpr_mu_unlock(&sync.mu);
+
+ gpr_mu_destroy(&sync.mu);
+ gpr_cv_destroy(&sync.cv);
+ grpc_credentials_release(creds);
+ gpr_cmdline_destroy(cl);
+ grpc_shutdown();
+ return 0;
+}