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 GRPCPP_SECURITY_CREDENTIALS_H
20 #define GRPCPP_SECURITY_CREDENTIALS_H
21 
22 #include <map>
23 #include <memory>
24 #include <vector>
25 
26 #include <grpc/grpc_security_constants.h>
27 #include <grpcpp/channel.h>
28 #include <grpcpp/impl/grpc_library.h>
29 #include <grpcpp/security/auth_context.h>
30 #include <grpcpp/security/tls_credentials_options.h>
31 #include <grpcpp/support/channel_arguments.h>
32 #include <grpcpp/support/client_interceptor.h>
33 #include <grpcpp/support/status.h>
34 #include <grpcpp/support/string_ref.h>
35 
36 struct grpc_call;
37 
38 namespace grpc {
39 class CallCredentials;
40 class SecureCallCredentials;
41 class SecureChannelCredentials;
42 class ChannelCredentials;
43 
44 std::shared_ptr<Channel> CreateCustomChannel(
45     const grpc::string& target,
46     const std::shared_ptr<grpc::ChannelCredentials>& creds,
47     const grpc::ChannelArguments& args);
48 
49 namespace experimental {
50 std::shared_ptr<grpc::Channel> CreateCustomChannelWithInterceptors(
51     const grpc::string& target,
52     const std::shared_ptr<grpc::ChannelCredentials>& creds,
53     const grpc::ChannelArguments& args,
54     std::vector<
55         std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>
56         interceptor_creators);
57 }  // namespace experimental
58 
59 /// Builds XDS Credentials.
60 std::shared_ptr<ChannelCredentials> XdsCredentials(
61     const std::shared_ptr<ChannelCredentials>& fallback_creds);
62 
63 /// A channel credentials object encapsulates all the state needed by a client
64 /// to authenticate with a server for a given channel.
65 /// It can make various assertions, e.g., about the client’s identity, role
66 /// for all the calls on that channel.
67 ///
68 /// \see https://grpc.io/docs/guides/auth.html
69 class ChannelCredentials : private grpc::internal::GrpcLibrary {
70  public:
71  protected:
72   friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
73       const std::shared_ptr<ChannelCredentials>& channel_creds,
74       const std::shared_ptr<CallCredentials>& call_creds);
75 
76   // TODO(yashykt): We need this friend declaration mainly for access to
77   // AsSecureCredentials(). Once we are able to remove insecure builds from gRPC
78   // (and also internal dependencies on the indirect method of creating a
79   // channel through credentials), we would be able to remove this.
80   friend std::shared_ptr<ChannelCredentials> grpc::XdsCredentials(
81       const std::shared_ptr<ChannelCredentials>& fallback_creds);
82 
83   virtual SecureChannelCredentials* AsSecureCredentials() = 0;
84 
85  private:
86   friend std::shared_ptr<grpc::Channel> CreateCustomChannel(
87       const grpc::string& target,
88       const std::shared_ptr<grpc::ChannelCredentials>& creds,
89       const grpc::ChannelArguments& args);
90 
91   friend std::shared_ptr<grpc::Channel>
92   grpc::experimental::CreateCustomChannelWithInterceptors(
93       const grpc::string& target,
94       const std::shared_ptr<grpc::ChannelCredentials>& creds,
95       const grpc::ChannelArguments& args,
96       std::vector<std::unique_ptr<
97           grpc::experimental::ClientInterceptorFactoryInterface>>
98           interceptor_creators);
99 
100   virtual std::shared_ptr<Channel> CreateChannelImpl(
101       const grpc::string& target, const ChannelArguments& args) = 0;
102 
103   // This function should have been a pure virtual function, but it is
104   // implemented as a virtual function so that it does not break API.
CreateChannelWithInterceptors(const grpc::string &,const ChannelArguments &,std::vector<std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>)105   virtual std::shared_ptr<Channel> CreateChannelWithInterceptors(
106       const grpc::string& /*target*/, const ChannelArguments& /*args*/,
107       std::vector<std::unique_ptr<
108           grpc::experimental::ClientInterceptorFactoryInterface>>
109       /*interceptor_creators*/) {
110     return nullptr;
111   }
112 
113   // TODO(yashkt): This is a hack that is needed since InsecureCredentials can
114   // not use grpc_channel_credentials internally and should be removed after
115   // insecure builds are removed from gRPC.
IsInsecure()116   virtual bool IsInsecure() const { return false; }
117 };
118 
119 /// A call credentials object encapsulates the state needed by a client to
120 /// authenticate with a server for a given call on a channel.
121 ///
122 /// \see https://grpc.io/docs/guides/auth.html
123 class CallCredentials : private grpc::internal::GrpcLibrary {
124  public:
125   /// Apply this instance's credentials to \a call.
126   virtual bool ApplyToCall(grpc_call* call) = 0;
DebugString()127   virtual grpc::string DebugString() {
128     return "CallCredentials did not provide a debug string";
129   }
130 
131  protected:
132   friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
133       const std::shared_ptr<ChannelCredentials>& channel_creds,
134       const std::shared_ptr<CallCredentials>& call_creds);
135 
136   friend std::shared_ptr<CallCredentials> CompositeCallCredentials(
137       const std::shared_ptr<CallCredentials>& creds1,
138       const std::shared_ptr<CallCredentials>& creds2);
139 
140   virtual SecureCallCredentials* AsSecureCredentials() = 0;
141 };
142 
143 /// Options used to build SslCredentials.
144 struct SslCredentialsOptions {
145   /// The buffer containing the PEM encoding of the server root certificates. If
146   /// this parameter is empty, the default roots will be used.  The default
147   /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH
148   /// environment variable pointing to a file on the file system containing the
149   /// roots.
150   grpc::string pem_root_certs;
151 
152   /// The buffer containing the PEM encoding of the client's private key. This
153   /// parameter can be empty if the client does not have a private key.
154   grpc::string pem_private_key;
155 
156   /// The buffer containing the PEM encoding of the client's certificate chain.
157   /// This parameter can be empty if the client does not have a certificate
158   /// chain.
159   grpc::string pem_cert_chain;
160 };
161 
162 // Factories for building different types of Credentials The functions may
163 // return empty shared_ptr when credentials cannot be created. If a
164 // Credentials pointer is returned, it can still be invalid when used to create
165 // a channel. A lame channel will be created then and all rpcs will fail on it.
166 
167 /// Builds credentials with reasonable defaults.
168 ///
169 /// \warning Only use these credentials when connecting to a Google endpoint.
170 /// Using these credentials to connect to any other service may result in this
171 /// service being able to impersonate your client for requests to Google
172 /// services.
173 std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials();
174 
175 /// Builds SSL Credentials given SSL specific options
176 std::shared_ptr<ChannelCredentials> SslCredentials(
177     const SslCredentialsOptions& options);
178 
179 /// Builds credentials for use when running in GCE
180 ///
181 /// \warning Only use these credentials when connecting to a Google endpoint.
182 /// Using these credentials to connect to any other service may result in this
183 /// service being able to impersonate your client for requests to Google
184 /// services.
185 std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials();
186 
187 constexpr long kMaxAuthTokenLifetimeSecs = 3600;
188 
189 /// Builds Service Account JWT Access credentials.
190 /// json_key is the JSON key string containing the client's private key.
191 /// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
192 /// (JWT) created with this credentials. It should not exceed
193 /// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value.
194 std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
195     const grpc::string& json_key,
196     long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs);
197 
198 /// Builds refresh token credentials.
199 /// json_refresh_token is the JSON string containing the refresh token along
200 /// with a client_id and client_secret.
201 ///
202 /// \warning Only use these credentials when connecting to a Google endpoint.
203 /// Using these credentials to connect to any other service may result in this
204 /// service being able to impersonate your client for requests to Google
205 /// services.
206 std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
207     const grpc::string& json_refresh_token);
208 
209 /// Builds access token credentials.
210 /// access_token is an oauth2 access token that was fetched using an out of band
211 /// mechanism.
212 ///
213 /// \warning Only use these credentials when connecting to a Google endpoint.
214 /// Using these credentials to connect to any other service may result in this
215 /// service being able to impersonate your client for requests to Google
216 /// services.
217 std::shared_ptr<CallCredentials> AccessTokenCredentials(
218     const grpc::string& access_token);
219 
220 /// Builds IAM credentials.
221 ///
222 /// \warning Only use these credentials when connecting to a Google endpoint.
223 /// Using these credentials to connect to any other service may result in this
224 /// service being able to impersonate your client for requests to Google
225 /// services.
226 std::shared_ptr<CallCredentials> GoogleIAMCredentials(
227     const grpc::string& authorization_token,
228     const grpc::string& authority_selector);
229 
230 /// Combines a channel credentials and a call credentials into a composite
231 /// channel credentials.
232 std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
233     const std::shared_ptr<ChannelCredentials>& channel_creds,
234     const std::shared_ptr<CallCredentials>& call_creds);
235 
236 /// Combines two call credentials objects into a composite call credentials.
237 std::shared_ptr<CallCredentials> CompositeCallCredentials(
238     const std::shared_ptr<CallCredentials>& creds1,
239     const std::shared_ptr<CallCredentials>& creds2);
240 
241 /// Credentials for an unencrypted, unauthenticated channel
242 std::shared_ptr<ChannelCredentials> InsecureChannelCredentials();
243 
244 /// User defined metadata credentials.
245 class MetadataCredentialsPlugin {
246  public:
~MetadataCredentialsPlugin()247   virtual ~MetadataCredentialsPlugin() {}
248 
249   /// If this method returns true, the Process function will be scheduled in
250   /// a different thread from the one processing the call.
IsBlocking()251   virtual bool IsBlocking() const { return true; }
252 
253   /// Type of credentials this plugin is implementing.
GetType()254   virtual const char* GetType() const { return ""; }
255 
256   /// Gets the auth metatada produced by this plugin.
257   /// The fully qualified method name is:
258   /// service_url + "/" + method_name.
259   /// The channel_auth_context contains (among other things), the identity of
260   /// the server.
261   virtual grpc::Status GetMetadata(
262       grpc::string_ref service_url, grpc::string_ref method_name,
263       const grpc::AuthContext& channel_auth_context,
264       std::multimap<grpc::string, grpc::string>* metadata) = 0;
265 
DebugString()266   virtual grpc::string DebugString() {
267     return "MetadataCredentialsPlugin did not provide a debug string";
268   }
269 };
270 
271 std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
272     std::unique_ptr<MetadataCredentialsPlugin> plugin);
273 
274 /// Builds External Account credentials.
275 /// json_string is the JSON string containing the credentials options.
276 /// scopes contains the scopes to be binded with the credentials.
277 std::shared_ptr<CallCredentials> ExternalAccountCredentials(
278     const grpc::string& json_string, const std::vector<grpc::string>& scopes);
279 
280 namespace experimental {
281 
282 /// Options for creating STS Oauth Token Exchange credentials following the IETF
283 /// draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16.
284 /// Optional fields may be set to empty string. It is the responsibility of the
285 /// caller to ensure that the subject and actor tokens are refreshed on disk at
286 /// the specified paths.
287 struct StsCredentialsOptions {
288   grpc::string token_exchange_service_uri;  // Required.
289   grpc::string resource;                    // Optional.
290   grpc::string audience;                    // Optional.
291   grpc::string scope;                       // Optional.
292   grpc::string requested_token_type;        // Optional.
293   grpc::string subject_token_path;          // Required.
294   grpc::string subject_token_type;          // Required.
295   grpc::string actor_token_path;            // Optional.
296   grpc::string actor_token_type;            // Optional.
297 };
298 
299 grpc::Status StsCredentialsOptionsFromJson(const std::string& json_string,
300                                            StsCredentialsOptions* options);
301 
302 /// Creates STS credentials options from the $STS_CREDENTIALS environment
303 /// variable. This environment variable points to the path of a JSON file
304 /// comforming to the schema described above.
305 grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options);
306 
307 std::shared_ptr<CallCredentials> StsCredentials(
308     const StsCredentialsOptions& options);
309 
310 std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
311     std::unique_ptr<MetadataCredentialsPlugin> plugin,
312     grpc_security_level min_security_level);
313 
314 /// Options used to build AltsCredentials.
315 struct AltsCredentialsOptions {
316   /// service accounts of target endpoint that will be acceptable
317   /// by the client. If service accounts are provided and none of them matches
318   /// that of the server, authentication will fail.
319   std::vector<grpc::string> target_service_accounts;
320 };
321 
322 /// Builds ALTS Credentials given ALTS specific options
323 std::shared_ptr<ChannelCredentials> AltsCredentials(
324     const AltsCredentialsOptions& options);
325 
326 /// Builds Local Credentials.
327 std::shared_ptr<ChannelCredentials> LocalCredentials(
328     grpc_local_connect_type type);
329 
330 /// Builds TLS Credentials given TLS options.
331 std::shared_ptr<ChannelCredentials> TlsCredentials(
332     const TlsChannelCredentialsOptions& options);
333 
334 }  // namespace experimental
335 }  // namespace grpc
336 
337 #endif  // GRPCPP_SECURITY_CREDENTIALS_H
338