Skip to content
Permalink
Browse files
8279064: New options for ktab to provide non-default salt
Reviewed-by: valeriep
  • Loading branch information
wangweij committed Jan 14, 2022
1 parent c359c35 commit 0d1a97f793309919bd6d67085630049eaafcced1
Showing 5 changed files with 157 additions and 23 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2022, 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
@@ -376,12 +376,33 @@ public void addEntry(PrincipalName service, char[] psswd,
addEntry(service, service.getSalt(), psswd, kvno, append);
}

// Called by KDC test
/**
* Adds a new entry in the key table.
* @param service the service which will have a new entry in the key table.
* @param salt specified non default salt, cannot be null
* @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, String salt, char[] psswd,
int kvno, boolean append) throws KrbException {

EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
psswd, salt);
psswd, salt);
addEntry(service, encKeys, kvno, append);
}

/**
* Adds a new entry in the key table.
* @param service the service which will have a new entry in the key table.
* @param encKeys the keys to be added
* @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, EncryptionKey[] encKeys,
int kvno, boolean append) throws KrbException {

// There should be only one maximum KVNO value for all etypes, so that
// all added keys can have the same KVNO.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2022, 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
@@ -35,7 +35,6 @@
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;
@@ -61,10 +60,12 @@ public class Ktab {
int etype = -1;
char[] password = null;

boolean forced = false; // true if delete without prompt. Default false
boolean fopt = false; // true if delete without prompt or
// add by contacting KDC. 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
String salt = null; // salt to use. Default null, means default salt

/**
* The main program that can be invoked at command line.
@@ -186,6 +187,12 @@ void processArgs(String[] args) {
error(args[i] + " is not valid after -" + action);
}
break;
case "-s": // salt for -a
if (++i >= args.length || args[i].startsWith("-")) {
error("A salt string must be specified after -s");
}
salt = args[i];
break;
case "-n": // kvno for -a
if (++i >= args.length || args[i].startsWith("-")) {
error("A KVNO must be specified after -n");
@@ -213,8 +220,8 @@ void processArgs(String[] args) {
case "-t": // list timestamps
showTime = true;
break;
case "-f": // force delete, no prompt
forced = true;
case "-f": // force delete or get salt from KDC
fopt = true;
break;
case "-append": // -a, new keys append to file
append = true;
@@ -258,6 +265,10 @@ void processArgs(String[] args) {
* a new key table.
*/
void addEntry() {
if (salt != null && fopt) {
System.err.println("-s and -f cannot coexist when adding a keytab entry.");
System.exit(-1);
}
PrincipalName pname = null;
try {
pname = new PrincipalName(principal);
@@ -283,7 +294,15 @@ void addEntry() {
}
try {
// admin.addEntry(pname, password);
table.addEntry(pname, password, vAdd, append);
if (fopt) {
KrbAsReqBuilder builder = new KrbAsReqBuilder(pname, password);
builder.action();
table.addEntry(pname, builder.getKeys(true), vAdd, append);
} else if (salt != null) {
table.addEntry(pname, salt, password, vAdd, append);
} else {
table.addEntry(pname, password, vAdd, append);
}
Arrays.fill(password, '0'); // clear password
// admin.save();
table.save();
@@ -367,7 +386,7 @@ void deleteEntry() {
PrincipalName pname = null;
try {
pname = new PrincipalName(principal);
if (!forced) {
if (!fopt) {
String answer;
BufferedReader cis =
new BufferedReader(new InputStreamReader(System.in));
@@ -424,6 +443,7 @@ void error(String... errors) {
printHelp();
System.exit(-1);
}

/**
* Prints out the help information.
*/
@@ -434,11 +454,13 @@ void printHelp() {
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"
System.out.println("-a <principal name> [<password>] [-n <kvno>] [-f | -s <salt>] [-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"
+ " the Key Version Numbers. If <salt> is specified, it will be used\n"
+ " instead of the default salt. If -f is specified, the KDC will be\n"
+ " contacted to fetch the salt. 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"
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2022, 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
@@ -207,13 +207,26 @@ public static Context fromUserKtab(
*/
public static Context fromUserKtab(Subject s,
String user, String ktab, boolean storeKey) throws Exception {
return fromUserKtab(s, user, ktab, false, storeKey);
}

/**
* Logins with username/keytab as a client.
*/
public static Context fromUserKtabAsClient(
String user, String ktab, boolean storeKey) throws Exception {
return fromUserKtab(new Subject(), user, ktab, true, storeKey);
}

private static Context fromUserKtab(Subject s,
String user, String ktab, boolean isInitiator, boolean storeKey) throws Exception {
Context out = new Context();
out.name = user;
out.s = s;
Krb5LoginModule krb5 = new Krb5LoginModule();
Map<String, String> map = new HashMap<>();

map.put("isInitiator", "false");
map.put("isInitiator", Boolean.toString(isInitiator));
map.put("doNotPrompt", "true");
map.put("useTicketCache", "false");
map.put("useKeyTab", "true");
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2022, 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 8279064
* @summary New options for ktab to provide non-default salt
* @requires os.family == "windows"
* @library /test/lib
* @library /sun/security/krb5/auto
* @compile -XDignore.symbol.file KtabSalt.java
* @run main jdk.test.lib.FileInstaller ../TestHosts TestHosts
* @run main/othervm -Djdk.net.hosts.file=TestHosts KtabSalt
*/

import jdk.test.lib.SecurityTools;
import jdk.test.lib.Utils;
import jdk.test.lib.process.OutputAnalyzer;

import javax.security.auth.login.LoginException;

public class KtabSalt {

public static void main(String[] args) throws Exception {

OneKDC kdc = new OneKDC(null).writeJAASConf();
kdc.addPrincipal("u1", "password".toCharArray(),
"this_is_my_salt", null);

// Using password works
Context.fromUserPass("u1", "password".toCharArray(), true);

// Using KDC's keytab works
kdc.writeKtab("ktab0");
Context.fromUserKtabAsClient("u1", "ktab0", true);

// Self-created keytab with default salt does not work
ktab("-a u1 password -k ktab1");
Utils.runAndCheckException(
() -> Context.fromUserKtabAsClient("u1", "ktab1", true),
LoginException.class);

// Self-creating keytab with specified salt works
ktab("-a u1 password -s this_is_my_salt -k ktab2");
Context.fromUserKtabAsClient("u1", "ktab2", true);

// Self-creating keytab with salt from KDC works
ktab("-a u1 password -f -k ktab3");
Context.fromUserKtabAsClient("u1", "ktab3", true);
}

static OutputAnalyzer ktab(String cmdLine) throws Exception {
String fullCmdLine = String.format(
"-J-Djava.security.krb5.conf=%s -J-Djdk.net.hosts.file=TestHosts %s",
OneKDC.KRB5_CONF, cmdLine);
return SecurityTools.ktab(fullCmdLine).shouldHaveExitValue(0);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2022, 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
@@ -69,31 +69,31 @@ public static void main(String[] args) throws Exception {
check(3,17,3,18,3,19,4,17,4,18,4,19,5,17,5,18,5,19);
ktab("-a me mine -n 6 -append");
check(3,17,3,18,3,19,4,17,4,18,4,19,5,17,5,18,5,19,6,17,6,18,6,19);
ktab("-d me 3");
ktab("-d me -f 3");
check(4,17,4,18,4,19,5,17,5,18,5,19,6,17,6,18,6,19);
ktab("-d me -e 17 6");
ktab("-d me -f -e 17 6");
check(4,17,4,18,4,19,5,17,5,18,5,19,6,18,6,19);
ktab("-d me -e 19 6");
ktab("-d me -f -e 19 6");
check(4,17,4,18,4,19,5,17,5,18,5,19,6,18);
ktab("-d me -e 17 5");
ktab("-d me -f -e 17 5");
check(4,17,4,18,4,19,5,18,5,19,6,18);
ktab("-d me old");
ktab("-d me -f old");
check(4,17,5,19,6,18);
try {
ktab("-d me old");
ktab("-d me -f old");
throw new Exception("Should fail");
} catch (Exception e) {
// no-op
}
check(4,17,5,19,6,18);
ktab("-d me");
ktab("-d me -f");
check();
}

static void ktab(String s) throws Exception {
File conf = new File(System.getProperty("test.src"), "onlythree.conf");
SecurityTools.ktab("-J-Djava.security.krb5.conf=" + conf
+ " -k " + KEYTAB + " -f " + s).shouldHaveExitValue(0);
+ " -k " + KEYTAB + " " + s).shouldHaveExitValue(0);
}

/**

1 comment on commit 0d1a97f

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 0d1a97f Jan 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.