package ssh;

import rmi.*;
import proof.*;
import sdsi.*;
import ssh.*;
import sdsi.sexp.*;

import Tools.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;
import java.security.interfaces.*;

/**
 * A class to test plugging SSH in under RMI using JDK1.2's
 * SocketFactory stuff. (I had gotten this entire arrangement working
 * once before by seriously rewiring JDK1.1.x's RMI; then they made
 * that fix obsolete :v/ That code is in class {@link ssh.SecureRMIProtocol}.)
 */
public class RMITest
	extends UnicastRemoteObject
	implements Hello {

	static SSHClientSocketFactory foo(SSHClientSocketFactory bar) {
		Class y = SfServerRef.class;
		return bar;
	}

	SDSIPrincipal serverIssuer;
	Tag requestTag;

	RMITest(SSHContext context, SDSIPrincipal serverIssuer)
		throws RemoteException {
		super(0, foo(new SSHClientSocketFactory(context)),
			new SSHServerSocketFactory(context));
		try {
			this.serverIssuer = serverIssuer;
			SexpList sl = (new SexpList()).append("tag").append("blue");
			requestTag = new Tag(sl);
			log.log("RMITest extends Hello instantiated.");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public String hello()
		throws RemoteException {
		ssh.RSA.RSAKey k = SSHSocket.whoCalledMe();
		log.log(k.hashCode()+" says hello()");
		SDSIRSAPublicKey subject = new SDSIRSAPublicKey(k);

		try {
			Proof proof = OneLineCacheRecipient.getCachedProof(subject);
			if (proof==null) {
				throw new InvalidProofException("no proof found");
			}
			proof.verify(serverIssuer, subject, requestTag);
			return "hullo!";
		} catch (InvalidProofException ex) {
			ProofRecipient pr = OneLineCacheRecipient.getRecipient();
			throw new SfNeedAuthorizationException(serverIssuer,
				subject, requestTag, pr);
		}
	}

	static Log log = new Log();
	static {
		log.setPrefix("RMITest: ");
		log.addLevel("default");
	}

	public static void main(String[] args) {
		try {
			Class x = SfServerRef.class;

			Options opts = new Options(args) {
				public void defineOptions() {
		programName = "RMITest";
				}
			};

			if (System.getSecurityManager()==null) {
				System.setSecurityManager(new RMISecurityManager());
			}

			InetAddress thisHost = InetAddress.getLocalHost();
			SSHContext context = SSHContext.getDefault();
			log.log("Server key hash = "
				+context.publicKey.hashCode());

			SDSIKeyPair kp = (SDSIKeyPair)
				KeyTools.processFilename("certs-client/0.keypair");
			SDSIRSAPublicKey serverIssuer =
				(SDSIRSAPublicKey) kp.getPublicKey();
			Naming.rebind("//"+thisHost.getHostName()+"/Hello",
				new RMITest(context, serverIssuer));

			log.log("Hello registered in RMI");

			log.log("Calling self.");
			Hello helloObject = (Hello) Naming.lookup(
				"//"+thisHost.getHostName()+"/Hello");
			String val = helloObject.hello();
			log.log("Returned "+val);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}
