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