1 // 2 // 3 // Copyright 2016 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H 20 #define GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H 21 22 #include <grpc/credentials.h> 23 #include <grpc/grpc.h> 24 #include <grpc/grpc_security.h> 25 #include <grpc/grpc_security_constants.h> 26 #include <grpc/status.h> 27 #include <grpc/support/port_platform.h> 28 #include <stddef.h> 29 30 #include <atomic> 31 #include <string> 32 #include <utility> 33 34 #include "absl/container/inlined_vector.h" 35 #include "absl/status/statusor.h" 36 #include "src/core/lib/debug/trace.h" 37 #include "src/core/lib/promise/activity.h" 38 #include "src/core/lib/promise/arena_promise.h" 39 #include "src/core/lib/promise/poll.h" 40 #include "src/core/lib/security/credentials/call_creds_util.h" 41 #include "src/core/lib/security/credentials/credentials.h" 42 #include "src/core/lib/slice/slice.h" 43 #include "src/core/lib/transport/transport.h" 44 #include "src/core/util/ref_counted.h" 45 #include "src/core/util/ref_counted_ptr.h" 46 #include "src/core/util/unique_type_name.h" 47 #include "src/core/util/useful.h" 48 49 // This type is forward declared as a C struct and we cannot define it as a 50 // class. Otherwise, compiler will complain about type mismatch due to 51 // -Wmismatched-tags. 52 struct grpc_plugin_credentials final : public grpc_call_credentials { 53 public: 54 explicit grpc_plugin_credentials(grpc_metadata_credentials_plugin plugin, 55 grpc_security_level min_security_level); 56 ~grpc_plugin_credentials() override; 57 Orphanedfinal58 void Orphaned() override {} 59 60 grpc_core::ArenaPromise<absl::StatusOr<grpc_core::ClientMetadataHandle>> 61 GetRequestMetadata(grpc_core::ClientMetadataHandle initial_metadata, 62 const GetRequestMetadataArgs* args) override; 63 64 std::string debug_string() override; 65 66 grpc_core::UniqueTypeName type() const override; 67 68 private: 69 class PendingRequest : public grpc_core::RefCounted<PendingRequest> { 70 public: PendingRequestfinal71 PendingRequest(grpc_core::RefCountedPtr<grpc_plugin_credentials> creds, 72 grpc_core::ClientMetadataHandle initial_metadata, 73 const grpc_call_credentials::GetRequestMetadataArgs* args) 74 : call_creds_(std::move(creds)), 75 context_( 76 grpc_core::MakePluginAuthMetadataContext(initial_metadata, args)), 77 md_(std::move(initial_metadata)) {} 78 ~PendingRequestfinal79 ~PendingRequest() override { 80 grpc_auth_metadata_context_reset(&context_); 81 for (size_t i = 0; i < metadata_.size(); i++) { 82 grpc_core::CSliceUnref(metadata_[i].key); 83 grpc_core::CSliceUnref(metadata_[i].value); 84 } 85 } 86 87 absl::StatusOr<grpc_core::ClientMetadataHandle> ProcessPluginResult( 88 const grpc_metadata* md, size_t num_md, grpc_status_code status, 89 const char* error_details); 90 91 grpc_core::Poll<absl::StatusOr<grpc_core::ClientMetadataHandle>> 92 PollAsyncResult(); 93 94 static void RequestMetadataReady(void* request, const grpc_metadata* md, 95 size_t num_md, grpc_status_code status, 96 const char* error_details); 97 contextfinal98 grpc_auth_metadata_context context() const { return context_; } credsfinal99 grpc_plugin_credentials* creds() const { return call_creds_.get(); } 100 101 private: 102 std::atomic<bool> ready_{false}; 103 grpc_core::Waker waker_{ 104 grpc_core::GetContext<grpc_core::Activity>()->MakeNonOwningWaker()}; 105 grpc_core::RefCountedPtr<grpc_plugin_credentials> call_creds_; 106 grpc_auth_metadata_context context_; 107 grpc_core::ClientMetadataHandle md_; 108 // final status 109 absl::InlinedVector<grpc_metadata, 2> metadata_; 110 std::string error_details_; 111 grpc_status_code status_; 112 }; 113 cmp_implfinal114 int cmp_impl(const grpc_call_credentials* other) const override { 115 // TODO(yashykt): Check if we can do something better here 116 return grpc_core::QsortCompare( 117 static_cast<const grpc_call_credentials*>(this), other); 118 } 119 120 grpc_metadata_credentials_plugin plugin_; 121 }; 122 123 #endif // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H 124