@@ -19,6 +19,7 @@ import (
1919 "google.golang.org/grpc"
2020 "google.golang.org/grpc/codes"
2121 "google.golang.org/grpc/credentials"
22+ "google.golang.org/grpc/credentials/alts"
2223 "google.golang.org/grpc/keepalive"
2324 "google.golang.org/grpc/metadata"
2425 "google.golang.org/grpc/status"
@@ -52,11 +53,14 @@ var (
5253 Print usage instructions and exit.` ))
5354 printVersion = flags .Bool ("version" , false , prettify (`
5455 Print version.` ))
56+
5557 plaintext = flags .Bool ("plaintext" , false , prettify (`
5658 Use plain-text HTTP/2 when connecting to server (no TLS).` ))
5759 insecure = flags .Bool ("insecure" , false , prettify (`
5860 Skip server certificate and domain verification. (NOT SECURE!) Not
5961 valid with -plaintext option.` ))
62+
63+ // TLS Options
6064 cacert = flags .String ("cacert" , "" , prettify (`
6165 File containing trusted root certificates for verifying the server.
6266 Ignored if -insecure is specified.` ))
6670 key = flags .String ("key" , "" , prettify (`
6771 File containing client private key, to present to the server. Not valid
6872 with -plaintext option. Must also provide -cert option.` ))
73+
74+ // ALTS Options
75+ usealts = flags .Bool ("alts" , false , prettify (`
76+ Use Application Layer Transport Security (ALTS) when connecting to server.` ))
77+ altsHandshakerServiceAddress = flags .String ("alts-handshaker-service" , "" , prettify (`If set, this server will be used to do the ATLS handshaking.` ))
78+ altsTargetServiceAccounts multiString
79+
6980 protoset multiString
7081 protoFiles multiString
7182 importPaths multiString
@@ -199,6 +210,14 @@ func init() {
199210 -use-reflection is used in combination with a -proto or -protoset flag,
200211 the provided descriptor sources will be used in addition to server
201212 reflection to resolve messages and extensions.` ))
213+ flags .Var (& altsTargetServiceAccounts , "alts-target-service-account" , prettify (`
214+ The full email address of the service account that the server is
215+ expected to be using when ALTS is used. You can specify this option
216+ multiple times to indicate multiple allowed service accounts. If the
217+ server authenticates with a service account that is not one of the
218+ expected accounts, the RPC will not be issued. If no such arguments are
219+ provided, no check will be performed, and the RPC will be issued
220+ regardless of the server's service account.` ))
202221}
203222
204223type multiString []string
@@ -267,6 +286,9 @@ func main() {
267286 os .Exit (0 )
268287 }
269288
289+ // default behavior is to use tls
290+ usetls := ! * plaintext && ! * usealts
291+
270292 // Do extra validation on arguments and figure out what user asked us to do.
271293 if * connectTimeout < 0 {
272294 fail (nil , "The -connect-timeout argument must not be negative." )
@@ -280,18 +302,27 @@ func main() {
280302 if * maxMsgSz < 0 {
281303 fail (nil , "The -max-msg-sz argument must not be negative." )
282304 }
283- if * plaintext && * insecure {
284- fail (nil , "The -plaintext and -insecure arguments are mutually exclusive." )
305+ if * plaintext && * usealts {
306+ fail (nil , "The -plaintext and -alts arguments are mutually exclusive." )
307+ }
308+ if * insecure && ! usetls {
309+ fail (nil , "The -insecure argument can only be used with TLS." )
285310 }
286- if * plaintext && * cert != "" {
287- fail (nil , "The -plaintext and -cert arguments are mutually exclusive ." )
311+ if * cert != "" && ! usetls {
312+ fail (nil , "The -cert argument can only be used with TLS ." )
288313 }
289- if * plaintext && * key != "" {
290- fail (nil , "The -plaintext and -key arguments are mutually exclusive ." )
314+ if * key != "" && ! usetls {
315+ fail (nil , "The -key argument can only be used with TLS ." )
291316 }
292317 if (* key == "" ) != (* cert == "" ) {
293318 fail (nil , "The -cert and -key arguments must be used together and both be present." )
294319 }
320+ if * altsHandshakerServiceAddress != "" && ! * usealts {
321+ fail (nil , "The -alts-handshaker-service argument must be used with the -alts argument." )
322+ }
323+ if len (altsTargetServiceAccounts ) > 0 && ! * usealts {
324+ fail (nil , "The -alts-target-service-account argument must be used with the -alts argument." )
325+ }
295326 if * format != "json" && * format != "text" {
296327 fail (nil , "The -format option must be 'json' or 'text'." )
297328 }
@@ -406,7 +437,20 @@ func main() {
406437 opts = append (opts , grpc .WithDefaultCallOptions (grpc .MaxCallRecvMsgSize (* maxMsgSz )))
407438 }
408439 var creds credentials.TransportCredentials
409- if ! * plaintext {
440+ if * plaintext {
441+ if * authority != "" {
442+ opts = append (opts , grpc .WithAuthority (* authority ))
443+ }
444+ } else if * usealts {
445+ clientOptions := alts .DefaultClientOptions ()
446+ if len (altsTargetServiceAccounts ) > 0 {
447+ clientOptions .TargetServiceAccounts = altsTargetServiceAccounts
448+ }
449+ if * altsHandshakerServiceAddress != "" {
450+ clientOptions .HandshakerServiceAddress = * altsHandshakerServiceAddress
451+ }
452+ creds = alts .NewClientCreds (clientOptions )
453+ } else if usetls {
410454 tlsConf , err := grpcurl .ClientTLSConfig (* insecure , * cacert , * cert , * key )
411455 if err != nil {
412456 fail (err , "Failed to create TLS config" )
@@ -439,8 +483,8 @@ func main() {
439483 if overrideName != "" {
440484 opts = append (opts , grpc .WithAuthority (overrideName ))
441485 }
442- } else if * authority != "" {
443- opts = append ( opts , grpc . WithAuthority ( * authority ) )
486+ } else {
487+ panic ( "Should have defaulted to use TLS." )
444488 }
445489
446490 grpcurlUA := "grpcurl/" + version
0 commit comments