import java.io.*;
import krb5.lib.*;
import krb5.lib.util.*;
import krb5.lib.ccache.*;
import krb5.lib.util.*;

public class krbauth {
    public static void main(String [] args) {
	String realm = "ATHENA.MIT.EDU"; 
	String kdc = "kerberos.mit.edu"; 
	String principal = "host/i-fear-reorgs.mit.edu";
	String keyfile = "/etc/krb5.keytab"; 
	
	// A innocent victum service to get a service ticket for as a test.
	// This service MUST already exist in kerberos, if it doesn't you're simply
	// going to get a doesn't exist exception.
	String service = "host/orca.mit.edu"; // Hi scott!
	
	try {
	    PrincipalName princname = new PrincipalName(principal, realm);
	    CCacheFactory ccacheFactory = CCacheFactory.getFactory();
	    CredentialsCache ccache =
	    ccacheFactory.newCCacheInstance("VmCCacheImpl");
	    KeytabFile keytab = new KeytabFile(keyfile); 
	    keytab.open(); // Must always open the keytab first before calling other funcs
	    // Lets start the auth sequence, by sending an authentication request to the
	    // kdc. 
	    KrbAsReq as_req = new KrbAsReq(new KDCOptions(),
					   princname,
					   null,
					   null,
					   null,
					   null,
					   null,
					   new HostAddresses(),
					   null);
	    as_req.send(kdc);
	    // We got a reply! Lets decode the authenticator. Here we're using the	  
	    // keytab's encryption key as the password. 
	    KrbAsRep as_rep = as_req.getKrbAsRep(keytab.getEncryptionKey(princname));
	    // Lets pull the creds the kdc sent us out of the reply now that we've
	    // decrypted it.
	    Credentials creds = as_rep.creds(); 
	    // Ok we've got our tgt, lets get a service ticket for our test entity
	    KrbTgsReq tgs_req = new KrbTgsReq(new KDCOptions(),
					      creds,
					      new ServiceName(service, realm),
					      null,
					      null,
					      null,
					      null,
					      null,
					      null,
					      null,
					      null);
	    // Send it off and get the response and creds
	    tgs_req.send(kdc);
	    KrbTgsRep tgs_rep = tgs_req.getKrbTgsRep(creds);
	    ccache.add(creds);
	    // Wooo we're done!
	    // Lets look at the contents of our initial creds. This should contain
	    // the target principal we started with and the krbtgt as the service.
	    System.out.println("The kerberos TGT");
	    System.out.println("Principal name: " + creds.client());
	    System.out.println("Server name: " + creds.server() + "\n");
    
	    // Now lets examine the service creds we recieved. This should contain 
	    // the same target principal we started with and the service we chose to get
	    // tickets for as the server.
	    System.out.println("The kerberos service ticket");
	    System.out.println("Principal name: " + tgs_rep.creds().client());
	    System.out.println("Server name: " + tgs_rep.creds().server());

	    // Destroy our credentials and cleanup.
	    creds.destroy();
	    tgs_rep.creds().destroy();
	    keytab.close();
	}
	catch (KrbException e) {
	    System.out.println(e.krbErrorMessage() + "\n");
	}
	catch (Exception e) {
	    System.out.println(e);
	}
    }
} 