www.pudn.com > encryption.rar > proxy.java
package encryption;
/**
* proxy -- a proxy server for telnet
* --
* $Id: proxy.java,v 1.4 1997/05/27 13:09:46 leo Exp $
* $timestamp: Tue May 27 15:08:19 1997 by Matthias L. Jugel :$
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* "The Java Telnet Applet" is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
***********************************************************************
MODIFIED BY CHRISTOFOROS PIRILLOS - MARCH 1999
Modified so it can redirect encrypted communication streams.
The original proxy takes as input 2 ports, establishes connection to
both, creates i/o streams from the sockets and starts the redirection.
I changed it, so it accepts on one side of the connection, a socket, an
input stream and an output stream. So it only has to create the socket
for the local port. The nature of the i/o streams is totaly transparent to
the proxy server.
*/
import java.net.*;
import java.io.*;
import java.util.*;
/**
* proxy class -- implements a proxy server to redirect network access
* @author Matthias L. Jugel, Marcus Meißner, Christoforos Pirillos
* @version $Id: proxy.java,v 1.4 1997/05/27 13:09:46 leo Exp $
* Modified to use encrypted streams by Christoforos Pirillos. MARCH 1999
*/
public class proxy implements Runnable
{
String remoteHost;
int localPort, remotePort;
Socket localSocket;
Thread listener, connection;
//C.Pirillos added this two variables.
InputStream encryptedInputStream;
OutputStream encryptedOutputStream;
/**
* Initialize the proxy
* @param lport local port
* @param raddr address of the destination
* @param rport port on the destination host
* @param in Encrypted InputStream
* @param out Encrypted OutputStream
* @param s local Socket
*/
//C.Pirillos
//changed this method to accept an InputStream, an OutputStream and a
//Socket
public proxy(int lport, String raddr, int rport,
String name, InputStream in, OutputStream out, Socket s)
{
localPort = lport;
remoteHost = raddr;
remotePort = rport;
//C.Pirillos
//added the next 3 lines
localSocket = s;
encryptedInputStream=in;
encryptedOutputStream=out;
log("destination host is "+remoteHost+" at port "+remotePort);
log("listening on port "+localPort);
listener = new Thread(this);
listener.setPriority(Thread.MIN_PRIORITY);
listener.start();
}
/**
* Cycle around until an error occurs and wait for incoming connections.
* An incoming connection will create two redirectors. One for
* local-host - destination-host and one for destination-host - local-host.
*/
public void run()
{
log("accepted connection from "+ localSocket);
try {
Socket destinationSocket = new Socket(remoteHost, remotePort);
log("connecting "+ localSocket.getInetAddress().getHostName() +" <-> "+
destinationSocket.getInetAddress().getHostName());
//C.Pirillos
//Modified the next two lines
//Original: redirector r1 = new redirector(localSocket,destinationSocket);
// redirector r2 = new redirector(destinationSocket,localSocket);
//This makes the proxy to redirect the encryptedInputStream to the
//OutputStream extracted from the destinationSocket, and the InputStream
//extracted from the destinationSocket to the encryptedOutputStream.
//Originally, all streams are extracted from the Sockets
redirector r1 = new redirector(encryptedInputStream, destinationSocket);
redirector r2 = new redirector(destinationSocket,encryptedOutputStream);
r1.couple(r2);
r2.couple(r1);
} catch(Exception e) {
e.printStackTrace();
System.err.println("proxy: error: cannot create sockets");
try {
DataOutputStream os = new DataOutputStream(encryptedOutputStream);
os.writeChars("Remote host refused connection.\n");
localSocket.close();
} catch(IOException ioe) { ioe.printStackTrace(); }
}
}
private void log(String msg)
{
System.out.println("proxy: ["+new Date()+"] "+msg);
}
}
/**
* A class useful for the proxy server.
* This class takes over control of newly created connections and redirects
* the data streams.
*/
class redirector implements Runnable
{
private redirector companion = null;
private Socket localSocket;
private InputStream from;
private OutputStream to;
private byte[] buffer = new byte[4096];
/**
* redirector gets the streams from sockets
*/
//C.Pirillos
//Originally there was only one redirector method.
//Since I have changed the signature of the method, it can't be used
//symmetricaly anymore, so I have to overload it.
//Originally this method took two Sockets as input.
public redirector(InputStream in, Socket remote)
{
try {
localSocket = remote;
from=in;
to = localSocket.getOutputStream();
} catch(Exception e) {
System.err.println("redirector: cannot get streams");
}
}
public redirector(Socket local, OutputStream out)
{
try {
localSocket = local;
from = localSocket.getInputStream();
to = out;
} catch(Exception e) {
System.err.println("redirector: cannot get streams");
}
}
/**
* couple this redirector instance with another one (usually the other
* direction of the connection)
*/
public void couple(redirector c) {
companion = c;
Thread listen = new Thread(this);
listen.start();
}
/**
* decouple us from our companion. This will let this redirector die after
* exiting from run()
*/
public void decouple() { companion = null; }
/**
* read data from the input and write it to the destination stream until
* an error occurs or our companion is decoupled from us
*/
public void run()
{
int count;
try {
while(companion != null) {
if((count = from.read(buffer)) < 0)
break;
to.write(buffer, 0, count);
//C.Pirillos
//For some reason when using the encrypted streams, you have to implicitly
//flush the outputStream
to.flush();
}
} catch(Exception e) {
System.err.println("redirector: connection lost");
}
try {
from.close();
to.close();
localSocket.close();
// is our companion dead? no, then decouple, because we die
if(companion != null) companion.decouple();
} catch(Exception io) {
System.err.println("redirector: error closing streams and sockets");
io.printStackTrace();
}
}
}