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