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_CREDENTIALS_CREDENTIALS_H 20 #define GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include <string> 25 #include <utility> 26 #include <vector> 27 28 #include "absl/status/statusor.h" 29 #include "absl/strings/string_view.h" 30 31 #include <grpc/grpc.h> 32 #include <grpc/grpc_security.h> 33 #include <grpc/grpc_security_constants.h> 34 #include <grpc/impl/grpc_types.h> 35 #include <grpc/support/log.h> 36 37 #include "src/core/lib/channel/channel_args.h" 38 #include "src/core/lib/gprpp/crash.h" 39 #include "src/core/lib/gprpp/ref_counted.h" 40 #include "src/core/lib/gprpp/ref_counted_ptr.h" 41 #include "src/core/lib/gprpp/unique_type_name.h" 42 #include "src/core/lib/promise/arena_promise.h" 43 #include "src/core/lib/security/security_connector/security_connector.h" 44 #include "src/core/lib/slice/slice.h" 45 #include "src/core/lib/transport/transport.h" 46 47 // --- Constants. --- 48 49 typedef enum { 50 GRPC_CREDENTIALS_OK = 0, 51 GRPC_CREDENTIALS_ERROR 52 } grpc_credentials_status; 53 54 #define GRPC_FAKE_TRANSPORT_SECURITY_TYPE "fake" 55 56 #define GRPC_AUTHORIZATION_METADATA_KEY "authorization" 57 #define GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY \ 58 "x-goog-iam-authorization-token" 59 #define GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY "x-goog-iam-authority-selector" 60 61 #define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60 62 63 #define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata.google.internal." 64 #define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \ 65 "/computeMetadata/v1/instance/service-accounts/default/token" 66 67 #define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "oauth2.googleapis.com" 68 #define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/token" 69 70 #define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \ 71 "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \ 72 "assertion=" 73 74 #define GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING \ 75 "client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token" 76 77 // --- Google utils --- 78 79 // It is the caller's responsibility to gpr_free the result if not NULL. 80 std::string grpc_get_well_known_google_credentials_file_path(void); 81 82 // Implementation function for the different platforms. 83 std::string grpc_get_well_known_google_credentials_file_path_impl(void); 84 85 // Override for testing only. Not thread-safe 86 typedef std::string (*grpc_well_known_credentials_path_getter)(void); 87 void grpc_override_well_known_credentials_path_getter( 88 grpc_well_known_credentials_path_getter getter); 89 90 // --- grpc_channel_credentials. --- 91 92 #define GRPC_ARG_CHANNEL_CREDENTIALS "grpc.internal.channel_credentials" 93 94 // This type is forward declared as a C struct and we cannot define it as a 95 // class. Otherwise, compiler will complain about type mismatch due to 96 // -Wmismatched-tags. 97 struct grpc_channel_credentials 98 : grpc_core::RefCounted<grpc_channel_credentials> { 99 public: ChannelArgNamegrpc_channel_credentials100 static absl::string_view ChannelArgName() { 101 return GRPC_ARG_CHANNEL_CREDENTIALS; 102 } 103 ChannelArgsComparegrpc_channel_credentials104 static int ChannelArgsCompare(const grpc_channel_credentials* args1, 105 const grpc_channel_credentials* args2) { 106 return args1->cmp(args2); 107 } 108 109 // Creates a security connector for the channel. Also updates passed in 110 // channel args for the channel. 111 virtual grpc_core::RefCountedPtr<grpc_channel_security_connector> 112 create_security_connector( 113 grpc_core::RefCountedPtr<grpc_call_credentials> call_creds, 114 const char* target, grpc_core::ChannelArgs* args) = 0; 115 116 // Creates a version of the channel credentials without any attached call 117 // credentials. This can be used in order to open a channel to a non-trusted 118 // gRPC load balancer. 119 virtual grpc_core::RefCountedPtr<grpc_channel_credentials> duplicate_without_call_credentialsgrpc_channel_credentials120 duplicate_without_call_credentials() { 121 // By default we just increment the refcount. 122 return Ref(); 123 } 124 125 // Allows credentials to optionally modify a parent channel's args. 126 // By default, leave channel args as is. update_argumentsgrpc_channel_credentials127 virtual grpc_core::ChannelArgs update_arguments(grpc_core::ChannelArgs args) { 128 return args; 129 } 130 131 // Compares this grpc_channel_credentials object with \a other. 132 // If this method returns 0, it means that gRPC can treat the two channel 133 // credentials as effectively the same. This method is used to compare 134 // `grpc_channel_credentials` objects when they are present in channel_args. 135 // One important usage of this is when channel args are used in SubchannelKey, 136 // which leads to a useful property that allows subchannels to be reused when 137 // two different `grpc_channel_credentials` objects are used but they compare 138 // as equal (assuming other channel args match). cmpgrpc_channel_credentials139 int cmp(const grpc_channel_credentials* other) const { 140 GPR_ASSERT(other != nullptr); 141 int r = type().Compare(other->type()); 142 if (r != 0) return r; 143 return cmp_impl(other); 144 } 145 146 // The pointer value \a type is used to uniquely identify a creds 147 // implementation for down-casting purposes. Every creds implementation should 148 // use a unique string instance, which should be returned by all instances of 149 // that creds implementation. 150 virtual grpc_core::UniqueTypeName type() const = 0; 151 152 private: 153 // Implementation for `cmp` method intended to be overridden by subclasses. 154 // Only invoked if `type()` and `other->type()` point to the same string. 155 virtual int cmp_impl(const grpc_channel_credentials* other) const = 0; 156 }; 157 158 // TODO(roth): Once we eliminate insecure builds, find a better way to 159 // plumb credentials so that it doesn't need to flow through channel 160 // args. For example, we'll want to expose it to LB policies by adding 161 // methods on the helper API. 162 163 // Util to encapsulate the channel credentials in a channel arg. 164 grpc_arg grpc_channel_credentials_to_arg(grpc_channel_credentials* credentials); 165 166 // Util to get the channel credentials from a channel arg. 167 grpc_channel_credentials* grpc_channel_credentials_from_arg( 168 const grpc_arg* arg); 169 170 // Util to find the channel credentials from channel args. 171 grpc_channel_credentials* grpc_channel_credentials_find_in_args( 172 const grpc_channel_args* args); 173 174 // --- grpc_core::CredentialsMetadataArray. --- 175 176 namespace grpc_core { 177 using CredentialsMetadataArray = std::vector<std::pair<Slice, Slice>>; 178 } 179 180 // --- grpc_call_credentials. --- 181 182 // This type is forward declared as a C struct and we cannot define it as a 183 // class. Otherwise, compiler will complain about type mismatch due to 184 // -Wmismatched-tags. 185 struct grpc_call_credentials 186 : public grpc_core::RefCounted<grpc_call_credentials> { 187 public: 188 // TODO(roth): Consider whether security connector actually needs to 189 // be part of this interface. Currently, it is here only for the 190 // url_scheme() method, which we might be able to instead add as an 191 // auth context property. 192 struct GetRequestMetadataArgs { 193 grpc_core::RefCountedPtr<grpc_channel_security_connector> 194 security_connector; 195 grpc_core::RefCountedPtr<grpc_auth_context> auth_context; 196 }; 197 198 // The pointer value \a type is used to uniquely identify a creds 199 // implementation for down-casting purposes. Every creds implementation should 200 // use a unique string instance, which should be returned by all instances of 201 // that creds implementation. 202 explicit grpc_call_credentials( 203 grpc_security_level min_security_level = GRPC_PRIVACY_AND_INTEGRITY) min_security_level_grpc_call_credentials204 : min_security_level_(min_security_level) {} 205 206 ~grpc_call_credentials() override = default; 207 208 virtual grpc_core::ArenaPromise< 209 absl::StatusOr<grpc_core::ClientMetadataHandle>> 210 GetRequestMetadata(grpc_core::ClientMetadataHandle initial_metadata, 211 const GetRequestMetadataArgs* args) = 0; 212 min_security_levelgrpc_call_credentials213 virtual grpc_security_level min_security_level() const { 214 return min_security_level_; 215 } 216 217 // Compares this grpc_call_credentials object with \a other. 218 // If this method returns 0, it means that gRPC can treat the two call 219 // credentials as effectively the same.. cmpgrpc_call_credentials220 int cmp(const grpc_call_credentials* other) const { 221 GPR_ASSERT(other != nullptr); 222 int r = type().Compare(other->type()); 223 if (r != 0) return r; 224 return cmp_impl(other); 225 } 226 debug_stringgrpc_call_credentials227 virtual std::string debug_string() { 228 return "grpc_call_credentials did not provide debug string"; 229 } 230 231 // The pointer value \a type is used to uniquely identify a creds 232 // implementation for down-casting purposes. Every creds implementation should 233 // use a unique string instance, which should be returned by all instances of 234 // that creds implementation. 235 virtual grpc_core::UniqueTypeName type() const = 0; 236 237 private: 238 // Implementation for `cmp` method intended to be overridden by subclasses. 239 // Only invoked if `type()` and `other->type()` point to the same string. 240 virtual int cmp_impl(const grpc_call_credentials* other) const = 0; 241 242 const grpc_security_level min_security_level_; 243 }; 244 245 // Metadata-only credentials with the specified key and value where 246 // asynchronicity can be simulated for testing. 247 grpc_call_credentials* grpc_md_only_test_credentials_create( 248 const char* md_key, const char* md_value); 249 250 // --- grpc_server_credentials. --- 251 252 #define GRPC_SERVER_CREDENTIALS_ARG "grpc.internal.server_credentials" 253 254 // This type is forward declared as a C struct and we cannot define it as a 255 // class. Otherwise, compiler will complain about type mismatch due to 256 // -Wmismatched-tags. 257 struct grpc_server_credentials 258 : public grpc_core::RefCounted<grpc_server_credentials> { 259 public: ~grpc_server_credentialsgrpc_server_credentials260 ~grpc_server_credentials() override { DestroyProcessor(); } 261 ChannelArgNamegrpc_server_credentials262 static absl::string_view ChannelArgName() { 263 return GRPC_SERVER_CREDENTIALS_ARG; 264 } 265 ChannelArgsComparegrpc_server_credentials266 static int ChannelArgsCompare(const grpc_server_credentials* a, 267 const grpc_server_credentials* b) { 268 return grpc_core::QsortCompare(a, b); 269 } 270 271 // Ownership of \a args is not passed. 272 virtual grpc_core::RefCountedPtr<grpc_server_security_connector> 273 create_security_connector(const grpc_core::ChannelArgs& args) = 0; 274 275 virtual grpc_core::UniqueTypeName type() const = 0; 276 auth_metadata_processorgrpc_server_credentials277 const grpc_auth_metadata_processor& auth_metadata_processor() const { 278 return processor_; 279 } 280 void set_auth_metadata_processor( 281 const grpc_auth_metadata_processor& processor); 282 283 private: DestroyProcessorgrpc_server_credentials284 void DestroyProcessor() { 285 if (processor_.destroy != nullptr && processor_.state != nullptr) { 286 processor_.destroy(processor_.state); 287 } 288 } 289 290 grpc_auth_metadata_processor processor_ = 291 grpc_auth_metadata_processor(); // Zero-initialize the C struct. 292 }; 293 294 grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials* c); 295 grpc_server_credentials* grpc_server_credentials_from_arg(const grpc_arg* arg); 296 grpc_server_credentials* grpc_find_server_credentials_in_args( 297 const grpc_channel_args* args); 298 299 #endif // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H 300