# HG changeset patch # User weijun # Date 1401431863 -28800 # Node ID dafd257bc7f39fafa0ad5462734de19f498aac37 # Parent 256eb760e01f1f2f7d259fd3f4ad046fbef5727a 8036779: sun.security.krb5.KdcComm interprets kdc_timeout as msec instead of sec Reviewed-by: xuelei diff -r 256eb760e01f -r dafd257bc7f3 jdk/src/share/classes/sun/security/krb5/KdcComm.java --- a/jdk/src/share/classes/sun/security/krb5/KdcComm.java Fri May 30 02:33:20 2014 +0400 +++ b/jdk/src/share/classes/sun/security/krb5/KdcComm.java Fri May 30 14:37:43 2014 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, 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 @@ -144,7 +144,8 @@ try { Config cfg = Config.getInstance(); String temp = cfg.get("libdefaults", "kdc_timeout"); - timeout = parsePositiveIntString(temp); + timeout = parseTimeString(temp); + temp = cfg.get("libdefaults", "max_retries"); max_retries = parsePositiveIntString(temp); temp = cfg.get("libdefaults", "udp_preference_limit"); @@ -426,6 +427,25 @@ } /** + * Parses a time value string. If it ends with "s", parses as seconds. + * Otherwise, parses as milliseconds. + * @param s the time string + * @return the integer value in milliseconds, or -1 if input is null or + * has an invalid format + */ + private static int parseTimeString(String s) { + if (s == null) { + return -1; + } + if (s.endsWith("s")) { + int seconds = parsePositiveIntString(s.substring(0, s.length()-1)); + return (seconds < 0) ? -1 : (seconds*1000); + } else { + return parsePositiveIntString(s); + } + } + + /** * Returns krb5.conf setting of {@code key} for a specific realm, * which can be: * 1. defined in the sub-stanza for the given realm inside [realms], or @@ -446,7 +466,11 @@ try { String value = Config.getInstance().get("realms", realm, key); - temp = parsePositiveIntString(value); + if (key.equals("kdc_timeout")) { + temp = parseTimeString(value); + } else { + temp = parsePositiveIntString(value); + } } catch (Exception exc) { // Ignored, defValue will be picked up } diff -r 256eb760e01f -r dafd257bc7f3 jdk/test/sun/security/krb5/auto/KDC.java --- a/jdk/test/sun/security/krb5/auto/KDC.java Fri May 30 02:33:20 2014 +0400 +++ b/jdk/test/sun/security/krb5/auto/KDC.java Fri May 30 14:37:43 2014 +0800 @@ -141,6 +141,8 @@ private BlockingQueue q = new ArrayBlockingQueue<>(100); // Options private Map options = new HashMap<>(); + // Realm-specific krb5.conf settings + private List conf = new ArrayList<>(); private Thread thread1, thread2, thread3; DatagramSocket u1 = null; @@ -243,7 +245,7 @@ /** * Sets an option * @param key the option name - * @param obj the value + * @param value the value */ public void setOption(Option key, Object value) { if (value == null) { @@ -373,6 +375,13 @@ } /** + * Add realm-specific krb5.conf setting + */ + public void addConf(String s) { + conf.add(s); + } + + /** * Writes a krb5.conf for one or more KDC that includes KDC locations for * each realm and the default realm name. You can also add extra strings * into the file. The method should be called like: @@ -397,6 +406,7 @@ * [realms] * REALM.NAME = { * kdc = host:port_number + * # realm-specific settings * } * * @@ -444,10 +454,10 @@ } } sb.append("\n[realms]\n"); - sb.append(realmLineForKDC(kdc)); + sb.append(kdc.realmLine()); for (Object o: more) { if (o instanceof KDC) { - sb.append(realmLineForKDC((KDC)o)); + sb.append(((KDC)o).realmLine()); } } FileOutputStream fos = new FileOutputStream(f); @@ -1133,14 +1143,16 @@ /** * Generates a line for a KDC to put inside [realms] of krb5.conf - * @param kdc the KDC - * @return REALM.NAME = { kdc = host:port } + * @return REALM.NAME = { kdc = host:port etc } */ - private static String realmLineForKDC(KDC kdc) { - return String.format("%s = {\n kdc = %s:%d\n}\n", - kdc.realm, - kdc.kdc, - kdc.port); + private String realmLine() { + StringBuilder sb = new StringBuilder(); + sb.append(realm).append(" = {\n kdc = ") + .append(kdc).append(':').append(port).append('\n'); + for (String s: conf) { + sb.append(" ").append(s).append('\n'); + } + return sb.append("}\n").toString(); } /** diff -r 256eb760e01f -r dafd257bc7f3 jdk/test/sun/security/krb5/auto/UdpTcp.java --- a/jdk/test/sun/security/krb5/auto/UdpTcp.java Fri May 30 02:33:20 2014 +0400 +++ b/jdk/test/sun/security/krb5/auto/UdpTcp.java Fri May 30 14:37:43 2014 +0800 @@ -43,9 +43,15 @@ OneKDC kdc = new OneKDC(null); kdc.writeJAASConf(); - KDC.saveConfig(OneKDC.KRB5_CONF, kdc, - "udp_preference_limit = " - + (args[0].equals("UDP") ? "1000" : "100")); + // Two styles of kdc_timeout setting. One global, one realm-specific. + if (args[0].equals("UDP")) { + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + "kdc_timeout = 10s"); + } else { + kdc.addConf("kdc_timeout = 10s"); + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + "udp_preference_limit = 1"); + } Config.refresh(); ByteArrayOutputStream bo = new ByteArrayOutputStream(); @@ -56,7 +62,7 @@ for (String line: new String(bo.toByteArray()).split("\n")) { if (line.contains(">>> KDCCommunication")) { - if (!line.contains(args[0])) { + if (!line.contains(args[0]) || !line.contains("timeout=10000")) { throw new Exception("No " + args[0] + " in: " + line); } }