diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java b/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java index 5ce5a345ab..8df9363f99 100644 --- a/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java +++ b/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java @@ -39,6 +39,8 @@ import io.grpc.netty.InternalProtocolNegotiators; import io.netty.channel.ChannelHandler; import io.netty.handler.ssl.SslContext; import io.netty.util.AsciiString; +import java.net.URI; +import java.net.URISyntaxException; import java.security.GeneralSecurityException; import java.util.List; import java.util.logging.Level; @@ -67,6 +69,10 @@ public final class AltsProtocolNegotiator { private static final AsciiString SCHEME = AsciiString.of("https"); private static final String DIRECT_PATH_SERVICE_CFE_CLUSTER_PREFIX = "google_cfe_"; + private static final String CFE_CLUSTER_RESOURCE_NAME_PREFIX = + "/envoy.config.cluster.v3.Cluster/google_cfe_"; + private static final String CFE_CLUSTER_AUTHORITY_NAME = + "traffic-director-c2p.xds.googleapis.com"; /** * ClientAltsProtocolNegotiatorFactory is a factory for doing client side negotiation of an ALTS @@ -288,11 +294,8 @@ public final class AltsProtocolNegotiator { ChannelHandler securityHandler; boolean isXdsDirectPath = false; if (clusterNameAttrKey != null) { - String clusterName = grpcHandler.getEagAttributes().get(clusterNameAttrKey); - if (clusterName != null - && !clusterName.startsWith(DIRECT_PATH_SERVICE_CFE_CLUSTER_PREFIX)) { - isXdsDirectPath = true; - } + isXdsDirectPath = isDirectPathCluster( + grpcHandler.getEagAttributes().get(clusterNameAttrKey)); } if (grpcHandler.getEagAttributes().get(GrpclbConstants.ATTR_LB_ADDR_AUTHORITY) != null || grpcHandler.getEagAttributes().get(GrpclbConstants.ATTR_LB_PROVIDED_BACKEND) != null @@ -312,6 +315,26 @@ public final class AltsProtocolNegotiator { return wuah; } + private boolean isDirectPathCluster(String clusterName) { + if (clusterName == null) { + return false; + } + if (clusterName.startsWith(DIRECT_PATH_SERVICE_CFE_CLUSTER_PREFIX)) { + return false; + } + if (!clusterName.startsWith("xdstp:")) { + return true; + } + try { + URI uri = new URI(clusterName); + // If authority AND path match our CFE checks, use TLS; otherwise use ALTS. + return !CFE_CLUSTER_AUTHORITY_NAME.equals(uri.getHost()) + || !uri.getPath().startsWith(CFE_CLUSTER_RESOURCE_NAME_PREFIX); + } catch (URISyntaxException e) { + return true; // Shouldn't happen, but assume ALTS. + } + } + @Override public void close() { logger.finest("ALTS Server ProtocolNegotiator Closed"); diff --git a/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java b/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java index f149c4306c..9a520720be 100644 --- a/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java @@ -185,5 +185,47 @@ public final class GoogleDefaultProtocolNegotiatorTest { XDS_CLUSTER_NAME_ATTR_KEY, "google_cfe_api.googleapis.com").build(); subtest_tlsHandler(attrs); } + + @Test + public void altsHandler_googleCfe_federation() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, "xdstp1://").build(); + subtest_altsHandler(attrs); + } + + @Test + public void tlsHanlder_googleCfe() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, + "xdstp://traffic-director-c2p.xds.googleapis.com/" + + "envoy.config.cluster.v3.Cluster/google_cfe_example/apis") + .build(); + subtest_tlsHandler(attrs); + } + + @Test + public void altsHanlder_nonGoogleCfe_authorityNotMatch() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, + "//example.com/envoy.config.cluster.v3.Cluster/google_cfe_") + .build(); + subtest_altsHandler(attrs); + } + + @Test + public void altsHanlder_nonGoogleCfe_pathNotMatch() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, + "//traffic-director-c2p.xds.googleapis.com/envoy.config.cluster.v3.Cluster/google_gfe") + .build(); + subtest_altsHandler(attrs); + } + + @Test + public void altsHandler_googleCfe_invalidUri() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, "//").build(); + subtest_altsHandler(attrs); + } } }