Mercurial > hg > openjdk > jdk7 > jdk
changeset 1306:37ed72fe7561
6851973: ignore incoming channel binding if acceptor does not set one
Reviewed-by: valeriep
author | weijun |
---|---|
date | Fri, 19 Jun 2009 18:03:27 +0800 |
parents | 81c176909720 |
children | ed38f9e6ad9a |
files | src/share/classes/sun/security/jgss/krb5/InitialToken.java test/sun/security/krb5/auto/IgnoreChannelBinding.java |
diffstat | 2 files changed, 136 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java Thu Jun 18 10:38:21 2009 -0400 +++ b/src/share/classes/sun/security/jgss/krb5/InitialToken.java Fri Jun 19 18:03:27 2009 +0800 @@ -33,6 +33,7 @@ import java.net.Inet6Address; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Arrays; import sun.security.krb5.*; import sun.security.jgss.HttpCaller; import sun.security.krb5.internal.Krb5; @@ -219,43 +220,35 @@ "Incorrect checksum"); } - byte[] remoteBindingBytes = new byte[CHECKSUM_BINDINGS_SIZE]; - System.arraycopy(checksumBytes, 4, remoteBindingBytes, 0, - CHECKSUM_BINDINGS_SIZE); - - byte[] noBindings = new byte[CHECKSUM_BINDINGS_SIZE]; - boolean tokenContainsBindings = - (!java.util.Arrays.equals(noBindings, remoteBindingBytes)); - ChannelBinding localBindings = context.getChannelBinding(); - if (tokenContainsBindings || - localBindings != null) { + // Ignore remote channel binding info when not requested at + // local side (RFC 4121 4.1.1.2: the acceptor MAY ignore...). + // + // All major krb5 implementors implement this "MAY", + // and some applications depend on it as a workaround + // for not having a way to negotiate the use of channel + // binding -- the initiator application always uses CB + // and hopes the acceptor will ignore the CB if the + // acceptor doesn't support CB. + if (localBindings != null) { + byte[] remoteBindingBytes = new byte[CHECKSUM_BINDINGS_SIZE]; + System.arraycopy(checksumBytes, 4, remoteBindingBytes, 0, + CHECKSUM_BINDINGS_SIZE); - boolean badBindings = false; - String errorMessage = null; - - if (tokenContainsBindings && - localBindings != null) { + byte[] noBindings = new byte[CHECKSUM_BINDINGS_SIZE]; + if (!Arrays.equals(noBindings, remoteBindingBytes)) { byte[] localBindingsBytes = computeChannelBinding(localBindings); - // System.out.println("ChannelBinding hash: " - // + getHexBytes(localBindingsBytes)); - badBindings = - (!java.util.Arrays.equals(localBindingsBytes, - remoteBindingBytes)); - errorMessage = "Bytes mismatch!"; - } else if (localBindings == null) { - errorMessage = "ChannelBinding not provided!"; - badBindings = true; + if (!Arrays.equals(localBindingsBytes, + remoteBindingBytes)) { + throw new GSSException(GSSException.BAD_BINDINGS, -1, + "Bytes mismatch!"); + } } else { - errorMessage = "Token missing ChannelBinding!"; - badBindings = true; + throw new GSSException(GSSException.BAD_BINDINGS, -1, + "Token missing ChannelBinding!"); } - - if (badBindings) - throw new GSSException(GSSException.BAD_BINDINGS, -1, - errorMessage); } flags = readLittleEndian(checksumBytes, 20, 4);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/IgnoreChannelBinding.java Fri Jun 19 18:03:27 2009 +0800 @@ -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. + */ + +/* + * @test + * @bug 6851973 + * @summary ignore incoming channel binding if acceptor does not set one + */ + +import java.net.InetAddress; +import org.ietf.jgss.ChannelBinding; +import org.ietf.jgss.GSSException; +import sun.security.jgss.GSSUtil; + +public class IgnoreChannelBinding { + + public static void main(String[] args) + throws Exception { + + new OneKDC(null).writeJAASConf(); + + Context c = Context.fromJAAS("client"); + Context s = Context.fromJAAS("server"); + + // All silent + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + Context.handshake(c, s); + + // Initiator req, acceptor ignore + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + c.x().setChannelBinding(new ChannelBinding( + InetAddress.getByName("client.rabbit.hole"), + InetAddress.getByName("host.rabbit.hole"), + new byte[0] + )); + s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + Context.handshake(c, s); + + // Both req, and match + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + c.x().setChannelBinding(new ChannelBinding( + InetAddress.getByName("client.rabbit.hole"), + InetAddress.getByName("host.rabbit.hole"), + new byte[0] + )); + s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + s.x().setChannelBinding(new ChannelBinding( + InetAddress.getByName("client.rabbit.hole"), + InetAddress.getByName("host.rabbit.hole"), + new byte[0] + )); + Context.handshake(c, s); + + // Both req, NOT match + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + c.x().setChannelBinding(new ChannelBinding( + InetAddress.getByName("client.rabbit.hole"), + InetAddress.getByName("host.rabbit.hole"), + new byte[0] + )); + s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + s.x().setChannelBinding(new ChannelBinding( + InetAddress.getByName("client.rabbit.hole"), + InetAddress.getByName("host.rabbit.hole"), + new byte[1] // 0 -> 1 + )); + try { + Context.handshake(c, s); + throw new Exception("Acceptor should reject initiator"); + } catch (GSSException ge) { + // Expected bahavior + } + + // Acceptor req, reject + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + s.x().setChannelBinding(new ChannelBinding( + InetAddress.getByName("client.rabbit.hole"), + InetAddress.getByName("host.rabbit.hole"), + new byte[0] + )); + try { + Context.handshake(c, s); + throw new Exception("Acceptor should reject initiator"); + } catch (GSSException ge) { + // Expected bahavior + if (ge.getMajor() != GSSException.BAD_BINDINGS) { + throw ge; + } + } + } +}