| /* |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Sun designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Sun in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| * CA 95054 USA or visit www.sun.com if you need additional information or |
| * have any questions. |
| */ |
| |
| /* |
| * (C) Copyright IBM Corp. 1999 All Rights Reserved. |
| * Copyright 1997 The Open Group Research Institute. All rights reserved. |
| */ |
| |
| 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.util.Arrays; |
| /** |
| * This class can execute as a command-line tool to help the user manage |
| * entires in the key table. |
| * Available functions include list/add/update/delete service key(s). |
| * |
| * @author Yanni Zhang |
| * @author Ram Marti |
| */ |
| |
| public class Ktab { |
| // KeyTabAdmin admin; |
| KeyTab table; |
| char action; |
| String name; // name and directory of key table |
| String principal; |
| char[] password = null; |
| |
| /** |
| * The main program that can be invoked at command line. |
| * <br>Usage: ktab <options> |
| * <br>available options to Ktab: |
| * <ul> |
| * <li><b>-l</b> list the keytab name and entries |
| * <li><b>-a</b> <<i>principal name</i>> |
| * (<<i>password</i>>) 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> <<i>principal name</i>> |
| * 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> <<i>keytab name</i> > |
| * specify keytab name and path with prefix FILE: |
| * <li><b>-help</b> display instructions. |
| */ |
| public static void main(String[] args) { |
| Ktab ktab = new Ktab(); |
| if ((args.length == 1) && (args[0].equalsIgnoreCase("-help"))) { |
| ktab.printHelp(); |
| System.exit(0); |
| } else if ((args == null) || (args.length == 0)) { |
| ktab.action = 'l'; |
| } else { |
| ktab.processArgs(args); |
| } |
| try { |
| if (ktab.name == null) { |
| // ktab.admin = new KeyTabAdmin(); // use the default keytab. |
| ktab.table = KeyTab.getInstance(); |
| if (ktab.table == null) { |
| if (ktab.action == 'a') { |
| ktab.table = KeyTab.create(); |
| } else { |
| System.out.println("No default key table exists."); |
| System.exit(-1); |
| } |
| } |
| } else { |
| if ((ktab.action != 'a') && |
| !(new File(ktab.name)).exists()) { |
| System.out.println("Key table " + |
| ktab.name + " does not exist."); |
| System.exit(-1); |
| } else { |
| ktab.table = KeyTab.getInstance(ktab.name); |
| } |
| if (ktab.table == null) { |
| if (ktab.action == 'a') { |
| ktab.table = KeyTab.create(ktab.name); |
| } else { |
| System.out.println("The format of key table " + |
| ktab.name + " is incorrect."); |
| System.exit(-1); |
| } |
| } |
| } |
| } catch (RealmException e) { |
| System.err.println("Error loading key table."); |
| System.exit(-1); |
| } catch (IOException e) { |
| System.err.println("Error loading key table."); |
| System.exit(-1); |
| } |
| switch (ktab.action) { |
| case 'l': |
| ktab.listKt(); |
| break; |
| case 'a': |
| ktab.addEntry(); |
| break; |
| case 'd': |
| ktab.deleteEntry(); |
| break; |
| default: |
| ktab.printHelp(); |
| System.exit(-1); |
| } |
| } |
| |
| /** |
| * Parses the command line arguments. |
| */ |
| void processArgs(String[] args) { |
| Character arg = null; |
| for (int i = 0; i < args.length; i++) { |
| if ((args[i].length() == 2) && (args[i].startsWith("-"))) { |
| arg = new Character(args[i].charAt(1)); |
| } else { |
| printHelp(); |
| System.exit(-1); |
| } |
| switch (arg.charValue()) { |
| case 'l': |
| case 'L': |
| action = 'l'; // list keytab location, name and entries |
| break; |
| case 'a': |
| case 'A': |
| action = 'a'; // add a new entry to keytab. |
| i++; |
| if ((i < args.length) && (!args[i].startsWith("-"))) { |
| principal = args[i]; |
| } else { |
| System.out.println("Please specify the principal name"+ |
| " after -a option."); |
| printHelp(); |
| System.exit(-1); |
| } |
| if ((i + 1 < args.length) && |
| (!args[i + 1].startsWith("-"))) { |
| password = args[i + 1].toCharArray(); |
| i++; |
| } else { |
| password = null; // prompt user for password later. |
| } |
| break; |
| case 'd': |
| case 'D': |
| action = 'd'; // delete an entry. |
| i++; |
| if ((i < args.length) && (!args[i].startsWith("-"))) { |
| principal = args[i]; |
| } else { |
| System.out.println("Please specify the principal" + |
| "name of the entry you want to " + |
| " delete after -d option."); |
| printHelp(); |
| System.exit(-1); |
| } |
| break; |
| case 'k': |
| case 'K': |
| i++; |
| if ((i < args.length) && (!args[i].startsWith("-"))) { |
| if (args[i].length() >= 5 && |
| args[i].substring(0, 5).equalsIgnoreCase("FILE:")) { |
| name = args[i].substring(5); |
| } else |
| name = args[i]; |
| } else { |
| System.out.println("Please specify the keytab "+ |
| "file name and location " + |
| "after -k option"); |
| printHelp(); |
| System.exit(-1); |
| } |
| break; |
| default: |
| printHelp(); |
| System.exit(-1); |
| } |
| } |
| } |
| |
| /** |
| * Adds a service key to key table. If the specified key table does not |
| * exist, the program will automatically generate |
| * a new key table. |
| */ |
| void addEntry() { |
| PrincipalName pname = null; |
| try { |
| pname = new PrincipalName(principal); |
| if (pname.getRealm() == null) { |
| pname.setRealm(Config.getInstance().getDefaultRealm()); |
| } |
| } catch (KrbException e) { |
| System.err.println("Failed to add " + principal + |
| " to keytab."); |
| e.printStackTrace(); |
| System.exit(-1); |
| } |
| if (password == null) { |
| try { |
| BufferedReader cis = |
| new BufferedReader(new InputStreamReader(System.in)); |
| System.out.print("Password for " + pname.toString() + ":"); |
| System.out.flush(); |
| password = cis.readLine().toCharArray(); |
| } catch (IOException e) { |
| System.err.println("Failed to read the password."); |
| e.printStackTrace(); |
| System.exit(-1); |
| } |
| |
| } |
| try { |
| // admin.addEntry(pname, password); |
| table.addEntry(pname, password); |
| Arrays.fill(password, '0'); // clear password |
| // admin.save(); |
| table.save(); |
| System.out.println("Done!"); |
| System.out.println("Service key for " + principal + |
| " is saved in " + table.tabName()); |
| |
| } catch (KrbException e) { |
| System.err.println("Failed to add " + principal + " to keytab."); |
| e.printStackTrace(); |
| System.exit(-1); |
| } catch (IOException e) { |
| System.err.println("Failed to save new entry."); |
| e.printStackTrace(); |
| System.exit(-1); |
| } |
| } |
| |
| /** |
| * 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(); |
| KeyTabEntry[] entries = table.getEntries(); |
| if ((entries != null) && (entries.length > 0)) { |
| System.out.println("KVNO 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("-"); |
| } |
| System.out.println(separator.toString()); |
| } |
| System.out.println(" " + version + " " + principal); |
| } |
| } else { |
| System.out.println("0 entry."); |
| } |
| } |
| |
| /** |
| * Deletes an entry from the key table. |
| */ |
| void deleteEntry() { |
| PrincipalName pname = null; |
| try { |
| pname = new PrincipalName(principal); |
| if (pname.getRealm() == null) { |
| pname.setRealm(Config.getInstance().getDefaultRealm()); |
| } |
| String answer; |
| BufferedReader cis = |
| new BufferedReader(new InputStreamReader(System.in)); |
| System.out.print("Are you sure you want to "+ |
| " delete service key for " + pname.toString() + |
| " in " + table.tabName() + "?(Y/N) :"); |
| |
| System.out.flush(); |
| answer = cis.readLine(); |
| if (answer.equalsIgnoreCase("Y") || |
| answer.equalsIgnoreCase("Yes")); |
| else { |
| // no error, the user did not want to delete the entry |
| System.exit(0); |
| } |
| |
| } catch (KrbException e) { |
| System.err.println("Error occured while deleting the entry. "+ |
| "Deletion failed."); |
| e.printStackTrace(); |
| System.exit(-1); |
| } catch (IOException e) { |
| System.err.println("Error occured while deleting the entry. "+ |
| " Deletion failed."); |
| e.printStackTrace(); |
| System.exit(-1); |
| } |
| // admin.deleteEntry(pname); |
| table.deleteEntry(pname); |
| |
| 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!"); |
| |
| } |
| |
| /** |
| * Prints out the help information. |
| */ |
| void printHelp() { |
| 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("-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("-k <keytab name>\t\tspecify keytab name and "+ |
| " path with prefix FILE:"); |
| } |
| } |