Mercurial > hg > release > icedtea7-forest-2.6 > jdk
changeset 9901:f87a938560e4
8031111: fix krb5 caddr
Reviewed-by: mbalao
author | andrew |
---|---|
date | Tue, 04 Feb 2020 02:50:59 +0000 |
parents | 82f3382912e9 |
children | e4e8739563d1 |
files | src/share/classes/sun/security/krb5/Config.java src/share/classes/sun/security/krb5/KrbCred.java src/share/classes/sun/security/krb5/internal/HostAddresses.java test/sun/security/krb5/auto/Addresses.java test/sun/security/krb5/auto/Forwarded.java test/sun/security/krb5/auto/KDC.java |
diffstat | 6 files changed, 229 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/security/krb5/Config.java Mon Feb 03 06:54:40 2020 +0000 +++ b/src/share/classes/sun/security/krb5/Config.java Tue Feb 04 02:50:59 2020 +0000 @@ -223,23 +223,28 @@ * and has no sub-key at all (given "forwardable" is defined, otherwise, * this method has no knowledge if it's a value name or a section name), */ - @SuppressWarnings("unchecked") public String get(String... keys) { - Vector<String> v = get0(keys); + Vector<String> v = getString0(keys); if (v == null) return null; return v.lastElement(); } /** - * Gets all values for the specified keys. - * @see #get(java.lang.String[]) + * 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}) */ public String getAll(String... keys) { - Vector<String> v = get0(keys); + Vector<String> v = getString0(keys); if (v == null) return null; StringBuilder sb = new StringBuilder(); boolean first = true; for (String s: v) { + s = s.replaceAll("[\\s,]+", " "); if (first) { sb.append(s); first = false; @@ -250,7 +255,27 @@ return sb.toString(); } - // Internal method. Returns the vector of strings for keys. + /** + * Returns true if keys exists, can be either final string(s) or sub-stanza + * @throws IllegalArgumentException if any of the keys is illegal + * (See {@link #get}) + */ + public boolean exists(String... keys) { + return get0(keys) != null; + } + + // Returns final string value(s) for given keys. + @SuppressWarnings("unchecked") + private Vector<String> getString0(String... keys) { + try { + return (Vector<String>)get0(keys); + } catch (ClassCastException cce) { + throw new IllegalArgumentException(cce); + } + } + + // Internal method. Returns the value for keys, which can be a sub-stanza + // or final string value(s). // The only method (except for toString) that reads stanzaTable directly. @SuppressWarnings("unchecked") private Vector<String> get0(String... keys) {
--- a/src/share/classes/sun/security/krb5/KrbCred.java Mon Feb 03 06:54:40 2020 +0000 +++ b/src/share/classes/sun/security/krb5/KrbCred.java Tue Feb 04 02:50:59 2020 +0000 @@ -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/src/share/classes/sun/security/krb5/internal/HostAddresses.java Mon Feb 03 06:54:40 2020 +0000 +++ b/src/share/classes/sun/security/krb5/internal/HostAddresses.java Tue Feb 04 02:50:59 2020 +0000 @@ -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/test/sun/security/krb5/auto/Addresses.java Tue Feb 04 02:50:59 2020 +0000 @@ -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 -Dsun.net.spi.nameservice.provider.1=ns,mock 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/test/sun/security/krb5/auto/Forwarded.java Tue Feb 04 02:50:59 2020 +0000 @@ -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 -Dsun.net.spi.nameservice.provider.1=ns,mock 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/test/sun/security/krb5/auto/KDC.java Mon Feb 03 06:54:40 2020 +0000 +++ b/test/sun/security/krb5/auto/KDC.java Tue Feb 04 02:50:59 2020 +0000 @@ -215,6 +215,10 @@ * What backend server can be delegated to */ OK_AS_DELEGATE, + /** + * If true, will check if TGS-REQ contains a non-null addresses field. + */ + CHECK_ADDRESSES, }; //static { @@ -793,6 +797,11 @@ if (body.kdcOptions.get(KDCOptions.FORWARDABLE)) { 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; @@ -840,10 +849,8 @@ timeAfter(0), from, till, renewTill, - 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) { @@ -868,10 +875,7 @@ from, till, renewTill, 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);