6854308: more ktab options
authorweijun
Wed, 22 Jul 2009 16:40:39 +0800
changeset 3317 a1ea2f1893f9
parent 3316 32d30c561c5a
child 3318 dade78e63c92
6854308: more ktab options Reviewed-by: mullan
jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java
jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java
--- a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java	Wed Jul 22 16:40:04 2009 +0800
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java	Wed Jul 22 16:40:39 2009 +0800
@@ -1,5 +1,5 @@
 /*
- * Portions Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Portions Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -403,11 +403,11 @@
     /**
      * Retrieves the key table entry with the specified service name.
      * @param service the service which may have an entry in the key table.
+     * @param keyType the etype to match, returns the 1st one if -1 provided
      * @return -1 if the entry is not found, else return the entry index
      * in the list.
      */
     private int retrieveEntry(PrincipalName service, int keyType) {
-        int found = -1;
         KeyTabEntry e;
         if (entries != null) {
             for (int i = 0; i < entries.size(); i++) {
@@ -418,7 +418,7 @@
                 }
             }
         }
-        return found;
+        return -1;
     }
 
     /**
@@ -476,12 +476,29 @@
     /**
      * Removes an entry from the key table.
      * @param service the service <code>PrincipalName</code>.
+     * @param etype the etype to match, first one if -1 provided
+     * @return 1 if removed successfully, 0 otherwise
      */
-    public void deleteEntry(PrincipalName service) {
-        int result = retrieveEntry(service, -1);
+    public int deleteEntry(PrincipalName service, int etype) {
+        int result = retrieveEntry(service, etype);
         if (result != -1) {
             entries.removeElementAt(result);
+            return 1;
         }
+        return 0;
+    }
+
+    /**
+     * Removes an entry from the key table.
+     * @param service the service <code>PrincipalName</code>.
+     * @return number of entries removed
+     */
+    public int deleteEntry(PrincipalName service) {
+        int count = 0;
+        while (deleteEntry(service, -1) > 0) {
+            count++;
+        }
+        return count;
     }
 
     /**
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java	Wed Jul 22 16:40:04 2009 +0800
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java	Wed Jul 22 16:40:39 2009 +0800
@@ -1,4 +1,5 @@
 /*
+ * Portions Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java	Wed Jul 22 16:40:04 2009 +0800
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java	Wed Jul 22 16:40:39 2009 +0800
@@ -1,4 +1,5 @@
 /*
+ * Portions Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,16 +31,15 @@
 package sun.security.krb5.internal.tools;
 
 import sun.security.krb5.*;
-import sun.security.krb5.internal.*;
 import sun.security.krb5.internal.ktab.*;
-import sun.security.krb5.KrbCryptoException;
-import java.lang.RuntimeException;
 import java.io.IOException;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
-import java.io.FileOutputStream;
 import java.io.File;
+import java.text.DateFormat;
 import java.util.Arrays;
+import java.util.Date;
+import sun.security.krb5.internal.crypto.EType;
 /**
  * This class can execute as a command-line tool to help the user manage
  * entires in the key table.
@@ -55,6 +55,9 @@
     char action;
     String name;   // name and directory of key table
     String principal;
+    boolean showEType;
+    boolean showTime;
+    int etype = -1;
     char[] password = null;
 
     /**
@@ -62,13 +65,14 @@
      * <br>Usage: ktab <options>
      * <br>available options to Ktab:
      * <ul>
-     * <li><b>-l</b>  list the keytab name and entries
+     * <li><b>-l [-e] [-t]</b>  list the keytab name and entries, -e show
+     * encryption etypes, -t show timestamps.
      * <li><b>-a</b>  &lt;<i>principal name</i>&gt;
      * (&lt;<i>password</i>&gt;)  add an entry to the keytab.
      * The entry is added only to the keytab. No changes are made to the
      * Kerberos database.
-     * <li><b>-d</b>  &lt;<i>principal name</i>&gt;
-     * delete an entry from the keytab
+     * <li><b>-d</b>  &lt;<i>principal name</i>&gt; [&lt;<i>etype</i>&gt;]
+     * delete an entry from the keytab.
      * The entry is deleted only from the keytab. No changes are made to the
      * Kerberos database.
      * <li><b>-k</b>  &lt;<i>keytab name</i> &gt;
@@ -182,6 +186,11 @@
                 i++;
                 if ((i < args.length) && (!args[i].startsWith("-"))) {
                     principal = args[i];
+                    int j = i + 1;
+                    if ((j < args.length) && (!args[j].startsWith("-"))) {
+                        etype = Integer.parseInt(args[j]);
+                        i = j;
+                    }
                 } else {
                     System.out.println("Please specify the principal" +
                                        "name of the entry you want to " +
@@ -207,6 +216,12 @@
                     System.exit(-1);
                 }
                 break;
+            case 'e':
+                showEType = true;
+                break;
+            case 't':
+                showTime = true;
+                break;
             default:
                 printHelp();
                 System.exit(-1);
@@ -271,25 +286,54 @@
      * Lists key table name and entries in it.
      */
     void listKt() {
-        int version;
-        String principal;
-        // System.out.println("Keytab name: " + admin.getKeyTabName());
-        System.out.println("Keytab name: " + table.tabName());
-        // KeyTabEntry[] entries = admin.getEntries();
+        System.out.println("Keytab name: " + KeyTab.tabName());
         KeyTabEntry[] entries = table.getEntries();
         if ((entries != null) && (entries.length > 0)) {
-            System.out.println("KVNO    Principal");
+            String[][] output = new String[entries.length+1][showTime?3:2];
+            int column = 0;
+            output[0][column++] = "KVNO";
+            if (showTime) output[0][column++] = "Timestamp";
+            output[0][column++] = "Principal";
             for (int i = 0; i < entries.length; i++) {
-                version = entries[i].getKey().getKeyVersionNumber().intValue();
-                principal = entries[i].getService().toString();
-                if (i == 0) {
-                    StringBuffer separator = new StringBuffer();
-                    for (int j = 0; j < 9 + principal.length(); j++) {
-                        separator.append("-");
+                column = 0;
+                output[i+1][column++] = entries[i].getKey().
+                        getKeyVersionNumber().toString();
+                if (showTime) output[i+1][column++] =
+                        DateFormat.getDateTimeInstance(
+                        DateFormat.SHORT, DateFormat.SHORT).format(
+                        new Date(entries[i].getTimeStamp().getTime()));
+                String princ = entries[i].getService().toString();
+                if (showEType) {
+                    int e = entries[i].getKey().getEType();
+                    output[i+1][column++] = princ + " (" + e + ":" +
+                            EType.toString(e) + ")";
+                } else {
+                    output[i+1][column++] = princ;
+                }
+            }
+            int[] width = new int[column];
+            for (int j=0; j<column; j++) {
+                for (int i=0; i <= entries.length; i++) {
+                    if (output[i][j].length() > width[j]) {
+                        width[j] = output[i][j].length();
                     }
-                    System.out.println(separator.toString());
                 }
-                System.out.println("  " + version + "     " + principal);
+                if (j != 0) width[j] = -width[j];
+            }
+            for (int j=0; j<column; j++) {
+                System.out.printf("%" + width[j] + "s ", output[0][j]);
+            }
+            System.out.println();
+            for (int j=0; j<column; j++) {
+                for (int k=0; k<Math.abs(width[j]); k++) System.out.print("-");
+                System.out.print(" ");
+            }
+            System.out.println();
+            for (int i=0; i<entries.length; i++) {
+                for (int j=0; j<column; j++) {
+                    System.out.printf("%" + width[j] + "s ", output[i+1][j]);
+                }
+                System.out.println();
             }
         } else {
             System.out.println("0 entry.");
@@ -309,9 +353,10 @@
             String answer;
             BufferedReader cis =
                 new BufferedReader(new InputStreamReader(System.in));
-            System.out.print("Are you sure you want to "+
+            System.out.print("Are you sure you want to"+
                              " delete service key for " + pname.toString() +
-                             " in " + table.tabName() + "?(Y/N) :");
+                             " (" + (etype==-1?"all etypes":("etype = "+etype)) +
+                             ") in " + table.tabName() + "?(Y/N): ");
 
             System.out.flush();
             answer = cis.readLine();
@@ -333,19 +378,26 @@
             e.printStackTrace();
             System.exit(-1);
         }
-        // admin.deleteEntry(pname);
-        table.deleteEntry(pname);
+
+        int count;
+        if (etype == -1) count = table.deleteEntry(pname);
+        else count = table.deleteEntry(pname, etype);
 
-        try {
-            table.save();
-        } catch (IOException e) {
-            System.err.println("Error occurs while saving the keytab." +
+        if (count == 0) {
+            System.err.println("No matched entry in the keytab. " +
                                "Deletion fails.");
-            e.printStackTrace();
             System.exit(-1);
+        } else {
+            try {
+                table.save();
+            } catch (IOException e) {
+                System.err.println("Error occurs while saving the keytab. " +
+                                   "Deletion fails.");
+                e.printStackTrace();
+                System.exit(-1);
+            }
+            System.out.println("Done!");
         }
-        System.out.println("Done!");
-
     }
 
     /**
@@ -355,12 +407,12 @@
         System.out.println("\nUsage: ktab " +
                            "<options>");
         System.out.println("available options to Ktab:");
-        System.out.println("-l\t\t\t\tlist the keytab name and entries");
+        System.out.println("-l [-e] [-t]\t\t\tlist the keytab name and entries,\n\t\t\t\t-e with etype, -t with timestamp");
         System.out.println("-a <principal name> (<password>)add an entry " +
                            "to the keytab");
-        System.out.println("-d <principal name>\t\tdelete an entry from "+
-                           "the keytab");
+        System.out.println("-d <principal name> [<etype>]\tdelete an "+
+                           "entry from the keytab");
         System.out.println("-k <keytab name>\t\tspecify keytab name and "+
-                           " path with prefix FILE:");
+                           "path with prefix FILE:");
     }
 }