• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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