blob: b773189c113e7e5b6e23b421972ab7454d378bcb [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Sun designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Sun in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 */
24
25/*
26 * (C) Copyright IBM Corp. 1999 All Rights Reserved.
27 * Copyright 1997 The Open Group Research Institute. All rights reserved.
28 */
29
30package sun.security.krb5.internal.tools;
31
32import sun.security.krb5.*;
33import sun.security.krb5.internal.*;
34import sun.security.krb5.internal.ktab.*;
35import sun.security.krb5.KrbCryptoException;
36import java.lang.RuntimeException;
37import java.io.IOException;
38import java.io.BufferedReader;
39import java.io.InputStreamReader;
40import java.io.FileOutputStream;
41import java.io.File;
42import java.util.Arrays;
43/**
44 * This class can execute as a command-line tool to help the user manage
45 * entires in the key table.
46 * Available functions include list/add/update/delete service key(s).
47 *
48 * @author Yanni Zhang
49 * @author Ram Marti
50 */
51
52public class Ktab {
53 // KeyTabAdmin admin;
54 KeyTab table;
55 char action;
56 String name; // name and directory of key table
57 String principal;
58 char[] password = null;
59
60 /**
61 * The main program that can be invoked at command line.
62 * <br>Usage: ktab <options>
63 * <br>available options to Ktab:
64 * <ul>
65 * <li><b>-l</b> list the keytab name and entries
66 * <li><b>-a</b> &lt;<i>principal name</i>&gt;
67 * (&lt;<i>password</i>&gt;) add an entry to the keytab.
68 * The entry is added only to the keytab. No changes are made to the
69 * Kerberos database.
70 * <li><b>-d</b> &lt;<i>principal name</i>&gt;
71 * delete an entry from the keytab
72 * The entry is deleted only from the keytab. No changes are made to the
73 * Kerberos database.
74 * <li><b>-k</b> &lt;<i>keytab name</i> &gt;
75 * specify keytab name and path with prefix FILE:
76 * <li><b>-help</b> display instructions.
77 */
78 public static void main(String[] args) {
79 Ktab ktab = new Ktab();
80 if ((args.length == 1) && (args[0].equalsIgnoreCase("-help"))) {
81 ktab.printHelp();
82 System.exit(0);
83 } else if ((args == null) || (args.length == 0)) {
84 ktab.action = 'l';
85 } else {
86 ktab.processArgs(args);
87 }
88 try {
89 if (ktab.name == null) {
90 // ktab.admin = new KeyTabAdmin(); // use the default keytab.
91 ktab.table = KeyTab.getInstance();
92 if (ktab.table == null) {
93 if (ktab.action == 'a') {
94 ktab.table = KeyTab.create();
95 } else {
96 System.out.println("No default key table exists.");
97 System.exit(-1);
98 }
99 }
100 } else {
101 if ((ktab.action != 'a') &&
102 !(new File(ktab.name)).exists()) {
103 System.out.println("Key table " +
104 ktab.name + " does not exist.");
105 System.exit(-1);
106 } else {
107 ktab.table = KeyTab.getInstance(ktab.name);
108 }
109 if (ktab.table == null) {
110 if (ktab.action == 'a') {
111 ktab.table = KeyTab.create(ktab.name);
112 } else {
113 System.out.println("The format of key table " +
114 ktab.name + " is incorrect.");
115 System.exit(-1);
116 }
117 }
118 }
119 } catch (RealmException e) {
120 System.err.println("Error loading key table.");
121 System.exit(-1);
122 } catch (IOException e) {
123 System.err.println("Error loading key table.");
124 System.exit(-1);
125 }
126 switch (ktab.action) {
127 case 'l':
128 ktab.listKt();
129 break;
130 case 'a':
131 ktab.addEntry();
132 break;
133 case 'd':
134 ktab.deleteEntry();
135 break;
136 default:
137 ktab.printHelp();
138 System.exit(-1);
139 }
140 }
141
142 /**
143 * Parses the command line arguments.
144 */
145 void processArgs(String[] args) {
146 Character arg = null;
147 for (int i = 0; i < args.length; i++) {
148 if ((args[i].length() == 2) && (args[i].startsWith("-"))) {
149 arg = new Character(args[i].charAt(1));
150 } else {
151 printHelp();
152 System.exit(-1);
153 }
154 switch (arg.charValue()) {
155 case 'l':
156 case 'L':
157 action = 'l'; // list keytab location, name and entries
158 break;
159 case 'a':
160 case 'A':
161 action = 'a'; // add a new entry to keytab.
162 i++;
163 if ((i < args.length) && (!args[i].startsWith("-"))) {
164 principal = args[i];
165 } else {
166 System.out.println("Please specify the principal name"+
167 " after -a option.");
168 printHelp();
169 System.exit(-1);
170 }
171 if ((i + 1 < args.length) &&
172 (!args[i + 1].startsWith("-"))) {
173 password = args[i + 1].toCharArray();
174 i++;
175 } else {
176 password = null; // prompt user for password later.
177 }
178 break;
179 case 'd':
180 case 'D':
181 action = 'd'; // delete an entry.
182 i++;
183 if ((i < args.length) && (!args[i].startsWith("-"))) {
184 principal = args[i];
185 } else {
186 System.out.println("Please specify the principal" +
187 "name of the entry you want to " +
188 " delete after -d option.");
189 printHelp();
190 System.exit(-1);
191 }
192 break;
193 case 'k':
194 case 'K':
195 i++;
196 if ((i < args.length) && (!args[i].startsWith("-"))) {
197 if (args[i].length() >= 5 &&
198 args[i].substring(0, 5).equalsIgnoreCase("FILE:")) {
199 name = args[i].substring(5);
200 } else
201 name = args[i];
202 } else {
203 System.out.println("Please specify the keytab "+
204 "file name and location " +
205 "after -k option");
206 printHelp();
207 System.exit(-1);
208 }
209 break;
210 default:
211 printHelp();
212 System.exit(-1);
213 }
214 }
215 }
216
217 /**
218 * Adds a service key to key table. If the specified key table does not
219 * exist, the program will automatically generate
220 * a new key table.
221 */
222 void addEntry() {
223 PrincipalName pname = null;
224 try {
225 pname = new PrincipalName(principal);
226 if (pname.getRealm() == null) {
227 pname.setRealm(Config.getInstance().getDefaultRealm());
228 }
229 } catch (KrbException e) {
230 System.err.println("Failed to add " + principal +
231 " to keytab.");
232 e.printStackTrace();
233 System.exit(-1);
234 }
235 if (password == null) {
236 try {
237 BufferedReader cis =
238 new BufferedReader(new InputStreamReader(System.in));
239 System.out.print("Password for " + pname.toString() + ":");
240 System.out.flush();
241 password = cis.readLine().toCharArray();
242 } catch (IOException e) {
243 System.err.println("Failed to read the password.");
244 e.printStackTrace();
245 System.exit(-1);
246 }
247
248 }
249 try {
250 // admin.addEntry(pname, password);
251 table.addEntry(pname, password);
252 Arrays.fill(password, '0'); // clear password
253 // admin.save();
254 table.save();
255 System.out.println("Done!");
256 System.out.println("Service key for " + principal +
257 " is saved in " + table.tabName());
258
259 } catch (KrbException e) {
260 System.err.println("Failed to add " + principal + " to keytab.");
261 e.printStackTrace();
262 System.exit(-1);
263 } catch (IOException e) {
264 System.err.println("Failed to save new entry.");
265 e.printStackTrace();
266 System.exit(-1);
267 }
268 }
269
270 /**
271 * Lists key table name and entries in it.
272 */
273 void listKt() {
274 int version;
275 String principal;
276 // System.out.println("Keytab name: " + admin.getKeyTabName());
277 System.out.println("Keytab name: " + table.tabName());
278 // KeyTabEntry[] entries = admin.getEntries();
279 KeyTabEntry[] entries = table.getEntries();
280 if ((entries != null) && (entries.length > 0)) {
281 System.out.println("KVNO Principal");
282 for (int i = 0; i < entries.length; i++) {
283 version = entries[i].getKey().getKeyVersionNumber().intValue();
284 principal = entries[i].getService().toString();
285 if (i == 0) {
286 StringBuffer separator = new StringBuffer();
287 for (int j = 0; j < 9 + principal.length(); j++) {
288 separator.append("-");
289 }
290 System.out.println(separator.toString());
291 }
292 System.out.println(" " + version + " " + principal);
293 }
294 } else {
295 System.out.println("0 entry.");
296 }
297 }
298
299 /**
300 * Deletes an entry from the key table.
301 */
302 void deleteEntry() {
303 PrincipalName pname = null;
304 try {
305 pname = new PrincipalName(principal);
306 if (pname.getRealm() == null) {
307 pname.setRealm(Config.getInstance().getDefaultRealm());
308 }
309 String answer;
310 BufferedReader cis =
311 new BufferedReader(new InputStreamReader(System.in));
312 System.out.print("Are you sure you want to "+
313 " delete service key for " + pname.toString() +
314 " in " + table.tabName() + "?(Y/N) :");
315
316 System.out.flush();
317 answer = cis.readLine();
318 if (answer.equalsIgnoreCase("Y") ||
319 answer.equalsIgnoreCase("Yes"));
320 else {
321 // no error, the user did not want to delete the entry
322 System.exit(0);
323 }
324
325 } catch (KrbException e) {
326 System.err.println("Error occured while deleting the entry. "+
327 "Deletion failed.");
328 e.printStackTrace();
329 System.exit(-1);
330 } catch (IOException e) {
331 System.err.println("Error occured while deleting the entry. "+
332 " Deletion failed.");
333 e.printStackTrace();
334 System.exit(-1);
335 }
336 // admin.deleteEntry(pname);
337 table.deleteEntry(pname);
338
339 try {
340 table.save();
341 } catch (IOException e) {
342 System.err.println("Error occurs while saving the keytab." +
343 "Deletion fails.");
344 e.printStackTrace();
345 System.exit(-1);
346 }
347 System.out.println("Done!");
348
349 }
350
351 /**
352 * Prints out the help information.
353 */
354 void printHelp() {
355 System.out.println("\nUsage: ktab " +
356 "<options>");
357 System.out.println("available options to Ktab:");
358 System.out.println("-l\t\t\t\tlist the keytab name and entries");
359 System.out.println("-a <principal name> (<password>)add an entry " +
360 "to the keytab");
361 System.out.println("-d <principal name>\t\tdelete an entry from "+
362 "the keytab");
363 System.out.println("-k <keytab name>\t\tspecify keytab name and "+
364 " path with prefix FILE:");
365 }
366}