From 21883b4026091fe2e4cf0e102a4a720a8b96c7bb Mon Sep 17 00:00:00 2001 From: Richard Maw Date: Tue, 11 Feb 2025 18:24:03 +0000 Subject: [PATCH 1/7] Add doc for connecting to MapTool with SSL This is documentation for a manual process that will be incrementally automated. --- doc/SSL.md | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 doc/SSL.md diff --git a/doc/SSL.md b/doc/SSL.md new file mode 100644 index 0000000000..579eb77530 --- /dev/null +++ b/doc/SSL.md @@ -0,0 +1,176 @@ +# Securing MapTool connections with SSL + +## 0. A brief explainer of the data model + +SSL requires the server to provide a certificate +signed by a Certification Authority that is trusted by the client. + +A GM with expirence administering web services could sort this out themselves +but even GMs with this experience will find this to be a barrier to entry +that discourages securing MapTool servers with SSL so we're going to assume +the average GM wants MapTool to manage this itself. + +Since MapTool isn't like a web server, we generally don't use domain names +and the certificates have a validity period much longer than the average game +we can't request a Let's Encrypt certificate +so we have to rely on self-signed certificates. + +Because certificates must include the addresses they're valid for +and MapTool must support dynamic IP address allocation +we must issue a new certificate every session. + +Issuing a new self-signed certificate every session would require out-of-band +verification every session which is going to become tiresome. + +The solution is that every MapTool server works as a Certification Authority +and this CA's root certificate can be verified once +and the server can issue a new certificate signed by the CA root certificate +for every session. + +Since MapTool already includes RSA keys for client authentication +we can build on top of this to make a CA for server security. + +## 1. Creating a Certification Authority + +**NOTE**: These manual steps are intended to be automated later. + +First, define some directories to organise things and some CA-specific files. + +``` +mkdir -p ~/.maptool-rptools/config/ca/{certs,crl,newcerts,private,csr} +echo 1000 > ~/.maptool-rptools/config/ca/serial +echo 0100 > ~/.maptool-rptools/config/ca/crlnumber +touch ~/.maptool-rptools/config/ca/index.txt +``` + +The private key should have its access restricted. + +``` +chmod 400 ~/.maptool-rptools/config/private.key +``` + +Then, we must generate the root certificate + +``` +openssl req -new -x509 -days 3650 -key ~/.maptool-rptools/config/private.key -out ~/.maptool-rptools/config/ca/certs/ca.crt -subj "/CN=MapTool $(cat ~/.maptool-rptools/client-id) CA Root" +``` + +`-subj "/CN=..."` is a unique identifier for the certificate. +It doesn't need to be globally unique but it must not be duplicated +within a certificate validation chain. +Using the MapTool client-id and giving it an appropriate prefix and suffix +should ensure sufficient uniqueness. + +## 2. Creating a new certificate + +**NOTE**: These manual steps are intended to be automated later. + +First we must determine the set of addresses the certificate will be valid for. +This shell snippet collects it using `miniupnpc`'s `external-ip` and parsing `ip`. + +``` +ips=() +localips=() +subjectAltName=() +if extip="$(external-ip)"; then + ips+=("$extip") + subjectAltName+=("IP:$extip") +fi +for localaddr in $(ip -json addr show up | jq -r '.[].addr_info[]|select(.scope == "global").local'); do + ips+=("$localladdr") + localips+=("$localladdr") + subjectAltName+=("IP:$localaddr") +done +``` + +Now create a Certificate Signing Request. +This is convoluted because the entity requesting a certificate isn't usually +the same as the CA. Usually `-key` is a different key from the CA but isn't required to be. + +If the addresses haven't been collected by the script above, +then the significant part is that `-subj "CN/="` should be the most public IP +but "subjectAltName" permits a certificate to be used for multiple addresses +and is specified as every address having the prefix `IP:` and separated by `,` +e.g. `-addext subjectAltName=IP:203.0.113.46,IP:192.168.1.10,IP:2001:db8::4d`. + + +``` +openssl req -new -key ~/.maptool-rptools/config/private.key -out ~/.maptool-rptools/config/ca/csr/server-1.csr -subj "/CN=${ips[0]}" -addext "subjectAltName=$(IFS=","; echo "${subjectAltName[*]}")" +``` + +Now create the certificate by signing the CSR. + +Note this is issued for 1 day because that is the minimum +and `-copy_extensions copy` is used to copy subjectAltName into the certificate. + +``` +openssl x509 -req -in ~/.maptool-rptools/config/ca/csr/server-1.csr -copy_extensions copy -CA ~/.maptool-rptools/config/ca/certs/ca.crt -CAkey ~/.maptool-rptools/config/private.key -CAcreateserial -days 1 -out ~/.maptool-rptools/config/ca/certs/server-1.crt +``` + +## 3. Starting a SSL enabled MapTool server + +**NOTE**: These manual steps are intended to be automated later. + +Without native SSL support, MapTool must use an SSL tunnel. + +`socat` requires a certificate bundled with the private key. +We can create this with the following command: + +``` +openssl rsa -in ~/.maptool-rptools/config/private.key | cat - ~/.maptool-rptools/config/ca/certs/server-1.crt >~/.maptool-rptools/config/ca/certs/server-1.pem +``` + +We can now create the server tunnel. + +``` +socat OPENSSL-LISTEN:51232,cert="$HOME/.maptool-rptools/config/ca/certs/server-1.pem",verify=0 TCP:127.0.0.1:51234 +``` + +where 51234 is the port the server is listening on and 51232 is a free port. + +While this command is running an SSL connection to 51232 will connect +to a MapTool server running on port 51234. + +## 4. Connecting to a SSL enabled MapTool server using a tunnel + +Without native SSL support, MapTool must use an SSL tunnel. + +### Creating a tunnel using the certificate store + +The command to create an SSL tunnel that a client can connect to in order to create an ssl connection is: + +``` +socat TCP-LISTEN:51231 OPENSSL:"${localips[0]}":51232,cafile="$HOME/.maptool-rptools/config/ca/certs/ca.crt",snihost"=${localips[0]}" +``` + +While this command is running MapTool can connect to port 51231 +to make a SSL connection via the first local IP address. +`snihost=` must match one of the addresses in `subjectAltName`. + +### Installing the certificate in the OS certificate store + +The need to provide `cafile` on the TCP-LISTEN command-line can be removed +by installing the certificate into the OS certificate store. + +``` +sudo install -D -m644 ~/.maptool-rptools/config/ca/certs/ca.crt /usr/local/share/ca-certificates/extra/maptool-$(cat ~/.maptool-rptools/client-id)-root-ca.crt +sudo update-ca-certificates +``` + +The command to create the tunnel then becomes: + +``` +socat TCP-LISTEN:51231 OPENSSL:"${localips[0]}":51232,snihost"=${localips[0]}" +``` + +### Connecting with MapTool through the tunnel + +Using the URI support in develop's version of MapTool we can instruct MapTool to connect through the proxy. + +``` +/opt/maptool/bin/MapTool-Develop rptools-maptool+tcp://${localips[0]}:51231 +``` +or while running from git +``` +./gradlew run --args=rptools-maptool+tcp://${localips[0]}:51231 +``` From 9d639d5cc0b6cfaed5796a293b39e89d423b2e79 Mon Sep 17 00:00:00 2001 From: Richard Maw Date: Tue, 11 Feb 2025 18:36:42 +0000 Subject: [PATCH 2/7] Make SocketConnection take a supplier function SocketConnection has two constructors, either one wrapping an existing socket or one that creates the socket when started. Creating the socket from just the host and port is insufficiently flexible for supporting SSL sockets and since the only difference for how to handle SSL sockets is how they are created, making creation more flexible is the minimal change required to support them. --- .../simple/connection/SocketConnection.java | 35 ++++++++++++------- .../clientserver/ConnectionFactory.java | 3 +- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/clientserver/src/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java b/clientserver/src/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java index 42124691c5..0d0439bfc3 100644 --- a/clientserver/src/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java +++ b/clientserver/src/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java @@ -17,6 +17,8 @@ import java.io.*; import java.net.Socket; import java.net.SocketTimeoutException; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -24,35 +26,39 @@ * @author drice */ public class SocketConnection extends AbstractConnection implements Connection { + + @FunctionalInterface + public interface SocketSupplier { + public T get() throws IOException; + } + /** Instance used for log messages. */ private static final Logger log = LogManager.getLogger(SocketConnection.class); - private final String id; - private SendThread send; - private ReceiveThread receive; - private Socket socket; - private String hostName; - private int port; + @Nonnull private final String id; + @Nullable private SendThread send; + @Nullable private ReceiveThread receive; + @Nullable private Socket socket; + @Nullable private SocketSupplier socketSupplier; - public SocketConnection(String id, String hostName, int port) { + public SocketConnection(@Nonnull String id, @Nonnull SocketSupplier socketSupplier) { this.id = id; - this.hostName = hostName; - this.port = port; + this.socketSupplier = socketSupplier; } - public SocketConnection(String id, Socket socket) { + public SocketConnection(@Nonnull String id, @Nonnull Socket socket) { this.id = id; - this.socket = socket; initialize(socket); } @Override + @Nonnull public String getId() { return id; } - private void initialize(Socket socket) { + private void initialize(@Nonnull Socket socket) { this.socket = socket; this.send = new SendThread(socket); this.receive = new ReceiveThread(socket); @@ -63,7 +69,10 @@ private void initialize(Socket socket) { @Override public void open() throws IOException { - initialize(new Socket(hostName, port)); + if (socketSupplier == null) { + throw new AssertionError("open should not be called when created with a Socket"); + } + initialize(socketSupplier.get()); } @Override diff --git a/src/main/java/net/rptools/clientserver/ConnectionFactory.java b/src/main/java/net/rptools/clientserver/ConnectionFactory.java index a3c4c9fee8..4e7ae2547d 100644 --- a/src/main/java/net/rptools/clientserver/ConnectionFactory.java +++ b/src/main/java/net/rptools/clientserver/ConnectionFactory.java @@ -15,6 +15,7 @@ package net.rptools.clientserver; import java.awt.EventQueue; +import java.net.Socket; import javax.annotation.Nonnull; import javax.annotation.Nullable; import net.rptools.clientserver.simple.connection.Connection; @@ -39,7 +40,7 @@ public static ConnectionFactory getInstance() { public Connection createConnection(@Nonnull String id, @Nonnull RemoteServerConfig config) { return switch (config) { case RemoteServerConfig.Socket(String hostName, int port) -> - new SocketConnection(id, hostName, port); + new SocketConnection(id, () -> new Socket(hostName, port)); case RemoteServerConfig.WebRTC(String serverName) -> new WebRTCConnection( id, From 3a2d72aad4a0b31f4f158298ef1a1df4f535f907 Mon Sep 17 00:00:00 2001 From: Richard Maw Date: Tue, 11 Feb 2025 18:43:36 +0000 Subject: [PATCH 3/7] Add SSLSocket variant of RemoteServerConfig For now this could plausibly be a boolean in RemoteServerConfig.Socket but it is expected to grow additional complication. --- .../java/net/rptools/clientserver/ConnectionFactory.java | 5 +++++ .../java/net/rptools/maptool/client/RemoteServerConfig.java | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/net/rptools/clientserver/ConnectionFactory.java b/src/main/java/net/rptools/clientserver/ConnectionFactory.java index 4e7ae2547d..2d6fc20d02 100644 --- a/src/main/java/net/rptools/clientserver/ConnectionFactory.java +++ b/src/main/java/net/rptools/clientserver/ConnectionFactory.java @@ -18,6 +18,7 @@ import java.net.Socket; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.net.ssl.SSLSocketFactory; import net.rptools.clientserver.simple.connection.Connection; import net.rptools.clientserver.simple.connection.SocketConnection; import net.rptools.clientserver.simple.connection.WebRTCConnection; @@ -39,6 +40,10 @@ public static ConnectionFactory getInstance() { @Nonnull public Connection createConnection(@Nonnull String id, @Nonnull RemoteServerConfig config) { return switch (config) { + case RemoteServerConfig.SSLSocket(String hostName, int port) -> + // TODO: Create socket with custom SSL context + new SocketConnection( + id, () -> SSLSocketFactory.getDefault().createSocket(hostName, port)); case RemoteServerConfig.Socket(String hostName, int port) -> new SocketConnection(id, () -> new Socket(hostName, port)); case RemoteServerConfig.WebRTC(String serverName) -> diff --git a/src/main/java/net/rptools/maptool/client/RemoteServerConfig.java b/src/main/java/net/rptools/maptool/client/RemoteServerConfig.java index 1581541736..a13212fdf2 100644 --- a/src/main/java/net/rptools/maptool/client/RemoteServerConfig.java +++ b/src/main/java/net/rptools/maptool/client/RemoteServerConfig.java @@ -17,6 +17,8 @@ import javax.annotation.Nonnull; public sealed interface RemoteServerConfig { + record SSLSocket(@Nonnull String hostName, int port) implements RemoteServerConfig {} + record Socket(@Nonnull String hostName, int port) implements RemoteServerConfig {} record WebRTC(@Nonnull String serverName) implements RemoteServerConfig {} From 692f4d944154ac6f901dce31c8f7cd594fd473d1 Mon Sep 17 00:00:00 2001 From: Richard Maw Date: Tue, 11 Feb 2025 20:08:05 +0000 Subject: [PATCH 4/7] Add useSSL flag to ServerAddress.Tcp This also adds support for rptools-maptool+tcps URIs to connect to SSL servers over the command-line. This adds the useSSL flag to an existing variant as the minimal change. --- package/linux/launcher.desktop | 2 +- package/windows/main.wxs | 13 ++++++++++ .../rptools/maptool/client/ServerAddress.java | 25 +++++++++++++------ .../ConnectionInfoDialog.java | 10 +++++--- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/package/linux/launcher.desktop b/package/linux/launcher.desktop index 251509cf9b..4263a6ccc8 100644 --- a/package/linux/launcher.desktop +++ b/package/linux/launcher.desktop @@ -6,5 +6,5 @@ Icon=/opt/maptool/lib/${projectName}${developerRelease}.png Terminal=false Type=Application Categories=Game -MimeType=application/maptool;x-scheme-handler/rptools-maptool+registry;x-scheme-handler/rptools-maptool+lan;x-scheme-handler/rptools-maptool+tcp +MimeType=application/maptool;x-scheme-handler/rptools-maptool+registry;x-scheme-handler/rptools-maptool+lan;x-scheme-handler/rptools-maptool+tcp;x-scheme-handler/rptools-maptool+tcps StartupWMClass=net-rptools-maptool-client-LaunchInstructions \ No newline at end of file diff --git a/package/windows/main.wxs b/package/windows/main.wxs index e0dc3d5cfe..9c9307c0ea 100644 --- a/package/windows/main.wxs +++ b/package/windows/main.wxs @@ -173,6 +173,19 @@ + + + + + + + + + + diff --git a/src/main/java/net/rptools/maptool/client/ServerAddress.java b/src/main/java/net/rptools/maptool/client/ServerAddress.java index b78a1626d5..e6d7ea807a 100644 --- a/src/main/java/net/rptools/maptool/client/ServerAddress.java +++ b/src/main/java/net/rptools/maptool/client/ServerAddress.java @@ -103,19 +103,28 @@ public URI toUri() { } } - record Tcp(@Nonnull String address, int port) implements ServerAddress { + record Tcp(@Nonnull String address, int port, boolean useSSL) implements ServerAddress { @Override @Nonnull public RemoteServerConfig findServer() { - return new RemoteServerConfig.Socket( - address(), port() == -1 ? ServerConfig.DEFAULT_PORT : port()); + var port = port(); + if (port == -1) { + port = ServerConfig.DEFAULT_PORT; + } + + if (useSSL) { + return new RemoteServerConfig.SSLSocket(address(), port); + } + + return new RemoteServerConfig.Socket(address(), port); } @Override @Nonnull public URI toUri() { try { - return new URI("rptools-maptool+tcp", null, address(), port(), "/", null, null); + var scheme = useSSL() ? "rptools-maptool+tcps" : "rptools-maptool+tcp"; + return new URI(scheme, null, address(), port(), "/", null, null); } catch (URISyntaxException e) { throw new AssertionError( "Scheme and path are given and the path is absolute and IP address authorities are all valid so this should be infallible", @@ -173,14 +182,14 @@ static ServerAddress parse(@Nonnull String s) return new ServerAddress.Lan(serviceIdentifier); case "rptools-maptool+tcp": + case "rptools-maptool+tcps": if (host == null) { - throw new IllegalArgumentException("rptools-maptool+tcp URIs must have a host"); + throw new IllegalArgumentException(scheme + " URIs must have a host"); } if (path != null && !path.isEmpty() && !path.equals("/")) { - throw new IllegalArgumentException( - "rptools-maptool+tcp URIs must have no path or just /"); + throw new IllegalArgumentException(scheme + " URIs must have no path or just /"); } - return new ServerAddress.Tcp(host, port); + return new ServerAddress.Tcp(host, port, scheme.endsWith("s")); case null: default: diff --git a/src/main/java/net/rptools/maptool/client/ui/connectioninfodialog/ConnectionInfoDialog.java b/src/main/java/net/rptools/maptool/client/ui/connectioninfodialog/ConnectionInfoDialog.java index 1496952221..2da7476880 100644 --- a/src/main/java/net/rptools/maptool/client/ui/connectioninfodialog/ConnectionInfoDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/connectioninfodialog/ConnectionInfoDialog.java @@ -107,7 +107,9 @@ public ConnectionInfoDialog(MapToolServer server) { return null; } return new ServerAddress.Tcp( - NetUtil.formatAddress(localAddresses.ipv4().get(0)), server.getPort()); + NetUtil.formatAddress(localAddresses.ipv4().get(0)), + server.getPort(), + false); }); Supplier> getLocalV6 = () -> @@ -119,7 +121,9 @@ public ConnectionInfoDialog(MapToolServer server) { return null; } return new ServerAddress.Tcp( - NetUtil.formatAddress(localAddresses.ipv6().get(0)), server.getPort()); + NetUtil.formatAddress(localAddresses.ipv6().get(0)), + server.getPort(), + false); }); Supplier> getExternal = () -> @@ -131,7 +135,7 @@ public ConnectionInfoDialog(MapToolServer server) { return null; } return new ServerAddress.Tcp( - NetUtil.formatAddress(address), server.getPort()); + NetUtil.formatAddress(address), server.getPort(), false); }); registerCopyButton(panel, "registryUriCopyButton", getServerName, ServerAddress::toUri); registerCopyButton(panel, "registryHttpUrlCopyButton", getServerName, ServerAddress::toHttpUrl); From 4e36a14cdac2f79cdc63f9e0e3cba0601b8774d1 Mon Sep 17 00:00:00 2001 From: Richard Maw Date: Tue, 11 Feb 2025 20:11:48 +0000 Subject: [PATCH 5/7] Document using URI to connect to SSL server --- doc/SSL.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/SSL.md b/doc/SSL.md index 579eb77530..b7b20959a1 100644 --- a/doc/SSL.md +++ b/doc/SSL.md @@ -174,3 +174,14 @@ or while running from git ``` ./gradlew run --args=rptools-maptool+tcp://${localips[0]}:51231 ``` + +## 5. Connecting to a SSL enabled MapTool server directly + +With the certificate installed in the system certificate store +the second `TCP-LISTEN` socat tunnel can be omitted +and the new `rptools-maptool+tcps://` scheme used +to connect from the command-line to port 51232. + +``` +./gradlew run --args=rptools-maptool+tcps://${localips[0]}:51232 +``` From b9a84a401e7c963c56b1fa4ec6e52051d1624165 Mon Sep 17 00:00:00 2001 From: Richard Maw Date: Tue, 11 Feb 2025 20:30:56 +0000 Subject: [PATCH 6/7] Add Use SSL checkbox to Connect to Server dialog --- .../ConnectToServerDialog.java | 17 ++++++++++++++++- .../ConnectToServerDialogPreferences.java | 9 +++++++++ .../ConnectToServerDialogView.form | 17 +++++++++++++++++ .../ConnectToServerDialogView.java | 2 +- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialog.java b/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialog.java index eeba2650af..28b9bea366 100644 --- a/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialog.java @@ -260,6 +260,15 @@ public JCheckBox getUsePublicKeyCheckBox() { return (JCheckBox) getComponent("@usePublicKey"); } + @Nonnull + public JCheckBox getUseSSLCheckBox() { + if (getComponent("@useSSL") instanceof JCheckBox checkBox) { + return checkBox; + } else { + throw new AssertionError("Connect to server dialog should have a JCheckBox named @useSSL"); + } + } + private void handleOK() { String username = getUsernameTextField().getText().trim(); if (username.length() == 0) { @@ -311,8 +320,14 @@ private void handleOK() { } getHostTextField().setText(host); + boolean useSSL = getUseSSLCheckBox().isSelected(); + // OK - connectionDetails = new RemoteServerConfig.Socket(host, portTemp); + if (useSSL) { + connectionDetails = new RemoteServerConfig.SSLSocket(host, portTemp); + } else { + connectionDetails = new RemoteServerConfig.Socket(host, portTemp); + } } else if (SwingUtil.hasComponent(selectedPanel, "rptoolsPanel")) { String serverName = getServerNameTextField().getText().trim(); if (serverName.length() == 0) { diff --git a/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogPreferences.java b/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogPreferences.java index 2ee18db341..21d6b1fd4e 100644 --- a/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogPreferences.java +++ b/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogPreferences.java @@ -31,6 +31,7 @@ public class ConnectToServerDialogPreferences { private static final String KEY_TAB = "tab"; private static final String KEY_SERVER_NAME = "serverName"; private static final String USE_PUBLIC_KEY = "usePublicKey"; + private static final String USE_SSL = "useSSL"; private static final String USE_WEB_RTC = "useWebRTC"; @Nonnull @@ -100,4 +101,12 @@ public boolean getUseWebRTC() { public void setUseWebRTC(boolean useWebRTC) { prefs.putBoolean(USE_WEB_RTC, useWebRTC); } + + public boolean getUseSSL() { + return prefs.getBoolean(USE_SSL, false); + } + + public void setUseSSL(boolean useSSL) { + prefs.putBoolean(USE_SSL, useSSL); + } } diff --git a/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogView.form b/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogView.form index e80a70480e..1338b15232 100644 --- a/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogView.form +++ b/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogView.form @@ -227,6 +227,23 @@ + + + + + + + + + + + + + + + + + diff --git a/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogView.java b/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogView.java index 41c249f5f5..c6e47598d5 100644 --- a/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogView.java +++ b/src/main/java/net/rptools/maptool/client/ui/connecttoserverdialog/ConnectToServerDialogView.java @@ -14,11 +14,11 @@ */ package net.rptools.maptool.client.ui.connecttoserverdialog; -import java.awt.*; import javax.swing.*; public class ConnectToServerDialogView { private JPanel mainPanel; + private JCheckBox directUseSSLCheckbox; public JComponent getRootComponent() { return mainPanel; From b2924396b90af2d2d52146991d9b15d6f1e42867 Mon Sep 17 00:00:00 2001 From: Richard Maw Date: Tue, 11 Feb 2025 21:30:17 +0000 Subject: [PATCH 7/7] Mention Use SSL checkbox in dialog --- doc/SSL.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/SSL.md b/doc/SSL.md index b7b20959a1..9bef405ace 100644 --- a/doc/SSL.md +++ b/doc/SSL.md @@ -185,3 +185,6 @@ to connect from the command-line to port 51232. ``` ./gradlew run --args=rptools-maptool+tcps://${localips[0]}:51232 ``` + +Alternatively the "Use SSL" checkbox in the "Direct" tab of the connect dialog +can be checked to specify to connect with SSL.