Skip to content

Commit 79013bd

Browse files
committed
don't drop TLS for endpoint locations in getStreams
1 parent 7f1f9f5 commit 79013bd

2 files changed

Lines changed: 61 additions & 1 deletion

File tree

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandler.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,22 @@ public List<CloseableEndpointStreamPair> getStreams(final FlightInfo flightInfo)
183183
sqlClient.getStream(endpoint.getTicket(), getOptions()), null);
184184
break;
185185
}
186+
final boolean encryptEndpoint =
187+
endpointUri.getScheme().equals(LocationSchemes.GRPC_TLS);
188+
if (builder.useEncryption && !encryptEndpoint) {
189+
exceptions.add(
190+
new SQLException(
191+
String.format(
192+
"Refusing to connect to endpoint location %s without encryption "
193+
+ "because the connection to %s is encrypted.",
194+
endpointUri, builder.getLocation().getUri())));
195+
continue;
196+
}
186197
final Builder builderForEndpoint =
187198
new Builder(ArrowFlightSqlClientHandler.this.builder)
188199
.withHost(endpointUri.getHost())
189200
.withPort(endpointUri.getPort())
190-
.withEncryption(endpointUri.getScheme().equals(LocationSchemes.GRPC_TLS))
201+
.withEncryption(encryptEndpoint)
191202
.withClientCache(flightClientCache)
192203
.withConnectTimeout(builder.connectTimeout);
193204

flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandlerTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,73 @@
1818

1919
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
2020
import static org.junit.jupiter.api.Assertions.assertThrows;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
2122
import static org.mockito.ArgumentMatchers.any;
2223
import static org.mockito.Mockito.doThrow;
2324
import static org.mockito.Mockito.mock;
25+
import static org.mockito.Mockito.verifyNoInteractions;
2426

2527
import java.sql.SQLException;
2628
import java.util.ArrayList;
2729
import java.util.Collection;
30+
import java.util.Collections;
2831
import java.util.Optional;
2932
import org.apache.arrow.flight.CallOption;
3033
import org.apache.arrow.flight.CallStatus;
3134
import org.apache.arrow.flight.CloseSessionRequest;
35+
import org.apache.arrow.flight.FlightDescriptor;
36+
import org.apache.arrow.flight.FlightEndpoint;
37+
import org.apache.arrow.flight.FlightInfo;
3238
import org.apache.arrow.flight.FlightStatusCode;
39+
import org.apache.arrow.flight.Location;
40+
import org.apache.arrow.flight.Ticket;
3341
import org.apache.arrow.flight.sql.FlightSqlClient;
42+
import org.apache.arrow.memory.BufferAllocator;
43+
import org.apache.arrow.memory.RootAllocator;
44+
import org.apache.arrow.vector.types.pojo.Schema;
45+
import org.junit.jupiter.api.Test;
3446
import org.junit.jupiter.params.ParameterizedTest;
3547
import org.junit.jupiter.params.provider.MethodSource;
3648

3749
public class ArrowFlightSqlClientHandlerTest {
3850

51+
@Test
52+
public void testGetStreamsRejectsUnencryptedEndpointOnEncryptedConnection() throws Exception {
53+
try (BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE)) {
54+
final FlightSqlClient sqlClient = mock(FlightSqlClient.class);
55+
final ArrowFlightSqlClientHandler.Builder builder =
56+
new ArrowFlightSqlClientHandler.Builder()
57+
.withHost("localhost")
58+
.withPort(443)
59+
.withEncryption(true)
60+
.withUsername("user")
61+
.withPassword("password")
62+
.withBufferAllocator(allocator);
63+
64+
final ArrowFlightSqlClientHandler handler =
65+
new ArrowFlightSqlClientHandler(
66+
"cacheKey", sqlClient, builder, new ArrayList<>(), Optional.empty(), null);
67+
68+
// A server-supplied location that asks the driver to drop back to plaintext.
69+
final FlightInfo flightInfo =
70+
new FlightInfo(
71+
new Schema(Collections.emptyList()),
72+
FlightDescriptor.command(new byte[0]),
73+
Collections.singletonList(
74+
new FlightEndpoint(
75+
new Ticket(new byte[0]),
76+
Location.forGrpcInsecure("other.example.com", 443))),
77+
-1,
78+
-1);
79+
80+
final SQLException ex =
81+
assertThrows(SQLException.class, () -> handler.getStreams(flightInfo));
82+
assertTrue(ex.getMessage().contains("without encryption"), ex.getMessage());
83+
// The credentials must not have been sent anywhere.
84+
verifyNoInteractions(sqlClient);
85+
}
86+
}
87+
3988
@ParameterizedTest
4089
@MethodSource
4190
public void testCloseHandlesFlightRuntimeException(

0 commit comments

Comments
 (0)