www.pudn.com > encryption.rar > AuthServer.java


/*
Christoforos Pirillos @ Villanova University - May 1999
based on code from the book "Java Network Programming" by Hughes
*/
package encryption;

import java.io.*;
import java.net.*;
import java.util.*;

/**Implements an authenticating secure server*/
public class AuthServer  {

Socket s;
int port;
protected X9_17KeyGen keys;
protected Hashtable passwords, ivs;

// used to create a dummy AuthServer, in order to add users in the
//database

public AuthServer ()  {
	passwords=new Hashtable();
	ivs=new Hashtable();
}

/**Accepts a random seedText which uses to generate the keys, and a port
number to start listening for incoming connections*/

public AuthServer (String seedText, int port) throws IOException {
	this.port=port;
	keys=new X9_17KeyGen (Password.keyFromPassword(seedText),
			Password.nextKeyFromPassword (seedText));
	passwords=new Hashtable();
	ivs=new Hashtable();
	
//open the passfile and read the existing entries into the Hashtables
	try {
		BufferedReader passfile= new BufferedReader 
			( new FileReader("passfile") );
	String entry;
	try {
	while ( (entry=passfile.readLine())!=null ) {
		StringTokenizer tokens = new StringTokenizer(entry);
		String username = tokens.nextToken();
		String password = tokens.nextToken();
		byte[] iv = new byte[8];
		System.out.println(username);
		Crypt.longToBytes(Long.parseLong(
						tokens.nextToken()),
						iv, 0);
		passwords.put(username,new Long (password) );
		ivs.put (username, iv);
	}
	}catch (IOException e) {}
	
	passfile.close();

	} catch (FileNotFoundException e) {
		System.out.println(e);
		System.exit(0);
	}
	

}


/**Accepts a username and password and puts them into the database*/

public void setPassword (String user, String password) throws IOException
{
	passwords.put (user,new Long
		(Password.keyFromPassword(password)));
	byte[] iv=new byte[8];
	Crypt.longToBytes (Password.nextKeyFromPassword(password),iv,0);
	ivs.put(user,iv);

// open the password file and store the pairs
	FileWriter passfile = new FileWriter("passfile",true);
	Enumeration users = passwords.keys();
	while (users.hasMoreElements()) {
		Object key = users.nextElement();
		String entry =
				key.toString()+" "+
				 passwords.get(key).toString()+" "+
			Long.toString( Crypt.bytesToLong
					((byte[])ivs.get(key),0)) +
				"\n";

		System.out.println(entry);		
		passfile.write(entry,0,entry.length());

	}
	passfile.close();	
}

/**The authentication of the client takes place in this method. It accepts
two streams and the Socket the client is connected on. If authentication
fails, it will throw an exception.*/

public void authenticate (InputStream i, OutputStream o, Socket s) throws
			IOException {
	String user = new DataInputStream(i).readUTF();
	long sessionKey=DES.paritySet (keys.nextKey());
	new DataOutputStream(o).writeLong(encodeKey(user,sessionKey));
	o.flush();
	Cipher sessionDES = new CBCCipher (new DES(sessionKey),
				(byte[])ivs.get(user));
	byte[] temp = new byte[8];
	new DataInputStream(i).readFully(temp);
	long challenge = Crypt.bytesToLong(sessionDES.decipher(temp),0);
	Crypt.longToBytes (challenge+1, temp, 0);
	o.write (sessionDES.encipher(temp));
	try {
		new DataInputStream(i).readFully(temp);
		long
		complete=Crypt.bytesToLong(sessionDES.decipher(temp),0);
		if (complete != challenge + 2)
			throw new AuthException("Incorrect Password.");
	   }catch (EOFException ex) {
		throw new AuthException ("Challenge/response failed.");
	  }
	
	InputStream sessionI=new CipherInputStream(i,sessionDES);
	OutputStream sessionO=new CipherOutputStream (o,sessionDES);
	accept (user, sessionI, sessionO, s);
}

/**Creates a new proxy server that will redirect the secure streams to the
telnet port (port 23)*/
protected void accept (String name, InputStream i, OutputStream o, Socket s)
 {
	new proxy(port, "localhost",23,name,i,o,s);
}

/**Encrypts a session key with the user's password*/ 
protected long encodeKey (String user, long key) throws AuthException {
	if (!passwords.containsKey(user))
		throw new AuthException("User not registered.");
	Long password = (Long)passwords.get(user);
	DES des=new DES (password.longValue());
	return des.encrypt(key);
}

/** Starts the Server at the port given on the command line and also uses
the second command line argument as seed text*/

public static void main (String args[]) throws IOException {
	if (args.length < 2)
		throw new RuntimeException 
		("Syntax: AuthServer  {seed text}\n"+
		" -user  ");	

// if a user-password is given, put it in the passfile and exit

	if (args[0].equals("-user")) {
	AuthServer dummyauth = new AuthServer();
		dummyauth.setPassword(args[1],args[2]);
		System.exit(0);
		}
		
	int port = Integer.parseInt(args[0]);
	ServerSocket server = new ServerSocket(port);
	StringBuffer seed=new StringBuffer();
	for (int i=1;i