diff --git a/BUILD b/BUILD index 32eea118648..e29e24d8930 100644 --- a/BUILD +++ b/BUILD @@ -428,6 +428,23 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc++_alts", + srcs = [ + "src/cpp/common/alts_context.cc", + ], + hdrs = [ + "include/grpcpp/alts_context.h", + ], + language = "c++", + standalone = True, + deps = [ + "alts_upb", + "alts_util", + "grpc++", + ], +) + grpc_cc_library( name = "grpc_csharp_ext", srcs = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index 1abc238d852..6a5aa23c825 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -627,6 +627,7 @@ if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX) add_dependencies(buildtests_cxx alts_concurrent_connectivity_test) endif() + add_dependencies(buildtests_cxx alts_context_test) add_dependencies(buildtests_cxx alts_counter_test) add_dependencies(buildtests_cxx alts_crypt_test) add_dependencies(buildtests_cxx alts_crypter_test) @@ -3819,6 +3820,66 @@ if(gRPC_INSTALL) ) endif() + +add_library(grpc++_alts + src/cpp/common/alts_context.cc +) + +set_target_properties(grpc++_alts PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_alts PROPERTIES COMPILE_PDB_NAME "grpc++_alts" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_alts.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++_alts + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++_alts + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ +) + +foreach(_hdr + include/grpcpp/alts_context.h + include/grpcpp/impl/codegen/security/auth_context.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS grpc++_alts EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + if(gRPC_BUILD_TESTS) if(gRPC_BUILD_CODEGEN) @@ -9842,6 +9903,46 @@ endif() endif() if(gRPC_BUILD_TESTS) +add_executable(alts_context_test + test/cpp/common/alts_context_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(alts_context_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(alts_context_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++_alts + grpc++ + grpc + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif() +if(gRPC_BUILD_TESTS) + add_executable(alts_counter_test test/core/tsi/alts/frame_protector/alts_counter_test.cc third_party/googletest/googletest/src/gtest-all.cc diff --git a/Makefile b/Makefile index b47ea7d1941..2c7455ea436 100644 --- a/Makefile +++ b/Makefile @@ -1151,6 +1151,7 @@ uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test uri_parser_test: $(BINDIR)/$(CONFIG)/uri_parser_test alarm_test: $(BINDIR)/$(CONFIG)/alarm_test alts_concurrent_connectivity_test: $(BINDIR)/$(CONFIG)/alts_concurrent_connectivity_test +alts_context_test: $(BINDIR)/$(CONFIG)/alts_context_test alts_counter_test: $(BINDIR)/$(CONFIG)/alts_counter_test alts_crypt_test: $(BINDIR)/$(CONFIG)/alts_crypt_test alts_crypter_test: $(BINDIR)/$(CONFIG)/alts_crypter_test @@ -1411,14 +1412,14 @@ static: static_c static_cxx static_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libupb.a -static_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a +static_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a static_csharp: static_c $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a shared: shared_c shared_cxx shared_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) +shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) shared_csharp: shared_c $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) grpc_csharp_ext: shared_csharp @@ -1630,6 +1631,7 @@ ifeq ($(EMBED_OPENSSL),true) buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/alarm_test \ $(BINDIR)/$(CONFIG)/alts_concurrent_connectivity_test \ + $(BINDIR)/$(CONFIG)/alts_context_test \ $(BINDIR)/$(CONFIG)/alts_counter_test \ $(BINDIR)/$(CONFIG)/alts_crypt_test \ $(BINDIR)/$(CONFIG)/alts_crypter_test \ @@ -1804,6 +1806,7 @@ else buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/alarm_test \ $(BINDIR)/$(CONFIG)/alts_concurrent_connectivity_test \ + $(BINDIR)/$(CONFIG)/alts_context_test \ $(BINDIR)/$(CONFIG)/alts_counter_test \ $(BINDIR)/$(CONFIG)/alts_crypt_test \ $(BINDIR)/$(CONFIG)/alts_crypter_test \ @@ -2240,6 +2243,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/alarm_test || ( echo test alarm_test failed ; exit 1 ) $(E) "[RUN] Testing alts_concurrent_connectivity_test" $(Q) $(BINDIR)/$(CONFIG)/alts_concurrent_connectivity_test || ( echo test alts_concurrent_connectivity_test failed ; exit 1 ) + $(E) "[RUN] Testing alts_context_test" + $(Q) $(BINDIR)/$(CONFIG)/alts_context_test || ( echo test alts_context_test failed ; exit 1 ) $(E) "[RUN] Testing alts_counter_test" $(Q) $(BINDIR)/$(CONFIG)/alts_counter_test || ( echo test alts_counter_test failed ; exit 1 ) $(E) "[RUN] Testing alts_crypt_test" @@ -2590,6 +2595,8 @@ strip-static_cxx: static_cxx ifeq ($(CONFIG),opt) $(E) "[STRIP] Stripping libgrpc++.a" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a + $(E) "[STRIP] Stripping libgrpc++_alts.a" + $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(E) "[STRIP] Stripping libgrpc++_error_details.a" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(E) "[STRIP] Stripping libgrpc++_reflection.a" @@ -2620,6 +2627,8 @@ strip-shared_cxx: shared_cxx ifeq ($(CONFIG),opt) $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) + $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" + $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" @@ -3195,6 +3204,9 @@ install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx $(E) "[INSTALL] Installing libgrpc++.a" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a + $(E) "[INSTALL] Installing libgrpc++_alts.a" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(prefix)/lib/libgrpc++_alts.a $(E) "[INSTALL] Installing libgrpc++_error_details.a" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(prefix)/lib/libgrpc++_error_details.a @@ -3281,6 +3293,15 @@ ifeq ($(SYSTEM),MINGW32) else ifneq ($(SYSTEM),Darwin) $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so +endif + $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) +ifeq ($(SYSTEM),MINGW32) + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_alts.a +else ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_alts.so.1 + $(Q) ln -sf $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_alts.so endif $(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)" $(Q) $(INSTALL) -d $(prefix)/lib @@ -6219,6 +6240,76 @@ endif endif +LIBGRPC++_ALTS_SRC = \ + src/cpp/common/alts_context.cc \ + +PUBLIC_HEADERS_CXX += \ + include/grpcpp/alts_context.h \ + include/grpcpp/impl/codegen/security/auth_context.h \ + +LIBGRPC++_ALTS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_ALTS_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libgrpc++_alts.a: openssl_dep_error + +$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpc++_alts.a: protobuf_dep_error + +$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error + +else + +$(LIBDIR)/$(CONFIG)/libgrpc++_alts.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_ALTS_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBGRPC++_ALTS_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(CARES_MERGE_OBJS) $(ADDRESS_SORTING_MERGE_OBJS) $(UPB_MERGE_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a +endif + + + +ifeq ($(SYSTEM),MINGW32) +$(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ALTS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(OPENSSL_DEP) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll +else +$(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ALTS_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(OPENSSL_DEP) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` +ifeq ($(SYSTEM),Darwin) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ +else + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_alts.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ + $(Q) ln -sf $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).so.1 + $(Q) ln -sf $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).so +endif +endif + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC++_ALTS_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_CORE_STATS_SRC = \ $(GENDIR)/src/proto/grpc/core/stats.pb.cc $(GENDIR)/src/proto/grpc/core/stats.grpc.pb.cc \ src/cpp/util/core_stats.cc \ @@ -13712,6 +13803,49 @@ $(OBJDIR)/$(CONFIG)/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.o: $(OBJDIR)/$(CONFIG)/test/core/tsi/alts/handshaker/alts_concurrent_connectivity_test.o: $(GENDIR)/test/core/tsi/alts/fake_handshaker/handshaker.pb.cc $(GENDIR)/test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.cc $(GENDIR)/test/core/tsi/alts/fake_handshaker/transport_security_common.pb.cc $(GENDIR)/test/core/tsi/alts/fake_handshaker/transport_security_common.grpc.pb.cc +ALTS_CONTEXT_TEST_SRC = \ + test/cpp/common/alts_context_test.cc \ + +ALTS_CONTEXT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ALTS_CONTEXT_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/alts_context_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/alts_context_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/alts_context_test: $(PROTOBUF_DEP) $(ALTS_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alts_context_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/common/alts_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_alts_context_test: $(ALTS_CONTEXT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(ALTS_CONTEXT_TEST_OBJS:.o=.dep) +endif +endif + + ALTS_COUNTER_TEST_SRC = \ test/core/tsi/alts/frame_protector/alts_counter_test.cc \ @@ -23215,6 +23349,7 @@ src/core/tsi/ssl_transport_security.cc: $(OPENSSL_DEP) src/core/tsi/transport_security.cc: $(OPENSSL_DEP) src/core/tsi/transport_security_grpc.cc: $(OPENSSL_DEP) src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP) +src/cpp/common/alts_context.cc: $(OPENSSL_DEP) src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP) src/cpp/common/secure_auth_context.cc: $(OPENSSL_DEP) src/cpp/common/secure_channel_arguments.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index eb1ef643ebf..4f76564622d 100644 --- a/build.yaml +++ b/build.yaml @@ -1879,6 +1879,17 @@ libs: - grpc++_codegen_proto - grpc++_codegen_base_src secure: check +- name: grpc++_alts + build: all + language: c++ + public_headers: + - include/grpcpp/alts_context.h + - include/grpcpp/impl/codegen/security/auth_context.h + src: + - src/cpp/common/alts_context.cc + deps: + - grpc++ + baselib: true - name: grpc++_core_stats build: private language: c++ @@ -3904,6 +3915,19 @@ targets: - grpc++_test_config platforms: - linux +- name: alts_context_test + build: test + language: c++ + src: + - test/cpp/common/alts_context_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++_alts + - grpc++ + - grpc + - gpr + - grpc++_test_config - name: alts_counter_test build: test language: c++ diff --git a/grpc.gyp b/grpc.gyp index caba8007d9b..a0e68c99815 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1749,6 +1749,16 @@ 'src/cpp/codegen/codegen_init.cc', ], }, + { + 'target_name': 'grpc++_alts', + 'type': 'static_library', + 'dependencies': [ + 'grpc++', + ], + 'sources': [ + 'src/cpp/common/alts_context.cc', + ], + }, { 'target_name': 'grpc++_core_stats', 'type': 'static_library', diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index 1be524a78f8..13d6e9ff8e0 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -105,6 +105,15 @@ typedef enum { GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY } grpc_ssl_client_certificate_request_type; +/* Security levels of grpc transport security */ +typedef enum { + GRPC_SECURITY_MIN, + GRPC_SECURITY_NONE = GRPC_SECURITY_MIN, + GRPC_INTEGRITY_ONLY, + GRPC_PRIVACY_AND_INTEGRITY, + GRPC_SECURITY_MAX = GRPC_PRIVACY_AND_INTEGRITY, +} grpc_security_level; + /** * Type of local connections for which local channel/server credentials will be * applied. It supports UDS and local TCP connections. diff --git a/include/grpcpp/alts_context.h b/include/grpcpp/alts_context.h new file mode 100644 index 00000000000..8eb2ef2ed87 --- /dev/null +++ b/include/grpcpp/alts_context.h @@ -0,0 +1,71 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_ALTS_CONTEXT_H +#define GRPCPP_ALTS_CONTEXT_H + +#include +#include + +#include + +struct grpc_gcp_AltsContext; + +namespace grpc { + +// AltsContext is wrapper class for grpc_gcp_AltsContext. +class AltsContext { + public: + struct RpcProtocolVersions { + struct Version { + int major_version; + int minor_version; + }; + Version max_rpc_version; + Version min_rpc_version; + }; + explicit AltsContext(const grpc_gcp_AltsContext* ctx); + AltsContext& operator=(const AltsContext&) = default; + AltsContext(const AltsContext&) = default; + + grpc::string application_protocol() const; + grpc::string record_protocol() const; + grpc::string peer_service_account() const; + grpc::string local_service_account() const; + grpc_security_level security_level() const; + RpcProtocolVersions peer_rpc_versions() const; + + private: + // TODO(ZhenLian): Also plumb field peer_attributes when it is in use + grpc::string application_protocol_; + grpc::string record_protocol_; + grpc::string peer_service_account_; + grpc::string local_service_account_; + grpc_security_level security_level_ = GRPC_SECURITY_NONE; + RpcProtocolVersions peer_rpc_versions_ = {{0, 0}, {0, 0}}; +}; + +// GetAltsContextFromAuthContext helps to get the AltsContext from AuthContext. +// Please make sure the underlying protocol is ALTS before calling this +// function. Otherwise a nullptr will be returned. +std::unique_ptr GetAltsContextFromAuthContext( + const AuthContext& auth_context); + +} // namespace grpc + +#endif // GRPCPP_ALTS_CONTEXT_H diff --git a/src/cpp/common/alts_context.cc b/src/cpp/common/alts_context.cc new file mode 100644 index 00000000000..98f4128d185 --- /dev/null +++ b/src/cpp/common/alts_context.cc @@ -0,0 +1,128 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include "src/core/lib/gprpp/memory.h" +#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" +#include "src/cpp/common/secure_auth_context.h" +#include "src/proto/grpc/gcp/altscontext.upb.h" + +namespace grpc { + +AltsContext::AltsContext(const grpc_gcp_AltsContext* ctx) { + upb_strview application_protocol = + grpc_gcp_AltsContext_application_protocol(ctx); + if (application_protocol.data != nullptr && application_protocol.size > 0) { + application_protocol_ = + grpc::string(application_protocol.data, application_protocol.size); + } + upb_strview record_protocol = grpc_gcp_AltsContext_record_protocol(ctx); + if (record_protocol.data != nullptr && record_protocol.size > 0) { + record_protocol_ = grpc::string(record_protocol.data, record_protocol.size); + } + upb_strview peer_service_account = + grpc_gcp_AltsContext_peer_service_account(ctx); + if (peer_service_account.data != nullptr && peer_service_account.size > 0) { + peer_service_account_ = + grpc::string(peer_service_account.data, peer_service_account.size); + } + upb_strview local_service_account = + grpc_gcp_AltsContext_local_service_account(ctx); + if (local_service_account.data != nullptr && local_service_account.size > 0) { + local_service_account_ = + grpc::string(local_service_account.data, local_service_account.size); + } + const grpc_gcp_RpcProtocolVersions* versions = + grpc_gcp_AltsContext_peer_rpc_versions(ctx); + if (versions != nullptr) { + const grpc_gcp_RpcProtocolVersions_Version* max_version = + grpc_gcp_RpcProtocolVersions_max_rpc_version(versions); + if (max_version != nullptr) { + int max_version_major = + grpc_gcp_RpcProtocolVersions_Version_major(max_version); + int max_version_minor = + grpc_gcp_RpcProtocolVersions_Version_minor(max_version); + peer_rpc_versions_.max_rpc_version.major_version = max_version_major; + peer_rpc_versions_.max_rpc_version.minor_version = max_version_minor; + } + const grpc_gcp_RpcProtocolVersions_Version* min_version = + grpc_gcp_RpcProtocolVersions_min_rpc_version(versions); + if (min_version != nullptr) { + int min_version_major = + grpc_gcp_RpcProtocolVersions_Version_major(min_version); + int min_version_minor = + grpc_gcp_RpcProtocolVersions_Version_minor(min_version); + peer_rpc_versions_.min_rpc_version.major_version = min_version_major; + peer_rpc_versions_.min_rpc_version.minor_version = min_version_minor; + } + } + if (grpc_gcp_AltsContext_security_level(ctx) >= GRPC_SECURITY_MIN || + grpc_gcp_AltsContext_security_level(ctx) <= GRPC_SECURITY_MAX) { + security_level_ = static_cast( + grpc_gcp_AltsContext_security_level(ctx)); + } +} + +grpc::string AltsContext::application_protocol() const { + return application_protocol_; +} + +grpc::string AltsContext::record_protocol() const { return record_protocol_; } + +grpc::string AltsContext::peer_service_account() const { + return peer_service_account_; +} + +grpc::string AltsContext::local_service_account() const { + return local_service_account_; +} + +grpc_security_level AltsContext::security_level() const { + return security_level_; +} + +AltsContext::RpcProtocolVersions AltsContext::peer_rpc_versions() const { + return peer_rpc_versions_; +} + +std::unique_ptr GetAltsContextFromAuthContext( + const AuthContext& auth_context) { + std::vector ctx_vector = + auth_context.FindPropertyValues(TSI_ALTS_CONTEXT); + if (ctx_vector.size() != 1) { + gpr_log(GPR_ERROR, "contains zero or more than one ALTS context."); + return nullptr; + } + upb::Arena context_arena; + grpc_gcp_AltsContext* ctx = grpc_gcp_AltsContext_parse( + ctx_vector[0].data(), ctx_vector[0].size(), context_arena.ptr()); + if (ctx == nullptr) { + gpr_log(GPR_ERROR, "fails to parse ALTS context."); + return nullptr; + } + if (grpc_gcp_AltsContext_security_level(ctx) < GRPC_SECURITY_MIN || + grpc_gcp_AltsContext_security_level(ctx) > GRPC_SECURITY_MAX) { + gpr_log(GPR_ERROR, "security_level is invalid."); + return nullptr; + } + return grpc_core::MakeUnique(AltsContext(ctx)); +} + +} // namespace grpc diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index 05e7bda330a..3f5e0ad24c1 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -108,3 +108,17 @@ grpc_cc_test( "//test/cpp/util:test_util", ], ) + +grpc_cc_test( + name = "alts_context_test", + srcs = ["alts_context_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + "//:grpc++_alts", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + diff --git a/test/cpp/common/alts_context_test.cc b/test/cpp/common/alts_context_test.cc new file mode 100644 index 00000000000..b5ce4e5800e --- /dev/null +++ b/test/cpp/common/alts_context_test.cc @@ -0,0 +1,155 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" +#include "src/cpp/common/secure_auth_context.h" +#include "src/proto/grpc/gcp/altscontext.upb.h" +#include "test/cpp/util/string_ref_helper.h" + +using grpc::testing::ToString; + +namespace grpc { +namespace { + +TEST(AltsContextTest, EmptyAuthContext) { + SecureAuthContext auth_context(nullptr); + std::unique_ptr alts_context = + GetAltsContextFromAuthContext(auth_context); + EXPECT_EQ(alts_context.get(), nullptr); +} + +TEST(AltsContextTest, AuthContextWithMoreThanOneAltsContext) { + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext auth_context(ctx.get()); + ctx.reset(); + auth_context.AddProperty(TSI_ALTS_CONTEXT, "context1"); + auth_context.AddProperty(TSI_ALTS_CONTEXT, "context2"); + std::unique_ptr alts_context = + GetAltsContextFromAuthContext(auth_context); + EXPECT_EQ(alts_context.get(), nullptr); +} + +TEST(AltsContextTest, AuthContextWithBadAltsContext) { + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext auth_context(ctx.get()); + ctx.reset(); + auth_context.AddProperty(TSI_ALTS_CONTEXT, + "bad context string serialization"); + std::unique_ptr alts_context = + GetAltsContextFromAuthContext(auth_context); + EXPECT_EQ(alts_context.get(), nullptr); +} + +TEST(AltsContextTest, AuthContextWithGoodAltsContextWithoutRpcVersions) { + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext auth_context(ctx.get()); + ctx.reset(); + + grpc::string expected_ap("application protocol"); + grpc::string expected_rp("record protocol"); + grpc::string expected_peer("peer"); + grpc::string expected_local("local"); + grpc_security_level expected_sl = GRPC_INTEGRITY_ONLY; + upb::Arena context_arena; + grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr()); + grpc_gcp_AltsContext_set_application_protocol( + context, upb_strview_make(expected_ap.data(), expected_ap.length())); + grpc_gcp_AltsContext_set_record_protocol( + context, upb_strview_make(expected_rp.data(), expected_rp.length())); + grpc_gcp_AltsContext_set_security_level(context, expected_sl); + grpc_gcp_AltsContext_set_peer_service_account( + context, upb_strview_make(expected_peer.data(), expected_peer.length())); + grpc_gcp_AltsContext_set_local_service_account( + context, + upb_strview_make(expected_local.data(), expected_local.length())); + size_t serialized_ctx_length; + char* serialized_ctx = grpc_gcp_AltsContext_serialize( + context, context_arena.ptr(), &serialized_ctx_length); + EXPECT_NE(serialized_ctx, nullptr); + auth_context.AddProperty(TSI_ALTS_CONTEXT, + string(serialized_ctx, serialized_ctx_length)); + std::unique_ptr alts_context = + GetAltsContextFromAuthContext(auth_context); + EXPECT_NE(alts_context.get(), nullptr); + EXPECT_EQ(expected_ap, alts_context->application_protocol()); + EXPECT_EQ(expected_rp, alts_context->record_protocol()); + EXPECT_EQ(expected_peer, alts_context->peer_service_account()); + EXPECT_EQ(expected_local, alts_context->local_service_account()); + EXPECT_EQ(expected_sl, alts_context->security_level()); + // all rpc versions should be 0 if not set + AltsContext::RpcProtocolVersions rpc_protocol_versions = + alts_context->peer_rpc_versions(); + EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.major_version); + EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version); + EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version); + EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version); +} + +TEST(AltsContextTest, AuthContextWithGoodAltsContext) { + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext auth_context(ctx.get()); + ctx.reset(); + + upb::Arena context_arena; + grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr()); + upb::Arena versions_arena; + grpc_gcp_RpcProtocolVersions* versions = + grpc_gcp_RpcProtocolVersions_new(versions_arena.ptr()); + upb::Arena max_major_version_arena; + grpc_gcp_RpcProtocolVersions_Version* version = + grpc_gcp_RpcProtocolVersions_Version_new(max_major_version_arena.ptr()); + grpc_gcp_RpcProtocolVersions_Version_set_major(version, 10); + grpc_gcp_RpcProtocolVersions_set_max_rpc_version(versions, version); + grpc_gcp_AltsContext_set_peer_rpc_versions(context, versions); + size_t serialized_ctx_length; + char* serialized_ctx = grpc_gcp_AltsContext_serialize( + context, context_arena.ptr(), &serialized_ctx_length); + EXPECT_NE(serialized_ctx, nullptr); + auth_context.AddProperty(TSI_ALTS_CONTEXT, + string(serialized_ctx, serialized_ctx_length)); + std::unique_ptr alts_context = + GetAltsContextFromAuthContext(auth_context); + EXPECT_NE(alts_context.get(), nullptr); + EXPECT_EQ("", alts_context->application_protocol()); + EXPECT_EQ("", alts_context->record_protocol()); + EXPECT_EQ("", alts_context->peer_service_account()); + EXPECT_EQ("", alts_context->local_service_account()); + EXPECT_EQ(GRPC_SECURITY_NONE, alts_context->security_level()); + AltsContext::RpcProtocolVersions rpc_protocol_versions = + alts_context->peer_rpc_versions(); + EXPECT_EQ(10, rpc_protocol_versions.max_rpc_version.major_version); + EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version); + EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version); + EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 9197a29d163..636d09c9565 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2983,6 +2983,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "alts_context_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false,