Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include <grpc/support/log.h>
35 : #include <grpc++/channel.h>
36 : #include <grpc++/impl/grpc_library.h>
37 : #include <grpc++/support/channel_arguments.h>
38 : #include "src/cpp/client/create_channel_internal.h"
39 : #include "src/cpp/client/secure_credentials.h"
40 :
41 : namespace grpc {
42 :
43 46 : std::shared_ptr<grpc::Channel> SecureCredentials::CreateChannel(
44 : const string& target, const grpc::ChannelArguments& args) {
45 : grpc_channel_args channel_args;
46 46 : args.SetChannelArgs(&channel_args);
47 : return CreateChannelInternal(
48 : args.GetSslTargetNameOverride(),
49 : grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args,
50 46 : nullptr));
51 : }
52 :
53 8 : bool SecureCredentials::ApplyToCall(grpc_call* call) {
54 8 : return grpc_call_set_credentials(call, c_creds_) == GRPC_CALL_OK;
55 : }
56 :
57 : namespace {
58 57 : std::shared_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
59 : return creds == nullptr
60 : ? nullptr
61 57 : : std::shared_ptr<Credentials>(new SecureCredentials(creds));
62 : }
63 : } // namespace
64 :
65 0 : std::shared_ptr<Credentials> GoogleDefaultCredentials() {
66 0 : GrpcLibrary init; // To call grpc_init().
67 0 : return WrapCredentials(grpc_google_default_credentials_create());
68 : }
69 :
70 : // Builds SSL Credentials given SSL specific options
71 46 : std::shared_ptr<Credentials> SslCredentials(
72 : const SslCredentialsOptions& options) {
73 46 : GrpcLibrary init; // To call grpc_init().
74 : grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
75 46 : options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
76 :
77 : grpc_credentials* c_creds = grpc_ssl_credentials_create(
78 92 : options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
79 138 : options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair, nullptr);
80 46 : return WrapCredentials(c_creds);
81 : }
82 :
83 : // Builds credentials for use when running in GCE
84 0 : std::shared_ptr<Credentials> GoogleComputeEngineCredentials() {
85 0 : GrpcLibrary init; // To call grpc_init().
86 : return WrapCredentials(
87 0 : grpc_google_compute_engine_credentials_create(nullptr));
88 : }
89 :
90 : // Builds JWT credentials.
91 0 : std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
92 : const grpc::string& json_key, long token_lifetime_seconds) {
93 0 : GrpcLibrary init; // To call grpc_init().
94 0 : if (token_lifetime_seconds <= 0) {
95 : gpr_log(GPR_ERROR,
96 0 : "Trying to create JWTCredentials with non-positive lifetime");
97 0 : return WrapCredentials(nullptr);
98 : }
99 : gpr_timespec lifetime =
100 0 : gpr_time_from_seconds(token_lifetime_seconds, GPR_TIMESPAN);
101 : return WrapCredentials(grpc_service_account_jwt_access_credentials_create(
102 0 : json_key.c_str(), lifetime, nullptr));
103 : }
104 :
105 : // Builds refresh token credentials.
106 2 : std::shared_ptr<Credentials> GoogleRefreshTokenCredentials(
107 : const grpc::string& json_refresh_token) {
108 2 : GrpcLibrary init; // To call grpc_init().
109 : return WrapCredentials(grpc_google_refresh_token_credentials_create(
110 2 : json_refresh_token.c_str(), nullptr));
111 : }
112 :
113 : // Builds access token credentials.
114 0 : std::shared_ptr<Credentials> AccessTokenCredentials(
115 : const grpc::string& access_token) {
116 0 : GrpcLibrary init; // To call grpc_init().
117 : return WrapCredentials(
118 0 : grpc_access_token_credentials_create(access_token.c_str(), nullptr));
119 : }
120 :
121 : // Builds IAM credentials.
122 3 : std::shared_ptr<Credentials> GoogleIAMCredentials(
123 : const grpc::string& authorization_token,
124 : const grpc::string& authority_selector) {
125 3 : GrpcLibrary init; // To call grpc_init().
126 : return WrapCredentials(grpc_google_iam_credentials_create(
127 3 : authorization_token.c_str(), authority_selector.c_str(), nullptr));
128 : }
129 :
130 : // Combines two credentials objects into a composite credentials.
131 0 : std::shared_ptr<Credentials> CompositeCredentials(
132 : const std::shared_ptr<Credentials>& creds1,
133 : const std::shared_ptr<Credentials>& creds2) {
134 : // Note that we are not saving shared_ptrs to the two credentials
135 : // passed in here. This is OK because the underlying C objects (i.e.,
136 : // creds1 and creds2) into grpc_composite_credentials_create will see their
137 : // refcounts incremented.
138 0 : SecureCredentials* s1 = creds1->AsSecureCredentials();
139 0 : SecureCredentials* s2 = creds2->AsSecureCredentials();
140 0 : if (s1 && s2) {
141 : return WrapCredentials(grpc_composite_credentials_create(
142 0 : s1->GetRawCreds(), s2->GetRawCreds(), nullptr));
143 : }
144 0 : return nullptr;
145 : }
146 :
147 6 : void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) {
148 12 : if (wrapper == nullptr) return;
149 : MetadataCredentialsPluginWrapper* w =
150 6 : reinterpret_cast<MetadataCredentialsPluginWrapper*>(wrapper);
151 6 : delete w;
152 : }
153 :
154 6 : void MetadataCredentialsPluginWrapper::GetMetadata(
155 : void* wrapper, const char* service_url,
156 : grpc_credentials_plugin_metadata_cb cb, void* user_data) {
157 6 : GPR_ASSERT(wrapper);
158 : MetadataCredentialsPluginWrapper* w =
159 6 : reinterpret_cast<MetadataCredentialsPluginWrapper*>(wrapper);
160 6 : if (!w->plugin_) {
161 0 : cb(user_data, NULL, 0, GRPC_STATUS_OK, NULL);
162 6 : return;
163 : }
164 6 : if (w->plugin_->IsBlocking()) {
165 3 : w->thread_pool_->Add(
166 : std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w,
167 3 : service_url, cb, user_data));
168 : } else {
169 3 : w->InvokePlugin(service_url, cb, user_data);
170 : }
171 : }
172 :
173 6 : void MetadataCredentialsPluginWrapper::InvokePlugin(
174 : const char* service_url, grpc_credentials_plugin_metadata_cb cb,
175 : void* user_data) {
176 6 : std::multimap<grpc::string, grpc::string> metadata;
177 12 : Status status = plugin_->GetMetadata(service_url, &metadata);
178 12 : std::vector<grpc_metadata> md;
179 10 : for (auto it = metadata.begin(); it != metadata.end(); ++it) {
180 : grpc_metadata md_entry;
181 4 : md_entry.key = it->first.c_str();
182 4 : md_entry.value = it->second.data();
183 4 : md_entry.value_length = it->second.size();
184 4 : md_entry.flags = 0;
185 4 : md.push_back(md_entry);
186 : }
187 6 : cb(user_data, md.empty() ? nullptr : &md[0], md.size(),
188 6 : static_cast<grpc_status_code>(status.error_code()),
189 24 : status.error_message().c_str());
190 6 : }
191 :
192 6 : MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper(
193 : std::unique_ptr<MetadataCredentialsPlugin> plugin)
194 6 : : thread_pool_(CreateDefaultThreadPool()), plugin_(std::move(plugin)) {}
195 :
196 6 : std::shared_ptr<Credentials> MetadataCredentialsFromPlugin(
197 : std::unique_ptr<MetadataCredentialsPlugin> plugin) {
198 6 : GrpcLibrary init; // To call grpc_init().
199 : MetadataCredentialsPluginWrapper* wrapper =
200 6 : new MetadataCredentialsPluginWrapper(std::move(plugin));
201 : grpc_metadata_credentials_plugin c_plugin = {
202 : MetadataCredentialsPluginWrapper::GetMetadata,
203 6 : MetadataCredentialsPluginWrapper::Destroy, wrapper};
204 : return WrapCredentials(
205 6 : grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr));
206 : }
207 :
208 : } // namespace grpc
|