• 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/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