import java.io.*;
import java.net.*;
import java.util.*;
import krb5.lib.*;
import krb5.lib.util.*;
import krb5.lib.ccache.*;

class jkinit {
    
    static void printUsage() {
        System.out.println("Usage: java jkinit -h | -? | [-l lifetime] [-r renewable_life] [-f] [-p]");
        System.out.println("\t\t[-s start_time] [-S target_service] [-k [-t keytab_file]]");
        System.out.println("\t\t[-R] [-v] [-c cache_name] [principal]");
        System.out.println();
        System.out.println("\t-h and -? display help");
        System.out.println("\t-l lifetime");
        System.out.println("\t-r renewable_life");
        System.out.println("\t-f sets forwardable");
        System.out.println("\t-p sets proxiable");
        System.out.println("\t-s <start_time> set the ticket start time");
        System.out.println("\t-S target_service");
        System.out.println("\t-k");
        System.out.println("\t-t keytab_file");
        System.out.println("\t-R");
        System.out.println("\t-v");
        System.out.println("\t-c cache_name");
    }

	public static void main(String args[]) {
	    String principal = null;
        String cacheName = null;
        
	    Getopt getopt = new Getopt("l:r:s:S:t:c:fhkpRv?", args);
	    if (getopt.invalidOptions()) {
	            System.out.println("jkinit: invalid option");
	            printUsage();
	            return;
	    }
	    
	    Dictionary opts = getopt.getOptTable();
	    Enumeration optsEnum = opts.keys();
	    while (optsEnum.hasMoreElements()) {
	        String opt = (String)optsEnum.nextElement();
	        if (opt.equals("h") || opt.equals("?")) {
	            printUsage();
	            return;
	        }
	        if (opt.equals("c")) {
	            cacheName = (String)opts.get("c");
	            if (cacheName == null || cacheName.length() == 0) {
	                printUsage();
	                return;
	            }
	        }
	    }

	    String[] trailingArgs = getopt.getTrailingArgs();
	    if (trailingArgs.length > 1) {
	        System.out.println("jkinit: too many args");
	        printUsage();
	        return;
	    }
	    if (trailingArgs.length > 0)
	        principal = trailingArgs[0];

	    try {
	        if (cacheName == null)
	            cacheName = Config.getDefaultCredentialsCacheName();
	        CredentialsCache ccache = Config.getCredentialsCache(cacheName);
	        
	        if (principal == null) {
	            PrincipalName principalName = ccache.getPrimaryPrincipal();
	            if (principalName != null)
	                principal = principalName.toString();
	            else {
	                System.out.println("jkinit: Unable to identify user from credentials cache");
	                return;
	            }
	        } else {
	            PrincipalName principalName = new PrincipalName(principal);
	            if (principalName.getRealm() == null) {
	                if (Config.DEFAULT_REALM != null) {
	                    principalName.setRealm(Config.DEFAULT_REALM);
	                    principal = principalName.toString();
	                } else {
	                    System.out.println("jkinit: User must be specified with realm, e.g., user@realm");
	                    return;
	                }
	            }
	        }
	        
	        System.out.print("Password for " + principal + ": ");
			BufferedReader inp = new BufferedReader(new InputStreamReader(System.in));
	        StringBuffer pw = new StringBuffer(inp.readLine());
	        Credentials initialCreds = ccache.getInitialCredentials(principal, pw);
	        if (initialCreds == null)
	            System.out.println("jkinit: Passowrd incorrect");
	        
	    } catch (KrbException e) {
	        if (e.returnCode() == Krb5.KRB_AP_ERR_BAD_INTEGRITY)
	            System.out.println("jkinit: Passowrd incorrect");
	        else
	            System.out.println("jkinit: " + e.krbErrorMessage());
	    } catch (UnknownHostException e2) {
	        System.out.println("jkinit: kdc hostname not found");
	    } catch (IOException e3) {
	        System.out.println("jkinit: io exception while trying to contact kdc");
	    }
	}
}
