changeset 2175:c7e5b058721a

S6851973, PR830: ignore incoming channel binding if acceptor does not set one 2011-12-22 Andrew John Hughes <ahughes@redhat.com> * Makefile.am: Add new patch. * NEWS: Updated. * patches/openjdk/6851973-kerberos.patch: Add OpenJDK backport.
author Andrew John Hughes <ahughes@redhat.com>
date Wed, 11 Jan 2012 12:01:29 +0000
parents e7e4c22d1946
children 70d67528801d
files ChangeLog Makefile.am NEWS patches/openjdk/6851973-kerberos.patch
diffstat 4 files changed, 212 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jan 06 13:17:57 2012 +0000
+++ b/ChangeLog	Wed Jan 11 12:01:29 2012 +0000
@@ -1,3 +1,10 @@
+2011-12-22  Andrew John Hughes  <ahughes@redhat.com>
+
+	* Makefile.am: Add new patch.
+	* NEWS: Updated.
+	* patches/openjdk/6851973-kerberos.patch:
+	Add OpenJDK backport.
+
 2011-12-22  Andrew John Hughes  <ahughes@redhat.com>
 
 	* Makefile.am: Add new patch.
--- a/Makefile.am	Fri Jan 06 13:17:57 2012 +0000
+++ b/Makefile.am	Wed Jan 11 12:01:29 2012 +0000
@@ -403,7 +403,8 @@
 	patches/support_linux_3.patch \
 	patches/libpng-1.5.patch \
 	patches/openjdk/7102369-7094468-rmiregistry.patch \
-	patches/openjdk/7103725-ssl_beast_regression.patch
+	patches/openjdk/7103725-ssl_beast_regression.patch \
+	patches/openjdk/6851973-kerberos.patch
 
 if WITH_ALT_HSBUILD
 ICEDTEA_PATCHES += patches/hotspot/$(HSBUILD)/openjdk-6886353-ignore_deoptimizealot.patch \
--- a/NEWS	Fri Jan 06 13:17:57 2012 +0000
+++ b/NEWS	Wed Jan 11 12:01:29 2012 +0000
@@ -14,6 +14,7 @@
   - S7102369: remove java.rmi.server.codebase property parsing from registyimpl
   - S7094468: rmiregistry clean up
   - S7103725, RH767129: REGRESSION - 6u29 breaks ssl connectivity using TLS_DH_anon_WITH_AES_128_CBC_SHA
+  - S6851973, PR830: ignore incoming channel binding if acceptor does not set one
 
 New in release 1.8.11 (2011-11-08):
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/6851973-kerberos.patch	Wed Jan 11 12:01:29 2012 +0000
@@ -0,0 +1,202 @@
+# HG changeset patch
+# User weijun
+# Date 1245405807 -28800
+# Node ID 37ed72fe7561c143a882d03944a7d2240cbafe89
+# Parent  81c176909720561ec1c44fa3d94b18845e350ee9
+6851973: ignore incoming channel binding if acceptor does not set one
+Reviewed-by: valeriep
+
+diff -r 81c176909720 -r 37ed72fe7561 src/share/classes/sun/security/jgss/krb5/InitialToken.java
+--- openjdk/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java	Thu Jun 18 10:38:21 2009 -0400
++++ openjdk/jdk/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);
+diff -r 81c176909720 -r 37ed72fe7561 test/sun/security/krb5/auto/IgnoreChannelBinding.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/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;
++            }
++        }
++    }
++}