001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
003: *
004: * This code is free software; you can redistribute it and/or modify it
005: * under the terms of the GNU General Public License version 2 only, as
006: * published by the Free Software Foundation. Sun designates this
007: * particular file as subject to the "Classpath" exception as provided
008: * by Sun in the LICENSE file that accompanied this code.
009: *
010: * This code is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
013: * version 2 for more details (a copy is included in the LICENSE file that
014: * accompanied this code).
015: *
016: * You should have received a copy of the GNU General Public License version
017: * 2 along with this work; if not, write to the Free Software Foundation,
018: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
021: * CA 95054 USA or visit www.sun.com if you need additional information or
022: * have any questions.
023: */
024:
025: /*
026: * (C) Copyright IBM Corp. 1999 All Rights Reserved.
027: * Copyright 1997 The Open Group Research Institute. All rights reserved.
028: */
029:
030: package sun.security.krb5.internal.tools;
031:
032: import sun.security.krb5.*;
033: import sun.security.krb5.internal.*;
034: import sun.security.krb5.internal.ktab.*;
035: import sun.security.krb5.KrbCryptoException;
036: import java.lang.RuntimeException;
037: import java.io.IOException;
038: import java.io.BufferedReader;
039: import java.io.InputStreamReader;
040: import java.io.FileOutputStream;
041: import java.io.File;
042: import java.util.Arrays;
043:
044: /**
045: * This class can execute as a command-line tool to help the user manage
046: * entires in the key table.
047: * Available functions include list/add/update/delete service key(s).
048: *
049: * @author Yanni Zhang
050: * @author Ram Marti
051: * @version 1.00 10 Jul 00
052: */
053:
054: public class Ktab {
055: // KeyTabAdmin admin;
056: KeyTab table;
057: char action;
058: String name; // name and directory of key table
059: String principal;
060: char[] password = null;
061:
062: /**
063: * The main program that can be invoked at command line.
064: * <br>Usage: ktab <options>
065: * <br>available options to Ktab:
066: * <ul>
067: * <li><b>-l</b> list the keytab name and entries
068: * <li><b>-a</b> <<i>principal name</i>>
069: * (<<i>password</i>>) add an entry to the keytab.
070: * The entry is added only to the keytab. No changes are made to the
071: * Kerberos database.
072: * <li><b>-d</b> <<i>principal name</i>>
073: * delete an entry from the keytab
074: * The entry is deleted only from the keytab. No changes are made to the
075: * Kerberos database.
076: * <li><b>-k</b> <<i>keytab name</i> >
077: * specify keytab name and path with prefix FILE:
078: * <li><b>-help</b> display instructions.
079: */
080: public static void main(String[] args) {
081: Ktab ktab = new Ktab();
082: if ((args.length == 1) && (args[0].equalsIgnoreCase("-help"))) {
083: ktab.printHelp();
084: System.exit(0);
085: } else if ((args == null) || (args.length == 0)) {
086: ktab.action = 'l';
087: } else {
088: ktab.processArgs(args);
089: }
090: try {
091: if (ktab.name == null) {
092: // ktab.admin = new KeyTabAdmin(); // use the default keytab.
093: ktab.table = KeyTab.getInstance();
094: if (ktab.table == null) {
095: if (ktab.action == 'a') {
096: ktab.table = KeyTab.create();
097: } else {
098: System.out
099: .println("No default key table exists.");
100: System.exit(-1);
101: }
102: }
103: } else {
104: if ((ktab.action != 'a')
105: && !(new File(ktab.name)).exists()) {
106: System.out.println("Key table " + ktab.name
107: + " does not exist.");
108: System.exit(-1);
109: } else {
110: ktab.table = KeyTab.getInstance(ktab.name);
111: }
112: if (ktab.table == null) {
113: if (ktab.action == 'a') {
114: ktab.table = KeyTab.create(ktab.name);
115: } else {
116: System.out.println("The format of key table "
117: + ktab.name + " is incorrect.");
118: System.exit(-1);
119: }
120: }
121: }
122: } catch (RealmException e) {
123: System.err.println("Error loading key table.");
124: System.exit(-1);
125: } catch (IOException e) {
126: System.err.println("Error loading key table.");
127: System.exit(-1);
128: }
129: switch (ktab.action) {
130: case 'l':
131: ktab.listKt();
132: break;
133: case 'a':
134: ktab.addEntry();
135: break;
136: case 'd':
137: ktab.deleteEntry();
138: break;
139: default:
140: ktab.printHelp();
141: System.exit(-1);
142: }
143: }
144:
145: /**
146: * Parses the command line arguments.
147: */
148: void processArgs(String[] args) {
149: Character arg = null;
150: for (int i = 0; i < args.length; i++) {
151: if ((args[i].length() == 2) && (args[i].startsWith("-"))) {
152: arg = new Character(args[i].charAt(1));
153: } else {
154: printHelp();
155: System.exit(-1);
156: }
157: switch (arg.charValue()) {
158: case 'l':
159: case 'L':
160: action = 'l'; // list keytab location, name and entries
161: break;
162: case 'a':
163: case 'A':
164: action = 'a'; // add a new entry to keytab.
165: i++;
166: if ((i < args.length) && (!args[i].startsWith("-"))) {
167: principal = args[i];
168: } else {
169: System.out
170: .println("Please specify the principal name"
171: + " after -a option.");
172: printHelp();
173: System.exit(-1);
174: }
175: if ((i + 1 < args.length)
176: && (!args[i + 1].startsWith("-"))) {
177: password = args[i + 1].toCharArray();
178: i++;
179: } else {
180: password = null; // prompt user for password later.
181: }
182: break;
183: case 'd':
184: case 'D':
185: action = 'd'; // delete an entry.
186: i++;
187: if ((i < args.length) && (!args[i].startsWith("-"))) {
188: principal = args[i];
189: } else {
190: System.out.println("Please specify the principal"
191: + "name of the entry you want to "
192: + " delete after -d option.");
193: printHelp();
194: System.exit(-1);
195: }
196: break;
197: case 'k':
198: case 'K':
199: i++;
200: if ((i < args.length) && (!args[i].startsWith("-"))) {
201: if (args[i].length() >= 5
202: && args[i].substring(0, 5)
203: .equalsIgnoreCase("FILE:")) {
204: name = args[i].substring(5);
205: } else
206: name = args[i];
207: } else {
208: System.out.println("Please specify the keytab "
209: + "file name and location "
210: + "after -k option");
211: printHelp();
212: System.exit(-1);
213: }
214: break;
215: default:
216: printHelp();
217: System.exit(-1);
218: }
219: }
220: }
221:
222: /**
223: * Adds a service key to key table. If the specified key table does not
224: * exist, the program will automatically generate
225: * a new key table.
226: */
227: void addEntry() {
228: PrincipalName pname = null;
229: try {
230: pname = new PrincipalName(principal);
231: if (pname.getRealm() == null) {
232: pname.setRealm(Config.getInstance().getDefaultRealm());
233: }
234: } catch (KrbException e) {
235: System.err.println("Failed to add " + principal
236: + " to keytab.");
237: e.printStackTrace();
238: System.exit(-1);
239: }
240: if (password == null) {
241: try {
242: BufferedReader cis = new BufferedReader(
243: new InputStreamReader(System.in));
244: System.out.print("Password for " + pname.toString()
245: + ":");
246: System.out.flush();
247: password = cis.readLine().toCharArray();
248: } catch (IOException e) {
249: System.err.println("Failed to read the password.");
250: e.printStackTrace();
251: System.exit(-1);
252: }
253:
254: }
255: try {
256: // admin.addEntry(pname, password);
257: table.addEntry(pname, password);
258: Arrays.fill(password, '0'); // clear password
259: // admin.save();
260: table.save();
261: System.out.println("Done!");
262: System.out.println("Service key for " + principal
263: + " is saved in " + table.tabName());
264:
265: } catch (KrbException e) {
266: System.err.println("Failed to add " + principal
267: + " to keytab.");
268: e.printStackTrace();
269: System.exit(-1);
270: } catch (IOException e) {
271: System.err.println("Failed to save new entry.");
272: e.printStackTrace();
273: System.exit(-1);
274: }
275: }
276:
277: /**
278: * Lists key table name and entries in it.
279: */
280: void listKt() {
281: int version;
282: String principal;
283: // System.out.println("Keytab name: " + admin.getKeyTabName());
284: System.out.println("Keytab name: " + table.tabName());
285: // KeyTabEntry[] entries = admin.getEntries();
286: KeyTabEntry[] entries = table.getEntries();
287: if ((entries != null) && (entries.length > 0)) {
288: System.out.println("KVNO Principal");
289: for (int i = 0; i < entries.length; i++) {
290: version = entries[i].getKey().getKeyVersionNumber()
291: .intValue();
292: principal = entries[i].getService().toString();
293: if (i == 0) {
294: StringBuffer separator = new StringBuffer();
295: for (int j = 0; j < 9 + principal.length(); j++) {
296: separator.append("-");
297: }
298: System.out.println(separator.toString());
299: }
300: System.out
301: .println(" " + version + " " + principal);
302: }
303: } else {
304: System.out.println("0 entry.");
305: }
306: }
307:
308: /**
309: * Deletes an entry from the key table.
310: */
311: void deleteEntry() {
312: PrincipalName pname = null;
313: try {
314: pname = new PrincipalName(principal);
315: if (pname.getRealm() == null) {
316: pname.setRealm(Config.getInstance().getDefaultRealm());
317: }
318: String answer;
319: BufferedReader cis = new BufferedReader(
320: new InputStreamReader(System.in));
321: System.out.print("Are you sure you want to "
322: + " delete service key for " + pname.toString()
323: + " in " + table.tabName() + "?(Y/N) :");
324:
325: System.out.flush();
326: answer = cis.readLine();
327: if (answer.equalsIgnoreCase("Y")
328: || answer.equalsIgnoreCase("Yes"))
329: ;
330: else {
331: // no error, the user did not want to delete the entry
332: System.exit(0);
333: }
334:
335: } catch (KrbException e) {
336: System.err
337: .println("Error occured while deleting the entry. "
338: + "Deletion failed.");
339: e.printStackTrace();
340: System.exit(-1);
341: } catch (IOException e) {
342: System.err
343: .println("Error occured while deleting the entry. "
344: + " Deletion failed.");
345: e.printStackTrace();
346: System.exit(-1);
347: }
348: // admin.deleteEntry(pname);
349: table.deleteEntry(pname);
350:
351: try {
352: table.save();
353: } catch (IOException e) {
354: System.err.println("Error occurs while saving the keytab."
355: + "Deletion fails.");
356: e.printStackTrace();
357: System.exit(-1);
358: }
359: System.out.println("Done!");
360:
361: }
362:
363: /**
364: * Prints out the help information.
365: */
366: void printHelp() {
367: System.out.println("\nUsage: ktab " + "<options>");
368: System.out.println("available options to Ktab:");
369: System.out
370: .println("-l\t\t\t\tlist the keytab name and entries");
371: System.out
372: .println("-a <principal name> (<password>)add an entry "
373: + "to the keytab");
374: System.out
375: .println("-d <principal name>\t\tdelete an entry from "
376: + "the keytab");
377: System.out
378: .println("-k <keytab name>\t\tspecify keytab name and "
379: + " path with prefix FILE:");
380: }
381: }
|