6843127: krb5 should not try to access unavailable kdc too often
Reviewed-by: valeriep, mullan
This commit is contained in:
parent
dc8d9d049e
commit
709a5076d8
@ -109,6 +109,7 @@ public class Config {
|
|||||||
public static synchronized void refresh() throws KrbException {
|
public static synchronized void refresh() throws KrbException {
|
||||||
singleton = new Config();
|
singleton = new Config();
|
||||||
KeyTab.refresh();
|
KeyTab.refresh();
|
||||||
|
KrbKdcReq.KdcAccessibility.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,25 +31,26 @@
|
|||||||
|
|
||||||
package sun.security.krb5;
|
package sun.security.krb5;
|
||||||
|
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.Locale;
|
||||||
import sun.security.krb5.internal.Krb5;
|
import sun.security.krb5.internal.Krb5;
|
||||||
import sun.security.krb5.internal.UDPClient;
|
import sun.security.krb5.internal.UDPClient;
|
||||||
import sun.security.krb5.internal.TCPClient;
|
import sun.security.krb5.internal.TCPClient;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InterruptedIOException;
|
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.security.PrivilegedActionException;
|
import java.security.PrivilegedActionException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
public abstract class KrbKdcReq {
|
public abstract class KrbKdcReq {
|
||||||
|
|
||||||
/**
|
|
||||||
* Default port for a KDC.
|
|
||||||
*/
|
|
||||||
private static final int DEFAULT_KDC_PORT = Krb5.KDC_INET_DEFAULT_PORT;
|
|
||||||
|
|
||||||
// Currently there is no option to specify retries
|
// Currently there is no option to specify retries
|
||||||
// in the kerberos configuration file
|
// in the kerberos configuration file
|
||||||
|
|
||||||
@ -66,7 +67,48 @@ public abstract class KrbKdcReq {
|
|||||||
|
|
||||||
private static int udpPrefLimit = -1;
|
private static int udpPrefLimit = -1;
|
||||||
|
|
||||||
|
private static final String BAD_POLICY_KEY = "krb5.kdc.bad.policy";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What to do when a KDC is unavailable, specified in the
|
||||||
|
* java.security file with key krb5.kdc.bad.policy.
|
||||||
|
* Possible values can be TRY_LAST or TRY_LESS
|
||||||
|
*/
|
||||||
|
private enum BpType {
|
||||||
|
NONE, TRY_LAST, TRY_LESS
|
||||||
|
}
|
||||||
|
private static int tryLessMaxRetries = 1;
|
||||||
|
private static int tryLessTimeout = 5000;
|
||||||
|
|
||||||
|
private static final BpType badPolicy;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
String value = AccessController.doPrivileged(
|
||||||
|
new PrivilegedAction<String>() {
|
||||||
|
public String run() {
|
||||||
|
return Security.getProperty(BAD_POLICY_KEY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (value != null) {
|
||||||
|
value = value.toLowerCase(Locale.ENGLISH);
|
||||||
|
String[] ss = value.split(":");
|
||||||
|
if ("tryless".equals(ss[0])) {
|
||||||
|
if (ss.length > 1) {
|
||||||
|
String[] params = ss[1].split(",");
|
||||||
|
tryLessMaxRetries = Integer.parseInt(params[0]);
|
||||||
|
if (params.length > 1) {
|
||||||
|
tryLessTimeout = Integer.parseInt(params[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
badPolicy = BpType.TRY_LESS;
|
||||||
|
} else if ("trylast".equals(ss[0])) {
|
||||||
|
badPolicy = BpType.TRY_LAST;
|
||||||
|
} else {
|
||||||
|
badPolicy = BpType.NONE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
badPolicy = BpType.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get default timeout.
|
* Get default timeout.
|
||||||
@ -131,22 +173,16 @@ public abstract class KrbKdcReq {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Get timeout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int timeout = getKdcTimeout(realm);
|
|
||||||
|
|
||||||
String kdcList = cfg.getKDCList(realm);
|
String kdcList = cfg.getKDCList(realm);
|
||||||
if (kdcList == null) {
|
if (kdcList == null) {
|
||||||
throw new KrbException("Cannot get kdc for realm " + realm);
|
throw new KrbException("Cannot get kdc for realm " + realm);
|
||||||
}
|
}
|
||||||
String tempKdc = null; // may include the port number also
|
String tempKdc = null; // may include the port number also
|
||||||
StringTokenizer st = new StringTokenizer(kdcList);
|
for (String tmp: KdcAccessibility.list(kdcList)) {
|
||||||
while (st.hasMoreTokens()) {
|
tempKdc = tmp;
|
||||||
tempKdc = st.nextToken();
|
|
||||||
try {
|
try {
|
||||||
send(realm,tempKdc,useTCP);
|
send(realm,tempKdc,useTCP);
|
||||||
|
KdcAccessibility.removeBad(tempKdc);
|
||||||
break;
|
break;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@ -154,6 +190,7 @@ public abstract class KrbKdcReq {
|
|||||||
tempKdc);
|
tempKdc);
|
||||||
e.printStackTrace(System.out);
|
e.printStackTrace(System.out);
|
||||||
}
|
}
|
||||||
|
KdcAccessibility.addBad(tempKdc);
|
||||||
savedException = e;
|
savedException = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,16 +211,21 @@ public abstract class KrbKdcReq {
|
|||||||
|
|
||||||
if (obuf == null)
|
if (obuf == null)
|
||||||
return;
|
return;
|
||||||
PrivilegedActionException savedException = null;
|
|
||||||
int port = Krb5.KDC_INET_DEFAULT_PORT;
|
|
||||||
|
|
||||||
/*
|
int port = Krb5.KDC_INET_DEFAULT_PORT;
|
||||||
* Get timeout.
|
int retries = DEFAULT_KDC_RETRY_LIMIT;
|
||||||
*/
|
|
||||||
int timeout = getKdcTimeout(realm);
|
int timeout = getKdcTimeout(realm);
|
||||||
/*
|
|
||||||
* Get port number for this KDC.
|
if (badPolicy == BpType.TRY_LESS &&
|
||||||
*/
|
KdcAccessibility.isBad(tempKdc)) {
|
||||||
|
if (retries > tryLessMaxRetries) {
|
||||||
|
retries = tryLessMaxRetries; // less retries
|
||||||
|
}
|
||||||
|
if (timeout > tryLessTimeout) {
|
||||||
|
timeout = tryLessTimeout; // less time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String kdc = null;
|
String kdc = null;
|
||||||
String portStr = null;
|
String portStr = null;
|
||||||
|
|
||||||
@ -225,12 +267,12 @@ public abstract class KrbKdcReq {
|
|||||||
+ port + ", timeout="
|
+ port + ", timeout="
|
||||||
+ timeout
|
+ timeout
|
||||||
+ ", number of retries ="
|
+ ", number of retries ="
|
||||||
+ DEFAULT_KDC_RETRY_LIMIT
|
+ retries
|
||||||
+ ", #bytes=" + obuf.length);
|
+ ", #bytes=" + obuf.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
KdcCommunication kdcCommunication =
|
KdcCommunication kdcCommunication =
|
||||||
new KdcCommunication(kdc, port, useTCP, timeout, obuf);
|
new KdcCommunication(kdc, port, useTCP, timeout, retries, obuf);
|
||||||
try {
|
try {
|
||||||
ibuf = AccessController.doPrivileged(kdcCommunication);
|
ibuf = AccessController.doPrivileged(kdcCommunication);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@ -258,14 +300,16 @@ public abstract class KrbKdcReq {
|
|||||||
private int port;
|
private int port;
|
||||||
private boolean useTCP;
|
private boolean useTCP;
|
||||||
private int timeout;
|
private int timeout;
|
||||||
|
private int retries;
|
||||||
private byte[] obuf;
|
private byte[] obuf;
|
||||||
|
|
||||||
public KdcCommunication(String kdc, int port, boolean useTCP,
|
public KdcCommunication(String kdc, int port, boolean useTCP,
|
||||||
int timeout, byte[] obuf) {
|
int timeout, int retries, byte[] obuf) {
|
||||||
this.kdc = kdc;
|
this.kdc = kdc;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.useTCP = useTCP;
|
this.useTCP = useTCP;
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
|
this.retries = retries;
|
||||||
this.obuf = obuf;
|
this.obuf = obuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +338,7 @@ public abstract class KrbKdcReq {
|
|||||||
} else {
|
} else {
|
||||||
// For each KDC we try DEFAULT_KDC_RETRY_LIMIT (3) times to
|
// For each KDC we try DEFAULT_KDC_RETRY_LIMIT (3) times to
|
||||||
// get the response
|
// get the response
|
||||||
for (int i=1; i <= DEFAULT_KDC_RETRY_LIMIT; i++) {
|
for (int i=1; i <= retries; i++) {
|
||||||
UDPClient kdcClient = new UDPClient(kdc, port, timeout);
|
UDPClient kdcClient = new UDPClient(kdc, port, timeout);
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@ -310,7 +354,7 @@ public abstract class KrbKdcReq {
|
|||||||
* Send the data to the kdc.
|
* Send the data to the kdc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
kdcClient.send(obuf);
|
kdcClient.send(obuf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* And get a response.
|
* And get a response.
|
||||||
@ -323,7 +367,7 @@ public abstract class KrbKdcReq {
|
|||||||
System.out.println ("SocketTimeOutException with " +
|
System.out.println ("SocketTimeOutException with " +
|
||||||
"attempt: " + i);
|
"attempt: " + i);
|
||||||
}
|
}
|
||||||
if (i == DEFAULT_KDC_RETRY_LIMIT) {
|
if (i == retries) {
|
||||||
ibuf = null;
|
ibuf = null;
|
||||||
throw se;
|
throw se;
|
||||||
}
|
}
|
||||||
@ -385,4 +429,67 @@ public abstract class KrbKdcReq {
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maintains a KDC accessible list. Unavailable KDCs are put into a
|
||||||
|
* blacklist, when a KDC in the blacklist is available, it's removed
|
||||||
|
* from there. No insertion order in the blacklist.
|
||||||
|
*
|
||||||
|
* There are two methods to deal with KDCs in the blacklist. 1. Only try
|
||||||
|
* them when there's no KDC not on the blacklist. 2. Still try them, but
|
||||||
|
* with lesser number of retries and smaller timeout value.
|
||||||
|
*/
|
||||||
|
static class KdcAccessibility {
|
||||||
|
// Known bad KDCs
|
||||||
|
private static Set<String> bads = new HashSet<String>();
|
||||||
|
|
||||||
|
private static synchronized void addBad(String kdc) {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println(">>> KdcAccessibility: add " + kdc);
|
||||||
|
}
|
||||||
|
bads.add(kdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized void removeBad(String kdc) {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println(">>> KdcAccessibility: remove " + kdc);
|
||||||
|
}
|
||||||
|
bads.remove(kdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized boolean isBad(String kdc) {
|
||||||
|
return bads.contains(kdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void reset() {
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println(">>> KdcAccessibility: reset");
|
||||||
|
}
|
||||||
|
bads.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a preferred KDC list by putting the bad ones at the end
|
||||||
|
private static synchronized String[] list(String kdcList) {
|
||||||
|
StringTokenizer st = new StringTokenizer(kdcList);
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
if (badPolicy == BpType.TRY_LAST) {
|
||||||
|
List<String> badkdcs = new ArrayList<String>();
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
String t = st.nextToken();
|
||||||
|
if (bads.contains(t)) badkdcs.add(t);
|
||||||
|
else list.add(t);
|
||||||
|
}
|
||||||
|
// Bad KDCs are put at last
|
||||||
|
list.addAll(badkdcs);
|
||||||
|
} else {
|
||||||
|
// All KDCs are returned in their original order,
|
||||||
|
// This include TRY_LESS and NONE
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
list.add(st.nextToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list.toArray(new String[list.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,3 +260,30 @@ networkaddress.cache.negative.ttl=10
|
|||||||
# Example,
|
# Example,
|
||||||
# ocsp.responderCertSerialNumber=2A:FF:00
|
# ocsp.responderCertSerialNumber=2A:FF:00
|
||||||
|
|
||||||
|
#
|
||||||
|
# Policy for failed Kerberos KDC lookups:
|
||||||
|
#
|
||||||
|
# When a KDC is unavailable (network error, service failure, etc), it is
|
||||||
|
# put inside a blacklist and accessed less often for future requests. The
|
||||||
|
# value (case-insensitive) for this policy can be:
|
||||||
|
#
|
||||||
|
# tryLast
|
||||||
|
# KDCs in the blacklist are always tried after those not on the list.
|
||||||
|
#
|
||||||
|
# tryLess[:max_retries,timeout]
|
||||||
|
# KDCs in the blacklist are still tried by their order in the configuration,
|
||||||
|
# but with smaller max_retries and timeout values. max_retries and timeout
|
||||||
|
# are optional numerical parameters (default 1 and 5000, which means once
|
||||||
|
# and 5 seconds). Please notes that if any of the values defined here is
|
||||||
|
# more than what is defined in krb5.conf, it will be ignored.
|
||||||
|
#
|
||||||
|
# Whenever a KDC is detected as available, it is removed from the blacklist.
|
||||||
|
# The blacklist is reset when krb5.conf is reloaded. You can add
|
||||||
|
# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
|
||||||
|
# reloaded whenever a JAAS authentication is attempted.
|
||||||
|
#
|
||||||
|
# Example,
|
||||||
|
# krb5.kdc.bad.policy = tryLast
|
||||||
|
# krb5.kdc.bad.policy = tryLess:2,2000
|
||||||
|
krb5.kdc.bad.policy = tryLast
|
||||||
|
|
||||||
|
113
jdk/test/sun/security/krb5/auto/BadKdc.java
Normal file
113
jdk/test/sun/security/krb5/auto/BadKdc.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import sun.security.krb5.Config;
|
||||||
|
|
||||||
|
public class BadKdc {
|
||||||
|
|
||||||
|
// Matches the krb5 debug output:
|
||||||
|
// >>> KDCCommunication: kdc=kdc.rabbit.hole UDP:14319, timeout=2000,...
|
||||||
|
// ^ kdc# ^ timeout
|
||||||
|
static final Pattern re = Pattern.compile(
|
||||||
|
">>> KDCCommunication: kdc=kdc.rabbit.hole UDP:(\\d)...., " +
|
||||||
|
"timeout=(\\d)000,");
|
||||||
|
public static void go(int[]... expected)
|
||||||
|
throws Exception {
|
||||||
|
System.setProperty("sun.security.krb5.debug", "true");
|
||||||
|
|
||||||
|
// Make sure KDCs' ports starts with 1 and 2 and 3,
|
||||||
|
// useful for checking debug output.
|
||||||
|
int p1 = 10000 + new java.util.Random().nextInt(10000);
|
||||||
|
int p2 = 20000 + new java.util.Random().nextInt(10000);
|
||||||
|
int p3 = 30000 + new java.util.Random().nextInt(10000);
|
||||||
|
|
||||||
|
FileWriter fw = new FileWriter("alternative-krb5.conf");
|
||||||
|
|
||||||
|
fw.write("[libdefaults]\n" +
|
||||||
|
"default_realm = " + OneKDC.REALM + "\n" +
|
||||||
|
"kdc_timeout = 2000\n");
|
||||||
|
fw.write("[realms]\n" + OneKDC.REALM + " = {\n" +
|
||||||
|
"kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" +
|
||||||
|
"kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" +
|
||||||
|
"kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" +
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
fw.close();
|
||||||
|
System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
|
||||||
|
Config.refresh();
|
||||||
|
|
||||||
|
// Turn on k3 only
|
||||||
|
KDC k3 = on(p3);
|
||||||
|
|
||||||
|
test(expected[0]);
|
||||||
|
test(expected[1]);
|
||||||
|
Config.refresh();
|
||||||
|
test(expected[2]);
|
||||||
|
|
||||||
|
k3.terminate(); // shutdown k3
|
||||||
|
on(p2); // k2 is on
|
||||||
|
test(expected[3]);
|
||||||
|
on(p1); // k1 and k2 is on
|
||||||
|
test(expected[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static KDC on(int p) throws Exception {
|
||||||
|
KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, p, true);
|
||||||
|
k.addPrincipal(OneKDC.USER, OneKDC.PASS);
|
||||||
|
k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One round of test for max_retries and timeout.
|
||||||
|
* @param timeout the expected timeout
|
||||||
|
* @param expected the expected kdc# timeout kdc# timeout...
|
||||||
|
*/
|
||||||
|
private static void test(int... expected) throws Exception {
|
||||||
|
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
PrintStream oldout = System.out;
|
||||||
|
System.setOut(new PrintStream(bo));
|
||||||
|
Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
|
||||||
|
System.setOut(oldout);
|
||||||
|
|
||||||
|
String[] lines = new String(bo.toByteArray()).split("\n");
|
||||||
|
System.out.println("----------------- TEST -----------------");
|
||||||
|
int count = 0;
|
||||||
|
for (String line: lines) {
|
||||||
|
Matcher m = re.matcher(line);
|
||||||
|
if (m.find()) {
|
||||||
|
System.out.println(line);
|
||||||
|
if (Integer.parseInt(m.group(1)) != expected[count++] ||
|
||||||
|
Integer.parseInt(m.group(2)) != expected[count++]) {
|
||||||
|
throw new Exception("Fail here");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count != expected.length) {
|
||||||
|
throw new Exception("Less rounds");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
jdk/test/sun/security/krb5/auto/BadKdc1.java
Normal file
53
jdk/test/sun/security/krb5/auto/BadKdc1.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6843127
|
||||||
|
* @run main/timeout=300 BadKdc1
|
||||||
|
* @summary krb5 should not try to access unavailable kdc too often
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
public class BadKdc1 {
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
throws Exception {
|
||||||
|
Security.setProperty("krb5.kdc.bad.policy", "tryLess");
|
||||||
|
BadKdc.go(
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
|
||||||
|
// The above line means try kdc1 for 2 seconds, then kdc1
|
||||||
|
// for 2 seconds,..., finally kdc3 for 2 seconds.
|
||||||
|
new int[]{1,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
|
||||||
|
// refresh
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
|
||||||
|
// k3 off, k2 on
|
||||||
|
new int[]{1,2,2,2,1,2,2,2}, // 1
|
||||||
|
// k1 on
|
||||||
|
new int[]{1,2,1,2} // empty
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
50
jdk/test/sun/security/krb5/auto/BadKdc2.java
Normal file
50
jdk/test/sun/security/krb5/auto/BadKdc2.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6843127
|
||||||
|
* @run main/timeout=300 BadKdc2
|
||||||
|
* @summary krb5 should not try to access unavailable kdc too often
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
public class BadKdc2 {
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
throws Exception {
|
||||||
|
Security.setProperty("krb5.kdc.bad.policy", "tryLess:2,1000");
|
||||||
|
BadKdc.go(
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
|
||||||
|
new int[]{1,1,1,1,2,1,2,1,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
|
||||||
|
// refresh
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
|
||||||
|
// k3 off, k2 on
|
||||||
|
new int[]{1,1,1,1,2,1,1,1,1,1,2,2}, // 1
|
||||||
|
// k1 on
|
||||||
|
new int[]{1,1,1,2} // empty
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
50
jdk/test/sun/security/krb5/auto/BadKdc3.java
Normal file
50
jdk/test/sun/security/krb5/auto/BadKdc3.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6843127
|
||||||
|
* @run main/timeout=300 BadKdc3
|
||||||
|
* @summary krb5 should not try to access unavailable kdc too often
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
public class BadKdc3 {
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
throws Exception {
|
||||||
|
Security.setProperty("krb5.kdc.bad.policy", "tryLast");
|
||||||
|
BadKdc.go(
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,3,2}, // 1, 2
|
||||||
|
new int[]{3,2,3,2}, // 1, 2
|
||||||
|
// refresh
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,3,2}, // 1, 2
|
||||||
|
// k3 off, k2 on
|
||||||
|
new int[]{3,2,3,2,3,2,1,2,1,2,1,2,2,2,2,2}, // 1, 3
|
||||||
|
// k1 on
|
||||||
|
new int[]{2,2,2,2} // 1, 3
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
50
jdk/test/sun/security/krb5/auto/BadKdc4.java
Normal file
50
jdk/test/sun/security/krb5/auto/BadKdc4.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6843127
|
||||||
|
* @run main/timeout=300 BadKdc4
|
||||||
|
* @summary krb5 should not try to access unavailable kdc too often
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
public class BadKdc4 {
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
throws Exception {
|
||||||
|
Security.setProperty("krb5.kdc.bad.policy", "");
|
||||||
|
BadKdc.go(
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
|
||||||
|
// refresh
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
|
||||||
|
// k3 off, k2 on
|
||||||
|
new int[]{1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2},
|
||||||
|
// k1 on
|
||||||
|
new int[]{1,2,1,2}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -141,6 +141,10 @@ public class KDC {
|
|||||||
// Options
|
// Options
|
||||||
private Map<Option,Object> options = new HashMap<Option,Object>();
|
private Map<Option,Object> options = new HashMap<Option,Object>();
|
||||||
|
|
||||||
|
private Thread thread1, thread2, thread3;
|
||||||
|
DatagramSocket u1 = null;
|
||||||
|
ServerSocket t1 = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Option names, to be expanded forever.
|
* Option names, to be expanded forever.
|
||||||
*/
|
*/
|
||||||
@ -940,8 +944,6 @@ public class KDC {
|
|||||||
* @throws java.io.IOException for any communication error
|
* @throws java.io.IOException for any communication error
|
||||||
*/
|
*/
|
||||||
protected void startServer(int port, boolean asDaemon) throws IOException {
|
protected void startServer(int port, boolean asDaemon) throws IOException {
|
||||||
DatagramSocket u1 = null;
|
|
||||||
ServerSocket t1 = null;
|
|
||||||
if (port > 0) {
|
if (port > 0) {
|
||||||
u1 = new DatagramSocket(port, InetAddress.getByName("127.0.0.1"));
|
u1 = new DatagramSocket(port, InetAddress.getByName("127.0.0.1"));
|
||||||
t1 = new ServerSocket(port);
|
t1 = new ServerSocket(port);
|
||||||
@ -966,7 +968,7 @@ public class KDC {
|
|||||||
this.port = port;
|
this.port = port;
|
||||||
|
|
||||||
// The UDP consumer
|
// The UDP consumer
|
||||||
Thread thread = new Thread() {
|
thread1 = new Thread() {
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
@ -982,11 +984,11 @@ public class KDC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
thread.setDaemon(asDaemon);
|
thread1.setDaemon(asDaemon);
|
||||||
thread.start();
|
thread1.start();
|
||||||
|
|
||||||
// The TCP consumer
|
// The TCP consumer
|
||||||
thread = new Thread() {
|
thread2 = new Thread() {
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
@ -1004,11 +1006,11 @@ public class KDC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
thread.setDaemon(asDaemon);
|
thread2.setDaemon(asDaemon);
|
||||||
thread.start();
|
thread2.start();
|
||||||
|
|
||||||
// The dispatcher
|
// The dispatcher
|
||||||
thread = new Thread() {
|
thread3 = new Thread() {
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
@ -1018,10 +1020,21 @@ public class KDC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
thread.setDaemon(true);
|
thread3.setDaemon(true);
|
||||||
thread.start();
|
thread3.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void terminate() {
|
||||||
|
try {
|
||||||
|
thread1.stop();
|
||||||
|
thread2.stop();
|
||||||
|
thread3.stop();
|
||||||
|
u1.close();
|
||||||
|
t1.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// OK
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Helper class to encapsulate a job in a KDC.
|
* Helper class to encapsulate a job in a KDC.
|
||||||
*/
|
*/
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import javax.security.auth.callback.Callback;
|
import javax.security.auth.callback.Callback;
|
||||||
import javax.security.auth.callback.CallbackHandler;
|
import javax.security.auth.callback.CallbackHandler;
|
||||||
|
Loading…
Reference in New Issue
Block a user