1 /* 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * (C) Copyright IBM Corp. 1999 All Rights Reserved. 28 * Copyright 1997 The Open Group Research Institute. All rights reserved. 29 */ 30 31 package sun.security.krb5.internal.tools; 32 33 import java.net.InetAddress; 34 import sun.security.krb5.*; 35 import sun.security.krb5.internal.*; 36 import sun.security.krb5.internal.ccache.*; 37 import sun.security.krb5.internal.ktab.*; 38 import sun.security.krb5.internal.crypto.EType; 39 40 /** 41 * This class can execute as a command-line tool to list entries in 42 * credential cache and key tab. 43 * 44 * @author Yanni Zhang 45 * @author Ram Marti 46 */ 47 public class Klist { 48 Object target; 49 // for credentials cache, options are 'f', 'e', 'a' and 'n'; 50 // for keytab, optionsare 't' and 'K' and 'e' 51 char[] options = new char[4]; 52 String name; // the name of credentials cache and keytable. 53 char action; // actions would be 'c' for credentials cache 54 // and 'k' for keytable. 55 private static boolean DEBUG = Krb5.DEBUG; 56 57 /** 58 * The main program that can be invoked at command line. 59 * <br>Usage: klist 60 * [[-c] [-f] [-e] [-a [-n]]] [-k [-t] [-K]] [name] 61 * -c specifies that credential cache is to be listed 62 * -k specifies that key tab is to be listed 63 * name name of the credentials cache or keytab 64 * <br>available options for credential caches: 65 * <ul> 66 * <li><b>-f</b> shows credentials flags 67 * <li><b>-e</b> shows the encryption type 68 * <li><b>-a</b> shows addresses 69 * <li><b>-n</b> do not reverse-resolve addresses 70 * </ul> 71 * available options for keytabs: 72 * <ul> 73 * <li><b>-t</b> shows keytab entry timestamps 74 * <li><b>-K</b> shows keytab entry DES keys 75 * </ul> 76 */ 77 public static void main(String[] args) { 78 Klist klist = new Klist(); 79 if ((args == null) || (args.length == 0)) { 80 klist.action = 'c'; // default will list default credentials cache. 81 } else { 82 klist.processArgs(args); 83 } 84 switch (klist.action) { 85 case 'c': 86 if (klist.name == null) { 87 klist.target = CredentialsCache.getInstance(); 88 klist.name = CredentialsCache.cacheName(); 89 } else 90 klist.target = CredentialsCache.getInstance(klist.name); 91 92 if (klist.target != null) { 93 klist.displayCache(); 94 } else { 95 klist.displayMessage("Credentials cache"); 96 System.exit(-1); 97 } 98 break; 99 case 'k': 100 KeyTab ktab = KeyTab.getInstance(klist.name); 101 if (ktab.isMissing()) { 102 System.out.println("KeyTab " + klist.name + " not found."); 103 System.exit(-1); 104 } else if (!ktab.isValid()) { 105 System.out.println("KeyTab " + klist.name 106 + " format not supported."); 107 System.exit(-1); 108 } 109 klist.target = ktab; 110 klist.name = ktab.tabName(); 111 klist.displayTab(); 112 break; 113 default: 114 if (klist.name != null) { 115 klist.printHelp(); 116 System.exit(-1); 117 } else { 118 klist.target = CredentialsCache.getInstance(); 119 klist.name = CredentialsCache.cacheName(); 120 if (klist.target != null) { 121 klist.displayCache(); 122 } else { 123 klist.displayMessage("Credentials cache"); 124 System.exit(-1); 125 } 126 } 127 } 128 } 129 130 /** 131 * Parses the command line arguments. 132 */ 133 void processArgs(String[] args) { 134 Character arg; 135 for (int i = 0; i < args.length; i++) { 136 if ((args[i].length() >= 2) && (args[i].startsWith("-"))) { 137 arg = Character.valueOf(args[i].charAt(1)); 138 switch (arg.charValue()) { 139 case 'c': 140 action = 'c'; 141 break; 142 case 'k': 143 action = 'k'; 144 break; 145 case 'a': 146 options[2] = 'a'; 147 break; 148 case 'n': 149 options[3] = 'n'; 150 break; 151 case 'f': 152 options[1] = 'f'; 153 break; 154 case 'e': 155 options[0] = 'e'; 156 break; 157 case 'K': 158 options[1] = 'K'; 159 break; 160 case 't': 161 options[2] = 't'; 162 break; 163 default: 164 printHelp(); 165 System.exit(-1); 166 } 167 168 } else { 169 if (!args[i].startsWith("-") && (i == args.length - 1)) { 170 // the argument is the last one. 171 name = args[i]; 172 arg = null; 173 } else { 174 printHelp(); // incorrect input format. 175 System.exit(-1); 176 } 177 } 178 } 179 } 180 181 void displayTab() { 182 KeyTab table = (KeyTab)target; 183 KeyTabEntry[] entries = table.getEntries(); 184 if (entries.length == 0) { 185 System.out.println("\nKey tab: " + name + 186 ", " + " 0 entries found.\n"); 187 } else { 188 if (entries.length == 1) 189 System.out.println("\nKey tab: " + name + 190 ", " + entries.length + " entry found.\n"); 191 else 192 System.out.println("\nKey tab: " + name + ", " + 193 entries.length + " entries found.\n"); 194 for (int i = 0; i < entries.length; i++) { 195 System.out.println("[" + (i + 1) + "] " + 196 "Service principal: " + 197 entries[i].getService().toString()); 198 System.out.println("\t KVNO: " + 199 entries[i].getKey().getKeyVersionNumber()); 200 if (options[0] == 'e') { 201 EncryptionKey key = entries[i].getKey(); 202 System.out.println("\t Key type: " + 203 key.getEType()); 204 } 205 if (options[1] == 'K') { 206 EncryptionKey key = entries[i].getKey(); 207 System.out.println("\t Key: " + 208 entries[i].getKeyString()); 209 } 210 if (options[2] == 't') { 211 System.out.println("\t Time stamp: " + 212 format(entries[i].getTimeStamp())); 213 } 214 } 215 } 216 } 217 218 void displayCache() { 219 CredentialsCache cache = (CredentialsCache)target; 220 sun.security.krb5.internal.ccache.Credentials[] creds = 221 cache.getCredsList(); 222 if (creds == null) { 223 System.out.println ("No credentials available in the cache " + 224 name); 225 System.exit(-1); 226 } 227 System.out.println("\nCredentials cache: " + name); 228 String defaultPrincipal = cache.getPrimaryPrincipal().toString(); 229 int num = creds.length; 230 231 if (num == 1) 232 System.out.println("\nDefault principal: " + 233 defaultPrincipal + ", " + 234 creds.length + " entry found.\n"); 235 else 236 System.out.println("\nDefault principal: " + 237 defaultPrincipal + ", " + 238 creds.length + " entries found.\n"); 239 if (creds != null) { 240 for (int i = 0; i < creds.length; i++) { 241 try { 242 String starttime; 243 String endtime; 244 String renewTill; 245 String servicePrincipal; 246 if (creds[i].getStartTime() != null) { 247 starttime = format(creds[i].getStartTime()); 248 } else { 249 starttime = format(creds[i].getAuthTime()); 250 } 251 endtime = format(creds[i].getEndTime()); 252 servicePrincipal = 253 creds[i].getServicePrincipal().toString(); 254 System.out.println("[" + (i + 1) + "] " + 255 " Service Principal: " + 256 servicePrincipal); 257 System.out.println(" Valid starting: " + starttime); 258 System.out.println(" Expires: " + endtime); 259 if (creds[i].getRenewTill() != null) { 260 renewTill = format(creds[i].getRenewTill()); 261 System.out.println( 262 " Renew until: " + renewTill); 263 } 264 if (options[0] == 'e') { 265 String eskey = EType.toString(creds[i].getEType()); 266 String etkt = EType.toString(creds[i].getTktEType()); 267 System.out.println(" EType (skey, tkt): " 268 + eskey + ", " + etkt); 269 } 270 if (options[1] == 'f') { 271 System.out.println(" Flags: " + 272 creds[i].getTicketFlags().toString()); 273 } 274 if (options[2] == 'a') { 275 boolean first = true; 276 InetAddress[] caddr 277 = creds[i].setKrbCreds().getClientAddresses(); 278 if (caddr != null) { 279 for (InetAddress ia: caddr) { 280 String out; 281 if (options[3] == 'n') { 282 out = ia.getHostAddress(); 283 } else { 284 out = ia.getCanonicalHostName(); 285 } 286 System.out.println(" " + 287 (first?"Addresses:":" ") + 288 " " + out); 289 first = false; 290 } 291 } else { 292 System.out.println(" [No host addresses info]"); 293 } 294 } 295 } catch (RealmException e) { 296 System.out.println("Error reading principal from "+ 297 "the entry."); 298 if (DEBUG) { 299 e.printStackTrace(); 300 } 301 System.exit(-1); 302 } 303 } 304 } else { 305 System.out.println("\nNo entries found."); 306 } 307 } 308 309 void displayMessage(String target) { 310 if (name == null) { 311 System.out.println("Default " + target + " not found."); 312 } else { 313 System.out.println(target + " " + name + " not found."); 314 } 315 } 316 /** 317 * Reformats the date from the form - 318 * dow mon dd hh:mm:ss zzz yyyy to mon/dd/yyyy hh:mm 319 * where dow is the day of the week, mon is the month, 320 * dd is the day of the month, hh is the hour of 321 * the day, mm is the minute within the hour, 322 * ss is the second within the minute, zzz is the time zone, 323 * and yyyy is the year. 324 * @param date the string form of Date object. 325 */ 326 private String format(KerberosTime kt) { 327 String date = kt.toDate().toString(); 328 return (date.substring(4, 7) + " " + date.substring(8, 10) + 329 ", " + date.substring(24) 330 + " " + date.substring(11, 19)); 331 } 332 /** 333 * Prints out the help information. 334 */ 335 void printHelp() { 336 System.out.println("\nUsage: klist " + 337 "[[-c] [-f] [-e] [-a [-n]]] [-k [-t] [-K]] [name]"); 338 System.out.println(" name\t name of credentials cache or " + 339 " keytab with the prefix. File-based cache or " 340 + "keytab's prefix is FILE:."); 341 System.out.println(" -c specifies that credential cache is to be " + 342 "listed"); 343 System.out.println(" -k specifies that key tab is to be listed"); 344 System.out.println(" options for credentials caches:"); 345 System.out.println("\t-f \t shows credentials flags"); 346 System.out.println("\t-e \t shows the encryption type"); 347 System.out.println("\t-a \t shows addresses"); 348 System.out.println("\t -n \t do not reverse-resolve addresses"); 349 System.out.println(" options for keytabs:"); 350 System.out.println("\t-t \t shows keytab entry timestamps"); 351 System.out.println("\t-K \t shows keytab entry key value"); 352 System.out.println("\t-e \t shows keytab entry key type"); 353 System.out.println("\nUsage: java sun.security.krb5.tools.Klist " + 354 "-help for help."); 355 } 356 }