-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
1,095 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import java.util.Properties; | ||
|
||
/** | ||
* Process command line arguments of the form "--argument=value". | ||
* Store arguments as in Arguments object (derived from Properties). | ||
* | ||
*/ | ||
|
||
public class Arguments extends Properties { | ||
public void setDefault(String arg, String value) { | ||
this.setProperty(arg, value); | ||
} | ||
public void loadArguments(String args[]) throws IllegalArgumentException { | ||
for(String argument : args) { | ||
if(!argument.startsWith("--")) { | ||
throw new IllegalArgumentException("Argument does not start with \"--\""); | ||
} | ||
|
||
String[] keyValue = argument.substring(2).split("=", 2); | ||
|
||
if(keyValue.length != 2 || keyValue[1].length() < 1) { | ||
throw new IllegalArgumentException("Argument \"" + keyValue[0] + "\"%s needs a value"); | ||
} | ||
this.setProperty(keyValue[0], keyValue[1]); | ||
} | ||
} | ||
|
||
public String get(String arg) { | ||
return this.getProperty(arg); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/** | ||
* Port forwarding client. Forward data | ||
* between two TCP ports. Based on Nakov TCP Socket Forward Server | ||
* and adapted for IK2206. | ||
* | ||
* See original copyright notice below. | ||
* (c) 2018 Peter Sjodin, KTH | ||
*/ | ||
|
||
/** | ||
* Nakov TCP Socket Forward Server - freeware | ||
* Version 1.0 - March, 2002 | ||
* (c) 2001 by Svetlin Nakov - http://www.nakov.com | ||
*/ | ||
|
||
|
||
import javax.crypto.BadPaddingException; | ||
import javax.crypto.IllegalBlockSizeException; | ||
import javax.crypto.NoSuchPaddingException; | ||
import java.lang.AssertionError; | ||
import java.lang.IllegalArgumentException; | ||
import java.lang.Integer; | ||
import java.security.InvalidKeyException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.cert.CertificateException; | ||
import java.security.spec.InvalidKeySpecException; | ||
import java.util.ArrayList; | ||
import java.net.ServerSocket; | ||
import java.net.Socket; | ||
import java.net.InetAddress; | ||
import java.net.UnknownHostException; | ||
import java.io.IOException; | ||
import java.io.FileInputStream; | ||
|
||
public class ForwardClient | ||
{ | ||
private static final boolean ENABLE_LOGGING = true; | ||
public static final int DEFAULTSERVERPORT = 2206; | ||
public static final String DEFAULTSERVERHOST = "localhost"; | ||
public static final String PROGRAMNAME = "ForwardClient"; | ||
|
||
private static Arguments arguments; | ||
private static int serverPort; | ||
private static String serverHost; | ||
private static Handshake client = new Handshake(); | ||
|
||
private static void doHandshake() throws IOException, CertificateException, BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException { | ||
|
||
/* Connect to forward server server */ | ||
System.out.println("Connect to " + arguments.get("handshakehost") + ":" + Integer.parseInt(arguments.get("handshakeport"))); | ||
Socket socket = new Socket(arguments.get("handshakehost"), Integer.parseInt(arguments.get("handshakeport"))); | ||
|
||
/* This is where the handshake should take place */ | ||
|
||
client.sendHello("ClientHello", arguments.get("usercert"), socket); | ||
client.verifyHello(arguments.get("cacert"), socket); | ||
client.clientForward("Forward", arguments.get("targethost"), arguments.get("targetport"), socket); | ||
client.receiveSession(socket, arguments.get("key")); | ||
socket.close(); | ||
|
||
/* | ||
* Fake the handshake result with static parameters. | ||
*/ | ||
|
||
/* This is to where the ForwardClient should connect. | ||
* The ForwardServer creates a socket | ||
* dynamically and communicates the address (hostname and port number) | ||
* to ForwardClient during the handshake (ServerHost, ServerPort parameters). | ||
* Here, we use a static address instead. | ||
*/ | ||
serverHost = Handshake.serverHost; | ||
serverPort = Handshake.serverPort; | ||
} | ||
|
||
/* | ||
* Let user know that we are waiting | ||
*/ | ||
private static void tellUser(ServerSocket listensocket) throws UnknownHostException { | ||
System.out.println("Client forwarder to target " + arguments.get("targethost") + ":" + arguments.get("targetport")); | ||
System.out.println("Waiting for incoming connections at " + | ||
InetAddress.getLocalHost().getHostAddress() + ":" + listensocket.getLocalPort()); | ||
} | ||
|
||
/* | ||
* Set up client forwarder. | ||
* Run handshake negotiation, then set up a listening socket and wait for user. | ||
* When user has connected, start port forwarder thread. | ||
*/ | ||
static public void startForwardClient() throws IOException, CertificateException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException { | ||
|
||
doHandshake(); | ||
|
||
// Wait for client. Accept one connection. | ||
|
||
ForwardServerClientThread forwardThread; | ||
ServerSocket listensocket; | ||
|
||
/* Create a new socket. This is to where the user should connect. | ||
* ForwardClient sets up port forwarding between this socket | ||
* and the ServerHost/ServerPort learned from the handshake */ | ||
listensocket = new ServerSocket(); | ||
/* Let the system pick a port number */ | ||
listensocket.bind(null); | ||
/* Tell the user, so the user knows where to connect */ | ||
tellUser(listensocket); | ||
|
||
Socket clientSocket = listensocket.accept(); | ||
String clientHostPort = clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort(); | ||
log("Accepted client from " + clientHostPort); | ||
|
||
forwardThread = new ForwardServerClientThread(clientSocket, serverHost, serverPort, client.getSessionKey(), client.getSessionIV()); | ||
forwardThread.start(); | ||
} | ||
|
||
/** | ||
* Prints given log message on the standart output if logging is enabled, | ||
* otherwise ignores it | ||
*/ | ||
public static void log(String aMessage) | ||
{ | ||
if (ENABLE_LOGGING) | ||
System.out.println(aMessage); | ||
} | ||
|
||
static void usage() { | ||
String indent = ""; | ||
System.err.println(indent + "Usage: " + PROGRAMNAME + " options"); | ||
System.err.println(indent + "Where options are:"); | ||
indent += " "; | ||
System.err.println(indent + "--targethost=<hostname>"); | ||
System.err.println(indent + "--targetport=<portnumber>"); | ||
System.err.println(indent + "--handshakehost=<hostname>"); | ||
System.err.println(indent + "--handshakeport=<portnumber>"); | ||
System.err.println(indent + "--usercert=<filename>"); | ||
System.err.println(indent + "--cacert=<filename>"); | ||
System.err.println(indent + "--key=<filename>"); | ||
} | ||
|
||
/** | ||
* Program entry point. Reads arguments and run | ||
* the forward server | ||
*/ | ||
public static void main(String[] args) throws IOException, CertificateException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException { | ||
try { | ||
arguments = new Arguments(); | ||
arguments.setDefault("handshakeport", Integer.toString(DEFAULTSERVERPORT)); | ||
arguments.setDefault("handshakehost", DEFAULTSERVERHOST); | ||
arguments.loadArguments(args); | ||
if (arguments.get("targetport") == null || arguments.get("targethost") == null) { | ||
throw new IllegalArgumentException("Target not specified"); | ||
} | ||
} catch(IllegalArgumentException ex) { | ||
System.out.println(ex); | ||
usage(); | ||
System.exit(1); | ||
} | ||
startForwardClient(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/** | ||
* Port forwarding server. Forward data | ||
* between two TCP ports. Based on Nakov TCP Socket Forward Server | ||
* and adapted for IK2206. | ||
* | ||
* Original copyright notice below. | ||
* (c) 2018 Peter Sjodin, KTH | ||
*/ | ||
|
||
/** | ||
* Nakov TCP Socket Forward Server - freeware | ||
* Version 1.0 - March, 2002 | ||
* (c) 2001 by Svetlin Nakov - http://www.nakov.com | ||
*/ | ||
|
||
import java.lang.AssertionError; | ||
import java.lang.Integer; | ||
import java.util.ArrayList; | ||
import java.net.ServerSocket; | ||
import java.net.Socket; | ||
import java.net.InetAddress; | ||
import java.net.InetSocketAddress; | ||
import java.net.UnknownHostException; | ||
import java.io.IOException; | ||
import java.io.FileInputStream; | ||
import java.util.Properties; | ||
import java.util.StringTokenizer; | ||
|
||
public class ForwardServer | ||
{ | ||
private static final boolean ENABLE_LOGGING = true; | ||
public static final int DEFAULTSERVERPORT = 2206; | ||
public static final String DEFAULTSERVERHOST = "localhost"; | ||
public static final String PROGRAMNAME = "ForwardServer"; | ||
private static Arguments arguments; | ||
|
||
|
||
private ServerSocket handshakeSocket; | ||
|
||
private ServerSocket listenSocket; | ||
private String targetHost; | ||
private int targetPort; | ||
private static Handshake server = new Handshake(); | ||
/** | ||
* Do handshake negotiation with client to authenticate, learn | ||
* target host/port, etc. | ||
*/ | ||
private void doHandshake() throws UnknownHostException, IOException, Exception { | ||
|
||
Socket clientSocket = handshakeSocket.accept(); | ||
String clientHostPort = clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort(); | ||
Logger.log("Incoming handshake connection from " + clientHostPort); | ||
|
||
/* This is where the handshake should take place */ | ||
|
||
server.verifyHello(arguments.get("cacert"), clientSocket); | ||
server.sendHello("ServerHello", arguments.get("usercert"), clientSocket); | ||
server.forwardVerify(clientSocket); | ||
|
||
/* | ||
* Fake the handshake result with static parameters. | ||
*/ | ||
|
||
/* listenSocket is a new socket where the ForwardServer waits for the | ||
* client to connect. The ForwardServer creates this socket and communicates | ||
* the socket's address to the ForwardClient during the handshake, so that the | ||
* ForwardClient knows to where it should connect (ServerHost/ServerPort parameters). | ||
* Here, we use a static address instead (serverHost/serverPort). | ||
* (This may give "Address already in use" errors, but that's OK for now.) | ||
*/ | ||
listenSocket = new ServerSocket(); | ||
listenSocket.bind(new InetSocketAddress(Handshake.serverHost, Handshake.serverPort)); | ||
server.session("Session", Handshake.serverHost, String.valueOf(Handshake.serverPort), clientSocket); | ||
clientSocket.close(); | ||
/* The final destination. The ForwardServer sets up port forwarding | ||
* between the listensocket (ie., ServerHost/ServerPort) and the target. | ||
*/ | ||
targetHost = Handshake.targetHost; | ||
targetPort = Handshake.targetPort; | ||
} | ||
|
||
/** | ||
* Starts the forward server - binds on a given port and starts serving | ||
*/ | ||
public void startForwardServer() | ||
//throws IOException | ||
throws Exception | ||
{ | ||
|
||
// Bind server on given TCP port | ||
int port = Integer.parseInt(arguments.get("handshakeport")); | ||
try { | ||
handshakeSocket = new ServerSocket(port); | ||
} catch (IOException ioe) { | ||
throw new IOException("Unable to bind to port " + port + ": " + ioe); | ||
} | ||
|
||
log("Nakov Forward Server started on TCP port " + port); | ||
|
||
// Accept client connections and process them until stopped | ||
while(true) { | ||
ForwardServerClientThread forwardThread; | ||
|
||
doHandshake(); | ||
|
||
forwardThread = new ForwardServerClientThread(this.listenSocket, this.targetHost, this.targetPort, server.getSessionKey(), server.getSessionIV()); | ||
forwardThread.start(); | ||
} | ||
} | ||
|
||
/** | ||
* Prints given log message on the standart output if logging is enabled, | ||
* otherwise ignores it | ||
*/ | ||
public void log(String aMessage) | ||
{ | ||
if (ENABLE_LOGGING) | ||
System.out.println(aMessage); | ||
} | ||
|
||
static void usage() { | ||
String indent = ""; | ||
System.err.println(indent + "Usage: " + PROGRAMNAME + " options"); | ||
System.err.println(indent + "Where options are:"); | ||
indent += " "; | ||
System.err.println(indent + "--handshakehost=<hostname>"); | ||
System.err.println(indent + "--handshakeport=<portnumber>"); | ||
System.err.println(indent + "--usercert=<filename>"); | ||
System.err.println(indent + "--cacert=<filename>"); | ||
System.err.println(indent + "--key=<filename>"); | ||
} | ||
|
||
/** | ||
* Program entry point. Reads settings, starts check-alive thread and | ||
* the forward server | ||
*/ | ||
public static void main(String[] args) | ||
throws Exception | ||
{ | ||
arguments = new Arguments(); | ||
arguments.setDefault("handshakeport", Integer.toString(DEFAULTSERVERPORT)); | ||
arguments.setDefault("handshakehost", DEFAULTSERVERHOST); | ||
arguments.loadArguments(args); | ||
|
||
ForwardServer srv = new ForwardServer(); | ||
srv.startForwardServer(); | ||
} | ||
|
||
} |
Oops, something went wrong.