1 // 2 // 3 // Copyright 2015 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_CONTEXT_SECURITY_CONTEXT_H 20 #define GRPC_SRC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H 21 22 #include <grpc/credentials.h> 23 #include <grpc/grpc.h> 24 #include <grpc/grpc_security.h> 25 #include <grpc/support/alloc.h> 26 #include <grpc/support/port_platform.h> 27 #include <stddef.h> 28 29 #include <memory> 30 #include <utility> 31 32 #include "absl/strings/string_view.h" 33 #include "src/core/lib/debug/trace.h" 34 #include "src/core/lib/resource_quota/arena.h" 35 #include "src/core/lib/security/credentials/credentials.h" // IWYU pragma: keep 36 #include "src/core/lib/surface/connection_context.h" 37 #include "src/core/util/debug_location.h" 38 #include "src/core/util/orphanable.h" 39 #include "src/core/util/ref_counted.h" 40 #include "src/core/util/ref_counted_ptr.h" 41 #include "src/core/util/useful.h" 42 43 // --- grpc_auth_context --- 44 45 // High level authentication context object. Can optionally be chained. 46 47 // Property names are always NULL terminated. 48 49 struct grpc_auth_property_array { 50 grpc_auth_property* array = nullptr; 51 size_t count = 0; 52 size_t capacity = 0; 53 }; 54 55 void grpc_auth_property_reset(grpc_auth_property* property); 56 57 #define GRPC_AUTH_CONTEXT_ARG "grpc.auth_context" 58 59 // This type is forward declared as a C struct and we cannot define it as a 60 // class. Otherwise, compiler will complain about type mismatch due to 61 // -Wmismatched-tags. 62 struct grpc_auth_context 63 : public grpc_core::RefCounted<grpc_auth_context, 64 grpc_core::NonPolymorphicRefCount> { 65 public: 66 // Base class for all extensions to inherit from. 67 class Extension { 68 public: 69 virtual ~Extension() = default; 70 }; grpc_auth_contextgrpc_auth_context71 explicit grpc_auth_context( 72 grpc_core::RefCountedPtr<grpc_auth_context> chained) 73 : grpc_core::RefCounted<grpc_auth_context, 74 grpc_core::NonPolymorphicRefCount>( 75 GRPC_TRACE_FLAG_ENABLED(auth_context_refcount) 76 ? "auth_context_refcount" 77 : nullptr), 78 chained_(std::move(chained)) { 79 if (chained_ != nullptr) { 80 peer_identity_property_name_ = chained_->peer_identity_property_name_; 81 } 82 connection_context_ = grpc_core::ConnectionContext::Create(); 83 } 84 ~grpc_auth_contextgrpc_auth_context85 ~grpc_auth_context() { 86 chained_.reset(DEBUG_LOCATION, "chained"); 87 if (properties_.array != nullptr) { 88 for (size_t i = 0; i < properties_.count; i++) { 89 grpc_auth_property_reset(&properties_.array[i]); 90 } 91 gpr_free(properties_.array); 92 } 93 } 94 ChannelArgNamegrpc_auth_context95 static absl::string_view ChannelArgName() { return GRPC_AUTH_CONTEXT_ARG; } ChannelArgsComparegrpc_auth_context96 static int ChannelArgsCompare(const grpc_auth_context* a, 97 const grpc_auth_context* b) { 98 return QsortCompare(a, b); 99 } 100 chainedgrpc_auth_context101 const grpc_auth_context* chained() const { return chained_.get(); } propertiesgrpc_auth_context102 const grpc_auth_property_array& properties() const { return properties_; } 103 connection_contextgrpc_auth_context104 grpc_core::ConnectionContext* connection_context() const { 105 return connection_context_.get(); 106 } 107 is_authenticatedgrpc_auth_context108 bool is_authenticated() const { 109 return peer_identity_property_name_ != nullptr; 110 } peer_identity_property_namegrpc_auth_context111 const char* peer_identity_property_name() const { 112 return peer_identity_property_name_; 113 } set_peer_identity_property_namegrpc_auth_context114 void set_peer_identity_property_name(const char* name) { 115 peer_identity_property_name_ = name; 116 } set_extensiongrpc_auth_context117 void set_extension(std::unique_ptr<Extension> extension) { 118 extension_ = std::move(extension); 119 } 120 121 void ensure_capacity(); 122 void add_property(const char* name, const char* value, size_t value_length); 123 void add_cstring_property(const char* name, const char* value); 124 125 private: 126 grpc_core::RefCountedPtr<grpc_auth_context> chained_; 127 grpc_auth_property_array properties_; 128 const char* peer_identity_property_name_ = nullptr; 129 std::unique_ptr<Extension> extension_; 130 grpc_core::OrphanablePtr<grpc_core::ConnectionContext> connection_context_; 131 }; 132 133 // --- grpc_security_context_extension --- 134 135 // Extension to the security context that may be set in a filter and accessed 136 // later by a higher level method on a grpc_call object. 137 138 struct grpc_security_context_extension { 139 void* instance = nullptr; 140 void (*destroy)(void*) = nullptr; 141 }; 142 143 namespace grpc_core { 144 145 class SecurityContext { 146 public: 147 virtual ~SecurityContext() = default; 148 }; 149 150 } // namespace grpc_core 151 152 // --- grpc_client_security_context --- 153 154 // Internal client-side security context. 155 156 struct grpc_client_security_context final : public grpc_core::SecurityContext { grpc_client_security_contextfinal157 explicit grpc_client_security_context( 158 grpc_core::RefCountedPtr<grpc_call_credentials> creds) 159 : creds(std::move(creds)) {} 160 ~grpc_client_security_context() override; 161 162 grpc_core::RefCountedPtr<grpc_call_credentials> creds; 163 grpc_core::RefCountedPtr<grpc_auth_context> auth_context; 164 grpc_security_context_extension extension; 165 }; 166 167 grpc_client_security_context* grpc_client_security_context_create( 168 grpc_core::Arena* arena, grpc_call_credentials* creds); 169 void grpc_client_security_context_destroy(void* ctx); 170 171 // --- grpc_server_security_context --- 172 173 // Internal server-side security context. 174 175 struct grpc_server_security_context final : public grpc_core::SecurityContext { 176 grpc_server_security_context() = default; 177 ~grpc_server_security_context() override; 178 179 grpc_core::RefCountedPtr<grpc_auth_context> auth_context; 180 grpc_security_context_extension extension; 181 }; 182 183 grpc_server_security_context* grpc_server_security_context_create( 184 grpc_core::Arena* arena); 185 void grpc_server_security_context_destroy(void* ctx); 186 187 // --- Channel args for auth context --- 188 189 grpc_arg grpc_auth_context_to_arg(grpc_auth_context* c); 190 grpc_auth_context* grpc_auth_context_from_arg(const grpc_arg* arg); 191 grpc_auth_context* grpc_find_auth_context_in_args( 192 const grpc_channel_args* args); 193 194 namespace grpc_core { 195 template <> 196 struct ArenaContextType<SecurityContext> { 197 static void Destroy(SecurityContext* p) { p->~SecurityContext(); } 198 }; 199 200 template <> 201 struct ContextSubclass<grpc_client_security_context> { 202 using Base = SecurityContext; 203 }; 204 template <> 205 struct ContextSubclass<grpc_server_security_context> { 206 using Base = SecurityContext; 207 }; 208 } // namespace grpc_core 209 210 #endif // GRPC_SRC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H 211