From 517170b01da744ae659af98f5b135572a8e7315d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Bigaret?=
 <sebastien.bigaret@telecom-bretagne.eu>
Date: Mon, 25 Jun 2018 14:09:55 +0200
Subject: [PATCH] Change praxis to use tunnel rmi over ssh, instead of rmi over
 http

HTTP proxying feature from RMI has been deprecated in JDK 8, and it is
completely removed in JDK 9.

New dependencies:

- sshjs, v0.24
  https://github.com/hierynomus/sshj
  https://mvnrepository.com/artifact/com.hierynomus/sshj

- Bouncy Castle Crypto package, v1.59
  https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk15on

- EdDSA Java v0.2.0
  https://mvnrepository.com/artifact/net.i2p.crypto/eddsa

- slf4j v1.7.7
  https://mvnrepository.com/artifact/org.slf4j/slf4j-api
---
 .classpath                                    |   4 +
 .../praxis/common/Launcher.java               |   2 +
 .../praxis/common/TestSSH.java                | 211 ++++++++++++++++++
 3 files changed, 217 insertions(+)
 create mode 100644 src/eu/telecom_bretagne/praxis/common/TestSSH.java

diff --git a/.classpath b/.classpath
index 4720ad68..4f580fab 100644
--- a/.classpath
+++ b/.classpath
@@ -15,6 +15,10 @@
 	<classpathentry kind="lib" path="lib/woodstox-core-5.0.3.jar"/>
 	<classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
 	<classpathentry kind="lib" path="lib/args4j-2.33.jar"/>
+	<classpathentry kind="lib" path="lib/sshj-0.24.0.jar" sourcepath="lib/sshj-0.24.0-sources.jar"/>
+	<classpathentry kind="lib" path="lib/slf4j-api-1.7.7.jar"/>
+	<classpathentry kind="lib" path="lib/eddsa-0.2.0.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="lib/bcprov-ext-jdk15on-159.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/src/eu/telecom_bretagne/praxis/common/Launcher.java b/src/eu/telecom_bretagne/praxis/common/Launcher.java
index d1b645f3..b6217a5e 100644
--- a/src/eu/telecom_bretagne/praxis/common/Launcher.java
+++ b/src/eu/telecom_bretagne/praxis/common/Launcher.java
@@ -174,6 +174,8 @@ public class Launcher
 		//if (System.getSecurityManager() == null)
         //    System.setSecurityManager(new SecurityManager());
 
+		TestSSH.connect(2000);
+		
         if (Configuration.isDefined("servers"))
 			Serveur.launch();
 		
diff --git a/src/eu/telecom_bretagne/praxis/common/TestSSH.java b/src/eu/telecom_bretagne/praxis/common/TestSSH.java
new file mode 100644
index 00000000..296c01e2
--- /dev/null
+++ b/src/eu/telecom_bretagne/praxis/common/TestSSH.java
@@ -0,0 +1,211 @@
+package eu.telecom_bretagne.praxis.common;
+
+import java.io.IOException;
+import java.net.*;
+import java.net.Proxy.Type;
+
+import javax.net.SocketFactory;
+
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.connection.channel.direct.LocalPortForwarder;
+
+/* https://www.blog-libre.org/2015/11/21/loption-match-de-sshd_config/
+ * Server needs:
+ *   -Djava.rmi.server.hostname=hostname_of_the_server
+ *   
+ * equivalent to:
+ *   ssh -4 -F /dev/null -N rmi@server-telecom-bretagne.diviz.org -L4040:localhost:4013
+ * 
+ * pour proxy:
+ *   https://stackoverflow.com/questions/47362298/is-there-any-replacement-for-http-tunneling-with-rmi-in-java-9
+ *   http://mark.koli.ch/configuring-apache-to-support-ssh-through-an-http-web-proxy-with-proxytunnel
+ *   https://github.com/hierynomus/sshj/blob/master/src/main/java/com/hierynomus/sshj/backport/Jdk7HttpProxySocket.java
+ *   http://dag.wiee.rs/howto/ssh-http-tunneling/ https://nurdletech.com/linux-notes/ssh/via-http.html
+ *   https://serverfault.com/questions/770185/apache-refuses-http-connect-over-ssl-on-non-default-virtual-host
+ *   
+ * test w/:
+
+ *   proxytunnel -p webservices-test.decision-deck.org:80 -d 149.202.172.184:22 -v
+ *   
+ * IMPORTANT:
+ * https://serverfault.com/questions/770185/apache-refuses-http-connect-over-ssl-on-non-default-virtual-host
+ * 
+ * -> doit être défini au niveau du default vhost
+ * 
+ * ProxyRequests on
+ * AllowCONNECT 22
+ * ProxyVia Full
+ * <Proxy *>
+ *   Order deny,allow
+ *   Deny from all
+ * </Proxy>
+ * # <ProxyMatch server-telecom-bretagne.diviz.org>
+ * <ProxyMatch 149.202.172.184>
+ *   Order deny,allow
+ *   #Deny from all
+ *   Allow from all
+ * </ProxyMatch>
+ * 
+ *  + dans le vhost en question? a priori non
+ *  
+ *  et /etc/ssh/sshd_config:
+ *  Match User rmi
+ *  X11Forwarding no
+ *  PermitOpen localhost:4013
+ *  PermitTunnel no
+ */
+
+/*
+
+Test avec FW:
+iptables -A OUTPUT -p tcp -d 149.202.172.184 --dport 4013 -j DROP
+iptables -A OUTPUT -p tcp -d 149.202.172.184 --dport 80 -j DROP
+
+ */
+/**
+ * @author big
+ */
+public class TestSSH
+{
+
+	public TestSSH()
+	{
+		// TODO Auto-generated constructor stub
+	}
+
+	static final String	PROXY_HOST = "webservices-test.decision-deck.org";
+
+	static final int	PROXY_PORT = 80;
+
+	public static void connect(int connectTimeout) throws IOException
+	{
+		Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
+		SocketFactory socketFactory = new SocketFactory() {
+
+			@Override
+			public Socket createSocket() throws IOException
+			{
+				System.out.println("######### create 0 ##########");
+				Socket socket = new Socket(proxy);
+				return socket;
+			}
+
+			@Override
+			public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
+			    throws IOException
+			{
+				System.out.println("######### create 1 ##########");
+				Socket socket = new Socket(proxy);
+				socket.bind(new InetSocketAddress(localAddress, localPort));
+				socket.connect(new InetSocketAddress(address, port), connectTimeout);
+				return socket;
+			}
+
+			@Override
+			public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
+			    throws IOException, UnknownHostException
+			{
+				System.out.println("######### create 2 ##########");
+				Socket socket = new Socket(host, port, localHost, localPort);
+				socket.bind(new InetSocketAddress(localHost, localPort));
+				socket.connect(new InetSocketAddress(host, port), connectTimeout);
+				return socket;
+			}
+
+			@Override
+			public Socket createSocket(InetAddress host, int port) throws IOException
+			{
+				System.out.println("######### create 3 ##########");
+				Socket socket =
+				    new Socket(new Proxy(Type.HTTP, new InetSocketAddress("server-telecom-bretagne.diviz.org", 80)));
+				socket.connect(new InetSocketAddress(host, port), connectTimeout);
+				return socket;
+			}
+
+			@Override
+			public Socket createSocket(String host, int port) throws IOException, UnknownHostException
+			{
+				System.out.println("######### create 4 ##########");
+				Socket socket =
+				    new Socket(new Proxy(Type.HTTP, new InetSocketAddress("server-telecom-bretagne.diviz.org", 80)));
+				socket.connect(new InetSocketAddress(host, port), connectTimeout);
+				return socket;
+			}
+		};
+
+		SSHClient ssh = new SSHClient();
+		// ssh.loadKnownHosts();
+		ssh.addHostKeyVerifier("e7:1b:bc:ca:c7:06:05:6f:a6:82:3d:e3:b6:1a:63:2d");
+
+        // the following is deprecated
+		// ssh.connect("server-telecom-bretagne.diviz.org", 22, new Proxy(Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT)));
+		ssh.setSocketFactory(socketFactory);
+		ssh.setConnectTimeout(connectTimeout);
+		ssh.connect("server-telecom-bretagne.diviz.org", 22);
+
+		ssh.authPassword("rmi", "meuhmeuh");
+		ssh.isConnected();
+
+		try
+		{
+
+			// ssh.authPublickey(System.getProperty("user.name"));
+
+			/* listen on localhost:4013, then forward all connections to the ssh server which forwards them to
+			 * localhost:4013, 4013 being the server's RMI registry port */
+			final LocalPortForwarder.Parameters params =
+			    new LocalPortForwarder.Parameters("127.0.0.1", 4013, "localhost", 4013);
+			final ServerSocket serverSocket = new ServerSocket();
+			serverSocket.setReuseAddress(true);
+			serverSocket.bind(new InetSocketAddress(params.getLocalHost(), params.getLocalPort()));
+			new Thread() {
+				@Override
+				public void run()
+				{
+					try
+					{
+						ssh.newLocalPortForwarder(params, serverSocket).listen();
+					}
+					catch (IOException e)
+					{
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					finally
+					{
+						try
+						{
+							serverSocket.close();
+						}
+						catch (IOException e)
+						{
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+						try
+						{
+							ssh.disconnect();
+						}
+						catch (IOException e)
+						{
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+				}
+			}.start();
+
+		}
+		finally
+		{
+		}
+
+	}
+
+	public static void main(String[] args) throws Exception
+	{
+		// TODO Auto-generated method stub
+		connect(2000);
+	}
+
+}
-- 
GitLab