Package com.notmacchallenge

Source Code of com.notmacchallenge.HttpTunnel

package com.notmacchallenge;

import java.io.*;
import java.net.*;
import java.security.KeyStore;
import java.security.Security;
import java.util.*;

import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class HttpTunnel implements Runnable
{
  String type = "";
  Socket sock1 = null;
  Socket sock2 = null;
  BufferedInputStream in1;
  String notMacIP = null;
  String notMacPort = "443";
  int port;
  String ip;
  String keystore;
  String keystorepass;
  String keypass;
  static RandomAccessFile log = null;

  static public void startTunnel()
  {
    Properties p = new Properties();
    try
    {
      new Thread(new HttpTunnel(null,null,null,null,null,"terminator")).start();

      p.load(new FileInputStream("/Library/Application Support/NotMac/httpTunnel.prop"));
      if (p.getProperty("type").equals("clientServer") || p.getProperty("type").equals("bothServer"))
      {
        String ip = p.getProperty("ip");
        String baseIP = ip.substring(0,ip.lastIndexOf(".")+1);
        String endIP = ip.substring(ip.lastIndexOf(".")+1);
        int end = Integer.parseInt(endIP);
        for (int x=0; x<3; x++)
        {
          new Thread(new HttpTunnel(443,baseIP+(end+x),p.getProperty("keystore"+x),p.getProperty("keystorepass"),p.getProperty("keypass"),p.getProperty("notMacIP"),p.getProperty("notMacPort"),"clientServer")).start();
          new Thread(new HttpTunnel(80,baseIP+(end+x),null,null,null,p.getProperty("notMacIP"),p.getProperty("notMacPort"),"clientServer")).start();
        }
      }
      if (p.getProperty("type").equals("mainServer") || p.getProperty("type").equals("bothServer"))
      {
        for (int x=0; x<60; x++)
        {
          try
          {
            new Socket("127.0.0.210",443).close();
            break;
          }
          catch(Exception e)
          {
          }
          Thread.sleep(500);
        }
        new Thread(new HttpTunnel(Integer.parseInt(p.getProperty("notMacPort")),null,"/Library/Application Support/NotMac/notmac.keystore","password","password",p.getProperty("notMacIP"),p.getProperty("notMacPort"),"mainServer")).start();//bind to all IPs
      }
    }
    catch(Exception e)
    {
      log(e);
    }
  }

  public HttpTunnel(int port, String ip, String keystore, String keystorepass, String keypass, String notMacIP, String notMacPort, String type)
  {
    this.port=port;
    this.ip=ip;
    this.keystore=keystore;
    this.keystorepass=keystorepass;
    this.keypass=keypass;
    this.type=type;
    this.notMacIP = notMacIP;
    this.notMacPort = notMacPort;
  }

  public HttpTunnel(BufferedInputStream in1, Socket sock1, Socket sock2, String notMacIP, String notMacPort, String type)
  {
    this.in1 = in1;
    this.sock1=sock1;
    this.sock2=sock2;
    this.type=type;
    this.notMacIP = notMacIP;
    this.notMacPort = notMacPort;
  }

  public void run()
  {
    if (type.equalsIgnoreCase("terminator"))
    {
      try
      {
        ServerSocket terminator = new ServerSocket(53819,1000,InetAddress.getByName("127.0.0.1"));
        terminator.accept().close();
        System.exit(0);
      }
      catch(Exception e)
      {
        log(e);
      }
      System.exit(0);
    }
    else if (type.equalsIgnoreCase("tunnel"))
    {
      String ip1=sock1.getLocalAddress().getHostAddress();
      String ip2=sock2.getLocalAddress().getHostAddress();
      log("Tunneling " + ip1+":"+sock1.getLocalPort() + " to " + ip2+":"+sock2.getPort());
      try
      {
        InputStream in = in1 == null?sock1.getInputStream():in1;
        OutputStream out = sock2.getOutputStream();
        log("Streaming from " + ip1 +":" + sock1.getPort() + " to " + ip2+":"+sock2.getPort());
        byte b[] = new byte[32768];
        int bytesRead = 0;
        while(bytesRead >= 0)
        {
          bytesRead = in.read(b);
          if (bytesRead > 0) {out.write(b,0,bytesRead);out.flush();}
        }
      }
      catch(Exception e)
      {
      }
      log("Closed " + ip1+":"+sock1.getPort() + " to " + ip2+":"+sock2.getPort());
      try{if (in1 != null) in1.close();}catch(Exception e) {}
      try {sock1.close();}catch(Exception e) {}
      try{Thread.sleep(500);}catch(Exception e) {}
      try {sock2.close();}catch(Exception e) {}
    }
    else if (type.equalsIgnoreCase("clientServer"))
    {
      String user = "test";
      String pass = "test";
      //load user and pass from config
      try
      {
        ServerSocket ss = null;
        if (port == 443) ss = getServerSocket(port,ip,keystore,keystorepass,keypass);
        else if (ip == null) ss = new ServerSocket(port);
        else ss = new ServerSocket(port,1000,InetAddress.getByName(ip));

        log("Listening on: "+type+" "+ip+":"+port);
        while(true)
        {
          Socket sockIN = ss.accept();
          log("1.)Got connection:"+ip+":"+port);

          log("Connecting to:"+notMacIP+":"+notMacPort);
          Socket sockOUT = new Socket(notMacIP,Integer.parseInt(notMacPort));
          if (Integer.parseInt(notMacPort) == 443)
          {
            TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() {
              public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}
              public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
              public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
            }};

            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());

            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            sockOUT = (SSLSocket)sc.getSocketFactory().createSocket(sockOUT,notMacIP,Integer.parseInt(notMacPort),true);
            ((SSLSocket)sockOUT).setUseClientMode(true);
            ((SSLSocket)sockOUT).startHandshake();
          }

          log("2.)Got connection:"+notMacIP+":"+notMacPort);
          new Thread(new HttpTunnel(null,sockIN,sockOUT,notMacIP,notMacPort,"tunnel")).start();//sock1 to sock2 read & write
          new Thread(new HttpTunnel(null,sockOUT,sockIN,notMacIP,notMacPort,"tunnel")).start();//and sock2 to sock1 read & write
        }
      }
      catch(Exception e)
      {
        log(e);
      }
    }
    else if (type.equalsIgnoreCase("mainServer"))
    {
      try
      {
        ServerSocket ss = null;
        if (port == 443) ss = getServerSocket(port,ip,keystore,keystorepass,keypass);
        else if (ip == null) ss = new ServerSocket(port);
        else ss = new ServerSocket(port,1000,InetAddress.getByName(ip));

        log("Listening on: "+type+" "+ip+":"+port);
        while(true)
        {
          try
          {
            Socket sockIN = ss.accept();
            BufferedInputStream bi = new BufferedInputStream(sockIN.getInputStream());
            Vector headers = getHeaders(bi);
            String host = "";
            int skipBytes = 0;
            for (int x=0; x<headers.size(); x++)
            {
              String data = headers.elementAt(x).toString();
              if (data.toUpperCase().startsWith("HOST:"))
              {
                host = data.substring(data.indexOf(":")+1).trim();
                if (host.indexOf(":") >= 0) host = host.substring(0,host.indexOf(":"));
              }
            }
            //validate username.  if ok, continue.
            boolean ok = true;
            if (ok && (host.toUpperCase().endsWith(".MAC.COM") || host.toUpperCase().endsWith(".APPLE.COM")))
            {
              bi.skip(skipBytes);
              Socket sockOUT = new Socket("127.0.0.1",53443);

              TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}
                public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
              }};

              SSLContext sc = SSLContext.getInstance("SSL");
              sc.init(null, trustAllCerts, new java.security.SecureRandom());
              HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
              sockOUT = (SSLSocket)sc.getSocketFactory().createSocket(sockOUT,notMacIP,53443,true);
              ((SSLSocket)sockOUT).setUseClientMode(true);
              ((SSLSocket)sockOUT).startHandshake();

              new Thread(new HttpTunnel(bi,sockIN,sockOUT,notMacIP,notMacPort,"tunnel")).start();//sock1 to sock2 read & write
              new Thread(new HttpTunnel(null,sockOUT,sockIN,notMacIP,notMacPort,"tunnel")).start();//and sock2 to sock1 read & write
            }
            else
            {
              sockIN.close();
            }
          }
          catch(Exception ee)
          {
            log(ee);
          }
        }
      }
      catch(Exception e)
      {
        log(e);
      }
    }
  }

  public Vector getHeaders(BufferedInputStream original_is) throws Exception
  {
    Vector headers = new Vector();
    byte headerBytes[] = new byte[32768];

    String headerStr = "";
    int bytesRead = 0;
    original_is.mark(256000);
    while (bytesRead >= 0)
    {
      bytesRead = original_is.read(headerBytes);
      if (bytesRead > 0)
      {
        headerStr += new String(headerBytes,0,bytesRead);
      }
      if (headerStr.indexOf("\r\n\r\n") >= 0 || headerStr.length() > 128000) break;
    }

    if (headerStr.equals(""))
    {
      return null;
    }
    else
    {
      bytesRead = headerStr.indexOf("\r\n\r\n")+4;
      original_is.reset();
      headerStr = headerStr.substring(0,bytesRead).trim();
      headerStr = NMCommon.url_decode(headerStr);
      BufferedReader bsr = new BufferedReader(new StringReader(headerStr));
      String data = "";
      while ((data=bsr.readLine()) != null)
      {
        data = data.trim();
        headers.addElement(data);
      }
    }

    return headers;
  }

  public ServerSocket getServerSocket(int serverPort, String listen_ip, String KEYSTORE, String keystorepass, String keypass) throws Exception
  {
    ServerSocketFactory ssf = getSSLContext(KEYSTORE,keystorepass,keypass,"SSLv3").getServerSocketFactory();
    SSLServerSocket serverSocket = null;
    if (listen_ip == null) serverSocket = (SSLServerSocket) ssf.createServerSocket(serverPort,serverPort);
    else serverSocket = (SSLServerSocket) ssf.createServerSocket(serverPort,1000,InetAddress.getByName(listen_ip));
    serverSocket.setEnabledCipherSuites(serverSocket.getSupportedCipherSuites());
    serverSocket.setNeedClientAuth(false);
    return serverSocket;
  }

  public SSLContext getSSLContext(String KEYSTORE, String keystorepass, String keypass, String secureType) throws Exception
  {
    Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    KeyStore keystore = KeyStore.getInstance("JKS");
    keystore.load(new FileInputStream(KEYSTORE), keystorepass.toCharArray());

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(keystore, keypass.toCharArray());

    SSLContext sslc = SSLContext.getInstance(secureType);
    sslc.init(kmf.getKeyManagers(), null, null);
    return sslc;
  }

  static public void log(String s)
  {
    try
    {
      if (log == null)
      {
        log = new RandomAccessFile("/Library/Application Support/NotMac/httpTunnel.log","rw");;
        log.seek(log.length());
      }
      log.write((s+"\r\n").getBytes());
      System.out.println(s);
    }
    catch(Exception e)
    {
    }
  }

  static public void log(Exception e)
  {
    StackTraceElement ste[] = e.getStackTrace();
    for (int x=0; x<ste.length; x++)
    {
      log(ste[x].getClassName()+"."+ste[x].getMethodName()+":"+ste[x].getLineNumber()+"\r\n");
    }
    e.printStackTrace();
  }

}
TOP

Related Classes of com.notmacchallenge.HttpTunnel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.