--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/Config.java Thu Jun 04 15:29:23 2015 +0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/Config.java Thu Jun 04 15:29:29 2015 +0800
@@ -260,7 +260,11 @@
}
/**
- * Gets all values for the specified keys.
+ * Gets all values (at least one) for the specified keys separated by
+ * a whitespace, or null if there is no such keys.
+ * The values can either be provided on a single line, or on multiple lines
+ * using the same key. When provided on a single line, the value can be
+ * comma or space separated.
* @throws IllegalArgumentException if any of the keys is illegal
* (See {@link #get})
*/
@@ -270,6 +274,7 @@
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String s: v) {
+ s = s.replaceAll("[\\s,]+", " ");
if (first) {
sb.append(s);
first = false;
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KrbCred.java Thu Jun 04 15:29:23 2015 +0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KrbCred.java Thu Jun 04 15:29:29 2015 +0800
@@ -34,6 +34,9 @@
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.KeyUsage;
import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
import sun.security.util.DerValue;
/**
@@ -76,10 +79,24 @@
options.set(KDCOptions.FORWARDABLE, true);
HostAddresses sAddrs = null;
- // XXX Also NT_GSS_KRB5_PRINCIPAL can be a host based principal
+
// GSSName.NT_HOSTBASED_SERVICE should display with KRB_NT_SRV_HST
- if (server.getNameType() == PrincipalName.KRB_NT_SRV_HST)
- sAddrs= new HostAddresses(server);
+ if (server.getNameType() == PrincipalName.KRB_NT_SRV_HST) {
+ sAddrs = new HostAddresses(server);
+ } else if (server.getNameType() == PrincipalName.KRB_NT_UNKNOWN) {
+ // Sometimes this is also a server
+ if (server.getNameStrings().length >= 2) {
+ String host = server.getNameStrings()[1];
+ try {
+ InetAddress[] addr = InetAddress.getAllByName(host);
+ if (addr != null && addr.length > 0) {
+ sAddrs = new HostAddresses(addr);
+ }
+ } catch (UnknownHostException ioe) {
+ // maybe we guessed wrong, let sAddrs be null
+ }
+ }
+ }
KrbTgsReq tgsReq = new KrbTgsReq(options, tgt, tgService,
null, null, null, null, sAddrs, null, null, null);
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/HostAddresses.java Thu Jun 04 15:29:23 2015 +0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/HostAddresses.java Thu Jun 04 15:29:29 2015 +0800
@@ -31,16 +31,14 @@
package sun.security.krb5.internal;
+import sun.security.krb5.Config;
import sun.security.krb5.PrincipalName;
import sun.security.krb5.KrbException;
import sun.security.krb5.Asn1Exception;
import sun.security.util.*;
-import java.util.Vector;
-import java.util.ArrayList;
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.UnknownHostException;
+
+import java.net.*;
+import java.util.*;
import java.io.IOException;
import sun.security.krb5.internal.ccache.CCacheOutputStream;
@@ -293,34 +291,35 @@
*/
public static HostAddresses getLocalAddresses() throws IOException
{
- String hostname = null;
- InetAddress[] inetAddresses = null;
+ Set<InetAddress> all = new LinkedHashSet<>();
try {
- InetAddress localHost = InetAddress.getLocalHost();
- hostname = localHost.getHostName();
- inetAddresses = InetAddress.getAllByName(hostname);
- HostAddress[] hAddresses = new HostAddress[inetAddresses.length];
- for (int i = 0; i < inetAddresses.length; i++)
- {
- hAddresses[i] = new HostAddress(inetAddresses[i]);
- }
if (DEBUG) {
- System.out.println(">>> KrbKdcReq local addresses for "
- + hostname + " are: ");
-
- for (int i = 0; i < inetAddresses.length; i++) {
- System.out.println("\n\t" + inetAddresses[i]);
- if (inetAddresses[i] instanceof Inet4Address)
- System.out.println("IPv4 address");
- if (inetAddresses[i] instanceof Inet6Address)
- System.out.println("IPv6 address");
+ System.out.println(">>> KrbKdcReq local addresses are:");
+ }
+ String extra = Config.getInstance().getAll(
+ "libdefaults", "extra_addresses");
+ if (extra != null) {
+ for (String s: extra.split("\\s+")) {
+ all.add(InetAddress.getByName(s));
+ if (DEBUG) {
+ System.out.println(" extra_addresses: "
+ + InetAddress.getByName(s));
+ }
}
}
- return (new HostAddresses(hAddresses));
+ for (NetworkInterface ni:
+ Collections.list(NetworkInterface.getNetworkInterfaces())) {
+ if (DEBUG) {
+ System.out.println(" NetworkInterface " + ni + ":");
+ System.out.println(" "
+ + Collections.list(ni.getInetAddresses()));
+ }
+ all.addAll(Collections.list(ni.getInetAddresses()));
+ }
+ return new HostAddresses(all.toArray(new InetAddress[all.size()]));
} catch (Exception exc) {
throw new IOException(exc.toString());
}
-
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/Addresses.java Thu Jun 04 15:29:29 2015 +0800
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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 8031111
+ * @summary fix krb5 caddr
+ * @compile -XDignore.symbol.file Addresses.java
+ * @run main/othervm Addresses
+ */
+
+import sun.security.krb5.Config;
+
+import javax.security.auth.kerberos.KerberosTicket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+
+public class Addresses {
+
+ public static void main(String[] args) throws Exception {
+
+ KDC.saveConfig(OneKDC.KRB5_CONF, new OneKDC(null),
+ "noaddresses = false",
+ "extra_addresses = 10.0.0.10, 10.0.0.11 10.0.0.12");
+ Config.refresh();
+
+ KerberosTicket ticket =
+ Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false)
+ .s().getPrivateCredentials(KerberosTicket.class)
+ .iterator().next();
+
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ InetAddress extra1 = InetAddress.getByName("10.0.0.10");
+ InetAddress extra2 = InetAddress.getByName("10.0.0.11");
+ InetAddress extra3 = InetAddress.getByName("10.0.0.12");
+
+ boolean loopbackFound = false;
+ boolean extra1Found = false;
+ boolean extra2Found = false;
+ boolean extra3Found = false;
+ boolean networkFound = false;
+
+ for (InetAddress ia: ticket.getClientAddresses()) {
+ System.out.println(ia);
+ if (ia.equals(loopback)) {
+ loopbackFound = true;
+ System.out.println(" loopback found");
+ } else if (ia.equals(extra1)) {
+ extra1Found = true;
+ System.out.println(" extra1 found");
+ } else if (ia.equals(extra2)) {
+ extra2Found = true;
+ System.out.println(" extra2 found");
+ } else if (ia.equals(extra3)) {
+ extra3Found = true;
+ System.out.println(" extra3 found");
+ } else if (ia instanceof Inet4Address) {
+ networkFound = true;
+ System.out.println(" another address (" + ia +
+ "), assumed real network");
+ }
+ }
+
+ if (!loopbackFound || !networkFound
+ || !extra1Found || !extra2Found || !extra3Found ) {
+ throw new Exception();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/Forwarded.java Thu Jun 04 15:29:29 2015 +0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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 8031111
+ * @summary fix krb5 caddr
+ * @compile -XDignore.symbol.file Forwarded.java
+ * @run main/othervm Forwarded
+ */
+
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.internal.KDCOptions;
+import sun.security.krb5.internal.KDCReqBody;
+import sun.security.krb5.internal.TGSReq;
+
+public class Forwarded {
+
+ public static void main(String[] args) throws Exception {
+
+ new OneKDC(null).setOption(KDC.Option.CHECK_ADDRESSES, true);
+
+ Context c;
+ c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+
+ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ c.x().requestCredDeleg(true);
+
+ c.take(new byte[0]);
+ }
+}
--- a/jdk/test/sun/security/krb5/auto/KDC.java Thu Jun 04 15:29:23 2015 +0800
+++ b/jdk/test/sun/security/krb5/auto/KDC.java Thu Jun 04 15:29:29 2015 +0800
@@ -205,6 +205,10 @@
* Sensitive accounts can never be delegated.
*/
SENSITIVE_ACCOUNTS,
+ /**
+ * If true, will check if TGS-REQ contains a non-null addresses field.
+ */
+ CHECK_ADDRESSES,
};
static {
@@ -734,6 +738,11 @@
bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
}
}
+ if (options.containsKey(Option.CHECK_ADDRESSES)
+ && body.kdcOptions.get(KDCOptions.FORWARDED)
+ && body.addresses == null) {
+ throw new KrbException(Krb5.KDC_ERR_BADOPTION);
+ }
if (body.kdcOptions.get(KDCOptions.FORWARDED) ||
etp.flags.get(Krb5.TKT_OPTS_FORWARDED)) {
bFlags[Krb5.TKT_OPTS_FORWARDED] = true;
@@ -800,10 +809,8 @@
new KerberosTime(new Date()),
body.from,
till, body.rtime,
- body.addresses != null // always set caddr
- ? body.addresses
- : new HostAddresses(
- new InetAddress[]{InetAddress.getLocalHost()}),
+ body.addresses != null ? body.addresses
+ : etp.caddr,
null);
EncryptionKey skey = keyForUser(service, e3, true);
if (skey == null) {
@@ -826,10 +833,7 @@
body.from,
till, body.rtime,
service,
- body.addresses != null // always set caddr
- ? body.addresses
- : new HostAddresses(
- new InetAddress[]{InetAddress.getLocalHost()})
+ body.addresses
);
EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
TGSRep tgsRep = new TGSRep(null,