# HG changeset patch # User Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> # Date 1702302461 -3600 # Node ID 1671f2eb130b76da7111edbdf70429f7258259c0 # Parent 5d04490bc58b4f512d74966db2f9a1a644595bc6 Send NUL bytes on non-TLS connect This avoids a hang if we accidentally make a non-TLS connection to a TLS server. The hang occurs because in that situation, the MAPI client ends up waiting for the server to send a MAPI challenge, while the TLS server ends up waiting for the client to send a TLS Client Hello message. The NUL bytes are illegal as a Client Hello and a no-op as a MAPI message. diff --git a/src/main/java/org/monetdb/mcl/net/MapiSocket.java b/src/main/java/org/monetdb/mcl/net/MapiSocket.java --- a/src/main/java/org/monetdb/mcl/net/MapiSocket.java +++ b/src/main/java/org/monetdb/mcl/net/MapiSocket.java @@ -86,6 +86,7 @@ import org.monetdb.mcl.parser.MCLParseEx * @see org.monetdb.mcl.io.BufferedMCLWriter */ public final class MapiSocket { + public static final byte[] NUL_BYTES = new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, }; private static final String[][] KNOWN_ALGORITHMS = new String[][] { {"SHA512", "SHA-512"}, {"SHA384", "SHA-384"}, @@ -348,8 +349,18 @@ public final class MapiSocket { private Socket wrapTLS(Socket sock, Target.Validated validated) throws IOException { if (validated.getTls()) return SecureSocket.wrap(validated, sock); - else - return sock; + else { + // Send an even number of NUL bytes. + // We expect the server to speak MAPI and in that case, it's a NOP. + // If we're accidentally connecting to a TLS server, the bytes are + // invalid as a Client Hello message and most TLS implementations + // drop the connection. + // This is nice because otherwise we would hang, as the TLS server + // is waiting for us to send a TLS CLient Hello, and we are waiting + // for a MAPI server to send a server challenge. + sock.getOutputStream().write(NUL_BYTES); + } + return sock; } private boolean handshake(Target.Validated validated, OptionsCallback callback, ArrayList<String> warnings) throws IOException, MCLException { diff --git a/tests/TLSTester.java b/tests/TLSTester.java --- a/tests/TLSTester.java +++ b/tests/TLSTester.java @@ -131,7 +131,7 @@ public class TLSTester { // test_connect_client_auth1(); // test_connect_client_auth2(); test_fail_tls_to_plain(); -// test_fail_plain_to_tls(); + test_fail_plain_to_tls(); // test_connect_server_name(); // test_connect_alpn_mapi9(); test_connect_trusted(); @@ -193,7 +193,7 @@ public class TLSTester { } private void test_fail_plain_to_tls() throws IOException, SQLException { - attempt("fail_plain_to_tls", "server1").with(Parameter.TLS, false).expectFailure("asdf"); + attempt("fail_plain_to_tls", "server1").with(Parameter.TLS, false).expectFailure("Cannot connect"); } private void test_connect_server_name() throws IOException, SQLException {