summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Schulthess2017-03-27 17:46:29 +0200
committerChristoph Schulthess2017-03-27 17:46:29 +0200
commitee73d50bb0663b378a94169b41e99ac7d5d4fb69 (patch)
treeb1bdd5d79324b18bcdad0d2f4161a0fd103bbdfc
parentDecluttered tasks, SSL is now Default Relay mode (diff)
downloadtmlite-bwlp-ee73d50bb0663b378a94169b41e99ac7d5d4fb69.tar.gz
tmlite-bwlp-ee73d50bb0663b378a94169b41e99ac7d5d4fb69.tar.xz
tmlite-bwlp-ee73d50bb0663b378a94169b41e99ac7d5d4fb69.zip
new relay task
-rw-r--r--src/main/java/org/openslx/taskmanager/tasks/DirectedRelay.java190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/taskmanager/tasks/DirectedRelay.java b/src/main/java/org/openslx/taskmanager/tasks/DirectedRelay.java
new file mode 100644
index 0000000..fffd707
--- /dev/null
+++ b/src/main/java/org/openslx/taskmanager/tasks/DirectedRelay.java
@@ -0,0 +1,190 @@
+package org.openslx.taskmanager.tasks;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.openslx.taskmanager.api.AbstractTask;
+
+import com.google.gson.annotations.Expose;
+
+public class DirectedRelay extends AbstractTask
+{
+
+ protected Output status = new Output();
+
+ @Expose
+ public String ip;
+ @Expose
+ public int port;
+
+ @Override
+ protected boolean execute()
+ {
+ SSLContext ctx = getSSLContext();
+ if ( ctx == null )
+ return false;
+
+ try ( SSLSocket dbgSock = getDbgSock( ctx );
+ SSLServerSocket srvSock = getSrvSock( ctx ) ) {
+ connectToDbg( dbgSock );
+ bindToPort( srvSock );
+ try ( SSLSocket poolSock = ( SSLSocket ) srvSock.accept() ) {
+ status.addMessage( "INFO: Connection from pool client established." );
+ relay( dbgSock, poolSock );
+ } catch ( Exception ex ) {
+ throw( ex );
+ }
+ } catch ( Exception e ) {
+ status.addMessage( "ERROR: " + e.getMessage() );
+ return false;
+ }
+ return true;
+ }
+
+ protected void connectToDbg ( SSLSocket dbgSock ) throws IOException {
+ InetSocketAddress addr = new InetSocketAddress( ip, port );
+ dbgSock.connect( addr );
+ status.addMessage( "INFO: Connected to debug server at " + ip + ":" + port + "." );
+ status.setDbgAddr( addr );
+ }
+
+ protected void bindToPort ( SSLServerSocket srvSock ) throws IOException {
+ srvSock.bind( null );
+ status.setListenPort( srvSock.getLocalPort() );
+ status.addMessage( "INFO: Listening on localhost:" + status.getListenPort() + "." );
+ }
+
+ protected SSLContext getSSLContext() {
+ SSLContext ctx = null;
+ try {
+ ctx = trustAll();
+ status.addMessage( "INFO: SSLContext created." );
+ } catch ( Exception e ) {
+ status.addMessage( "ERROR: Failed to create SSLContext." );
+ }
+ return ctx;
+ }
+
+ private boolean relay( SSLSocket dbgSock, SSLSocket poolSock ) {
+ Relay toDbg = new Relay( poolSock, dbgSock, status );
+ Relay toPool = new Relay( dbgSock, poolSock, status );
+ toDbg.setName( "PoolToDebug" );
+ toPool.setName( "DebugToPool" );
+ toDbg.start();
+ toPool.start();
+
+ try {
+ for ( Relay r : new Relay[]{ toDbg, toPool })
+ r.join();
+ } catch ( InterruptedException ix ) {
+ status.addMessage( "INFO: Relay closed: " + Thread.currentThread().getName() );
+ }
+
+ return true;
+ }
+
+ protected SSLContext trustAll () throws Exception
+ {
+ TrustManager[] trustAllMgr = new TrustManager[] { new X509TrustManager() {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted( X509Certificate[] certs, String authType ) {}
+ public void checkServerTrusted( X509Certificate[] certs, String authType ) {}
+ }
+ };
+ SSLContext ctx = SSLContext.getInstance( "SSL" );
+ ctx.init( null, trustAllMgr, new java.security.SecureRandom() );
+ return ctx;
+ }
+
+ private SSLServerSocket getSrvSock( SSLContext ctx ) throws IOException
+ {
+ SSLServerSocketFactory sssf = ctx.getServerSocketFactory();
+ return ( SSLServerSocket ) sssf.createServerSocket();
+ }
+
+ private SSLSocket getDbgSock( SSLContext ctx ) throws IOException
+ {
+ SSLSocketFactory ssf = ctx.getSocketFactory();
+ return ( SSLSocket ) ssf.createSocket();
+ }
+
+ @Override
+ protected boolean initTask()
+ {
+ this.setStatusObject( this.status );
+ status.addMessage( "INFO: Initiating directed relay to debug server at: " + ip + ":" + port + "." );
+ return true;
+ }
+
+ public static class Output
+ {
+
+ protected String messages = null;
+ protected Date d = null;
+ protected InetSocketAddress dbgAddr = null;
+ protected int listenPort;
+
+ public void setListenPort ( int port ) { listenPort = port; }
+ public int getListenPort () { return listenPort; }
+ public void setDbgAddr ( InetSocketAddress addr ) { dbgAddr = addr; }
+
+ public void addMessage( String str )
+ {
+ d = new Date();
+ if ( messages == null ) {
+ messages = d.toString() + "-" + str;
+ } else {
+ messages += "\n" + d.toString() + "-" + str;
+ }
+ }
+ }
+
+ private class Relay extends Thread
+ {
+ boolean active = true;
+ private byte[] buffer = new byte[16384];
+
+ private SSLSocket srcSock;
+ private SSLSocket destSock;
+
+ private Output status;
+
+ public Relay ( SSLSocket srcSock, SSLSocket destSock, Output status ) {
+ this.srcSock = srcSock;
+ this.destSock = destSock;
+ this.status = status;
+ }
+
+ @Override
+ public void run() {
+ boolean first = true;
+ int readBytes;
+ try ( InputStream in = srcSock.getInputStream();
+ OutputStream out = destSock.getOutputStream() ) {
+ while( active ) {
+ readBytes = in.read( buffer );
+ out.write( buffer, 0, readBytes );
+ if ( first )
+ status.addMessage( "INFO: Relay operating: " + this.getName() );
+ }
+ } catch ( Exception e ) {
+ active = false;
+ return;
+ }
+ }
+ }
+}