1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2016 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker
19*cc02d7e2SAndroid Build Coastguard Worker #include "test/cpp/util/cli_credentials.h"
20*cc02d7e2SAndroid Build Coastguard Worker
21*cc02d7e2SAndroid Build Coastguard Worker #include "absl/flags/flag.h"
22*cc02d7e2SAndroid Build Coastguard Worker
23*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/slice.h>
24*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/log.h>
25*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/slice.h>
26*cc02d7e2SAndroid Build Coastguard Worker
27*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/gprpp/crash.h"
28*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/gprpp/load_file.h"
29*cc02d7e2SAndroid Build Coastguard Worker
30*cc02d7e2SAndroid Build Coastguard Worker ABSL_RETIRED_FLAG(bool, enable_ssl, false,
31*cc02d7e2SAndroid Build Coastguard Worker "Replaced by --channel_creds_type=ssl.");
32*cc02d7e2SAndroid Build Coastguard Worker ABSL_RETIRED_FLAG(bool, use_auth, false,
33*cc02d7e2SAndroid Build Coastguard Worker "Replaced by --channel_creds_type=gdc.");
34*cc02d7e2SAndroid Build Coastguard Worker ABSL_RETIRED_FLAG(std::string, access_token, "",
35*cc02d7e2SAndroid Build Coastguard Worker "Replaced by --call_creds=access_token=<token>.");
36*cc02d7e2SAndroid Build Coastguard Worker ABSL_FLAG(
37*cc02d7e2SAndroid Build Coastguard Worker std::string, ssl_target, "",
38*cc02d7e2SAndroid Build Coastguard Worker "If not empty, treat the server host name as this for ssl/tls certificate "
39*cc02d7e2SAndroid Build Coastguard Worker "validation.");
40*cc02d7e2SAndroid Build Coastguard Worker ABSL_FLAG(
41*cc02d7e2SAndroid Build Coastguard Worker std::string, ssl_client_cert, "",
42*cc02d7e2SAndroid Build Coastguard Worker "If not empty, load this PEM formatted client certificate file. Requires "
43*cc02d7e2SAndroid Build Coastguard Worker "use of --ssl_client_key.");
44*cc02d7e2SAndroid Build Coastguard Worker ABSL_FLAG(std::string, ssl_client_key, "",
45*cc02d7e2SAndroid Build Coastguard Worker "If not empty, load this PEM formatted private key. Requires use of "
46*cc02d7e2SAndroid Build Coastguard Worker "--ssl_client_cert");
47*cc02d7e2SAndroid Build Coastguard Worker ABSL_FLAG(
48*cc02d7e2SAndroid Build Coastguard Worker std::string, local_connect_type, "local_tcp",
49*cc02d7e2SAndroid Build Coastguard Worker "The type of local connections for which local channel credentials will "
50*cc02d7e2SAndroid Build Coastguard Worker "be applied. Should be local_tcp or uds.");
51*cc02d7e2SAndroid Build Coastguard Worker ABSL_FLAG(
52*cc02d7e2SAndroid Build Coastguard Worker std::string, channel_creds_type, "",
53*cc02d7e2SAndroid Build Coastguard Worker "The channel creds type: insecure, ssl, gdc (Google Default Credentials), "
54*cc02d7e2SAndroid Build Coastguard Worker "alts, or local.");
55*cc02d7e2SAndroid Build Coastguard Worker ABSL_FLAG(
56*cc02d7e2SAndroid Build Coastguard Worker std::string, call_creds, "",
57*cc02d7e2SAndroid Build Coastguard Worker "Call credentials to use: none (default), or access_token=<token>. If "
58*cc02d7e2SAndroid Build Coastguard Worker "provided, the call creds are composited on top of channel creds.");
59*cc02d7e2SAndroid Build Coastguard Worker
60*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
61*cc02d7e2SAndroid Build Coastguard Worker namespace testing {
62*cc02d7e2SAndroid Build Coastguard Worker
63*cc02d7e2SAndroid Build Coastguard Worker namespace {
64*cc02d7e2SAndroid Build Coastguard Worker
65*cc02d7e2SAndroid Build Coastguard Worker const char ACCESS_TOKEN_PREFIX[] = "access_token=";
66*cc02d7e2SAndroid Build Coastguard Worker constexpr int ACCESS_TOKEN_PREFIX_LEN =
67*cc02d7e2SAndroid Build Coastguard Worker sizeof(ACCESS_TOKEN_PREFIX) / sizeof(*ACCESS_TOKEN_PREFIX) - 1;
68*cc02d7e2SAndroid Build Coastguard Worker
IsAccessToken(const std::string & auth)69*cc02d7e2SAndroid Build Coastguard Worker bool IsAccessToken(const std::string& auth) {
70*cc02d7e2SAndroid Build Coastguard Worker return auth.length() > ACCESS_TOKEN_PREFIX_LEN &&
71*cc02d7e2SAndroid Build Coastguard Worker auth.compare(0, ACCESS_TOKEN_PREFIX_LEN, ACCESS_TOKEN_PREFIX) == 0;
72*cc02d7e2SAndroid Build Coastguard Worker }
73*cc02d7e2SAndroid Build Coastguard Worker
AccessToken(const std::string & auth)74*cc02d7e2SAndroid Build Coastguard Worker std::string AccessToken(const std::string& auth) {
75*cc02d7e2SAndroid Build Coastguard Worker if (!IsAccessToken(auth)) {
76*cc02d7e2SAndroid Build Coastguard Worker return "";
77*cc02d7e2SAndroid Build Coastguard Worker }
78*cc02d7e2SAndroid Build Coastguard Worker return std::string(auth, ACCESS_TOKEN_PREFIX_LEN);
79*cc02d7e2SAndroid Build Coastguard Worker }
80*cc02d7e2SAndroid Build Coastguard Worker
81*cc02d7e2SAndroid Build Coastguard Worker } // namespace
82*cc02d7e2SAndroid Build Coastguard Worker
GetDefaultChannelCredsType() const83*cc02d7e2SAndroid Build Coastguard Worker std::string CliCredentials::GetDefaultChannelCredsType() const {
84*cc02d7e2SAndroid Build Coastguard Worker return "insecure";
85*cc02d7e2SAndroid Build Coastguard Worker }
86*cc02d7e2SAndroid Build Coastguard Worker
GetDefaultCallCreds() const87*cc02d7e2SAndroid Build Coastguard Worker std::string CliCredentials::GetDefaultCallCreds() const { return "none"; }
88*cc02d7e2SAndroid Build Coastguard Worker
89*cc02d7e2SAndroid Build Coastguard Worker std::shared_ptr<grpc::ChannelCredentials>
GetChannelCredentials() const90*cc02d7e2SAndroid Build Coastguard Worker CliCredentials::GetChannelCredentials() const {
91*cc02d7e2SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_channel_creds_type) == "insecure") {
92*cc02d7e2SAndroid Build Coastguard Worker return grpc::InsecureChannelCredentials();
93*cc02d7e2SAndroid Build Coastguard Worker } else if (absl::GetFlag(FLAGS_channel_creds_type) == "ssl") {
94*cc02d7e2SAndroid Build Coastguard Worker grpc::SslCredentialsOptions ssl_creds_options;
95*cc02d7e2SAndroid Build Coastguard Worker // TODO(@Capstan): This won't affect Google Default Credentials using SSL.
96*cc02d7e2SAndroid Build Coastguard Worker if (!absl::GetFlag(FLAGS_ssl_client_cert).empty()) {
97*cc02d7e2SAndroid Build Coastguard Worker auto cert = grpc_core::LoadFile(absl::GetFlag(FLAGS_ssl_client_cert),
98*cc02d7e2SAndroid Build Coastguard Worker /*add_null_terminator=*/false);
99*cc02d7e2SAndroid Build Coastguard Worker if (!cert.ok()) {
100*cc02d7e2SAndroid Build Coastguard Worker gpr_log(GPR_ERROR, "error loading file %s: %s",
101*cc02d7e2SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_ssl_client_cert).c_str(),
102*cc02d7e2SAndroid Build Coastguard Worker cert.status().ToString().c_str());
103*cc02d7e2SAndroid Build Coastguard Worker } else {
104*cc02d7e2SAndroid Build Coastguard Worker ssl_creds_options.pem_cert_chain = std::string(cert->as_string_view());
105*cc02d7e2SAndroid Build Coastguard Worker }
106*cc02d7e2SAndroid Build Coastguard Worker }
107*cc02d7e2SAndroid Build Coastguard Worker if (!absl::GetFlag(FLAGS_ssl_client_key).empty()) {
108*cc02d7e2SAndroid Build Coastguard Worker auto key = grpc_core::LoadFile(absl::GetFlag(FLAGS_ssl_client_key),
109*cc02d7e2SAndroid Build Coastguard Worker /*add_null_terminator=*/false);
110*cc02d7e2SAndroid Build Coastguard Worker if (!key.ok()) {
111*cc02d7e2SAndroid Build Coastguard Worker gpr_log(GPR_ERROR, "error loading file %s: %s",
112*cc02d7e2SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_ssl_client_key).c_str(),
113*cc02d7e2SAndroid Build Coastguard Worker key.status().ToString().c_str());
114*cc02d7e2SAndroid Build Coastguard Worker } else {
115*cc02d7e2SAndroid Build Coastguard Worker ssl_creds_options.pem_private_key = std::string(key->as_string_view());
116*cc02d7e2SAndroid Build Coastguard Worker }
117*cc02d7e2SAndroid Build Coastguard Worker }
118*cc02d7e2SAndroid Build Coastguard Worker return grpc::SslCredentials(ssl_creds_options);
119*cc02d7e2SAndroid Build Coastguard Worker } else if (absl::GetFlag(FLAGS_channel_creds_type) == "gdc") {
120*cc02d7e2SAndroid Build Coastguard Worker return grpc::GoogleDefaultCredentials();
121*cc02d7e2SAndroid Build Coastguard Worker } else if (absl::GetFlag(FLAGS_channel_creds_type) == "alts") {
122*cc02d7e2SAndroid Build Coastguard Worker return grpc::experimental::AltsCredentials(
123*cc02d7e2SAndroid Build Coastguard Worker grpc::experimental::AltsCredentialsOptions());
124*cc02d7e2SAndroid Build Coastguard Worker } else if (absl::GetFlag(FLAGS_channel_creds_type) == "local") {
125*cc02d7e2SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_local_connect_type) == "local_tcp") {
126*cc02d7e2SAndroid Build Coastguard Worker return grpc::experimental::LocalCredentials(LOCAL_TCP);
127*cc02d7e2SAndroid Build Coastguard Worker } else if (absl::GetFlag(FLAGS_local_connect_type) == "uds") {
128*cc02d7e2SAndroid Build Coastguard Worker return grpc::experimental::LocalCredentials(UDS);
129*cc02d7e2SAndroid Build Coastguard Worker } else {
130*cc02d7e2SAndroid Build Coastguard Worker fprintf(stderr,
131*cc02d7e2SAndroid Build Coastguard Worker "--local_connect_type=%s invalid; must be local_tcp or uds.\n",
132*cc02d7e2SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_local_connect_type).c_str());
133*cc02d7e2SAndroid Build Coastguard Worker }
134*cc02d7e2SAndroid Build Coastguard Worker }
135*cc02d7e2SAndroid Build Coastguard Worker fprintf(stderr,
136*cc02d7e2SAndroid Build Coastguard Worker "--channel_creds_type=%s invalid; must be insecure, ssl, gdc, "
137*cc02d7e2SAndroid Build Coastguard Worker "alts, or local.\n",
138*cc02d7e2SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_channel_creds_type).c_str());
139*cc02d7e2SAndroid Build Coastguard Worker return std::shared_ptr<grpc::ChannelCredentials>();
140*cc02d7e2SAndroid Build Coastguard Worker }
141*cc02d7e2SAndroid Build Coastguard Worker
GetCallCredentials() const142*cc02d7e2SAndroid Build Coastguard Worker std::shared_ptr<grpc::CallCredentials> CliCredentials::GetCallCredentials()
143*cc02d7e2SAndroid Build Coastguard Worker const {
144*cc02d7e2SAndroid Build Coastguard Worker if (IsAccessToken(absl::GetFlag(FLAGS_call_creds))) {
145*cc02d7e2SAndroid Build Coastguard Worker return grpc::AccessTokenCredentials(
146*cc02d7e2SAndroid Build Coastguard Worker AccessToken(absl::GetFlag(FLAGS_call_creds)));
147*cc02d7e2SAndroid Build Coastguard Worker }
148*cc02d7e2SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_call_creds) == "none") {
149*cc02d7e2SAndroid Build Coastguard Worker // Nothing to do; creds, if any, are baked into the channel.
150*cc02d7e2SAndroid Build Coastguard Worker return std::shared_ptr<grpc::CallCredentials>();
151*cc02d7e2SAndroid Build Coastguard Worker }
152*cc02d7e2SAndroid Build Coastguard Worker fprintf(stderr,
153*cc02d7e2SAndroid Build Coastguard Worker "--call_creds=%s invalid; must be none "
154*cc02d7e2SAndroid Build Coastguard Worker "or access_token=<token>.\n",
155*cc02d7e2SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_call_creds).c_str());
156*cc02d7e2SAndroid Build Coastguard Worker return std::shared_ptr<grpc::CallCredentials>();
157*cc02d7e2SAndroid Build Coastguard Worker }
158*cc02d7e2SAndroid Build Coastguard Worker
GetCredentials() const159*cc02d7e2SAndroid Build Coastguard Worker std::shared_ptr<grpc::ChannelCredentials> CliCredentials::GetCredentials()
160*cc02d7e2SAndroid Build Coastguard Worker const {
161*cc02d7e2SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_call_creds).empty()) {
162*cc02d7e2SAndroid Build Coastguard Worker absl::SetFlag(&FLAGS_call_creds, GetDefaultCallCreds());
163*cc02d7e2SAndroid Build Coastguard Worker }
164*cc02d7e2SAndroid Build Coastguard Worker if (absl::GetFlag(FLAGS_channel_creds_type).empty()) {
165*cc02d7e2SAndroid Build Coastguard Worker absl::SetFlag(&FLAGS_channel_creds_type, GetDefaultChannelCredsType());
166*cc02d7e2SAndroid Build Coastguard Worker }
167*cc02d7e2SAndroid Build Coastguard Worker std::shared_ptr<grpc::ChannelCredentials> channel_creds =
168*cc02d7e2SAndroid Build Coastguard Worker GetChannelCredentials();
169*cc02d7e2SAndroid Build Coastguard Worker // Composite any call-type credentials on top of the base channel.
170*cc02d7e2SAndroid Build Coastguard Worker std::shared_ptr<grpc::CallCredentials> call_creds = GetCallCredentials();
171*cc02d7e2SAndroid Build Coastguard Worker return (channel_creds == nullptr || call_creds == nullptr)
172*cc02d7e2SAndroid Build Coastguard Worker ? channel_creds
173*cc02d7e2SAndroid Build Coastguard Worker : grpc::CompositeChannelCredentials(channel_creds, call_creds);
174*cc02d7e2SAndroid Build Coastguard Worker }
175*cc02d7e2SAndroid Build Coastguard Worker
GetCredentialUsage() const176*cc02d7e2SAndroid Build Coastguard Worker std::string CliCredentials::GetCredentialUsage() const {
177*cc02d7e2SAndroid Build Coastguard Worker return " --ssl_target ; Set server host for ssl validation\n"
178*cc02d7e2SAndroid Build Coastguard Worker " --ssl_client_cert ; Client cert for ssl\n"
179*cc02d7e2SAndroid Build Coastguard Worker " --ssl_client_key ; Client private key for ssl\n"
180*cc02d7e2SAndroid Build Coastguard Worker " --local_connect_type ; Set to local_tcp or uds\n"
181*cc02d7e2SAndroid Build Coastguard Worker " --channel_creds_type ; Set to insecure, ssl, gdc, alts, or "
182*cc02d7e2SAndroid Build Coastguard Worker "local\n"
183*cc02d7e2SAndroid Build Coastguard Worker " --call_creds ; Set to none, or"
184*cc02d7e2SAndroid Build Coastguard Worker " access_token=<token>\n";
185*cc02d7e2SAndroid Build Coastguard Worker }
186*cc02d7e2SAndroid Build Coastguard Worker
GetSslTargetNameOverride() const187*cc02d7e2SAndroid Build Coastguard Worker std::string CliCredentials::GetSslTargetNameOverride() const {
188*cc02d7e2SAndroid Build Coastguard Worker bool use_ssl = absl::GetFlag(FLAGS_channel_creds_type) == "ssl" ||
189*cc02d7e2SAndroid Build Coastguard Worker absl::GetFlag(FLAGS_channel_creds_type) == "gdc";
190*cc02d7e2SAndroid Build Coastguard Worker return use_ssl ? absl::GetFlag(FLAGS_ssl_target) : "";
191*cc02d7e2SAndroid Build Coastguard Worker }
192*cc02d7e2SAndroid Build Coastguard Worker
193*cc02d7e2SAndroid Build Coastguard Worker } // namespace testing
194*cc02d7e2SAndroid Build Coastguard Worker } // namespace grpc
195