diff options
author | Christoph Schulthess | 2017-03-27 17:46:29 +0200 |
---|---|---|
committer | Christoph Schulthess | 2017-03-27 17:46:29 +0200 |
commit | ee73d50bb0663b378a94169b41e99ac7d5d4fb69 (patch) | |
tree | b1bdd5d79324b18bcdad0d2f4161a0fd103bbdfc | |
parent | Decluttered tasks, SSL is now Default Relay mode (diff) | |
download | tmlite-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.java | 190 |
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; + } + } + } +} |