Mercurial > hg > monetdb-java
changeset 803:1671f2eb130b monetdbs
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.
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Mon, 11 Dec 2023 14:47:41 +0100 (16 months ago) |
parents | 5d04490bc58b |
children | 361441253305 |
files | src/main/java/org/monetdb/mcl/net/MapiSocket.java tests/TLSTester.java |
diffstat | 2 files changed, 15 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- 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 {
--- 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 {