Line data Source code
1 : #include "source/common/grpc/google_grpc_creds_impl.h" 2 : 3 : #include "envoy/config/core/v3/grpc_service.pb.h" 4 : #include "envoy/grpc/google_grpc_creds.h" 5 : 6 : #include "source/common/config/datasource.h" 7 : 8 : namespace Envoy { 9 : namespace Grpc { 10 : 11 : std::shared_ptr<grpc::ChannelCredentials> CredsUtility::getChannelCredentials( 12 2 : const envoy::config::core::v3::GrpcService::GoogleGrpc& google_grpc, Api::Api& api) { 13 2 : if (google_grpc.has_channel_credentials()) { 14 0 : switch (google_grpc.channel_credentials().credential_specifier_case()) { 15 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::ChannelCredentials:: 16 0 : CredentialSpecifierCase::kSslCredentials: { 17 0 : const auto& ssl_credentials = google_grpc.channel_credentials().ssl_credentials(); 18 0 : const grpc::SslCredentialsOptions ssl_credentials_options = { 19 0 : Config::DataSource::read(ssl_credentials.root_certs(), true, api), 20 0 : Config::DataSource::read(ssl_credentials.private_key(), true, api), 21 0 : Config::DataSource::read(ssl_credentials.cert_chain(), true, api), 22 0 : }; 23 0 : return grpc::SslCredentials(ssl_credentials_options); 24 0 : } 25 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::ChannelCredentials:: 26 0 : CredentialSpecifierCase::kLocalCredentials: { 27 0 : return grpc::experimental::LocalCredentials(UDS); 28 0 : } 29 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::ChannelCredentials:: 30 0 : CredentialSpecifierCase::kGoogleDefault: { 31 0 : return grpc::GoogleDefaultCredentials(); 32 0 : } 33 0 : default: 34 0 : return nullptr; 35 0 : } 36 0 : } 37 2 : return nullptr; 38 2 : } 39 : 40 : std::shared_ptr<grpc::ChannelCredentials> CredsUtility::defaultSslChannelCredentials( 41 0 : const envoy::config::core::v3::GrpcService& grpc_service_config, Api::Api& api) { 42 0 : auto creds = getChannelCredentials(grpc_service_config.google_grpc(), api); 43 0 : if (creds != nullptr) { 44 0 : return creds; 45 0 : } 46 0 : return grpc::SslCredentials({}); 47 0 : } 48 : 49 : std::vector<std::shared_ptr<grpc::CallCredentials>> 50 2 : CredsUtility::callCredentials(const envoy::config::core::v3::GrpcService::GoogleGrpc& google_grpc) { 51 2 : std::vector<std::shared_ptr<grpc::CallCredentials>> creds; 52 2 : for (const auto& credential : google_grpc.call_credentials()) { 53 0 : std::shared_ptr<grpc::CallCredentials> new_call_creds; 54 0 : switch (credential.credential_specifier_case()) { 55 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::CallCredentials:: 56 0 : CredentialSpecifierCase::kAccessToken: { 57 0 : new_call_creds = grpc::AccessTokenCredentials(credential.access_token()); 58 0 : break; 59 0 : } 60 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::CallCredentials:: 61 0 : CredentialSpecifierCase::kGoogleComputeEngine: { 62 0 : new_call_creds = grpc::GoogleComputeEngineCredentials(); 63 0 : break; 64 0 : } 65 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::CallCredentials:: 66 0 : CredentialSpecifierCase::kGoogleRefreshToken: { 67 0 : new_call_creds = grpc::GoogleRefreshTokenCredentials(credential.google_refresh_token()); 68 0 : break; 69 0 : } 70 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::CallCredentials:: 71 0 : CredentialSpecifierCase::kServiceAccountJwtAccess: { 72 0 : new_call_creds = grpc::ServiceAccountJWTAccessCredentials( 73 0 : credential.service_account_jwt_access().json_key(), 74 0 : credential.service_account_jwt_access().token_lifetime_seconds()); 75 0 : break; 76 0 : } 77 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::CallCredentials:: 78 0 : CredentialSpecifierCase::kGoogleIam: { 79 0 : new_call_creds = grpc::GoogleIAMCredentials(credential.google_iam().authorization_token(), 80 0 : credential.google_iam().authority_selector()); 81 0 : break; 82 0 : } 83 0 : case envoy::config::core::v3::GrpcService::GoogleGrpc::CallCredentials:: 84 0 : CredentialSpecifierCase::kStsService: { 85 0 : grpc::experimental::StsCredentialsOptions options = { 86 0 : credential.sts_service().token_exchange_service_uri(), 87 0 : credential.sts_service().resource(), 88 0 : credential.sts_service().audience(), 89 0 : credential.sts_service().scope(), 90 0 : credential.sts_service().requested_token_type(), 91 0 : credential.sts_service().subject_token_path(), 92 0 : credential.sts_service().subject_token_type(), 93 0 : credential.sts_service().actor_token_path(), 94 0 : credential.sts_service().actor_token_type(), 95 0 : }; 96 0 : new_call_creds = grpc::experimental::StsCredentials(options); 97 0 : break; 98 0 : } 99 0 : default: 100 : // We don't handle plugin credentials here, callers can do so instead if they want. 101 0 : continue; 102 0 : } 103 : // Any of the above creds creation can fail, if they do they return nullptr 104 : // and we ignore them. 105 0 : if (new_call_creds != nullptr) { 106 0 : creds.emplace_back(new_call_creds); 107 0 : } 108 0 : } 109 2 : return creds; 110 2 : } 111 : 112 : std::shared_ptr<grpc::ChannelCredentials> CredsUtility::defaultChannelCredentials( 113 2 : const envoy::config::core::v3::GrpcService& grpc_service_config, Api::Api& api) { 114 2 : std::shared_ptr<grpc::ChannelCredentials> channel_creds = 115 2 : getChannelCredentials(grpc_service_config.google_grpc(), api); 116 2 : if (channel_creds == nullptr) { 117 2 : channel_creds = grpc::InsecureChannelCredentials(); 118 2 : } 119 2 : auto call_creds_vec = callCredentials(grpc_service_config.google_grpc()); 120 2 : if (call_creds_vec.empty()) { 121 2 : return channel_creds; 122 2 : } 123 0 : std::shared_ptr<grpc::CallCredentials> call_creds = call_creds_vec[0]; 124 0 : for (uint32_t i = 1; i < call_creds_vec.size(); ++i) { 125 0 : call_creds = grpc::CompositeCallCredentials(call_creds, call_creds_vec[i]); 126 0 : } 127 0 : return grpc::CompositeChannelCredentials(channel_creds, call_creds); 128 2 : } 129 : 130 : /** 131 : * Default implementation of Google Grpc Credentials Factory 132 : * Uses ssl creds if available, or defaults to insecure channel. 133 : * 134 : * This is not the same as google_default credentials. This is the default implementation that is 135 : * loaded if no other implementation is configured. 136 : */ 137 : class DefaultGoogleGrpcCredentialsFactory : public GoogleGrpcCredentialsFactory { 138 : 139 : public: 140 : std::shared_ptr<grpc::ChannelCredentials> 141 : getChannelCredentials(const envoy::config::core::v3::GrpcService& grpc_service_config, 142 2 : Api::Api& api) override { 143 2 : return CredsUtility::defaultChannelCredentials(grpc_service_config, api); 144 2 : } 145 : 146 14 : std::string name() const override { return "envoy.grpc_credentials.default"; } 147 : }; 148 : 149 : /** 150 : * Static registration for the default Google gRPC credentials factory. @see RegisterFactory. 151 : */ 152 : REGISTER_FACTORY(DefaultGoogleGrpcCredentialsFactory, GoogleGrpcCredentialsFactory); 153 : 154 : } // namespace Grpc 155 : } // namespace Envoy