mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-19 18:07:49 +00:00
6950546: "ktab -d name etype" to "ktab -d name [-e etype] [kvno | all | old]"
6984764: kerberos fails if service side keytab is generated using JDK ktab Reviewed-by: valeriep
This commit is contained in:
parent
6f104b3aa2
commit
d2ef113186
@ -34,7 +34,6 @@ package sun.security.krb5.internal.ktab;
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import java.util.Vector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.io.IOException;
|
||||
@ -42,7 +41,10 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.File;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* This class represents key table. The key table functions deal with storing
|
||||
@ -239,23 +241,22 @@ public class KeyTab implements KeyTabConstants {
|
||||
EncryptionKey key;
|
||||
int size = entries.size();
|
||||
ArrayList<EncryptionKey> keys = new ArrayList<EncryptionKey> (size);
|
||||
if (entries != null) {
|
||||
for (int i = size-1; i >= 0; i--) {
|
||||
entry = entries.elementAt(i);
|
||||
if (entry.service.match(service)) {
|
||||
if (EType.isSupported(entry.keyType)) {
|
||||
key = new EncryptionKey(entry.keyblock,
|
||||
entry.keyType,
|
||||
new Integer(entry.keyVersion));
|
||||
keys.add(key);
|
||||
if (DEBUG) {
|
||||
System.out.println("Added key: " + entry.keyType +
|
||||
"version: " + entry.keyVersion);
|
||||
}
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Found unsupported keytype (" +
|
||||
entry.keyType + ") for " + service);
|
||||
|
||||
for (int i = size-1; i >= 0; i--) {
|
||||
entry = entries.elementAt(i);
|
||||
if (entry.service.match(service)) {
|
||||
if (EType.isSupported(entry.keyType)) {
|
||||
key = new EncryptionKey(entry.keyblock,
|
||||
entry.keyType,
|
||||
new Integer(entry.keyVersion));
|
||||
keys.add(key);
|
||||
if (DEBUG) {
|
||||
System.out.println("Added key: " + entry.keyType +
|
||||
"version: " + entry.keyVersion);
|
||||
}
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Found unsupported keytype (" +
|
||||
entry.keyType + ") for " + service);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -313,16 +314,14 @@ public class KeyTab implements KeyTabConstants {
|
||||
*/
|
||||
public boolean findServiceEntry(PrincipalName service) {
|
||||
KeyTabEntry entry;
|
||||
if (entries != null) {
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
entry = entries.elementAt(i);
|
||||
if (entry.service.match(service)) {
|
||||
if (EType.isSupported(entry.keyType)) {
|
||||
return true;
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Found unsupported keytype (" +
|
||||
entry.keyType + ") for " + service);
|
||||
}
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
entry = entries.elementAt(i);
|
||||
if (entry.service.match(service)) {
|
||||
if (EType.isSupported(entry.keyType)) {
|
||||
return true;
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Found unsupported keytype (" +
|
||||
entry.keyType + ") for " + service);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -337,78 +336,45 @@ public class KeyTab implements KeyTabConstants {
|
||||
* Adds a new entry in the key table.
|
||||
* @param service the service which will have a new entry in the key table.
|
||||
* @param psswd the password which generates the key.
|
||||
* @param kvno the kvno to use, -1 means automatic increasing
|
||||
* @param append false if entries with old kvno would be removed.
|
||||
* Note: if kvno is not -1, entries with the same kvno are always removed
|
||||
*/
|
||||
public void addEntry(PrincipalName service, char[] psswd)
|
||||
throws KrbException {
|
||||
public void addEntry(PrincipalName service, char[] psswd,
|
||||
int kvno, boolean append) throws KrbException {
|
||||
|
||||
EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
|
||||
psswd, service.getSalt());
|
||||
|
||||
for (int i = 0; encKeys != null && i < encKeys.length; i++) {
|
||||
int keyType = encKeys[i].getEType();
|
||||
byte[] keyValue = encKeys[i].getBytes();
|
||||
int result = retrieveEntry(service, keyType);
|
||||
int kvno = 1;
|
||||
if (result != -1) {
|
||||
KeyTabEntry oldEntry = entries.elementAt(result);
|
||||
kvno = oldEntry.keyVersion;
|
||||
entries.removeElementAt(result);
|
||||
kvno += 1;
|
||||
} else
|
||||
kvno = 1;
|
||||
// There should be only one maximum KVNO value for all etypes, so that
|
||||
// all added keys can have the same KVNO.
|
||||
|
||||
KeyTabEntry newEntry = new KeyTabEntry(service,
|
||||
service.getRealm(),
|
||||
new KerberosTime(System.currentTimeMillis()),
|
||||
kvno, keyType, keyValue);
|
||||
if (entries == null)
|
||||
entries = new Vector<KeyTabEntry> ();
|
||||
entries.addElement(newEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only used by KDC test. This method can specify kvno and does not
|
||||
* remove any old keys.
|
||||
*/
|
||||
public void addEntry(PrincipalName service, char[] psswd, int kvno)
|
||||
throws KrbException {
|
||||
|
||||
EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
|
||||
psswd, service.getSalt());
|
||||
|
||||
for (int i = 0; encKeys != null && i < encKeys.length; i++) {
|
||||
int keyType = encKeys[i].getEType();
|
||||
byte[] keyValue = encKeys[i].getBytes();
|
||||
KeyTabEntry newEntry = new KeyTabEntry(service,
|
||||
service.getRealm(),
|
||||
new KerberosTime(System.currentTimeMillis()),
|
||||
kvno, keyType, keyValue);
|
||||
if (entries == null)
|
||||
entries = new Vector<KeyTabEntry> ();
|
||||
entries.addElement(newEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the key table entry with the specified service name.
|
||||
* @param service the service which may have an entry in the key table.
|
||||
* @param keyType the etype to match, returns the 1st one if -1 provided
|
||||
* @return -1 if the entry is not found, else return the entry index
|
||||
* in the list.
|
||||
*/
|
||||
private int retrieveEntry(PrincipalName service, int keyType) {
|
||||
KeyTabEntry e;
|
||||
if (entries != null) {
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
e = entries.elementAt(i);
|
||||
if (service.match(e.getService()) &&
|
||||
(keyType == -1 || e.keyType == keyType)) {
|
||||
return i;
|
||||
int maxKvno = 0; // only useful when kvno == -1
|
||||
for (int i = entries.size()-1; i >= 0; i--) {
|
||||
KeyTabEntry e = entries.get(i);
|
||||
if (e.service.match(service)) {
|
||||
if (e.keyVersion > maxKvno) {
|
||||
maxKvno = e.keyVersion;
|
||||
}
|
||||
if (!append || e.keyVersion == kvno) {
|
||||
entries.removeElementAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
if (kvno == -1) {
|
||||
kvno = maxKvno + 1;
|
||||
}
|
||||
|
||||
for (int i = 0; encKeys != null && i < encKeys.length; i++) {
|
||||
int keyType = encKeys[i].getEType();
|
||||
byte[] keyValue = encKeys[i].getBytes();
|
||||
|
||||
KeyTabEntry newEntry = new KeyTabEntry(service,
|
||||
service.getRealm(),
|
||||
new KerberosTime(System.currentTimeMillis()),
|
||||
kvno, keyType, keyValue);
|
||||
entries.addElement(newEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -416,15 +382,11 @@ public class KeyTab implements KeyTabConstants {
|
||||
* @return array of <code>KeyTabEntry</code>.
|
||||
*/
|
||||
public KeyTabEntry[] getEntries() {
|
||||
if (entries != null) {
|
||||
KeyTabEntry[] kentries = new KeyTabEntry[entries.size()];
|
||||
for (int i = 0; i < kentries.length; i++) {
|
||||
kentries[i] = entries.elementAt(i);
|
||||
}
|
||||
return kentries;
|
||||
} else {
|
||||
return null;
|
||||
KeyTabEntry[] kentries = new KeyTabEntry[entries.size()];
|
||||
for (int i = 0; i < kentries.length; i++) {
|
||||
kentries[i] = entries.elementAt(i);
|
||||
}
|
||||
return kentries;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -464,29 +426,55 @@ public class KeyTab implements KeyTabConstants {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an entry from the key table.
|
||||
* Removes entries from the key table.
|
||||
* @param service the service <code>PrincipalName</code>.
|
||||
* @param etype the etype to match, first one if -1 provided
|
||||
* @return 1 if removed successfully, 0 otherwise
|
||||
* @param etype the etype to match, remove all if -1
|
||||
* @param kvno what kvno to remove, -1 for all, -2 for old
|
||||
* @return the number of entries deleted
|
||||
*/
|
||||
public int deleteEntry(PrincipalName service, int etype) {
|
||||
int result = retrieveEntry(service, etype);
|
||||
if (result != -1) {
|
||||
entries.removeElementAt(result);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an entry from the key table.
|
||||
* @param service the service <code>PrincipalName</code>.
|
||||
* @return number of entries removed
|
||||
*/
|
||||
public int deleteEntry(PrincipalName service) {
|
||||
public int deleteEntries(PrincipalName service, int etype, int kvno) {
|
||||
int count = 0;
|
||||
while (deleteEntry(service, -1) > 0) {
|
||||
count++;
|
||||
|
||||
// Remember the highest KVNO for each etype. Used for kvno == -2
|
||||
Map<Integer,Integer> highest = new HashMap<>();
|
||||
|
||||
for (int i = entries.size()-1; i >= 0; i--) {
|
||||
KeyTabEntry e = entries.get(i);
|
||||
if (service.match(e.getService())) {
|
||||
if (etype == -1 || e.keyType == etype) {
|
||||
if (kvno == -2) {
|
||||
// Two rounds for kvno == -2. In the first round (here),
|
||||
// only find out highest KVNO for each etype
|
||||
if (highest.containsKey(e.keyType)) {
|
||||
int n = highest.get(e.keyType);
|
||||
if (e.keyVersion > n) {
|
||||
highest.put(e.keyType, e.keyVersion);
|
||||
}
|
||||
} else {
|
||||
highest.put(e.keyType, e.keyVersion);
|
||||
}
|
||||
} else if (kvno == -1 || e.keyVersion == kvno) {
|
||||
entries.removeElementAt(i);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second round for kvno == -2, remove old entries
|
||||
if (kvno == -2) {
|
||||
for (int i = entries.size()-1; i >= 0; i--) {
|
||||
KeyTabEntry e = entries.get(i);
|
||||
if (service.match(e.getService())) {
|
||||
if (etype == -1 || e.keyType == etype) {
|
||||
int n = highest.get(e.keyType);
|
||||
if (e.keyVersion != n) {
|
||||
entries.removeElementAt(i);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2010, 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
|
||||
@ -39,10 +39,11 @@ 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
|
||||
* entires in the key table.
|
||||
* entries in the key table.
|
||||
* Available functions include list/add/update/delete service key(s).
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
@ -60,30 +61,20 @@ public class Ktab {
|
||||
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.
|
||||
* <br>Usage: ktab <options>
|
||||
* <br>available options to Ktab:
|
||||
* <ul>
|
||||
* <li><b>-l [-e] [-t]</b> list the keytab name and entries, -e show
|
||||
* encryption etypes, -t show timestamps.
|
||||
* <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>> [<<i>etype</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.
|
||||
* 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();
|
||||
System.exit(0);
|
||||
return;
|
||||
} else if ((args == null) || (args.length == 0)) {
|
||||
ktab.action = 'l';
|
||||
} else {
|
||||
@ -139,7 +130,6 @@ public class Ktab {
|
||||
break;
|
||||
default:
|
||||
ktab.printHelp();
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,84 +137,129 @@ public class Ktab {
|
||||
* Parses the command line arguments.
|
||||
*/
|
||||
void processArgs(String[] args) {
|
||||
Character arg = null;
|
||||
|
||||
// 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].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 (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:
|
||||
printHelp();
|
||||
break;
|
||||
}
|
||||
if ((i + 1 < args.length) &&
|
||||
(!args[i + 1].startsWith("-"))) {
|
||||
password = args[i + 1].toCharArray();
|
||||
i++;
|
||||
} else {
|
||||
password = null; // prompt user for password later.
|
||||
} else { // optional standalone arguments
|
||||
if (argAlreadyAppeared) {
|
||||
error("Useless extra argument " + args[i]);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
action = 'd'; // delete an entry.
|
||||
i++;
|
||||
if ((i < args.length) && (!args[i].startsWith("-"))) {
|
||||
principal = args[i];
|
||||
int j = i + 1;
|
||||
if ((j < args.length) && (!args[j].startsWith("-"))) {
|
||||
etype = Integer.parseInt(args[j]);
|
||||
i = j;
|
||||
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 {
|
||||
System.out.println("Please specify the principal" +
|
||||
"name of the entry you want to " +
|
||||
" delete after -d option.");
|
||||
printHelp();
|
||||
System.exit(-1);
|
||||
error("Useless extra argument " + args[i]);
|
||||
}
|
||||
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;
|
||||
case 'e':
|
||||
showEType = true;
|
||||
break;
|
||||
case 't':
|
||||
showTime = true;
|
||||
break;
|
||||
default:
|
||||
printHelp();
|
||||
System.exit(-1);
|
||||
argAlreadyAppeared = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,7 +298,7 @@ public class Ktab {
|
||||
}
|
||||
try {
|
||||
// admin.addEntry(pname, password);
|
||||
table.addEntry(pname, password);
|
||||
table.addEntry(pname, password, vAdd, append);
|
||||
Arrays.fill(password, '0'); // clear password
|
||||
// admin.save();
|
||||
table.save();
|
||||
@ -350,23 +385,25 @@ public class Ktab {
|
||||
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() +
|
||||
" (" + (etype==-1?"all etypes":("etype = "+etype)) +
|
||||
") in " + table.tabName() + "?(Y/N): ");
|
||||
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);
|
||||
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.");
|
||||
@ -379,9 +416,7 @@ public class Ktab {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
int count;
|
||||
if (etype == -1) count = table.deleteEntry(pname);
|
||||
else count = table.deleteEntry(pname, etype);
|
||||
int count = table.deleteEntries(pname, etype, vDel);
|
||||
|
||||
if (count == 0) {
|
||||
System.err.println("No matched entry in the keytab. " +
|
||||
@ -396,23 +431,47 @@ public class Ktab {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
System.out.println("Done!");
|
||||
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 " +
|
||||
"<options>");
|
||||
System.out.println("available options to Ktab:");
|
||||
System.out.println("-l [-e] [-t]\t\t\tlist the keytab name and entries,\n\t\t\t\t-e with etype, -t with timestamp");
|
||||
System.out.println("-a <principal name> (<password>)add an entry " +
|
||||
"to the keytab");
|
||||
System.out.println("-d <principal name> [<etype>]\tdelete an "+
|
||||
"entry from the keytab");
|
||||
System.out.println("-k <keytab name>\t\tspecify keytab name and "+
|
||||
"path with prefix FILE:");
|
||||
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:");
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ public class KDC {
|
||||
name.indexOf('/') < 0 ?
|
||||
PrincipalName.KRB_NT_UNKNOWN :
|
||||
PrincipalName.KRB_NT_SRV_HST),
|
||||
kdc.passwords.get(name));
|
||||
kdc.passwords.get(name), -1, true);
|
||||
}
|
||||
}
|
||||
ktab.save();
|
||||
|
||||
59
jdk/test/sun/security/krb5/tools/KtabCheck.java
Normal file
59
jdk/test/sun/security/krb5/tools/KtabCheck.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import sun.security.krb5.internal.ktab.KeyTab;
|
||||
import sun.security.krb5.internal.ktab.KeyTabEntry;
|
||||
|
||||
/**
|
||||
* This class is called by the test ktcheck.sh and is not meant to run
|
||||
* by itself.
|
||||
*/
|
||||
public class KtabCheck {
|
||||
/**
|
||||
* Checks if a keytab contains exactly the keys (kvno and etype)
|
||||
* @param args keytabname kvno etype...
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Checking " + Arrays.toString(args));
|
||||
KeyTab ktab = KeyTab.getInstance(args[0]);
|
||||
Set<String> expected = new HashSet<String>();
|
||||
for (int i=1; i<args.length; i += 2) {
|
||||
expected.add(args[i]+":"+args[i+1]);
|
||||
}
|
||||
for (KeyTabEntry e: ktab.getEntries()) {
|
||||
// KVNO and etype
|
||||
String vne = e.getKey().getKeyVersionNumber() + ":" +
|
||||
e.getKey().getEType();
|
||||
if (!expected.contains(vne)) {
|
||||
throw new Exception("No " + vne + " in expected");
|
||||
}
|
||||
expected.remove(vne);
|
||||
}
|
||||
if (!expected.isEmpty()) {
|
||||
throw new Exception("Extra elements in expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
94
jdk/test/sun/security/krb5/tools/ktcheck.sh
Normal file
94
jdk/test/sun/security/krb5/tools/ktcheck.sh
Normal file
@ -0,0 +1,94 @@
|
||||
#
|
||||
# Copyright (c) 2010, 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# @test
|
||||
# @bug 6950546
|
||||
# @summary "ktab -d name etype" to "ktab -d name [-e etype] [kvno | all | old]"
|
||||
# @run shell ktcheck.sh
|
||||
#
|
||||
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
JAVAC_CMD=`which javac`
|
||||
TESTJAVA=`dirname $JAVAC_CMD`/..
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC="."
|
||||
fi
|
||||
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
CYGWIN* )
|
||||
FS="/"
|
||||
;;
|
||||
Windows_* )
|
||||
FS="\\"
|
||||
;;
|
||||
* )
|
||||
FS="/"
|
||||
echo "Unsupported system!"
|
||||
exit 0;
|
||||
;;
|
||||
esac
|
||||
|
||||
KEYTAB=ktab.tmp
|
||||
|
||||
rm $KEYTAB
|
||||
${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}KtabCheck.java
|
||||
|
||||
EXTRA_OPTIONS="-Djava.security.krb5.conf=${TESTSRC}${FS}onlythree.conf"
|
||||
KTAB="${TESTJAVA}${FS}bin${FS}ktab -J${EXTRA_OPTIONS} -k $KEYTAB -f"
|
||||
CHECK="${TESTJAVA}${FS}bin${FS}java ${EXTRA_OPTIONS} KtabCheck $KEYTAB"
|
||||
|
||||
echo ${EXTRA_OPTIONS}
|
||||
|
||||
$KTAB -a me mine
|
||||
$CHECK 1 16 1 23 1 17 || exit 1
|
||||
$KTAB -a me mine -n 0
|
||||
$CHECK 0 16 0 23 0 17 || exit 1
|
||||
$KTAB -a me mine -n 1 -append
|
||||
$CHECK 0 16 0 23 0 17 1 16 1 23 1 17 || exit 1
|
||||
$KTAB -a me mine -append
|
||||
$CHECK 0 16 0 23 0 17 1 16 1 23 1 17 2 16 2 23 2 17 || exit 1
|
||||
$KTAB -a me mine
|
||||
$CHECK 3 16 3 23 3 17 || exit 1
|
||||
$KTAB -a me mine -n 4 -append
|
||||
$CHECK 3 16 3 23 3 17 4 16 4 23 4 17 || exit 1
|
||||
$KTAB -a me mine -n 5 -append
|
||||
$CHECK 3 16 3 23 3 17 4 16 4 23 4 17 5 16 5 23 5 17 || exit 1
|
||||
$KTAB -a me mine -n 6 -append
|
||||
$CHECK 3 16 3 23 3 17 4 16 4 23 4 17 5 16 5 23 5 17 6 16 6 23 6 17 || exit 1
|
||||
$KTAB -d me 3
|
||||
$CHECK 4 16 4 23 4 17 5 16 5 23 5 17 6 16 6 23 6 17 || exit 1
|
||||
$KTAB -d me -e 16 6
|
||||
$CHECK 4 16 4 23 4 17 5 16 5 23 5 17 6 23 6 17 || exit 1
|
||||
$KTAB -d me -e 17 6
|
||||
$CHECK 4 16 4 23 4 17 5 16 5 23 5 17 6 23 || exit 1
|
||||
$KTAB -d me -e 16 5
|
||||
$CHECK 4 16 4 23 4 17 5 23 5 17 6 23 || exit 1
|
||||
$KTAB -d me old
|
||||
$CHECK 4 16 5 17 6 23 || exit 1
|
||||
$KTAB -d me old
|
||||
$CHECK 4 16 5 17 6 23 || exit 1
|
||||
$KTAB -d me
|
||||
$CHECK || exit 1
|
||||
9
jdk/test/sun/security/krb5/tools/onlythree.conf
Normal file
9
jdk/test/sun/security/krb5/tools/onlythree.conf
Normal file
@ -0,0 +1,9 @@
|
||||
[libdefaults]
|
||||
default_realm = LOCAL.COM
|
||||
default_tkt_enctypes = des3-cbc-sha1 rc4-hmac aes128-cts
|
||||
|
||||
[realms]
|
||||
LOCAL.COM = {
|
||||
kdc = localhost
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user