1 /*
2 *
3 * Copyright 2016 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 #include "test/cpp/util/cli_credentials.h"
20
21 #include <gflags/gflags.h>
22 #include <grpc/slice.h>
23 #include <grpc/support/log.h>
24 #include <grpcpp/impl/codegen/slice.h>
25
26 #include "src/core/lib/iomgr/load_file.h"
27
28 DEFINE_bool(
29 enable_ssl, false,
30 "Whether to use ssl/tls. Deprecated. Use --channel_creds_type=ssl.");
31 DEFINE_bool(use_auth, false,
32 "Whether to create default google credentials. Deprecated. Use "
33 "--channel_creds_type=gdc.");
34 DEFINE_string(
35 access_token, "",
36 "The access token that will be sent to the server to authenticate RPCs. "
37 "Deprecated. Use --call_creds=access_token=<token>.");
38 DEFINE_string(
39 ssl_target, "",
40 "If not empty, treat the server host name as this for ssl/tls certificate "
41 "validation.");
42 DEFINE_string(
43 ssl_client_cert, "",
44 "If not empty, load this PEM formatted client certificate file. Requires "
45 "use of --ssl_client_key.");
46 DEFINE_string(
47 ssl_client_key, "",
48 "If not empty, load this PEM formatted private key. Requires use of "
49 "--ssl_client_cert");
50 DEFINE_string(
51 local_connect_type, "local_tcp",
52 "The type of local connections for which local channel credentials will "
53 "be applied. Should be local_tcp or uds.");
54 DEFINE_string(
55 channel_creds_type, "",
56 "The channel creds type: insecure, ssl, gdc (Google Default Credentials), "
57 "alts, or local.");
58 DEFINE_string(
59 call_creds, "",
60 "Call credentials to use: none (default), or access_token=<token>. If "
61 "provided, the call creds are composited on top of channel creds.");
62
63 namespace grpc {
64 namespace testing {
65
66 namespace {
67
68 const char ACCESS_TOKEN_PREFIX[] = "access_token=";
69 constexpr int ACCESS_TOKEN_PREFIX_LEN =
70 sizeof(ACCESS_TOKEN_PREFIX) / sizeof(*ACCESS_TOKEN_PREFIX) - 1;
71
IsAccessToken(const grpc::string & auth)72 bool IsAccessToken(const grpc::string& auth) {
73 return auth.length() > ACCESS_TOKEN_PREFIX_LEN &&
74 auth.compare(0, ACCESS_TOKEN_PREFIX_LEN, ACCESS_TOKEN_PREFIX) == 0;
75 }
76
AccessToken(const grpc::string & auth)77 grpc::string AccessToken(const grpc::string& auth) {
78 if (!IsAccessToken(auth)) {
79 return "";
80 }
81 return grpc::string(auth, ACCESS_TOKEN_PREFIX_LEN);
82 }
83
84 } // namespace
85
GetDefaultChannelCredsType() const86 grpc::string CliCredentials::GetDefaultChannelCredsType() const {
87 // Compatibility logic for --enable_ssl.
88 if (FLAGS_enable_ssl) {
89 fprintf(stderr,
90 "warning: --enable_ssl is deprecated. Use "
91 "--channel_creds_type=ssl.\n");
92 return "ssl";
93 }
94 // Compatibility logic for --use_auth.
95 if (FLAGS_access_token.empty() && FLAGS_use_auth) {
96 fprintf(stderr,
97 "warning: --use_auth is deprecated. Use "
98 "--channel_creds_type=gdc.\n");
99 return "gdc";
100 }
101 return "insecure";
102 }
103
GetDefaultCallCreds() const104 grpc::string CliCredentials::GetDefaultCallCreds() const {
105 if (!FLAGS_access_token.empty()) {
106 fprintf(stderr,
107 "warning: --access_token is deprecated. Use "
108 "--call_creds=access_token=<token>.\n");
109 return grpc::string("access_token=") + FLAGS_access_token;
110 }
111 return "none";
112 }
113
114 std::shared_ptr<grpc::ChannelCredentials>
GetChannelCredentials() const115 CliCredentials::GetChannelCredentials() const {
116 if (FLAGS_channel_creds_type.compare("insecure") == 0) {
117 return grpc::InsecureChannelCredentials();
118 } else if (FLAGS_channel_creds_type.compare("ssl") == 0) {
119 grpc::SslCredentialsOptions ssl_creds_options;
120 // TODO(@Capstan): This won't affect Google Default Credentials using SSL.
121 if (!FLAGS_ssl_client_cert.empty()) {
122 grpc_slice cert_slice = grpc_empty_slice();
123 GRPC_LOG_IF_ERROR(
124 "load_file",
125 grpc_load_file(FLAGS_ssl_client_cert.c_str(), 1, &cert_slice));
126 ssl_creds_options.pem_cert_chain =
127 grpc::StringFromCopiedSlice(cert_slice);
128 grpc_slice_unref(cert_slice);
129 }
130 if (!FLAGS_ssl_client_key.empty()) {
131 grpc_slice key_slice = grpc_empty_slice();
132 GRPC_LOG_IF_ERROR(
133 "load_file",
134 grpc_load_file(FLAGS_ssl_client_key.c_str(), 1, &key_slice));
135 ssl_creds_options.pem_private_key =
136 grpc::StringFromCopiedSlice(key_slice);
137 grpc_slice_unref(key_slice);
138 }
139 return grpc::SslCredentials(ssl_creds_options);
140 } else if (FLAGS_channel_creds_type.compare("gdc") == 0) {
141 return grpc::GoogleDefaultCredentials();
142 } else if (FLAGS_channel_creds_type.compare("alts") == 0) {
143 return grpc::experimental::AltsCredentials(
144 grpc::experimental::AltsCredentialsOptions());
145 } else if (FLAGS_channel_creds_type.compare("local") == 0) {
146 if (FLAGS_local_connect_type.compare("local_tcp") == 0) {
147 return grpc::experimental::LocalCredentials(LOCAL_TCP);
148 } else if (FLAGS_local_connect_type.compare("uds") == 0) {
149 return grpc::experimental::LocalCredentials(UDS);
150 } else {
151 fprintf(stderr,
152 "--local_connect_type=%s invalid; must be local_tcp or uds.\n",
153 FLAGS_local_connect_type.c_str());
154 }
155 }
156 fprintf(stderr,
157 "--channel_creds_type=%s invalid; must be insecure, ssl, gdc, "
158 "alts, or local.\n",
159 FLAGS_channel_creds_type.c_str());
160 return std::shared_ptr<grpc::ChannelCredentials>();
161 }
162
GetCallCredentials() const163 std::shared_ptr<grpc::CallCredentials> CliCredentials::GetCallCredentials()
164 const {
165 if (IsAccessToken(FLAGS_call_creds)) {
166 return grpc::AccessTokenCredentials(AccessToken(FLAGS_call_creds));
167 }
168 if (FLAGS_call_creds.compare("none") == 0) {
169 // Nothing to do; creds, if any, are baked into the channel.
170 return std::shared_ptr<grpc::CallCredentials>();
171 }
172 fprintf(stderr,
173 "--call_creds=%s invalid; must be none "
174 "or access_token=<token>.\n",
175 FLAGS_call_creds.c_str());
176 return std::shared_ptr<grpc::CallCredentials>();
177 }
178
GetCredentials() const179 std::shared_ptr<grpc::ChannelCredentials> CliCredentials::GetCredentials()
180 const {
181 if (FLAGS_call_creds.empty()) {
182 FLAGS_call_creds = GetDefaultCallCreds();
183 } else if (!FLAGS_access_token.empty() && !IsAccessToken(FLAGS_call_creds)) {
184 fprintf(stderr,
185 "warning: ignoring --access_token because --call_creds "
186 "already set to %s.\n",
187 FLAGS_call_creds.c_str());
188 }
189 if (FLAGS_channel_creds_type.empty()) {
190 FLAGS_channel_creds_type = GetDefaultChannelCredsType();
191 } else if (FLAGS_enable_ssl && FLAGS_channel_creds_type.compare("ssl") != 0) {
192 fprintf(stderr,
193 "warning: ignoring --enable_ssl because "
194 "--channel_creds_type already set to %s.\n",
195 FLAGS_channel_creds_type.c_str());
196 } else if (FLAGS_use_auth && FLAGS_channel_creds_type.compare("gdc") != 0) {
197 fprintf(stderr,
198 "warning: ignoring --use_auth because "
199 "--channel_creds_type already set to %s.\n",
200 FLAGS_channel_creds_type.c_str());
201 }
202 // Legacy transport upgrade logic for insecure requests.
203 if (IsAccessToken(FLAGS_call_creds) &&
204 FLAGS_channel_creds_type.compare("insecure") == 0) {
205 fprintf(stderr,
206 "warning: --channel_creds_type=insecure upgraded to ssl because "
207 "an access token was provided.\n");
208 FLAGS_channel_creds_type = "ssl";
209 }
210 std::shared_ptr<grpc::ChannelCredentials> channel_creds =
211 GetChannelCredentials();
212 // Composite any call-type credentials on top of the base channel.
213 std::shared_ptr<grpc::CallCredentials> call_creds = GetCallCredentials();
214 return (channel_creds == nullptr || call_creds == nullptr)
215 ? channel_creds
216 : grpc::CompositeChannelCredentials(channel_creds, call_creds);
217 }
218
GetCredentialUsage() const219 const grpc::string CliCredentials::GetCredentialUsage() const {
220 return " --enable_ssl ; Set whether to use ssl "
221 "(deprecated)\n"
222 " --use_auth ; Set whether to create default google"
223 " credentials\n"
224 " ; (deprecated)\n"
225 " --access_token ; Set the access token in metadata,"
226 " overrides --use_auth\n"
227 " ; (deprecated)\n"
228 " --ssl_target ; Set server host for ssl validation\n"
229 " --ssl_client_cert ; Client cert for ssl\n"
230 " --ssl_client_key ; Client private key for ssl\n"
231 " --local_connect_type ; Set to local_tcp or uds\n"
232 " --channel_creds_type ; Set to insecure, ssl, gdc, alts, or "
233 "local\n"
234 " --call_creds ; Set to none, or"
235 " access_token=<token>\n";
236 }
237
GetSslTargetNameOverride() const238 const grpc::string CliCredentials::GetSslTargetNameOverride() const {
239 bool use_ssl = FLAGS_channel_creds_type.compare("ssl") == 0 ||
240 FLAGS_channel_creds_type.compare("gdc") == 0;
241 return use_ssl ? FLAGS_ssl_target : "";
242 }
243
244 } // namespace testing
245 } // namespace grpc
246