From 2ebebbd89664cf8d7ae87c769d419d0058051682 Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Tue, 12 Apr 2011 17:06:00 +0200 Subject: [PATCH] Huge amount of changes: * moved TcpProxy server thread into separate class * implemented on boot startup * fixed service stop problem and anything else I forgot about (bad boy, should commit more often) Signed-off-by: Balint Kovacs --- AndroidManifest.xml | 26 +- bin/SSLDroid.apk | Bin 16359 -> 23216 bytes bin/classes.dex | Bin 10844 -> 13300 bytes bin/resources.ap_ | Bin 9178 -> 15022 bytes .../blint/ssldroid/BootStartupReceiver.java | 16 +- src/hu/blint/ssldroid/SSLDroid.java | 45 ++-- src/hu/blint/ssldroid/SSLDroidGui.java | 4 +- src/hu/blint/ssldroid/TcpProxy.java | 209 ++++------------ .../blint/ssldroid/TcpProxyServerThread.java | 224 ++++++++++++++++++ 9 files changed, 319 insertions(+), 205 deletions(-) create mode 100644 src/hu/blint/ssldroid/TcpProxyServerThread.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d02df83..88ba21f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2,29 +2,27 @@ - - - + - + + + + + + + + + + + - - - - - - - - - \ No newline at end of file diff --git a/bin/SSLDroid.apk b/bin/SSLDroid.apk index 5b66f79f181d098a8fa8fdfc1a4ddab9bc5d8dc6..7432a98b80ce592e23696eaab7b4548995af38c2 100644 GIT binary patch delta 14752 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 I{xkZ204bhO`~Uy| delta 7736 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 w6Ctb%fKd(T{)YO$Nx}PX009&2fBZM?d> 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 literal 10844 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 O1muw6cXs%``~Lu#56-s$ diff --git a/bin/resources.ap_ b/bin/resources.ap_ index 871f0088f397662dfa9c08153612c1521b3871af..40337c3fb785e925aba326d6b6b990fe20aa57fe 100644 GIT binary patch delta 7204 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 GTlhb}s+}JI delta 1335 zcmZ2iddpoRz?+#xgaHKfR#e!58DL_fgd8tKj){Q-B)7R({2QYXNKt4)d;Jw=28IM4 z1_oh<$@!L|^;4(a_6v3tY5RY-C}ZITCRQ&^_Jv2Bmt;L+eR!&fLqL#c?Sf-1n=jp9 z%H+N%{q>OhhePQGaX&cXelW!S;yIEY@IP{HX8T>Uobu1*=i@eCGta(uX5O`ahBBvy zW|m302Sl>2o3EB#{w|n*h3PBH&?R<3^H=ImInQ`&g+%G>TMOdq1KzKge}(mHd)My< z$*h^b9BLQU1&WLOIiM4|q%Pp2SiQ!MA_x*4fEl5PI;J*H1FsCGz&I zmxX7-CSIEpk@v7;Z|bkJkNE2CRr^X@-ZR;Hd+huZJjuPWZg)?`+3Jb=R4ezLY3(WV z`fc~OZ075QPeKIF%fxxb%-kl|SMIjyl+E#dMz>Y#K25KvyR-POUUXvBbd{=EHKC`O zYQ3&@F$iG`^vV;vR(}nT?2SKIgv z6LEp>H$i1&L$i3v+yeKM6|t7i=Pd5I&CS2_=|s#e*~}=OrFMC*_J8{py7@um zTb2Unx3=>i*Q;pQ%N$==6Efq~GNpiJ97(UfH~c!St*|@dubs<=$VIc#_tT;d-Cz6L`f2X^8@o*E-OhcJvS0JF?`ZgA_mVlgewXfhXE8Z{ck27h z3G4Sy(^tR$$xdUxhN-k?Quf-LRaav_hHF=b{M(7p!ovnLDB5&Hp_SotJXKWuOuIGKdv0XQA$-%hU6YsxTUCDXYJ7Ui~wLNkC zdj!u)Z>-qsTTv@lv3Qnw*2iD7>OU-!t4N+@p7wE(Z^d7^ipR6e^FIEP{&1y!x#Q_N z-_KDo@1HGs<{OpllX2T+@?Wtn=cYO=y>qp^;>2NVneQL?)Jyq1v**3DNS4q0bWSzq zv-!8c>yqzwym@x!KRapxadXd&dly(47(kd0SWpzD7U!21ZPt-}#L5gRBm|XtxWNns zy(ShgW2uomn-Hi-K`mb>> S2B >>>"); - - fromBrowserToServer.start(); - fromServerToBrowser.start(); - - if (server.isInterrupted()) { - ss.close(); - return; - } - - } catch (Exception ee) { - Log.d("SSLDroid", "Ouch: " + ee.getMessage()); - // ee.printStackTrace(); - } - } - } - }; + try { + ss = new ServerSocket(listenPort); + Log.d("SSLDroid", "Listening for connections on port " + + listenPort + " ..."); + //ttg.doLog("Listening for connections on port " + ttg.getListenPort() + " ..."); + } catch (Exception e) { + Log.d("SSLDroid", "Error setting up listening socket: " + + e.toString()); + //createNotification(e.getMessage(), "Error setting up listening socket: "+e.toString()); + //e.printStackTrace(); + System.exit(1); + } + server = new TcpProxyServerThread(ss, listenPort, tunnelHost, tunnelPort, keyFile, keyPass); server.start(); } public void stop() { - if (server != null) - server.interrupt(); + if (server != null){ + try { + ss.close(); + server.interrupt(); + } catch (Exception e) { + Log.d("SSLDroid", "Interrupt failure: " + e.toString()); + createNotification(e.getMessage(), "Ouch: "+e.toString());; + } + } Log.d("SSLDroid", "Stopping service"); } - public static class Relay extends Thread { - private InputStream in; - private OutputStream out; - private final static int BUFSIZ = 4096; - private byte buf[] = new byte[BUFSIZ]; - public Relay(InputStream in, OutputStream out, String prefix) { - this.in = in; - this.out = out; - } - - public void run() { - int n = 0; - - try { - while ((n = in.read(buf)) > 0) { - out.write(buf, 0, n); - out.flush(); - - for (int i = 0; i < n; i++) { - if (buf[i] == 7) - buf[i] = '#'; - } - - if (Thread.interrupted()) { - // We've been interrupted: no more serving. - return; - } - } - } catch (SocketException e) { - Log.d("SSLDroid", e.getMessage()); - } catch (IOException e) { - Log.d("SSLDroid", e.getMessage()); - } finally { - try { - in.close(); - out.close(); - } catch (IOException e) { - Log.d("SSLDroid", e.getMessage()); - } - } - - Log.d("SSLDroid", "Quitting stream proxy..."); - } - } -} \ No newline at end of file +} diff --git a/src/hu/blint/ssldroid/TcpProxyServerThread.java b/src/hu/blint/ssldroid/TcpProxyServerThread.java new file mode 100644 index 0000000..43195b5 --- /dev/null +++ b/src/hu/blint/ssldroid/TcpProxyServerThread.java @@ -0,0 +1,224 @@ +package hu.blint.ssldroid; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import java.sql.Timestamp; +import java.util.Date; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +import android.util.Log; + +public class TcpProxyServerThread extends Thread { + + int listenPort; + String tunnelHost; + int tunnelPort; + String keyFile, keyPass; + Relay inRelay, outRelay; + ServerSocket ss = null; + + public TcpProxyServerThread(ServerSocket ss, int listenPort, String tunnelHost, int tunnelPort, String keyFile, String keyPass) { + this.listenPort = listenPort; + this.tunnelHost = tunnelHost; + this.tunnelPort = tunnelPort; + this.keyFile = keyFile; + this.keyPass = keyPass; + this.ss = ss; + } + + /*@Override + public static void yield(){ + try { + ss.close(); + } catch (IOException e) { + Log.d("SSLDroid", "Error loading the client certificate file:" + e.toString()); + } + }*/ + + + + private static SSLSocketFactory sslSocketFactory; + + public final SSLSocketFactory getSocketFactory(String pkcsFile, + String pwd) { + if (sslSocketFactory == null) { + try { + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509"); + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + keyStore.load(new FileInputStream(pkcsFile), pwd.toCharArray()); + keyManagerFactory.init(keyStore, pwd.toCharArray()); + SSLContext context = SSLContext.getInstance("TLS"); + context.init(keyManagerFactory.getKeyManagers(), null, + new SecureRandom()); + sslSocketFactory = (SSLSocketFactory) context.getSocketFactory(); + + } catch (FileNotFoundException e) { + Log.d("SSLDroid", "Error loading the client certificate file:" + + e.toString()); + createNotification(e.getMessage(), e.toString()); + //log += "Error loading the client certificate file:" + e.toString() + "\n"; + // Toast.makeText(none, "SSLDroid Sulyos Errorhiba" + + // e.toString(), Toast.LENGTH_LONG).show(); + } catch (KeyManagementException e) { + Log.d("SSLDroid", "No SSL algorithm support: " + e.toString()); + createNotification(e.getMessage(), e.toString()); + //log += "No SSL algorithm support: " + e.toString() + "\n"; + } catch (NoSuchAlgorithmException e) { + Log.d("SSLDroid", "No common SSL algorithm found: " + e.toString()); + createNotification(e.getMessage(), e.toString()); + //log += "No common SSL algorithm found: " + e.toString() + "\n"; + } catch (KeyStoreException e) { + Log.d("SSLDroid", "Error setting up keystore:" + e.toString()); + createNotification(e.getMessage(), e.toString()); + //log += "Error setting up keystore:" + e.toString() + "\n"; + } catch (java.security.cert.CertificateException e) { + Log.d("SSLDroid", "Error loading the client certificate:" + + e.toString()); + createNotification(e.getMessage(), e.toString()); + //log += "Error loading the client certificate:" + e.toString() + "\n"; + } catch (IOException e) { + Log.d("SSLDroid", "Error loading the client certificate file:" + + e.toString()); + createNotification(e.getMessage(), e.toString()); + //log += "Error loading the client certificate file:" + e.toString() + "\n"; + } catch (UnrecoverableKeyException e) { + Log.d("SSLDroid", "Error loading the client certificate:" + + e.toString()); + createNotification(e.getMessage(), e.toString()); + //log += "Error loading the client certificate:" + e.toString() + "\n"; + } + } + return sslSocketFactory; + } + + public void createNotification(String title, String text) { + try { + FileWriter outFile = new FileWriter("/mnt/sdcard/ssldroid.txt"); + PrintWriter out = new PrintWriter(outFile); + Date date= new Date(); + + out.println(new Timestamp(date.getTime())+" "+title+" "+text); + out.close(); + } catch (IOException e){ + return; + } + } + + public class Relay extends Thread { + private InputStream in; + private OutputStream out; + private final static int BUFSIZ = 4096; + private byte buf[] = new byte[BUFSIZ]; + + public Relay(InputStream in, OutputStream out) { + this.in = in; + this.out = out; + } + + public void run() { + int n = 0; + + try { + while ((n = in.read(buf)) > 0) { + if (Thread.interrupted()) { + // We've been interrupted: no more relaying + Log.d("SSLDroid", "Interrupted thread"); + return; + } + out.write(buf, 0, n); + out.flush(); + + for (int i = 0; i < n; i++) { + if (buf[i] == 7) + buf[i] = '#'; + } + } + } catch (SocketException e) { + Log.d("SSLDroid", e.toString()); + createNotification(e.getMessage(), e.toString()); + } catch (IOException e) { + Log.d("SSLDroid", e.toString()); + createNotification(e.getMessage(), e.toString()); + } finally { + try { + in.close(); + out.close(); + } catch (IOException e) { + Log.d("SSLDroid", e.toString()); + createNotification(e.getMessage(), e.toString()); + } + } + Log.d("SSLDroid", "Quitting stream proxy..."); + } + } + + public void run() { + while (true) { + try { + if (isInterrupted()){ + Log.d("SSLDroid", "Interrupted server thread, closing sockets..."); + ss.close(); + return; + } + // accept the connection from my client + Socket sc = null; + try { + sc = ss.accept(); + } catch (SocketException e){ + Log.d("SSLDroid", "Accept failure: " + e.toString()); + } + + Socket st = null; + + try { + st = (SSLSocket) getSocketFactory(keyFile, keyPass).createSocket(tunnelHost, tunnelPort); + ((SSLSocket) st).startHandshake(); + } catch (Exception e) { + Log.d("SSLDroid", "SSL failure: " + e.toString()); + //createNotification(e.getMessage(), "SSL failure: "+e.toString()); + Thread.sleep(10000); + continue; + //st = new Socket(ttg.getTunnelHost(), ttg.getTunnelPort()); + } + + Log.d("SSLDroid", "Tunnelling port " + + listenPort + " to port " + + tunnelPort + " on host " + + tunnelHost + " ..."); + + // relay the stuff thru + Thread fromBrowserToServer = new Relay( + sc.getInputStream(), st.getOutputStream()); + Thread fromServerToBrowser = new Relay( + st.getInputStream(), sc.getOutputStream()); + + fromBrowserToServer.start(); + fromServerToBrowser.start(); + + } catch (Exception ee) { + Log.d("SSLDroid", "Ouch: " + ee.toString()); + createNotification(ee.getMessage(), "Ouch: "+ee.toString()); + //ttg.doLog("Ouch: " + ee.toString()); + } + } + } +}; +