Java proxy gateway available!

Aaron Williams (aaronw@eng.adaptec.com)
Fri, 9 May 1997 12:07:02 PST


I have a preliminary Java proxy client available for getting out through
a firewall. Right now it basically just emulates the Perl script, but
it will work on systems that don't support Perl. It may have some bugs
as it's just something I quickly hacked together (and my Java knowlege
is not that great yet).

I cannot write a Java gateway for the other side due to the fact that
Java will block forever when receiving on a UDP port. At least in the
OS/2 1.0.2 version interrupt() does not work to break this.

I have included the code below:

Begin UDPGateway.java
// DES Challenge gateway for going through a firewall
// Written by Aaron Williams
// aaronw@home.com
// I take no responsibility for any damage this may cause (if any)
// or any bugs in this code.
import java.net.*;
import java.net.DatagramPacket;
import java.io.*;
import java.lang.*;
import java.lang.Integer;
import java.lang.Object;
import java.lang.Thread;

public class UDPGateway
{
public static void main(String args[])
{
start(args);
}

static void start(String args[])
{
try {
if (args.length < 4) {
System.out.println("Too few arguments!");
System.out.println("Usage:");
System.out.println("java UDPGateway proxy port gateway port");

return;
}
String proxyaddr = args[0];
Integer proxyport = new Integer(args[1]);
String gateway = args[2];
Integer gatewayport = new Integer(args[3]);

System.out.println("Proxy: "+proxyaddr);
System.out.println("Proxy Port: "+proxyport.intValue());
System.out.println("Gateway: "+gateway);
System.out.println("Gateway Port: "+gatewayport.intValue());

// bind to datagram socket
DatagramSocket socket = new DatagramSocket(8669);

byte buffer[] = new byte[1480];

DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
socket.receive(packet);
Proxy proxy = new Proxy(proxyaddr, proxyport.intValue(), gateway,
gatewayport.intValue(), packet);
}
} catch (Exception ex) {
System.out.println(ex);
}
}
}

class Proxy implements Runnable
{
String gateway, proxy;
Thread thread = null;
DatagramPacket packet = null;
int proxyport, gatewayport;

public Proxy(String px, int pp, String gw, int gp, DatagramPacket dp)
{
proxy = px;
proxyport = pp;
gatewayport = gp;
packet = dp;
gateway = gw;
this.thread = new Thread(this);
this.thread.setName("Proxy thread");
this.thread.start();
}
public void run()
{
try {
byte b[] = packet.getData();
System.out.println("Packet length:"+packet.getLength());
String s = new String(b,0);
s = s.substring(0,packet.getLength());

InetAddress destaddr = packet.getAddress();
System.out.println("Source Address = "+packet.getAddress().getHostName());
//System.out.println("Source Address = "+destaddr.getHostAddress());
//System.out.println("Source Address = "+destaddr.getHostName());

Socket socket = new Socket(proxy, proxyport);
DataInputStream instream = new DataInputStream(socket.getInputStream());
PrintStream outstream = new PrintStream(socket.getOutputStream(), true);

String out = "GET http://"+gateway+":"+gatewayport+"/";

// convert spaces
// The default URL encoding scheme does not work with the gateway!
int strlen = s.length();
for (int i=0; i<strlen; i++)
{
char c = s.charAt(i);
if (c == ' ')
out += "%20";
else
out += c;
}

//String out = "GET http://"+gateway+":"+gatewayport+"/"+URLEncoder.encode(s)+" HTTP/1.0";
System.out.println(out+" HTTP/1.0");
outstream.println(out+" HTTP/1.0");
outstream.println("User-Agent: UDP2TCPGateway/1.1");
outstream.println();
String line = null;
// skip over HTTP headers
do {
line = instream.readLine();
} while (line.length() > 0);
// read the response
line = instream.readLine();
if (line == null)
return;

int bytesread=0;
int bufferindex=0;
int strindex=0;
strlen = line.length();

// This is a pain! I also have to convert the data from the
// gateway back. Looks like I only need to worry about spaces,
// though. My own gateways should be *much* better, however.

byte outbuffer[] = new byte[2048];
byte tempbuf[] = new byte[1];

do {
if (line.charAt(strindex) != '%')
{
line.getBytes(strindex, strindex+1, outbuffer, bufferindex);
System.out.print(line.substring(strindex, strindex+1));
}
else
{
if (line.substring(strindex, strindex+3).equals("%20"))
{
System.out.print(' ');
outbuffer[bufferindex] = 0x20;
strindex += 2;
}
else
{
System.out.println("Unknown % Value! Line="+line);
System.out.println("Substring = "+line.substring(strindex, strindex+3)+"###");
return;
}
}
bufferindex++;
strindex++;
} while (strindex < strlen);

bytesread=bufferindex;
System.out.println();

DatagramPacket outpacket = new DatagramPacket(outbuffer, bytesread,
destaddr, packet.getPort());

DatagramSocket udpsocket = new DatagramSocket();
try {
udpsocket.send(outpacket);
} catch (Exception ex) {
System.out.println("Exception sending datagram "+ex);
System.out.println("data = "+new String(outpacket.getData(),0));

System.out.println("addr = "+outpacket.getAddress().getHostName());
System.out.println("addr = "+destaddr.getHostName());

System.out.println("port = "+outpacket.getPort());

}

socket.close();
} catch (Exception ex) {
System.out.println(ex);
}

}
}

-----------------------------------------------------------------------------
Aaron Williams
Adaptec, Inc.
aaronw@eng.adaptec.com
(408) 945-8600 x3425
Inter-Networking Technology
Check out our web site at HTTP://www.adaptec.com/networking/ATM.html
Personal Java-based home page at HTTP://24.1.65.193 (9am-midnight PST only)