I'm trying to write a tcp stream 'tunnel' (similar to the ones SSH handles by default) but with one exception, I have to rewrite certain information as it flows through.
I'm certain there's something similar out there but I have not been able to find it. I have three main questions:
Edit: The information being rewritten would be just the initial authentication.
A straight pass-through tunnel with logging can be cobbled together from existing (or easily found) utilities.
socat -v -x tcp-l:8080,fork,reuseaddr tcp:localhost:80 2>log
In this example, connecting to http://localhost:8080/
will pass through to http://localhost:80/
, and log data transferred to log
.
The tool TCPreen is specialized for this exact purpose.
If you have root privileges, there are many analyzers such as tcpdump and tcpflow which can capture packets directly from the network, without having to redirect traffic.
socat
can also do some very basic stream modification with the ,cr
and ,crnl
options, which strip/add/replace \r
characters.
In any case, back to the original question… It's been ages since I've written any Java, and this is totally untested, but a tunnel that can modify traffic before retransmitting isn't difficult.
public class ForwardAndChangeCaseThread extends Thread {
private Socket in, out;
public ForwardAndChangeCaseThread(Socket in, Socket out) {
this.in = in; this.out = out;
}
public void run() {
byte[] buf = new byte[4096];
InputStream in = this.in.getInputStream();
OutputStream out = this.out.getOutputStream();
int count;
while ((count = in.read(buf)) > 0) {
for (int i = 0; i < count; i++)
if (buf[i] >= 0x40) buf[i] ^= 0x20;
out.write(buf, 0, count);
}
}
}
public class TcpForwarder {
public static void main(String[] args) {
ServerSocket listen = new ServerSocket(8080, 1);
for (;;) {
Socket local = listen.accept();
Socket remote = new Socket("localhost", 80);
new ForwardAndChangeCaseThread(local, remote).start();
new ForwardAndChangeCaseThread(remote, local).start();
}
}
}