Skip to content

Commit

Permalink
Enable xDS credentials (#424)
Browse files Browse the repository at this point in the history
* Enable xDS credentials

This change should be relatively straightforward. It is a noop outside of the
context of xDS (as demonstrated by the fact that the tests all pass), but it
enables xDS-provided certificates (i.e. the ones that would be
provided/specified in GRPC_XDS_BOOTSTRAP). See proposal
[A29](https://github.com/grpc/proposal/blob/master/A29-xds-tls-security.md#go)
for additional detail.

* Only enable xds credentials if the target is an xDS target

* Update after merge
  • Loading branch information
PapaCharlie committed Feb 12, 2024
1 parent 184c8f7 commit 5592211
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions grpcurl.go
Expand Up @@ -28,6 +28,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
xdsCredentials "google.golang.org/grpc/credentials/xds"
"google.golang.org/grpc/metadata"
protov2 "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/descriptorpb"
Expand Down Expand Up @@ -609,6 +610,21 @@ func ServerTransportCredentials(cacertFile, serverCertFile, serverKeyFile string
// and blocking until the returned connection is ready. If the given credentials are nil, the
// connection will be insecure (plain-text).
func BlockingDial(ctx context.Context, network, address string, creds credentials.TransportCredentials, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
if creds == nil {
creds = insecure.NewCredentials()
}

var err error
if strings.HasPrefix(address, "xds:///") {
// The xds:/// prefix is used to signal to the gRPC client to use an xDS server to resolve the
// target. The relevant credentials will be automatically pulled from the GRPC_XDS_BOOTSTRAP or
// GRPC_XDS_BOOTSTRAP_CONFIG env vars.
creds, err = xdsCredentials.NewClientCredentials(xdsCredentials.ClientOptions{FallbackCreds: creds})
if err != nil {
return nil, err
}
}

// grpc.Dial doesn't provide any information on permanent connection errors (like
// TLS handshake failures). So in order to provide good error messages, we need a
// custom dialer that can provide that info. That means we manage the TLS handshake.
Expand All @@ -624,12 +640,11 @@ func BlockingDial(ctx context.Context, network, address string, creds credential

// custom credentials and dialer will notify on error via the
// writeResult function
if creds != nil {
creds = &errSignalingCreds{
TransportCredentials: creds,
writeResult: writeResult,
}
creds = &errSignalingCreds{
TransportCredentials: creds,
writeResult: writeResult,
}

dialer := func(ctx context.Context, address string) (net.Conn, error) {
// NB: We *could* handle the TLS handshake ourselves, in the custom
// dialer (instead of customizing both the dialer and the credentials).
Expand All @@ -655,13 +670,8 @@ func BlockingDial(ctx context.Context, network, address string, creds credential
opts = append([]grpc.DialOption{grpc.FailOnNonTempDialError(true)}, opts...)
// But we don't want caller to be able to override these two, so we put
// them *after* the explicitly provided options.
opts = append(opts, grpc.WithBlock(), grpc.WithContextDialer(dialer))
opts = append(opts, grpc.WithBlock(), grpc.WithContextDialer(dialer), grpc.WithTransportCredentials(creds))

if creds == nil {
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
} else {
opts = append(opts, grpc.WithTransportCredentials(creds))
}
conn, err := grpc.DialContext(ctx, address, opts...)
var res interface{}
if err != nil {
Expand Down

0 comments on commit 5592211

Please sign in to comment.