8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,290 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.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 java.io.File;
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.ccache.*;
import java.io.IOException;
import java.util.Arrays;
import sun.security.util.Password;
import javax.security.auth.kerberos.KeyTab;
/**
* Kinit tool for obtaining Kerberos v5 tickets.
*
* @author Yanni Zhang
* @author Ram Marti
*/
public class Kinit {
private KinitOptions options;
private static final boolean DEBUG = Krb5.DEBUG;
/**
* The main method is used to accept user command line input for ticket
* request. Read {@link KinitOptions#printHelp} for usages or call
* java sun.security.krb5.internal.tools.Kinit -help
* to bring up help menu.
* <p>
* We currently support only file-based credentials cache to
* store the tickets obtained from the KDC.
* By default, for all Unix platforms a cache file named
* {@code /tmp/krb5cc_<uid>} will be generated. The {@code <uid>} is the
* numeric user identifier.
* For all other platforms, a cache file named
* {@code <USER_HOME>/krb5cc_<USER_NAME>} would be generated.
* <p>
* {@code <USER_HOME>} is obtained from {@code java.lang.System}
* property <i>user.home</i>.
* {@code <USER_NAME>} is obtained from {@code java.lang.System}
* property <i>user.name</i>.
* If {@code <USER_HOME>} is null the cache file would be stored in
* the current directory that the program is running from.
* {@code <USER_NAME>} is operating system's login username.
* It could be different from user's principal name.
* <p>
* For instance, on Windows NT, it could be
* {@code c:\winnt\profiles\duke\krb5cc_duke}, in
* which duke is the {@code <USER_NAME>} and {@code c:\winnt\profile\duke} is the
* {@code <USER_HOME>}.
* <p>
* A single user could have multiple principal names,
* but the primary principal of the credentials cache could only be one,
* which means one cache file could only store tickets for one
* specific user principal. If the user switches
* the principal name at the next Kinit, the cache file generated for the
* new ticket would overwrite the old cache file by default.
* To avoid overwriting, you need to specify
* a different cache file name when you request a
* new ticket.
* <p>
* You can specify the location of the cache file by using the -c option
*/
public static void main(String[] args) {
try {
Kinit self = new Kinit(args);
}
catch (Exception e) {
String msg = null;
if (e instanceof KrbException) {
msg = ((KrbException)e).krbErrorMessage() + " " +
((KrbException)e).returnCodeMessage();
} else {
msg = e.getMessage();
}
if (msg != null) {
System.err.println("Exception: " + msg);
} else {
System.out.println("Exception: " + e);
}
e.printStackTrace();
System.exit(-1);
}
return;
}
/**
* Constructs a new Kinit object.
* @param args array of ticket request options.
* Avaiable options are: -f, -p, -c, principal, password.
* @exception IOException if an I/O error occurs.
* @exception RealmException if the Realm could not be instantiated.
* @exception KrbException if error occurs during Kerberos operation.
*/
private Kinit(String[] args)
throws IOException, RealmException, KrbException {
if (args == null || args.length == 0) {
options = new KinitOptions();
} else {
options = new KinitOptions(args);
}
switch (options.action) {
case 1:
acquire();
break;
case 2:
renew();
break;
default:
throw new KrbException("kinit does not support action "
+ options.action);
}
}
private void renew()
throws IOException, RealmException, KrbException {
PrincipalName principal = options.getPrincipal();
String realm = principal.getRealmAsString();
CredentialsCache cache = CredentialsCache.getInstance(options.cachename);
if (cache == null) {
throw new IOException("Unable to find existing cache file " +
options.cachename);
}
sun.security.krb5.internal.ccache.Credentials credentials =
cache.getCreds(PrincipalName.tgsService(realm, realm));
credentials = credentials.setKrbCreds()
.renew()
.toCCacheCreds();
cache = CredentialsCache.create(principal, options.cachename);
if (cache == null) {
throw new IOException("Unable to create the cache file " +
options.cachename);
}
cache.update(credentials);
cache.save();
}
private void acquire()
throws IOException, RealmException, KrbException {
String princName = null;
PrincipalName principal = options.getPrincipal();
if (principal != null) {
princName = principal.toString();
}
KrbAsReqBuilder builder;
if (DEBUG) {
System.out.println("Principal is " + principal);
}
char[] psswd = options.password;
boolean useKeytab = options.useKeytabFile();
if (!useKeytab) {
if (princName == null) {
throw new IllegalArgumentException
(" Can not obtain principal name");
}
if (psswd == null) {
System.out.print("Password for " + princName + ":");
System.out.flush();
psswd = Password.readPassword(System.in);
if (DEBUG) {
System.out.println(">>> Kinit console input " +
new String(psswd));
}
}
builder = new KrbAsReqBuilder(principal, psswd);
} else {
if (DEBUG) {
System.out.println(">>> Kinit using keytab");
}
if (princName == null) {
throw new IllegalArgumentException
("Principal name must be specified.");
}
String ktabName = options.keytabFileName();
if (ktabName != null) {
if (DEBUG) {
System.out.println(
">>> Kinit keytab file name: " + ktabName);
}
}
builder = new KrbAsReqBuilder(principal, ktabName == null
? KeyTab.getInstance()
: KeyTab.getInstance(new File(ktabName)));
}
KDCOptions opt = new KDCOptions();
setOptions(KDCOptions.FORWARDABLE, options.forwardable, opt);
setOptions(KDCOptions.PROXIABLE, options.proxiable, opt);
builder.setOptions(opt);
String realm = options.getKDCRealm();
if (realm == null) {
realm = Config.getInstance().getDefaultRealm();
}
if (DEBUG) {
System.out.println(">>> Kinit realm name is " + realm);
}
PrincipalName sname = PrincipalName.tgsService(realm, realm);
builder.setTarget(sname);
if (DEBUG) {
System.out.println(">>> Creating KrbAsReq");
}
if (options.getAddressOption())
builder.setAddresses(HostAddresses.getLocalAddresses());
builder.setTill(options.lifetime);
builder.setRTime(options.renewable_lifetime);
builder.action();
sun.security.krb5.internal.ccache.Credentials credentials =
builder.getCCreds();
builder.destroy();
// we always create a new cache and store the ticket we get
CredentialsCache cache =
CredentialsCache.create(principal, options.cachename);
if (cache == null) {
throw new IOException("Unable to create the cache file " +
options.cachename);
}
cache.update(credentials);
cache.save();
if (options.password == null) {
// Assume we're running interactively
System.out.println("New ticket is stored in cache file " +
options.cachename);
} else {
Arrays.fill(options.password, '0');
}
// clear the password
if (psswd != null) {
Arrays.fill(psswd, '0');
}
options = null; // release reference to options
}
private static void setOptions(int flag, int option, KDCOptions opt) {
switch (option) {
case 0:
break;
case -1:
opt.set(flag, false);
break;
case 1:
opt.set(flag, true);
}
}
}

View file

@ -0,0 +1,272 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.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.ccache.*;
import java.io.IOException;
import java.time.Instant;
import java.io.FileInputStream;
/**
* Maintains user-specific options or default settings when the user requests
* a KDC ticket using Kinit.
*
* @author Yanni Zhang
* @author Ram Marti
*/
class KinitOptions {
// 1. acquire, 2. renew, 3. validate
public int action = 1;
// forwardable and proxiable flags have two states:
// -1 - flag set to be not forwardable or proxiable;
// 1 - flag set to be forwardable or proxiable.
public short forwardable = 0;
public short proxiable = 0;
public KerberosTime lifetime;
public KerberosTime renewable_lifetime;
public String target_service;
public String keytab_file;
public String cachename;
private PrincipalName principal;
public String realm;
char[] password = null;
public boolean keytab;
private boolean DEBUG = Krb5.DEBUG;
private boolean includeAddresses = true; // default.
private boolean useKeytab = false; // default = false.
private String ktabName; // keytab file name
public KinitOptions() throws RuntimeException, RealmException {
// no args were specified in the command line;
// use default values
cachename = FileCredentialsCache.getDefaultCacheName();
if (cachename == null) {
throw new RuntimeException("default cache name error");
}
principal = getDefaultPrincipal();
}
public void setKDCRealm(String r) throws RealmException {
realm = r;
}
public String getKDCRealm() {
if (realm == null) {
if (principal != null) {
return principal.getRealmString();
}
}
return null;
}
public KinitOptions(String[] args)
throws KrbException, RuntimeException, IOException {
// currently we provide support for -f -p -c principal options
String p = null; // store principal
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-f")) {
forwardable = 1;
} else if (args[i].equals("-p")) {
proxiable = 1;
} else if (args[i].equals("-c")) {
if (args[i + 1].startsWith("-")) {
throw new IllegalArgumentException("input format " +
" not correct: " +
" -c option " +
"must be followed " +
"by the cache name");
}
cachename = args[++i];
if ((cachename.length() >= 5) &&
cachename.substring(0, 5).equalsIgnoreCase("FILE:")) {
cachename = cachename.substring(5);
};
} else if (args[i].equals("-A")) {
includeAddresses = false;
} else if (args[i].equals("-k")) {
useKeytab = true;
} else if (args[i].equals("-t")) {
if (ktabName != null) {
throw new IllegalArgumentException
("-t option/keytab file name repeated");
} else if (i + 1 < args.length) {
ktabName = args[++i];
} else {
throw new IllegalArgumentException
("-t option requires keytab file name");
}
useKeytab = true;
} else if (args[i].equals("-R")) {
action = 2;
} else if (args[i].equals("-l")) {
lifetime = getTime(Config.duration(args[++i]));
} else if (args[i].equals("-r")) {
renewable_lifetime = getTime(Config.duration(args[++i]));
} else if (args[i].equalsIgnoreCase("-help")) {
printHelp();
System.exit(0);
} else if (p == null) { // Haven't yet processed a "principal"
p = args[i];
try {
principal = new PrincipalName(p);
} catch (Exception e) {
throw new IllegalArgumentException("invalid " +
"Principal name: " + p +
e.getMessage());
}
} else if (this.password == null) {
// Have already processed a Principal, this must be a password
password = args[i].toCharArray();
} else {
throw new IllegalArgumentException("too many parameters");
}
}
// we should get cache name before getting the default principal name
if (cachename == null) {
cachename = FileCredentialsCache.getDefaultCacheName();
if (cachename == null) {
throw new RuntimeException("default cache name error");
}
}
if (principal == null) {
principal = getDefaultPrincipal();
}
}
PrincipalName getDefaultPrincipal() {
// get default principal name from the cachename if it is
// available.
try {
CCacheInputStream cis =
new CCacheInputStream(new FileInputStream(cachename));
int version;
if ((version = cis.readVersion()) ==
FileCCacheConstants.KRB5_FCC_FVNO_4) {
cis.readTag();
} else {
if (version == FileCCacheConstants.KRB5_FCC_FVNO_1 ||
version == FileCCacheConstants.KRB5_FCC_FVNO_2) {
cis.setNativeByteOrder();
}
}
PrincipalName p = cis.readPrincipal(version);
cis.close();
if (DEBUG) {
System.out.println(">>>KinitOptions principal name from "+
"the cache is :" + p);
}
return p;
} catch (IOException e) {
// ignore any exceptions; we will use the user name as the
// principal name
if (DEBUG) {
e.printStackTrace();
}
} catch (RealmException e) {
if (DEBUG) {
e.printStackTrace();
}
}
String username = System.getProperty("user.name");
if (DEBUG) {
System.out.println(">>>KinitOptions default username is :"
+ username);
}
try {
PrincipalName p = new PrincipalName(username);
return p;
} catch (RealmException e) {
// ignore exception , return null
if (DEBUG) {
System.out.println ("Exception in getting principal " +
"name " + e.getMessage());
e.printStackTrace();
}
}
return null;
}
void printHelp() {
System.out.println("Usage:\n\n1. Initial ticket request:\n" +
" kinit [-A] [-f] [-p] [-c cachename] " +
"[-l lifetime] [-r renewable_time]\n" +
" [[-k [-t keytab_file_name]] [principal] " +
"[password]");
System.out.println("2. Renew a ticket:\n" +
" kinit -R [-c cachename] [principal]");
System.out.println("\nAvailable options to " +
"Kerberos 5 ticket request:");
System.out.println("\t-A do not include addresses");
System.out.println("\t-f forwardable");
System.out.println("\t-p proxiable");
System.out.println("\t-c cache name " +
"(i.e., FILE:\\d:\\myProfiles\\mykrb5cache)");
System.out.println("\t-l lifetime");
System.out.println("\t-r renewable time " +
"(total lifetime a ticket can be renewed)");
System.out.println("\t-k use keytab");
System.out.println("\t-t keytab file name");
System.out.println("\tprincipal the principal name "+
"(i.e., qweadf@ATHENA.MIT.EDU qweadf)");
System.out.println("\tpassword the principal's Kerberos password");
}
public boolean getAddressOption() {
return includeAddresses;
}
public boolean useKeytabFile() {
return useKeytab;
}
public String keytabFileName() {
return ktabName;
}
public PrincipalName getPrincipal() {
return principal;
}
private KerberosTime getTime(int s) {
return new KerberosTime(Instant.now().plusSeconds(s));
}
}

View file

@ -0,0 +1,356 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.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 java.net.InetAddress;
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.ccache.*;
import sun.security.krb5.internal.ktab.*;
import sun.security.krb5.internal.crypto.EType;
/**
* This class can execute as a command-line tool to list entries in
* credential cache and key tab.
*
* @author Yanni Zhang
* @author Ram Marti
*/
public class Klist {
Object target;
// for credentials cache, options are 'f', 'e', 'a' and 'n';
// for keytab, optionsare 't' and 'K' and 'e'
char[] options = new char[4];
String name; // the name of credentials cache and keytable.
char action; // actions would be 'c' for credentials cache
// and 'k' for keytable.
private static boolean DEBUG = Krb5.DEBUG;
/**
* The main program that can be invoked at command line.
* <br>Usage: klist
* [[-c] [-f] [-e] [-a [-n]]] [-k [-t] [-K]] [name]
* -c specifies that credential cache is to be listed
* -k specifies that key tab is to be listed
* name name of the credentials cache or keytab
* <br>available options for credential caches:
* <ul>
* <li><b>-f</b> shows credentials flags
* <li><b>-e</b> shows the encryption type
* <li><b>-a</b> shows addresses
* <li><b>-n</b> do not reverse-resolve addresses
* </ul>
* available options for keytabs:
* <ul>
* <li><b>-t</b> shows keytab entry timestamps
* <li><b>-K</b> shows keytab entry DES keys
* </ul>
*/
public static void main(String[] args) {
Klist klist = new Klist();
if ((args == null) || (args.length == 0)) {
klist.action = 'c'; // default will list default credentials cache.
} else {
klist.processArgs(args);
}
switch (klist.action) {
case 'c':
if (klist.name == null) {
klist.target = CredentialsCache.getInstance();
klist.name = CredentialsCache.cacheName();
} else
klist.target = CredentialsCache.getInstance(klist.name);
if (klist.target != null) {
klist.displayCache();
} else {
klist.displayMessage("Credentials cache");
System.exit(-1);
}
break;
case 'k':
KeyTab ktab = KeyTab.getInstance(klist.name);
if (ktab.isMissing()) {
System.out.println("KeyTab " + klist.name + " not found.");
System.exit(-1);
} else if (!ktab.isValid()) {
System.out.println("KeyTab " + klist.name
+ " format not supported.");
System.exit(-1);
}
klist.target = ktab;
klist.name = ktab.tabName();
klist.displayTab();
break;
default:
if (klist.name != null) {
klist.printHelp();
System.exit(-1);
} else {
klist.target = CredentialsCache.getInstance();
klist.name = CredentialsCache.cacheName();
if (klist.target != null) {
klist.displayCache();
} else {
klist.displayMessage("Credentials cache");
System.exit(-1);
}
}
}
}
/**
* Parses the command line arguments.
*/
void processArgs(String[] args) {
Character arg;
for (int i = 0; i < args.length; i++) {
if ((args[i].length() >= 2) && (args[i].startsWith("-"))) {
arg = Character.valueOf(args[i].charAt(1));
switch (arg.charValue()) {
case 'c':
action = 'c';
break;
case 'k':
action = 'k';
break;
case 'a':
options[2] = 'a';
break;
case 'n':
options[3] = 'n';
break;
case 'f':
options[1] = 'f';
break;
case 'e':
options[0] = 'e';
break;
case 'K':
options[1] = 'K';
break;
case 't':
options[2] = 't';
break;
default:
printHelp();
System.exit(-1);
}
} else {
if (!args[i].startsWith("-") && (i == args.length - 1)) {
// the argument is the last one.
name = args[i];
arg = null;
} else {
printHelp(); // incorrect input format.
System.exit(-1);
}
}
}
}
void displayTab() {
KeyTab table = (KeyTab)target;
KeyTabEntry[] entries = table.getEntries();
if (entries.length == 0) {
System.out.println("\nKey tab: " + name +
", " + " 0 entries found.\n");
} else {
if (entries.length == 1)
System.out.println("\nKey tab: " + name +
", " + entries.length + " entry found.\n");
else
System.out.println("\nKey tab: " + name + ", " +
entries.length + " entries found.\n");
for (int i = 0; i < entries.length; i++) {
System.out.println("[" + (i + 1) + "] " +
"Service principal: " +
entries[i].getService().toString());
System.out.println("\t KVNO: " +
entries[i].getKey().getKeyVersionNumber());
if (options[0] == 'e') {
EncryptionKey key = entries[i].getKey();
System.out.println("\t Key type: " +
key.getEType());
}
if (options[1] == 'K') {
EncryptionKey key = entries[i].getKey();
System.out.println("\t Key: " +
entries[i].getKeyString());
}
if (options[2] == 't') {
System.out.println("\t Time stamp: " +
format(entries[i].getTimeStamp()));
}
}
}
}
void displayCache() {
CredentialsCache cache = (CredentialsCache)target;
sun.security.krb5.internal.ccache.Credentials[] creds =
cache.getCredsList();
if (creds == null) {
System.out.println ("No credentials available in the cache " +
name);
System.exit(-1);
}
System.out.println("\nCredentials cache: " + name);
String defaultPrincipal = cache.getPrimaryPrincipal().toString();
int num = creds.length;
if (num == 1)
System.out.println("\nDefault principal: " +
defaultPrincipal + ", " +
creds.length + " entry found.\n");
else
System.out.println("\nDefault principal: " +
defaultPrincipal + ", " +
creds.length + " entries found.\n");
if (creds != null) {
for (int i = 0; i < creds.length; i++) {
try {
String starttime;
String endtime;
String renewTill;
String servicePrincipal;
if (creds[i].getStartTime() != null) {
starttime = format(creds[i].getStartTime());
} else {
starttime = format(creds[i].getAuthTime());
}
endtime = format(creds[i].getEndTime());
servicePrincipal =
creds[i].getServicePrincipal().toString();
System.out.println("[" + (i + 1) + "] " +
" Service Principal: " +
servicePrincipal);
System.out.println(" Valid starting: " + starttime);
System.out.println(" Expires: " + endtime);
if (creds[i].getRenewTill() != null) {
renewTill = format(creds[i].getRenewTill());
System.out.println(
" Renew until: " + renewTill);
}
if (options[0] == 'e') {
String eskey = EType.toString(creds[i].getEType());
String etkt = EType.toString(creds[i].getTktEType());
System.out.println(" EType (skey, tkt): "
+ eskey + ", " + etkt);
}
if (options[1] == 'f') {
System.out.println(" Flags: " +
creds[i].getTicketFlags().toString());
}
if (options[2] == 'a') {
boolean first = true;
InetAddress[] caddr
= creds[i].setKrbCreds().getClientAddresses();
if (caddr != null) {
for (InetAddress ia: caddr) {
String out;
if (options[3] == 'n') {
out = ia.getHostAddress();
} else {
out = ia.getCanonicalHostName();
}
System.out.println(" " +
(first?"Addresses:":" ") +
" " + out);
first = false;
}
} else {
System.out.println(" [No host addresses info]");
}
}
} catch (RealmException e) {
System.out.println("Error reading principal from "+
"the entry.");
if (DEBUG) {
e.printStackTrace();
}
System.exit(-1);
}
}
} else {
System.out.println("\nNo entries found.");
}
}
void displayMessage(String target) {
if (name == null) {
System.out.println("Default " + target + " not found.");
} else {
System.out.println(target + " " + name + " not found.");
}
}
/**
* Reformats the date from the form -
* dow mon dd hh:mm:ss zzz yyyy to mon/dd/yyyy hh:mm
* where dow is the day of the week, mon is the month,
* dd is the day of the month, hh is the hour of
* the day, mm is the minute within the hour,
* ss is the second within the minute, zzz is the time zone,
* and yyyy is the year.
* @param date the string form of Date object.
*/
private String format(KerberosTime kt) {
String date = kt.toDate().toString();
return (date.substring(4, 7) + " " + date.substring(8, 10) +
", " + date.substring(24)
+ " " + date.substring(11, 19));
}
/**
* Prints out the help information.
*/
void printHelp() {
System.out.println("\nUsage: klist " +
"[[-c] [-f] [-e] [-a [-n]]] [-k [-t] [-K]] [name]");
System.out.println(" name\t name of credentials cache or " +
" keytab with the prefix. File-based cache or "
+ "keytab's prefix is FILE:.");
System.out.println(" -c specifies that credential cache is to be " +
"listed");
System.out.println(" -k specifies that key tab is to be listed");
System.out.println(" options for credentials caches:");
System.out.println("\t-f \t shows credentials flags");
System.out.println("\t-e \t shows the encryption type");
System.out.println("\t-a \t shows addresses");
System.out.println("\t -n \t do not reverse-resolve addresses");
System.out.println(" options for keytabs:");
System.out.println("\t-t \t shows keytab entry timestamps");
System.out.println("\t-K \t shows keytab entry key value");
System.out.println("\t-e \t shows keytab entry key type");
System.out.println("\nUsage: java sun.security.krb5.tools.Klist " +
"-help for help.");
}
}

View file

@ -0,0 +1,453 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.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.ktab.*;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.File;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import sun.security.krb5.internal.crypto.EType;
/**
* This class can execute as a command-line tool to help the user manage
* entries 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;
boolean showEType;
boolean showTime;
int etype = -1;
char[] password = null;
boolean forced = false; // true if delete without prompt. Default false
boolean append = false; // true if new keys are appended. Default false
int vDel = -1; // kvno to delete, -1 all, -2 old. Default -1
int vAdd = -1; // kvno to add. Default -1, means auto incremented
/**
* The main program that can be invoked at command line.
* See {@link #printHelp} for usages.
*/
public static void main(String[] args) {
Ktab ktab = new Ktab();
if ((args.length == 1) && (args[0].equalsIgnoreCase("-help"))) {
ktab.printHelp();
return;
} else if ((args == null) || (args.length == 0)) {
ktab.action = 'l';
} else {
ktab.processArgs(args);
}
ktab.table = KeyTab.getInstance(ktab.name);
if (ktab.table.isMissing() && ktab.action != 'a') {
if (ktab.name == null) {
System.out.println("No default key table exists.");
} else {
System.out.println("Key table " +
ktab.name + " does not exist.");
}
System.exit(-1);
}
if (!ktab.table.isValid()) {
if (ktab.name == null) {
System.out.println("The format of the default key table " +
" is incorrect.");
} else {
System.out.println("The format of key table " +
ktab.name + " is incorrect.");
}
System.exit(-1);
}
switch (ktab.action) {
case 'l':
ktab.listKt();
break;
case 'a':
ktab.addEntry();
break;
case 'd':
ktab.deleteEntry();
break;
default:
ktab.error("A command must be provided");
}
}
/**
* Parses the command line arguments.
*/
void processArgs(String[] args) {
// Commands (should appear before options):
// -l
// -a <princ>
// -d <princ>
// Options:
// -e <etype> (for -d)
// -e (for -l)
// -n <kvno>
// -k <keytab>
// -t
// -f
// -append
// Optional extra arguments:
// password for -a
// [kvno|all|old] for -d
boolean argAlreadyAppeared = false;
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
switch (args[i].toLowerCase(Locale.US)) {
// Commands
case "-l": // list
action = 'l';
break;
case "-a": // add a new entry to keytab.
action = 'a';
if (++i >= args.length || args[i].startsWith("-")) {
error("A principal name must be specified after -a");
}
principal = args[i];
break;
case "-d": // delete entries
action = 'd';
if (++i >= args.length || args[i].startsWith("-")) {
error("A principal name must be specified after -d");
}
principal = args[i];
break;
// Options
case "-e":
if (action == 'l') { // list etypes
showEType = true;
} else if (action == 'd') { // delete etypes
if (++i >= args.length || args[i].startsWith("-")) {
error("An etype must be specified after -e");
}
try {
etype = Integer.parseInt(args[i]);
if (etype <= 0) {
throw new NumberFormatException();
}
} catch (NumberFormatException nfe) {
error(args[i] + " is not a valid etype");
}
} else {
error(args[i] + " is not valid after -" + action);
}
break;
case "-n": // kvno for -a
if (++i >= args.length || args[i].startsWith("-")) {
error("A KVNO must be specified after -n");
}
try {
vAdd = Integer.parseInt(args[i]);
if (vAdd < 0) {
throw new NumberFormatException();
}
} catch (NumberFormatException nfe) {
error(args[i] + " is not a valid KVNO");
}
break;
case "-k": // specify keytab to use
if (++i >= args.length || args[i].startsWith("-")) {
error("A keytab name must be specified after -k");
}
if (args[i].length() >= 5 &&
args[i].substring(0, 5).equalsIgnoreCase("FILE:")) {
name = args[i].substring(5);
} else {
name = args[i];
}
break;
case "-t": // list timestamps
showTime = true;
break;
case "-f": // force delete, no prompt
forced = true;
break;
case "-append": // -a, new keys append to file
append = true;
break;
default:
error("Unknown command: " + args[i]);
break;
}
} else { // optional standalone arguments
if (argAlreadyAppeared) {
error("Useless extra argument " + args[i]);
}
if (action == 'a') {
password = args[i].toCharArray();
} else if (action == 'd') {
switch (args[i]) {
case "all": vDel = -1; break;
case "old": vDel = -2; break;
default: {
try {
vDel = Integer.parseInt(args[i]);
if (vDel < 0) {
throw new NumberFormatException();
}
} catch (NumberFormatException nfe) {
error(args[i] + " is not a valid KVNO");
}
}
}
} else {
error("Useless extra argument " + args[i]);
}
argAlreadyAppeared = true;
}
}
}
/**
* 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);
} 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, vAdd, append);
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() {
System.out.println("Keytab name: " + table.tabName());
KeyTabEntry[] entries = table.getEntries();
if ((entries != null) && (entries.length > 0)) {
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++) {
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();
}
}
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.");
}
}
/**
* Deletes an entry from the key table.
*/
void deleteEntry() {
PrincipalName pname = null;
try {
pname = new PrincipalName(principal);
if (!forced) {
String answer;
BufferedReader cis =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("Are you sure you want to delete "+
"service key(s) for " + pname.toString() +
" (" + (etype==-1?"all etypes":("etype="+etype)) + ", " +
(vDel==-1?"all kvno":(vDel==-2?"old kvno":("kvno=" + vDel))) +
") 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 occurred while deleting the entry. "+
"Deletion failed.");
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
System.err.println("Error occurred while deleting the entry. "+
" Deletion failed.");
e.printStackTrace();
System.exit(-1);
}
int count = table.deleteEntries(pname, etype, vDel);
if (count == 0) {
System.err.println("No matched entry in the keytab. " +
"Deletion fails.");
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! " + count + " entries removed.");
}
}
void error(String... errors) {
for (String error: errors) {
System.out.println("Error: " + error + ".");
}
printHelp();
System.exit(-1);
}
/**
* Prints out the help information.
*/
void printHelp() {
System.out.println("\nUsage: ktab <commands> <options>");
System.out.println();
System.out.println("Available commands:");
System.out.println();
System.out.println("-l [-e] [-t]\n"
+ " list the keytab name and entries. -e with etype, -t with timestamp.");
System.out.println("-a <principal name> [<password>] [-n <kvno>] [-append]\n"
+ " add new key entries to the keytab for the given principal name with\n"
+ " optional <password>. If a <kvno> is specified, new keys' Key Version\n"
+ " Numbers equal to the value, otherwise, automatically incrementing\n"
+ " the Key Version Numbers. If -append is specified, new keys are\n"
+ " appended to the keytab, otherwise, old keys for the\n"
+ " same principal are removed.");
System.out.println("-d <principal name> [-f] [-e <etype>] [<kvno> | all | old]\n"
+ " delete key entries from the keytab for the specified principal. If\n"
+ " <kvno> is specified, delete keys whose Key Version Numbers match\n"
+ " kvno. If \"all\" is specified, delete all keys. If \"old\" is specified,\n"
+ " delete all keys except those with the highest kvno. Default action\n"
+ " is \"all\". If <etype> is specified, only keys of this encryption type\n"
+ " are deleted. <etype> should be specified as the numberic value etype\n"
+ " defined in RFC 3961, section 8. A prompt to confirm the deletion is\n"
+ " displayed unless -f is specified.");
System.out.println();
System.out.println("Common option(s):");
System.out.println();
System.out.println("-k <keytab name>\n"
+ " specify keytab name and path with prefix FILE:");
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#define UNICODE
#include <jni.h>
#include <windows.h>
#include <stdlib.h>
/*
* Class: sun_security_krb5_Config
* Method: getWindowsDirectory
* Signature: (Z)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_sun_security_krb5_Config_getWindowsDirectory(
JNIEnv* env, jclass configClass, jboolean isSystem) {
TCHAR lpPath[MAX_PATH+1];
UINT len;
if (isSystem) {
len = GetSystemWindowsDirectory(lpPath, MAX_PATH);
} else {
len = GetWindowsDirectory(lpPath, MAX_PATH);
}
if (len) {
return (*env)->NewString(env, lpPath, len);
} else {
return NULL;
}
}