| // |
| // |
| // Copyright 2015 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 GRPC_SRC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H |
| #define GRPC_SRC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H |
| |
| #include "absl/status/statusor.h" |
| |
| #include <grpc/credentials.h> |
| #include <grpc/grpc_security.h> |
| #include <grpc/grpc_security_constants.h> |
| #include <grpc/support/port_platform.h> |
| |
| #include "src/core/lib/channel/channel_args.h" |
| #include "src/core/lib/channel/channel_fwd.h" |
| #include "src/core/lib/channel/channel_stack.h" |
| #include "src/core/lib/channel/promise_based_filter.h" |
| #include "src/core/lib/gprpp/ref_counted_ptr.h" |
| #include "src/core/lib/promise/arena_promise.h" |
| #include "src/core/lib/security/credentials/credentials.h" |
| #include "src/core/lib/security/security_connector/security_connector.h" |
| #include "src/core/lib/transport/transport.h" |
| |
| namespace grpc_core { |
| |
| // Handles calling out to credentials to fill in metadata per call. |
| class ClientAuthFilter final : public ChannelFilter { |
| public: |
| static const grpc_channel_filter kFilter; |
| |
| ClientAuthFilter( |
| RefCountedPtr<grpc_channel_security_connector> security_connector, |
| RefCountedPtr<grpc_auth_context> auth_context); |
| |
| static absl::StatusOr<std::unique_ptr<ClientAuthFilter>> Create( |
| const ChannelArgs& args, ChannelFilter::Args); |
| |
| // Construct a promise for one call. |
| ArenaPromise<ServerMetadataHandle> MakeCallPromise( |
| CallArgs call_args, NextPromiseFactory next_promise_factory) override; |
| |
| private: |
| ArenaPromise<absl::StatusOr<CallArgs>> GetCallCredsMetadata( |
| CallArgs call_args); |
| |
| // Contains refs to security connector and auth context. |
| grpc_call_credentials::GetRequestMetadataArgs args_; |
| }; |
| |
| class ServerAuthFilter final : public ImplementChannelFilter<ServerAuthFilter> { |
| private: |
| class RunApplicationCode { |
| public: |
| RunApplicationCode(ServerAuthFilter* filter, ClientMetadata& metadata); |
| |
| RunApplicationCode(const RunApplicationCode&) = delete; |
| RunApplicationCode& operator=(const RunApplicationCode&) = delete; |
| RunApplicationCode(RunApplicationCode&& other) noexcept |
| : state_(std::exchange(other.state_, nullptr)) {} |
| RunApplicationCode& operator=(RunApplicationCode&& other) noexcept { |
| state_ = std::exchange(other.state_, nullptr); |
| return *this; |
| } |
| |
| Poll<absl::Status> operator()(); |
| |
| private: |
| // Called from application code. |
| static void OnMdProcessingDone(void* user_data, |
| const grpc_metadata* consumed_md, |
| size_t num_consumed_md, |
| const grpc_metadata* response_md, |
| size_t num_response_md, |
| grpc_status_code status, |
| const char* error_details); |
| |
| struct State; |
| State* state_; |
| }; |
| |
| public: |
| static const grpc_channel_filter kFilter; |
| |
| ServerAuthFilter(RefCountedPtr<grpc_server_credentials> server_credentials, |
| RefCountedPtr<grpc_auth_context> auth_context); |
| |
| static absl::StatusOr<std::unique_ptr<ServerAuthFilter>> Create( |
| const ChannelArgs& args, ChannelFilter::Args); |
| |
| class Call { |
| public: |
| explicit Call(ServerAuthFilter* filter); |
| auto OnClientInitialMetadata(ClientMetadata& md, ServerAuthFilter* filter) { |
| return If( |
| filter->server_credentials_ == nullptr || |
| filter->server_credentials_->auth_metadata_processor().process == |
| nullptr, |
| ImmediateOkStatus(), |
| [filter, md = &md]() { return RunApplicationCode(filter, *md); }); |
| } |
| static const NoInterceptor OnServerInitialMetadata; |
| static const NoInterceptor OnClientToServerMessage; |
| static const NoInterceptor OnServerToClientMessage; |
| static const NoInterceptor OnServerTrailingMetadata; |
| static const NoInterceptor OnFinalize; |
| }; |
| |
| private: |
| ArenaPromise<absl::StatusOr<CallArgs>> GetCallCredsMetadata( |
| CallArgs call_args); |
| |
| RefCountedPtr<grpc_server_credentials> server_credentials_; |
| RefCountedPtr<grpc_auth_context> auth_context_; |
| }; |
| |
| } // namespace grpc_core |
| |
| // Exposed for testing purposes only. |
| // Check if the channel's security level is higher or equal to |
| // that of call credentials to make a decision whether the transfer |
| // of call credentials should be allowed or not. |
| bool grpc_check_security_level(grpc_security_level channel_level, |
| grpc_security_level call_cred_level); |
| |
| #endif // GRPC_SRC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H |