From 16749e9e96738c88fdefa496a9e7a127740d0282 Mon Sep 17 00:00:00 2001
From: UnfamiliarLegacy <74633542+UnfamiliarLegacy@users.noreply.github.com>
Date: Mon, 13 Feb 2023 03:32:34 +0100
Subject: [PATCH 1/2] Update jetty and drop javax.websocket-api
---
G-Earth/pom.xml | 5 +-
.../proxy/nitro/websocket/NitroSession.java | 2 +-
.../nitro/websocket/NitroWebsocketClient.java | 3 +-
.../nitro/websocket/NitroWebsocketServer.java | 111 +++++++++---------
.../nitro/NitroPacketHandler.java | 14 ++-
5 files changed, 74 insertions(+), 61 deletions(-)
diff --git a/G-Earth/pom.xml b/G-Earth/pom.xml
index 53526ad..3c4a4ff 100644
--- a/G-Earth/pom.xml
+++ b/G-Earth/pom.xml
@@ -10,7 +10,7 @@
1.8
- 9.4.48.v20220622
+ 9.4.50.v20221201
1.3.5
@@ -238,14 +238,11 @@
maven-artifact
3.6.3
-
-
javax.websocket
javax.websocket-api
1.1
-
org.eclipse.jetty
jetty-server
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroSession.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroSession.java
index f85854e..d7f4665 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroSession.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroSession.java
@@ -1,6 +1,6 @@
package gearth.protocol.connection.proxy.nitro.websocket;
-import javax.websocket.Session;
+import org.eclipse.jetty.websocket.api.Session;
public interface NitroSession {
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketClient.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketClient.java
index d003c31..7ebfc7d 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketClient.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketClient.java
@@ -50,6 +50,7 @@ public class NitroWebsocketClient implements NitroSession {
activeSession = (JsrSession) session;
activeSession.setMaxBinaryMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
+ activeSession.setMaxTextMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
// Set proper headers to spoof being a real client.
final Map> headers = new HashMap<>(activeSession.getUpgradeRequest().getHeaders());
@@ -94,7 +95,7 @@ public class NitroWebsocketClient implements NitroSession {
}
@Override
- public Session getSession() {
+ public org.eclipse.jetty.websocket.api.Session getSession() {
return activeSession;
}
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java
index 3df6cb7..5ed19c1 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java
@@ -5,17 +5,21 @@ import gearth.protocol.HMessage;
import gearth.protocol.connection.proxy.nitro.NitroConstants;
import gearth.protocol.packethandler.PacketHandler;
import gearth.protocol.packethandler.nitro.NitroPacketHandler;
-import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
-import org.eclipse.jetty.websocket.jsr356.JsrExtension;
+import org.eclipse.jetty.websocket.api.Session;
+import org.eclipse.jetty.websocket.api.WebSocketListener;
+import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.websocket.*;
import java.io.IOException;
import java.net.URI;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
-public class NitroWebsocketServer extends Endpoint implements NitroSession {
+public class NitroWebsocketServer implements WebSocketListener, NitroSession {
private static final Logger logger = LoggerFactory.getLogger(NitroWebsocketServer.class);
@@ -39,66 +43,34 @@ public class NitroWebsocketServer extends Endpoint implements NitroSession {
public void connect(String websocketUrl, Map> clientHeaders) throws IOException {
try {
- logger.info("Connecting to origin websocket at {}", websocketUrl);
+ logger.info("Building origin websocket connection ({})", websocketUrl);
- ClientEndpointConfig.Builder builder = ClientEndpointConfig.Builder.create();
+ final WebSocketClient client = new WebSocketClient();
- builder.extensions(Collections.singletonList(new JsrExtension(new ExtensionConfig("permessage-deflate;client_max_window_bits"))));
+ client.setMaxBinaryMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
+ client.setMaxTextMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
- builder.configurator(new ClientEndpointConfig.Configurator() {
- @Override
- public void beforeRequest(Map> headers) {
- clientHeaders.forEach((key, value) -> {
- if (SKIP_HEADERS.contains(key)) {
- return;
- }
+ final ClientUpgradeRequest request = new ClientUpgradeRequest();
- headers.remove(key);
- headers.put(key, value);
- });
+ clientHeaders.forEach((key, value) -> {
+ if (SKIP_HEADERS.contains(key)) {
+ return;
}
+
+ request.setHeader(key, value);
});
- ClientEndpointConfig config = builder.build();
+ logger.info("Connecting to origin websocket at {}", websocketUrl);
- ContainerProvider.getWebSocketContainer().connectToServer(this, config, URI.create(websocketUrl));
+ client.start();
+ client.connect(this, URI.create(websocketUrl), request);
logger.info("Connected to origin websocket");
- } catch (DeploymentException e) {
- throw new IOException("Failed to deploy websocket client", e);
+ } catch (Exception e) {
+ throw new IOException("Failed to start websocket client to origin " + websocketUrl, e);
}
}
- @Override
- public void onOpen(Session session, EndpointConfig config) {
- this.activeSession = session;
- this.activeSession.setMaxBinaryMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
- this.activeSession.addMessageHandler(new MessageHandler.Whole() {
- @Override
- public void onMessage(byte[] message) {
- try {
- packetHandler.act(message);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- });
- }
-
- @Override
- public void onClose(Session session, CloseReason closeReason) {
- // Hotel closed connection.
- client.shutdownProxy();
- }
-
- @Override
- public void onError(Session session, Throwable throwable) {
- throwable.printStackTrace();
-
- // Shutdown.
- client.shutdownProxy();
- }
-
@Override
public Session getSession() {
return activeSession;
@@ -118,10 +90,43 @@ public class NitroWebsocketServer extends Endpoint implements NitroSession {
try {
activeSession.close();
- } catch (IOException e) {
+ } catch (Exception e) {
e.printStackTrace();
} finally {
activeSession = null;
}
}
+
+ @Override
+ public void onWebSocketBinary(byte[] bytes, int i, int i1) {
+ try {
+ packetHandler.act(bytes);
+ } catch (IOException e) {
+ logger.error("Failed to handle packet", e);
+ }
+ }
+
+ @Override
+ public void onWebSocketText(String s) {
+ logger.warn("Received text message from hotel");
+ }
+
+ @Override
+ public void onWebSocketClose(int i, String s) {
+ // Hotel closed connection.
+ client.shutdownProxy();
+ }
+
+ @Override
+ public void onWebSocketConnect(org.eclipse.jetty.websocket.api.Session session) {
+ activeSession = session;
+ }
+
+ @Override
+ public void onWebSocketError(Throwable throwable) {
+ throwable.printStackTrace();
+
+ // Shutdown.
+ client.shutdownProxy();
+ }
}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java
index d8b69b0..fc72f34 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java
@@ -6,13 +6,17 @@ import gearth.protocol.connection.proxy.nitro.websocket.NitroSession;
import gearth.protocol.packethandler.PacketHandler;
import gearth.protocol.packethandler.PayloadBuffer;
import gearth.services.extension_handler.ExtensionHandler;
+import org.eclipse.jetty.websocket.api.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import javax.websocket.Session;
import java.io.IOException;
import java.nio.ByteBuffer;
public class NitroPacketHandler extends PacketHandler {
+ private static final Logger logger = LoggerFactory.getLogger(NitroPacketHandler.class);
+
private final HMessage.Direction direction;
private final NitroSession session;
private final PayloadBuffer payloadBuffer;
@@ -39,7 +43,13 @@ public class NitroPacketHandler extends PacketHandler {
buffer = buffer.clone();
}
- localSession.getAsyncRemote().sendBinary(ByteBuffer.wrap(buffer));
+ try {
+ localSession.getRemote().sendBytes(ByteBuffer.wrap(buffer));
+ } catch (IOException e) {
+ logger.error("Error sending packet to nitro client", e);
+ return false;
+ }
+
return true;
}
From 8a880a13df643a7b23eb1e0987cead6a7c014367 Mon Sep 17 00:00:00 2001
From: UnfamiliarLegacy <74633542+UnfamiliarLegacy@users.noreply.github.com>
Date: Mon, 13 Feb 2023 05:03:56 +0100
Subject: [PATCH 2/2] Allow untrusted SSL certificates for Nitro
---
.../nitro/websocket/NitroWebsocketServer.java | 55 +++++++++++++++++--
1 file changed, 51 insertions(+), 4 deletions(-)
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java
index 5ed19c1..37ca63d 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java
@@ -5,6 +5,8 @@ import gearth.protocol.HMessage;
import gearth.protocol.connection.proxy.nitro.NitroConstants;
import gearth.protocol.packethandler.PacketHandler;
import gearth.protocol.packethandler.nitro.NitroPacketHandler;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
@@ -12,8 +14,13 @@ import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.URI;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -45,10 +52,7 @@ public class NitroWebsocketServer implements WebSocketListener, NitroSession {
try {
logger.info("Building origin websocket connection ({})", websocketUrl);
- final WebSocketClient client = new WebSocketClient();
-
- client.setMaxBinaryMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
- client.setMaxTextMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
+ final WebSocketClient client = createWebSocketClient();
final ClientUpgradeRequest request = new ClientUpgradeRequest();
@@ -129,4 +133,47 @@ public class NitroWebsocketServer implements WebSocketListener, NitroSession {
// Shutdown.
client.shutdownProxy();
}
+
+ private SSLContext createSSLContext() {
+ final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType) {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType) {
+ }
+ }};
+
+ try {
+ final SSLContext sslContext = SSLContext.getInstance("TLS");
+
+ sslContext.init(null, trustAllCerts, new SecureRandom());
+
+ return sslContext;
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to setup ssl context", e);
+ }
+ }
+
+ private HttpClient createHttpClient() {
+ final SslContextFactory.Client factory = new SslContextFactory.Client();
+
+ factory.setSslContext(createSSLContext());
+
+ return new HttpClient(factory);
+ }
+
+ private WebSocketClient createWebSocketClient() {
+ final WebSocketClient client = new WebSocketClient(createHttpClient());
+
+ client.setMaxBinaryMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
+ client.setMaxTextMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE);
+
+ return client;
+ }
}