changeset 10681:ccb0249b0db4

8056141: Move com.sun.security.jgss into a new module Reviewed-by: alanb, chegar, mchung
author weijun
date Wed, 17 Sep 2014 13:55:30 +0800
parents eac4f63808a2
children f015c3079e02
files src/java.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java src/java.security.jgss/share/classes/com/sun/security/jgss/Extender.java src/java.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java src/java.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java src/java.security.jgss/share/classes/com/sun/security/jgss/InquireType.java src/java.security.jgss/share/classes/com/sun/security/jgss/package-info.java src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java src/jdk.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java src/jdk.security.jgss/share/classes/com/sun/security/jgss/Extender.java src/jdk.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireType.java src/jdk.security.jgss/share/classes/com/sun/security/jgss/package-info.java src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
diffstat 24 files changed, 1558 insertions(+), 1558 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.jgss;
-
-/**
- * Kerberos 5 AuthorizationData entry.
- */
-@jdk.Exported
-public final class AuthorizationDataEntry {
-
-    private final int type;
-    private final byte[] data;
-
-    /**
-     * Create an AuthorizationDataEntry object.
-     * @param type the ad-type
-     * @param data the ad-data, a copy of the data will be saved
-     * inside the object.
-     */
-    public AuthorizationDataEntry(int type, byte[] data) {
-        this.type = type;
-        this.data = data.clone();
-    }
-
-    /**
-     * Get the ad-type field.
-     * @return ad-type
-     */
-    public int getType() {
-        return type;
-    }
-
-    /**
-     * Get a copy of the ad-data field.
-     * @return ad-data
-     */
-    public byte[] getData() {
-        return data.clone();
-    }
-
-    public String toString() {
-        return "AuthorizationDataEntry: type="+type+", data=" +
-                data.length + " bytes:\n" +
-                new sun.misc.HexDumpEncoder().encodeBuffer(data);
-    }
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.jgss;
-
-import org.ietf.jgss.*;
-import sun.security.jgss.GSSContextImpl;
-import sun.security.krb5.internal.AuthorizationData;
-
-/**
- * The extended GSSContext interface for supporting additional
- * functionalities not defined by {@code org.ietf.jgss.GSSContext},
- * such as querying context-specific attributes.
- */
-@jdk.Exported
-public interface ExtendedGSSContext extends GSSContext {
-
-    // The impl is almost identical to GSSContextImpl with only 2 differences:
-    // 1. It implements the extended interface
-    // 2. It translates result to data types here in inquireSecContext
-    static class ExtendedGSSContextImpl extends GSSContextImpl
-            implements ExtendedGSSContext {
-
-        public ExtendedGSSContextImpl(GSSContextImpl old) {
-            super(old);
-        }
-
-        @Override
-        public Object inquireSecContext(InquireType type) throws GSSException {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkPermission(
-                        new InquireSecContextPermission(type.toString()));
-            }
-            Object output = super.inquireSecContext(type.name());
-            if (output != null) {
-                if (type == InquireType.KRB5_GET_AUTHZ_DATA) {
-                    AuthorizationData ad = (AuthorizationData) output;
-                    AuthorizationDataEntry[] authzData =
-                            new AuthorizationDataEntry[ad.count()];
-                    for (int i = 0; i < ad.count(); i++) {
-                        authzData[i] = new AuthorizationDataEntry(
-                                ad.item(i).adType, ad.item(i).adData);
-                    }
-                    output = authzData;
-                }
-            }
-            return output;
-        }
-    }
-
-    /**
-     * Return the mechanism-specific attribute associated with {@code type}.
-     * <p>
-     * If there is a security manager, an {@link InquireSecContextPermission}
-     * with the name {@code type.mech} must be granted. Otherwise, this could
-     * result in a {@link SecurityException}.
-     * <p>
-     * Example:
-     * <pre>
-     *      GSSContext ctxt = m.createContext(...)
-     *      // Establishing the context
-     *      if (ctxt instanceof ExtendedGSSContext) {
-     *          ExtendedGSSContext ex = (ExtendedGSSContext)ctxt;
-     *          try {
-     *              Key key = (key)ex.inquireSecContext(
-     *                      InquireType.KRB5_GET_SESSION_KEY);
-     *              // read key info
-     *          } catch (GSSException gsse) {
-     *              // deal with exception
-     *          }
-     *      }
-     * </pre>
-     * @param type the type of the attribute requested
-     * @return the attribute, see the method documentation for details.
-     * @throws GSSException containing  the following
-     * major error codes:
-     *   {@link GSSException#BAD_MECH GSSException.BAD_MECH} if the mechanism
-     *   does not support this method,
-     *   {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE} if the
-     *   type specified is not supported,
-     *   {@link GSSException#NO_CONTEXT GSSException.NO_CONTEXT} if the
-     *   security context is invalid,
-     *   {@link GSSException#FAILURE GSSException.FAILURE} for other
-     *   unspecified failures.
-     * @throws SecurityException if a security manager exists and a proper
-     *   {@link InquireSecContextPermission} is not granted.
-     * @see InquireSecContextPermission
-     * @see InquireType
-     */
-    public Object inquireSecContext(InquireType type)
-            throws GSSException;
-
-    /**
-     * Requests that the delegation policy be respected. When a true value is
-     * requested, the underlying context would use the delegation policy
-     * defined by the environment as a hint to determine whether credentials
-     * delegation should be performed. This request can only be made on the
-     * context initiator's side and it has to be done prior to the first
-     * call to <code>initSecContext</code>.
-     * <p>
-     * When this flag is false, delegation will only be tried when the
-     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
-     * is true.
-     * <p>
-     * When this flag is true but the
-     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
-     * is false, delegation will be only tried if the delegation policy permits
-     * delegation.
-     * <p>
-     * When both this flag and the
-     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
-     * are true, delegation will be always tried. However, if the delegation
-     * policy does not permit delegation, the value of
-     * {@link #getDelegPolicyState} will be false, even
-     * if delegation is performed successfully.
-     * <p>
-     * In any case, if the delegation is not successful, the value returned
-     * by {@link GSSContext#getCredDelegState()} is false, and the value
-     * returned by {@link #getDelegPolicyState()} is also false.
-     * <p>
-     * Not all mechanisms support delegation policy. Therefore, the
-     * application should check to see if the request was honored with the
-     * {@link #getDelegPolicyState() getDelegPolicyState} method. When
-     * delegation policy is not supported, <code>requestDelegPolicy</code>
-     * should return silently without throwing an exception.
-     * <p>
-     * Note: for the Kerberos 5 mechanism, the delegation policy is expressed
-     * through the OK-AS-DELEGATE flag in the service ticket. When it's true,
-     * the KDC permits delegation to the target server. In a cross-realm
-     * environment, in order for delegation be permitted, all cross-realm TGTs
-     * on the authentication path must also have the OK-AS-DELAGATE flags set.
-     * @param state true if the policy should be respected
-     * @throws GSSException containing the following
-     * major error codes:
-     *   {@link GSSException#FAILURE GSSException.FAILURE}
-     */
-    public void requestDelegPolicy(boolean state) throws GSSException;
-
-    /**
-     * Returns the delegation policy response. Called after a security context
-     * is established. This method can be only called on the initiator's side.
-     * See {@link ExtendedGSSContext#requestDelegPolicy}.
-     * @return the delegation policy response
-     */
-    public boolean getDelegPolicyState();
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.jgss;
-
-import org.ietf.jgss.*;
-import sun.security.jgss.GSSCredentialImpl;
-
-/**
- * The extended GSSCredential interface for supporting additional
- * functionalities not defined by {@code org.ietf.jgss.GSSCredential}.
- * @since 1.8
- */
-@jdk.Exported
-public interface ExtendedGSSCredential extends GSSCredential {
-
-    static class ExtendedGSSCredentialImpl extends GSSCredentialImpl
-            implements ExtendedGSSCredential {
-
-        public ExtendedGSSCredentialImpl(GSSCredentialImpl old) {
-            super(old);
-        }
-    }
-
-    /**
-     * Impersonates a principal. In Kerberos, this can be implemented
-     * using the Microsoft S4U2self extension.
-     * <p>
-     * A {@link GSSException#NO_CRED GSSException.NO_CRED} will be thrown if the
-     * impersonation fails. A {@link GSSException#FAILURE GSSException.FAILURE}
-     * will be  thrown if the impersonation method is not available to this
-     * credential object.
-     * @param name the name of the principal to impersonate
-     * @return a credential for that principal
-     * @throws GSSException  containing the following
-     * major error codes:
-     *   {@link GSSException#NO_CRED GSSException.NO_CRED}
-     *   {@link GSSException#FAILURE GSSException.FAILURE}
-     */
-    public GSSCredential impersonate(GSSName name) throws GSSException;
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/jgss/Extender.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.jgss;
-
-import org.ietf.jgss.GSSContext;
-import org.ietf.jgss.GSSCredential;
-import sun.security.jgss.GSSContextImpl;
-import sun.security.jgss.GSSCredentialImpl;
-import sun.security.jgss.JgssExtender;
-
-// The com.sun.security.jgss extension to JGSS-API
-class Extender extends JgssExtender {
-
-    static {
-        JgssExtender.setExtender(new Extender());
-    }
-
-    public GSSCredential wrap(GSSCredential cred) {
-        if (cred instanceof ExtendedGSSCredential.ExtendedGSSCredentialImpl) {
-            return cred;
-        } else {
-            return new ExtendedGSSCredential.ExtendedGSSCredentialImpl((GSSCredentialImpl)cred);
-        }
-    }
-
-    public GSSContext wrap(GSSContext ctxt) {
-        if (ctxt instanceof ExtendedGSSContext.ExtendedGSSContextImpl) {
-            return ctxt;
-        } else {
-            return new ExtendedGSSContext.ExtendedGSSContextImpl((GSSContextImpl)ctxt);
-        }
-    }
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.jgss;
-
-import javax.security.auth.Subject;
-import org.ietf.jgss.GSSName;
-import org.ietf.jgss.GSSCredential;
-
-/**
- * GSS-API Utilities for using in conjunction with Sun Microsystem's
- * implementation of Java GSS-API.
- */
-@jdk.Exported
-public class GSSUtil {
-
-    /**
-     * Use this method to convert a GSSName and GSSCredential into a
-     * Subject. Typically this would be done by a server that wants to
-     * impersonate a client thread at the Java level by setting a client
-     * Subject in the current access control context. If the server is merely
-     * interested in using a principal based policy in its local JVM, then
-     * it only needs to provide the GSSName of the client.
-     *
-     * The elements from the GSSName are placed in the principals set of this
-     * Subject and those from the GSSCredential are placed in the private
-     * credentials set of the Subject. Any Kerberos specific elements that
-     * are added to the subject will be instances of the standard Kerberos
-     * implementation classes defined in javax.security.auth.kerberos.
-     *
-     * @return a Subject with the entries that contain elements from the
-     * given GSSName and GSSCredential.
-     *
-     * @param principals a GSSName containing one or more mechanism specific
-     * representations of the same entity. These mechanism specific
-     * representations will be populated in the returned Subject's principal
-     * set.
-     *
-     * @param credentials a GSSCredential containing one or more mechanism
-     * specific credentials for the same entity. These mechanism specific
-     * credentials will be populated in the returned Subject's private
-     * credential set. Passing in a value of null will imply that the private
-     * credential set should be left empty.
-     */
-    public static Subject createSubject(GSSName principals,
-                                     GSSCredential credentials) {
-
-        return  sun.security.jgss.GSSUtil.getSubject(principals,
-                                                     credentials);
-    }
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.jgss;
-
-import java.security.BasicPermission;
-
-/**
- * This class is used to protect various attributes of an established
- * GSS security context that can be accessed using the
- * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext}
- * method.
- *
- * <p>The target name is the {@link InquireType} allowed.
- */
-@jdk.Exported
-public final class InquireSecContextPermission extends BasicPermission {
-    private static final long serialVersionUID = -7131173349668647297L;
-
-    /**
-     * Constructs a new {@code InquireSecContextPermission} object with
-     * the specified name. The name is the symbolic name of the
-     * {@link InquireType} allowed.
-     *
-     * @param name the {@link InquireType} allowed by this
-     * permission. "*" means all {@link InquireType}s are allowed.
-     *
-     * @throws NullPointerException if <code>name</code> is <code>null</code>.
-     * @throws IllegalArgumentException if <code>name</code> is empty.
-     */
-    public InquireSecContextPermission(String name) {
-        super(name);
-    }
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/jgss/InquireType.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.jgss;
-
-/**
- * Attribute types that can be specified as an argument of
- * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext}
- */
-@jdk.Exported
-public enum InquireType {
-    /**
-     * Attribute type for retrieving the session key of an established
-     * Kerberos 5 security context. The returned object is an instance of
-     * {@link java.security.Key}, which has the following properties:
-     *    <ul>
-     *    <li>Algorithm: enctype as a string, where
-     *        enctype is defined in RFC 3961, section 8.
-     *    <li>Format: "RAW"
-     *    <li>Encoded form: the raw key bytes, not in any ASN.1 encoding
-     *    </ul>
-     * @deprecated as of 1.9, replaced by {@link #KRB5_GET_SESSION_KEY_EX}
-     * which returns an instance of
-     * {@link javax.security.auth.kerberos.EncryptionKey}
-     * that implements the {@link javax.crypto.SecretKey} interface and
-     * has similar methods with {@link javax.security.auth.kerberos.KerberosKey}.
-     */
-    @Deprecated
-    KRB5_GET_SESSION_KEY,
-    /**
-     * Attribute type for retrieving the session key of an
-     * established Kerberos 5 security context. The return value is an
-     * instance of {@link javax.security.auth.kerberos.EncryptionKey}.
-     *
-     * @since 1.9
-     */
-    KRB5_GET_SESSION_KEY_EX,
-    /**
-     * Attribute type for retrieving the service ticket flags of an
-     * established Kerberos 5 security context. The returned object is
-     * a boolean array for the service ticket flags, which is long enough
-     * to contain all true bits. This means if the user wants to get the
-     * <em>n</em>'th bit but the length of the returned array is less than
-     * <em>n</em>, it is regarded as false.
-     */
-    KRB5_GET_TKT_FLAGS,
-    /**
-     * Attribute type for retrieving the authorization data in the
-     * service ticket of an established Kerberos 5 security context.
-     * Only supported on the acceptor side.
-     */
-    KRB5_GET_AUTHZ_DATA,
-    /**
-     * Attribute type for retrieving the authtime in the service ticket
-     * of an established Kerberos 5 security context. The returned object
-     * is a String object in the standard KerberosTime format defined in
-     * RFC 4120 Section 5.2.3.
-     */
-    KRB5_GET_AUTHTIME,
-    /**
-     * Attribute type for retrieving the KRB_CRED message that an initiator
-     * is about to send to an acceptor. The return type is an instance of
-     * {@link javax.security.auth.kerberos.KerberosCredMessage}.
-     *
-     * @since 1.9
-     */
-    KRB5_GET_KRB_CRED,
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/jgss/package-info.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-@jdk.Exported
-package com.sun.security.jgss;
--- a/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2000, 2006, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.sasl.gsskerb;
-
-import javax.security.sasl.*;
-import com.sun.security.sasl.util.PolicyUtils;
-
-import java.util.Map;
-import javax.security.auth.callback.CallbackHandler;
-
-/**
-  * Client/server factory for GSSAPI (Kerberos V5) SASL client/server mechs.
-  * See GssKrb5Client/GssKrb5Server for input requirements.
-  *
-  * @author Rosanna Lee
-  */
-public final class FactoryImpl implements SaslClientFactory, SaslServerFactory {
-    private static final String myMechs[] = {
-        "GSSAPI"};
-
-    private static final int mechPolicies[] = {
-        PolicyUtils.NOPLAINTEXT|PolicyUtils.NOANONYMOUS|PolicyUtils.NOACTIVE
-    };
-
-    private static final int GSS_KERB_V5 = 0;
-
-    public FactoryImpl() {
-    }
-
-    public SaslClient createSaslClient(String[] mechs,
-        String authorizationId,
-        String protocol,
-        String serverName,
-        Map<String,?> props,
-        CallbackHandler cbh) throws SaslException {
-
-            for (int i = 0; i < mechs.length; i++) {
-                if (mechs[i].equals(myMechs[GSS_KERB_V5])
-                    && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) {
-                    return new GssKrb5Client(
-                        authorizationId,
-                        protocol,
-                        serverName,
-                        props,
-                        cbh);
-                }
-            }
-            return null;
-    };
-
-    public SaslServer createSaslServer(String mech,
-        String protocol,
-        String serverName,
-        Map<String,?> props,
-        CallbackHandler cbh) throws SaslException {
-            if (mech.equals(myMechs[GSS_KERB_V5])
-                && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) {
-                if (cbh == null) {
-                    throw new SaslException(
-                "Callback handler with support for AuthorizeCallback required");
-                }
-                return new GssKrb5Server(
-                    protocol,
-                    serverName,
-                    props,
-                    cbh);
-            }
-            return null;
-    };
-
-    public String[] getMechanismNames(Map<String,?> props) {
-        return PolicyUtils.filterMechs(myMechs, mechPolicies, props);
-    }
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-
-package com.sun.security.sasl.gsskerb;
-
-import java.util.Locale;
-import java.util.Map;
-import java.util.logging.Level;
-import javax.security.sasl.*;
-import com.sun.security.sasl.util.AbstractSaslImpl;
-import org.ietf.jgss.*;
-import com.sun.security.jgss.ExtendedGSSContext;
-import com.sun.security.jgss.InquireType;
-
-abstract class GssKrb5Base extends AbstractSaslImpl {
-
-    private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2";
-    protected static Oid KRB5_OID;
-    protected static final byte[] EMPTY = new byte[0];
-
-    static {
-        try {
-            KRB5_OID = new Oid(KRB5_OID_STR);
-        } catch (GSSException ignore) {}
-    }
-
-    protected GSSContext secCtx = null;
-    protected static final int JGSS_QOP = 0;    // unrelated to SASL QOP mask
-
-    protected GssKrb5Base(Map<String, ?> props, String className)
-        throws SaslException {
-        super(props, className);
-    }
-
-    /**
-     * Retrieves this mechanism's name.
-     *
-     * @return  The string "GSSAPI".
-     */
-    public String getMechanismName() {
-        return "GSSAPI";
-    }
-
-    @Override
-    public Object getNegotiatedProperty(String propName) {
-        if (!completed) {
-            throw new IllegalStateException("Authentication incomplete");
-        }
-        String xprefix = "com.sun.security.jgss.inquiretype.";
-        if (propName.startsWith(xprefix)) {
-            String type = propName.substring(xprefix.length());
-            if (logger.isLoggable(Level.FINEST)) {
-                logger.logp(Level.FINE, "GssKrb5Base",
-                        "getNegotiatedProperty", propName);
-            }
-            for (InquireType t: InquireType.values()) {
-                if (t.name().toLowerCase(Locale.US).equals(type)) {
-                    try {
-                        return ((ExtendedGSSContext)secCtx).inquireSecContext(t);
-                    } catch (GSSException e) {
-                        if (logger.isLoggable(Level.FINEST)) {
-                            logger.log(Level.WARNING, "inquireSecContext error", e);
-                        }
-                        return null;
-                    }
-                }
-            }
-            // No such InquireType. Although not likely to be defined
-            // as a property in a parent class, still try it.
-        }
-        return super.getNegotiatedProperty(propName);
-    }
-
-    public byte[] unwrap(byte[] incoming, int start, int len)
-        throws SaslException {
-        if (!completed) {
-            throw new IllegalStateException("GSSAPI authentication not completed");
-        }
-
-        // integrity will be true if either privacy or integrity negotiated
-        if (!integrity) {
-            throw new IllegalStateException("No security layer negotiated");
-        }
-
-        try {
-            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
-            byte[] answer = secCtx.unwrap(incoming, start, len, msgProp);
-            if (logger.isLoggable(Level.FINEST)) {
-                traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
-                    incoming, start, len);
-                traceOutput(myClassName, "KRB502:Unwrap", "unwrapped: ",
-                    answer, 0, answer.length);
-            }
-            return answer;
-        } catch (GSSException e) {
-            throw new SaslException("Problems unwrapping SASL buffer", e);
-        }
-    }
-
-    public byte[] wrap(byte[] outgoing, int start, int len) throws SaslException {
-        if (!completed) {
-            throw new IllegalStateException("GSSAPI authentication not completed");
-        }
-
-        // integrity will be true if either privacy or integrity negotiated
-        if (!integrity) {
-            throw new IllegalStateException("No security layer negotiated");
-        }
-
-        // Generate GSS token
-        try {
-            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
-            byte[] answer = secCtx.wrap(outgoing, start, len, msgProp);
-            if (logger.isLoggable(Level.FINEST)) {
-                traceOutput(myClassName, "KRB503:Wrap", "outgoing: ",
-                    outgoing, start, len);
-                traceOutput(myClassName, "KRB504:Wrap", "wrapped: ",
-                    answer, 0, answer.length);
-            }
-            return answer;
-
-        } catch (GSSException e) {
-            throw new SaslException("Problem performing GSS wrap", e);
-        }
-    }
-
-    public void dispose() throws SaslException {
-        if (secCtx != null) {
-            try {
-                secCtx.dispose();
-            } catch (GSSException e) {
-                throw new SaslException("Problem disposing GSS context", e);
-            }
-            secCtx = null;
-        }
-    }
-
-    protected void finalize() throws Throwable {
-        dispose();
-    }
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,329 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.sasl.gsskerb;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.logging.Level;
-import javax.security.sasl.*;
-
-// JAAS
-import javax.security.auth.callback.CallbackHandler;
-
-// JGSS
-import org.ietf.jgss.*;
-
-/**
-  * Implements the GSSAPI SASL client mechanism for Kerberos V5.
-  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
-  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-04.txt">draft-ietf-cat-sasl-gssapi-04.txt</a>).
-  * It uses the Java Bindings for GSSAPI
-  * (<A HREF="http://www.ietf.org/rfc/rfc2853.txt">RFC 2853</A>)
-  * for getting GSSAPI/Kerberos V5 support.
-  *
-  * The client/server interactions are:
-  * C0: bind (GSSAPI, initial response)
-  * S0: sasl-bind-in-progress, challenge 1 (output of accept_sec_context or [])
-  * C1: bind (GSSAPI, response 1 (output of init_sec_context or []))
-  * S1: sasl-bind-in-progress challenge 2 (security layer, server max recv size)
-  * C2: bind (GSSAPI, response 2 (security layer, client max recv size, authzid))
-  * S2: bind success response
-  *
-  * Expects the client's credentials to be supplied from the
-  * javax.security.sasl.credentials property or from the thread's Subject.
-  * Otherwise the underlying KRB5 mech will attempt to acquire Kerberos creds
-  * by logging into Kerberos (via default TextCallbackHandler).
-  * These creds will be used for exchange with server.
-  *
-  * Required callbacks: none.
-  *
-  * Environment properties that affect behavior of implementation:
-  *
-  * javax.security.sasl.qop
-  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
-  * javax.security.sasl.maxbuf
-  * - max receive buffer size; default is 65536
-  * javax.security.sasl.sendmaxbuffer
-  * - max send buffer size; default is 65536; (min with server max recv size)
-  *
-  * javax.security.sasl.server.authentication
-  * - "true" means require mutual authentication; default is "false"
-  *
-  * javax.security.sasl.credentials
-  * - an {@link org.ietf.jgss.GSSCredential} used for delegated authentication.
-  *
-  * @author Rosanna Lee
-  */
-
-final class GssKrb5Client extends GssKrb5Base implements SaslClient {
-    // ---------------- Constants -----------------
-    private static final String MY_CLASS_NAME = GssKrb5Client.class.getName();
-
-    private boolean finalHandshake = false;
-    private boolean mutual = false;       // default false
-    private byte[] authzID;
-
-    /**
-     * Creates a SASL mechanism with client credentials that it needs
-     * to participate in GSS-API/Kerberos v5 authentication exchange
-     * with the server.
-     */
-    GssKrb5Client(String authzID, String protocol, String serverName,
-        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
-
-        super(props, MY_CLASS_NAME);
-
-        String service = protocol + "@" + serverName;
-        logger.log(Level.FINE, "KRB5CLNT01:Requesting service name: {0}",
-            service);
-
-        try {
-            GSSManager mgr = GSSManager.getInstance();
-
-            // Create the name for the requested service entity for Krb5 mech
-            GSSName acceptorName = mgr.createName(service,
-                GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
-
-            // Parse properties to check for supplied credentials
-            GSSCredential credentials = null;
-            if (props != null) {
-                Object prop = props.get(Sasl.CREDENTIALS);
-                if (prop != null && prop instanceof GSSCredential) {
-                    credentials = (GSSCredential) prop;
-                    logger.log(Level.FINE,
-                        "KRB5CLNT01:Using the credentials supplied in " +
-                        "javax.security.sasl.credentials");
-                }
-            }
-
-            // Create a context using credentials for Krb5 mech
-            secCtx = mgr.createContext(acceptorName,
-                KRB5_OID,   /* mechanism */
-                credentials, /* credentials */
-                GSSContext.INDEFINITE_LIFETIME);
-
-            // Request credential delegation when credentials have been supplied
-            if (credentials != null) {
-                secCtx.requestCredDeleg(true);
-            }
-
-            // Parse properties  to set desired context options
-            if (props != null) {
-                // Mutual authentication
-                String prop = (String)props.get(Sasl.SERVER_AUTH);
-                if (prop != null) {
-                    mutual = "true".equalsIgnoreCase(prop);
-                }
-            }
-            secCtx.requestMutualAuth(mutual);
-
-            // Always specify potential need for integrity and confidentiality
-            // Decision will be made during final handshake
-            secCtx.requestConf(true);
-            secCtx.requestInteg(true);
-
-        } catch (GSSException e) {
-            throw new SaslException("Failure to initialize security context", e);
-        }
-
-        if (authzID != null && authzID.length() > 0) {
-            try {
-                this.authzID = authzID.getBytes("UTF8");
-            } catch (IOException e) {
-                throw new SaslException("Cannot encode authorization ID", e);
-            }
-        }
-    }
-
-    public boolean hasInitialResponse() {
-        return true;
-    }
-
-    /**
-     * Processes the challenge data.
-     *
-     * The server sends a challenge data using which the client must
-     * process using GSS_Init_sec_context.
-     * As per RFC 2222, when GSS_S_COMPLETE is returned, we do
-     * an extra handshake to determine the negotiated security protection
-     * and buffer sizes.
-     *
-     * @param challengeData A non-null byte array containing the
-     * challenge data from the server.
-     * @return A non-null byte array containing the response to be
-     * sent to the server.
-     */
-    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {
-        if (completed) {
-            throw new IllegalStateException(
-                "GSSAPI authentication already complete");
-        }
-
-        if (finalHandshake) {
-            return doFinalHandshake(challengeData);
-        } else {
-
-            // Security context not established yet; continue with init
-
-            try {
-                byte[] gssOutToken = secCtx.initSecContext(challengeData,
-                    0, challengeData.length);
-                if (logger.isLoggable(Level.FINER)) {
-                    traceOutput(MY_CLASS_NAME, "evaluteChallenge",
-                        "KRB5CLNT02:Challenge: [raw]", challengeData);
-                    traceOutput(MY_CLASS_NAME, "evaluateChallenge",
-                        "KRB5CLNT03:Response: [after initSecCtx]", gssOutToken);
-                }
-
-                if (secCtx.isEstablished()) {
-                    finalHandshake = true;
-                    if (gssOutToken == null) {
-                        // RFC 2222 7.2.1:  Client responds with no data
-                        return EMPTY;
-                    }
-                }
-
-                return gssOutToken;
-            } catch (GSSException e) {
-                throw new SaslException("GSS initiate failed", e);
-            }
-        }
-    }
-
-    private byte[] doFinalHandshake(byte[] challengeData) throws SaslException {
-        try {
-            // Security context already established. challengeData
-            // should contain security layers and server's maximum buffer size
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
-                    "KRB5CLNT04:Challenge [raw]:", challengeData);
-            }
-
-            if (challengeData.length == 0) {
-                // Received S0, should return []
-                return EMPTY;
-            }
-
-            // Received S1 (security layer, server max recv size)
-
-            byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
-                challengeData.length, new MessageProp(0, false));
-
-            // First octet is a bit-mask specifying the protections
-            // supported by the server
-            if (logger.isLoggable(Level.FINE)) {
-                if (logger.isLoggable(Level.FINER)) {
-                    traceOutput(MY_CLASS_NAME, "doFinalHandshake",
-                        "KRB5CLNT05:Challenge [unwrapped]:", gssOutToken);
-                }
-                logger.log(Level.FINE, "KRB5CLNT06:Server protections: {0}",
-                    gssOutToken[0]);
-            }
-
-            // Client selects preferred protection
-            // qop is ordered list of qop values
-            byte selectedQop = findPreferredMask(gssOutToken[0], qop);
-            if (selectedQop == 0) {
-                throw new SaslException(
-                    "No common protection layer between client and server");
-            }
-
-            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
-                privacy = true;
-                integrity = true;
-            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
-                integrity = true;
-            }
-
-            // 2nd-4th octets specifies maximum buffer size expected by
-            // server (in network byte order)
-            int srvMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
-
-            // Determine the max send buffer size based on what the
-            // server is able to receive and our specified max
-            sendMaxBufSize = (sendMaxBufSize == 0) ? srvMaxBufSize :
-                Math.min(sendMaxBufSize, srvMaxBufSize);
-
-            // Update context to limit size of returned buffer
-            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
-                sendMaxBufSize);
-
-            if (logger.isLoggable(Level.FINE)) {
-                logger.log(Level.FINE,
-"KRB5CLNT07:Client max recv size: {0}; server max recv size: {1}; rawSendSize: {2}",
-                    new Object[] {recvMaxBufSize,
-                                  srvMaxBufSize,
-                                  rawSendSize});
-            }
-
-            // Construct negotiated security layers and client's max
-            // receive buffer size and authzID
-            int len = 4;
-            if (authzID != null) {
-                len += authzID.length;
-            }
-
-            byte[] gssInToken = new byte[len];
-            gssInToken[0] = selectedQop;
-
-            if (logger.isLoggable(Level.FINE)) {
-                logger.log(Level.FINE,
-            "KRB5CLNT08:Selected protection: {0}; privacy: {1}; integrity: {2}",
-                    new Object[]{selectedQop,
-                                 Boolean.valueOf(privacy),
-                                 Boolean.valueOf(integrity)});
-            }
-
-            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
-            if (authzID != null) {
-                // copy authorization id
-                System.arraycopy(authzID, 0, gssInToken, 4, authzID.length);
-                logger.log(Level.FINE, "KRB5CLNT09:Authzid: {0}", authzID);
-            }
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
-                    "KRB5CLNT10:Response [raw]", gssInToken);
-            }
-
-            gssOutToken = secCtx.wrap(gssInToken,
-                0, gssInToken.length,
-                new MessageProp(0 /* qop */, false /* privacy */));
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
-                    "KRB5CLNT11:Response [after wrap]", gssOutToken);
-            }
-
-            completed = true;  // server authenticated
-
-            return gssOutToken;
-        } catch (GSSException e) {
-            throw new SaslException("Final handshake failed", e);
-        }
-    }
-}
--- a/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java	Wed Sep 17 13:55:12 2014 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package com.sun.security.sasl.gsskerb;
-
-import javax.security.sasl.*;
-import java.io.*;
-import java.util.Map;
-import java.util.logging.Level;
-
-// JAAS
-import javax.security.auth.callback.*;
-
-// JGSS
-import org.ietf.jgss.*;
-
-/**
-  * Implements the GSSAPI SASL server mechanism for Kerberos V5.
-  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
-  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-00.txt">draft-ietf-cat-sasl-gssapi-00.txt</a>).
-  *
-  * Expects thread's Subject to contain server's Kerberos credentials
-  * - If not, underlying KRB5 mech will attempt to acquire Kerberos creds
-  *   by logging into Kerberos (via default TextCallbackHandler).
-  * - These creds will be used for exchange with client.
-  *
-  * Required callbacks:
-  * - AuthorizeCallback
-  *      handler must verify that authid/authzids are allowed and set
-  *      authorized ID to be the canonicalized authzid (if applicable).
-  *
-  * Environment properties that affect behavior of implementation:
-  *
-  * javax.security.sasl.qop
-  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
-  * javax.security.sasl.maxbuf
-  * - max receive buffer size; default is 65536
-  * javax.security.sasl.sendmaxbuffer
-  * - max send buffer size; default is 65536; (min with client max recv size)
-  *
-  * @author Rosanna Lee
-  */
-final class GssKrb5Server extends GssKrb5Base implements SaslServer {
-    private static final String MY_CLASS_NAME = GssKrb5Server.class.getName();
-
-    private int handshakeStage = 0;
-    private String peer;
-    private String me;
-    private String authzid;
-    private CallbackHandler cbh;
-
-    // When serverName is null, the server will be unbound. We need to save and
-    // check the protocol name after the context is established. This value
-    // will be null if serverName is not null.
-    private final String protocolSaved;
-    /**
-     * Creates a SASL mechanism with server credentials that it needs
-     * to participate in GSS-API/Kerberos v5 authentication exchange
-     * with the client.
-     */
-    GssKrb5Server(String protocol, String serverName,
-        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
-
-        super(props, MY_CLASS_NAME);
-
-        this.cbh = cbh;
-
-        String service;
-        if (serverName == null) {
-            protocolSaved = protocol;
-            service = null;
-        } else {
-            protocolSaved = null;
-            service = protocol + "@" + serverName;
-        }
-
-        logger.log(Level.FINE, "KRB5SRV01:Using service name: {0}", service);
-
-        try {
-            GSSManager mgr = GSSManager.getInstance();
-
-            // Create the name for the requested service entity for Krb5 mech
-            GSSName serviceName = service == null ? null:
-                    mgr.createName(service, GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
-
-            GSSCredential cred = mgr.createCredential(serviceName,
-                GSSCredential.INDEFINITE_LIFETIME,
-                KRB5_OID, GSSCredential.ACCEPT_ONLY);
-
-            // Create a context using the server's credentials
-            secCtx = mgr.createContext(cred);
-
-            if ((allQop&INTEGRITY_ONLY_PROTECTION) != 0) {
-                // Might need integrity
-                secCtx.requestInteg(true);
-            }
-
-            if ((allQop&PRIVACY_PROTECTION) != 0) {
-                // Might need privacy
-                secCtx.requestConf(true);
-            }
-        } catch (GSSException e) {
-            throw new SaslException("Failure to initialize security context", e);
-        }
-        logger.log(Level.FINE, "KRB5SRV02:Initialization complete");
-    }
-
-
-    /**
-     * Processes the response data.
-     *
-     * The client sends response data to which the server must
-     * process using GSS_accept_sec_context.
-     * As per RFC 2222, the GSS authenication completes (GSS_S_COMPLETE)
-     * we do an extra hand shake to determine the negotiated security protection
-     * and buffer sizes.
-     *
-     * @param responseData A non-null but possible empty byte array containing the
-     * response data from the client.
-     * @return A non-null byte array containing the challenge to be
-     * sent to the client, or null when no more data is to be sent.
-     */
-    public byte[] evaluateResponse(byte[] responseData) throws SaslException {
-        if (completed) {
-            throw new SaslException(
-                "SASL authentication already complete");
-        }
-
-        if (logger.isLoggable(Level.FINER)) {
-            traceOutput(MY_CLASS_NAME, "evaluateResponse",
-                "KRB5SRV03:Response [raw]:", responseData);
-        }
-
-        switch (handshakeStage) {
-        case 1:
-            return doHandshake1(responseData);
-
-        case 2:
-            return doHandshake2(responseData);
-
-        default:
-            // Security context not established yet; continue with accept
-
-            try {
-                byte[] gssOutToken = secCtx.acceptSecContext(responseData,
-                    0, responseData.length);
-
-                if (logger.isLoggable(Level.FINER)) {
-                    traceOutput(MY_CLASS_NAME, "evaluateResponse",
-                        "KRB5SRV04:Challenge: [after acceptSecCtx]", gssOutToken);
-                }
-
-                if (secCtx.isEstablished()) {
-                    handshakeStage = 1;
-
-                    peer = secCtx.getSrcName().toString();
-                    me = secCtx.getTargName().toString();
-
-                    logger.log(Level.FINE,
-                            "KRB5SRV05:Peer name is : {0}, my name is : {1}",
-                            new Object[]{peer, me});
-
-                    // me might take the form of proto@host or proto/host
-                    if (protocolSaved != null &&
-                            !protocolSaved.equalsIgnoreCase(me.split("[/@]")[0])) {
-                        throw new SaslException(
-                                "GSS context targ name protocol error: " + me);
-                    }
-
-                    if (gssOutToken == null) {
-                        return doHandshake1(EMPTY);
-                    }
-                }
-
-                return gssOutToken;
-            } catch (GSSException e) {
-                throw new SaslException("GSS initiate failed", e);
-            }
-        }
-    }
-
-    private byte[] doHandshake1(byte[] responseData) throws SaslException {
-        try {
-            // Security context already established. responseData
-            // should contain no data
-            if (responseData != null && responseData.length > 0) {
-                throw new SaslException(
-                    "Handshake expecting no response data from server");
-            }
-
-            // Construct 4 octets of data:
-            // First octet contains bitmask specifying protections supported
-            // 2nd-4th octets contains max receive buffer of server
-
-            byte[] gssInToken = new byte[4];
-            gssInToken[0] = allQop;
-            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
-
-            if (logger.isLoggable(Level.FINE)) {
-                logger.log(Level.FINE,
-                    "KRB5SRV06:Supported protections: {0}; recv max buf size: {1}",
-                    new Object[]{allQop,
-                                 recvMaxBufSize});
-            }
-
-            handshakeStage = 2;  // progress to next stage
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doHandshake1",
-                    "KRB5SRV07:Challenge [raw]", gssInToken);
-            }
-
-            byte[] gssOutToken = secCtx.wrap(gssInToken, 0, gssInToken.length,
-                new MessageProp(0 /* gop */, false /* privacy */));
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doHandshake1",
-                    "KRB5SRV08:Challenge [after wrap]", gssOutToken);
-            }
-            return gssOutToken;
-
-        } catch (GSSException e) {
-            throw new SaslException("Problem wrapping handshake1", e);
-        }
-    }
-
-    private byte[] doHandshake2(byte[] responseData) throws SaslException {
-        try {
-            // Expecting 4 octets from client selected protection
-            // and client's receive buffer size
-            byte[] gssOutToken = secCtx.unwrap(responseData, 0,
-                responseData.length, new MessageProp(0, false));
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doHandshake2",
-                    "KRB5SRV09:Response [after unwrap]", gssOutToken);
-            }
-
-            // First octet is a bit-mask specifying the selected protection
-            byte selectedQop = gssOutToken[0];
-            if ((selectedQop&allQop) == 0) {
-                throw new SaslException("Client selected unsupported protection: "
-                    + selectedQop);
-            }
-            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
-                privacy = true;
-                integrity = true;
-            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
-                integrity = true;
-            }
-
-            // 2nd-4th octets specifies maximum buffer size expected by
-            // client (in network byte order). This is the server's send
-            // buffer maximum.
-            int clntMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
-
-            // Determine the max send buffer size based on what the
-            // client is able to receive and our specified max
-            sendMaxBufSize = (sendMaxBufSize == 0) ? clntMaxBufSize :
-                Math.min(sendMaxBufSize, clntMaxBufSize);
-
-            // Update context to limit size of returned buffer
-            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
-                sendMaxBufSize);
-
-            if (logger.isLoggable(Level.FINE)) {
-                logger.log(Level.FINE,
-            "KRB5SRV10:Selected protection: {0}; privacy: {1}; integrity: {2}",
-                    new Object[]{selectedQop,
-                                 Boolean.valueOf(privacy),
-                                 Boolean.valueOf(integrity)});
-                logger.log(Level.FINE,
-"KRB5SRV11:Client max recv size: {0}; server max send size: {1}; rawSendSize: {2}",
-                    new Object[] {clntMaxBufSize,
-                                  sendMaxBufSize,
-                                  rawSendSize});
-            }
-
-            // Get authorization identity, if any
-            if (gssOutToken.length > 4) {
-                try {
-                    authzid = new String(gssOutToken, 4,
-                        gssOutToken.length - 4, "UTF-8");
-                } catch (UnsupportedEncodingException uee) {
-                    throw new SaslException ("Cannot decode authzid", uee);
-                }
-            } else {
-                authzid = peer;
-            }
-            logger.log(Level.FINE, "KRB5SRV12:Authzid: {0}", authzid);
-
-            AuthorizeCallback acb = new AuthorizeCallback(peer, authzid);
-
-            // In Kerberos, realm is embedded in peer name
-            cbh.handle(new Callback[] {acb});
-            if (acb.isAuthorized()) {
-                authzid = acb.getAuthorizedID();
-                completed = true;
-            } else {
-                // Authorization failed
-                throw new SaslException(peer +
-                    " is not authorized to connect as " + authzid);
-            }
-
-            return null;
-        } catch (GSSException e) {
-            throw new SaslException("Final handshake step failed", e);
-        } catch (IOException e) {
-            throw new SaslException("Problem with callback handler", e);
-        } catch (UnsupportedCallbackException e) {
-            throw new SaslException("Problem with callback handler", e);
-        }
-    }
-
-    public String getAuthorizationID() {
-        if (completed) {
-            return authzid;
-        } else {
-            throw new IllegalStateException("Authentication incomplete");
-        }
-    }
-
-    public Object getNegotiatedProperty(String propName) {
-        if (!completed) {
-            throw new IllegalStateException("Authentication incomplete");
-        }
-
-        Object result;
-        switch (propName) {
-            case Sasl.BOUND_SERVER_NAME:
-                try {
-                    // me might take the form of proto@host or proto/host
-                    result = me.split("[/@]")[1];
-                } catch (Exception e) {
-                    result = null;
-                }
-                break;
-            default:
-                result = super.getNegotiatedProperty(propName);
-        }
-        return result;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.jgss;
+
+/**
+ * Kerberos 5 AuthorizationData entry.
+ */
+@jdk.Exported
+public final class AuthorizationDataEntry {
+
+    private final int type;
+    private final byte[] data;
+
+    /**
+     * Create an AuthorizationDataEntry object.
+     * @param type the ad-type
+     * @param data the ad-data, a copy of the data will be saved
+     * inside the object.
+     */
+    public AuthorizationDataEntry(int type, byte[] data) {
+        this.type = type;
+        this.data = data.clone();
+    }
+
+    /**
+     * Get the ad-type field.
+     * @return ad-type
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Get a copy of the ad-data field.
+     * @return ad-data
+     */
+    public byte[] getData() {
+        return data.clone();
+    }
+
+    public String toString() {
+        return "AuthorizationDataEntry: type="+type+", data=" +
+                data.length + " bytes:\n" +
+                new sun.misc.HexDumpEncoder().encodeBuffer(data);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2009, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.jgss;
+
+import org.ietf.jgss.*;
+import sun.security.jgss.GSSContextImpl;
+import sun.security.krb5.internal.AuthorizationData;
+
+/**
+ * The extended GSSContext interface for supporting additional
+ * functionalities not defined by {@code org.ietf.jgss.GSSContext},
+ * such as querying context-specific attributes.
+ */
+@jdk.Exported
+public interface ExtendedGSSContext extends GSSContext {
+
+    // The impl is almost identical to GSSContextImpl with only 2 differences:
+    // 1. It implements the extended interface
+    // 2. It translates result to data types here in inquireSecContext
+    static class ExtendedGSSContextImpl extends GSSContextImpl
+            implements ExtendedGSSContext {
+
+        public ExtendedGSSContextImpl(GSSContextImpl old) {
+            super(old);
+        }
+
+        @Override
+        public Object inquireSecContext(InquireType type) throws GSSException {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(
+                        new InquireSecContextPermission(type.toString()));
+            }
+            Object output = super.inquireSecContext(type.name());
+            if (output != null) {
+                if (type == InquireType.KRB5_GET_AUTHZ_DATA) {
+                    AuthorizationData ad = (AuthorizationData) output;
+                    AuthorizationDataEntry[] authzData =
+                            new AuthorizationDataEntry[ad.count()];
+                    for (int i = 0; i < ad.count(); i++) {
+                        authzData[i] = new AuthorizationDataEntry(
+                                ad.item(i).adType, ad.item(i).adData);
+                    }
+                    output = authzData;
+                }
+            }
+            return output;
+        }
+    }
+
+    /**
+     * Return the mechanism-specific attribute associated with {@code type}.
+     * <p>
+     * If there is a security manager, an {@link InquireSecContextPermission}
+     * with the name {@code type.mech} must be granted. Otherwise, this could
+     * result in a {@link SecurityException}.
+     * <p>
+     * Example:
+     * <pre>
+     *      GSSContext ctxt = m.createContext(...)
+     *      // Establishing the context
+     *      if (ctxt instanceof ExtendedGSSContext) {
+     *          ExtendedGSSContext ex = (ExtendedGSSContext)ctxt;
+     *          try {
+     *              Key key = (key)ex.inquireSecContext(
+     *                      InquireType.KRB5_GET_SESSION_KEY);
+     *              // read key info
+     *          } catch (GSSException gsse) {
+     *              // deal with exception
+     *          }
+     *      }
+     * </pre>
+     * @param type the type of the attribute requested
+     * @return the attribute, see the method documentation for details.
+     * @throws GSSException containing  the following
+     * major error codes:
+     *   {@link GSSException#BAD_MECH GSSException.BAD_MECH} if the mechanism
+     *   does not support this method,
+     *   {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE} if the
+     *   type specified is not supported,
+     *   {@link GSSException#NO_CONTEXT GSSException.NO_CONTEXT} if the
+     *   security context is invalid,
+     *   {@link GSSException#FAILURE GSSException.FAILURE} for other
+     *   unspecified failures.
+     * @throws SecurityException if a security manager exists and a proper
+     *   {@link InquireSecContextPermission} is not granted.
+     * @see InquireSecContextPermission
+     * @see InquireType
+     */
+    public Object inquireSecContext(InquireType type)
+            throws GSSException;
+
+    /**
+     * Requests that the delegation policy be respected. When a true value is
+     * requested, the underlying context would use the delegation policy
+     * defined by the environment as a hint to determine whether credentials
+     * delegation should be performed. This request can only be made on the
+     * context initiator's side and it has to be done prior to the first
+     * call to <code>initSecContext</code>.
+     * <p>
+     * When this flag is false, delegation will only be tried when the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * is true.
+     * <p>
+     * When this flag is true but the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * is false, delegation will be only tried if the delegation policy permits
+     * delegation.
+     * <p>
+     * When both this flag and the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * are true, delegation will be always tried. However, if the delegation
+     * policy does not permit delegation, the value of
+     * {@link #getDelegPolicyState} will be false, even
+     * if delegation is performed successfully.
+     * <p>
+     * In any case, if the delegation is not successful, the value returned
+     * by {@link GSSContext#getCredDelegState()} is false, and the value
+     * returned by {@link #getDelegPolicyState()} is also false.
+     * <p>
+     * Not all mechanisms support delegation policy. Therefore, the
+     * application should check to see if the request was honored with the
+     * {@link #getDelegPolicyState() getDelegPolicyState} method. When
+     * delegation policy is not supported, <code>requestDelegPolicy</code>
+     * should return silently without throwing an exception.
+     * <p>
+     * Note: for the Kerberos 5 mechanism, the delegation policy is expressed
+     * through the OK-AS-DELEGATE flag in the service ticket. When it's true,
+     * the KDC permits delegation to the target server. In a cross-realm
+     * environment, in order for delegation be permitted, all cross-realm TGTs
+     * on the authentication path must also have the OK-AS-DELAGATE flags set.
+     * @param state true if the policy should be respected
+     * @throws GSSException containing the following
+     * major error codes:
+     *   {@link GSSException#FAILURE GSSException.FAILURE}
+     */
+    public void requestDelegPolicy(boolean state) throws GSSException;
+
+    /**
+     * Returns the delegation policy response. Called after a security context
+     * is established. This method can be only called on the initiator's side.
+     * See {@link ExtendedGSSContext#requestDelegPolicy}.
+     * @return the delegation policy response
+     */
+    public boolean getDelegPolicyState();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.jgss;
+
+import org.ietf.jgss.*;
+import sun.security.jgss.GSSCredentialImpl;
+
+/**
+ * The extended GSSCredential interface for supporting additional
+ * functionalities not defined by {@code org.ietf.jgss.GSSCredential}.
+ * @since 1.8
+ */
+@jdk.Exported
+public interface ExtendedGSSCredential extends GSSCredential {
+
+    static class ExtendedGSSCredentialImpl extends GSSCredentialImpl
+            implements ExtendedGSSCredential {
+
+        public ExtendedGSSCredentialImpl(GSSCredentialImpl old) {
+            super(old);
+        }
+    }
+
+    /**
+     * Impersonates a principal. In Kerberos, this can be implemented
+     * using the Microsoft S4U2self extension.
+     * <p>
+     * A {@link GSSException#NO_CRED GSSException.NO_CRED} will be thrown if the
+     * impersonation fails. A {@link GSSException#FAILURE GSSException.FAILURE}
+     * will be  thrown if the impersonation method is not available to this
+     * credential object.
+     * @param name the name of the principal to impersonate
+     * @return a credential for that principal
+     * @throws GSSException  containing the following
+     * major error codes:
+     *   {@link GSSException#NO_CRED GSSException.NO_CRED}
+     *   {@link GSSException#FAILURE GSSException.FAILURE}
+     */
+    public GSSCredential impersonate(GSSName name) throws GSSException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/Extender.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.jgss;
+
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import sun.security.jgss.GSSContextImpl;
+import sun.security.jgss.GSSCredentialImpl;
+import sun.security.jgss.JgssExtender;
+
+// The com.sun.security.jgss extension to JGSS-API
+class Extender extends JgssExtender {
+
+    static {
+        JgssExtender.setExtender(new Extender());
+    }
+
+    public GSSCredential wrap(GSSCredential cred) {
+        if (cred instanceof ExtendedGSSCredential.ExtendedGSSCredentialImpl) {
+            return cred;
+        } else {
+            return new ExtendedGSSCredential.ExtendedGSSCredentialImpl((GSSCredentialImpl)cred);
+        }
+    }
+
+    public GSSContext wrap(GSSContext ctxt) {
+        if (ctxt instanceof ExtendedGSSContext.ExtendedGSSContextImpl) {
+            return ctxt;
+        } else {
+            return new ExtendedGSSContext.ExtendedGSSContextImpl((GSSContextImpl)ctxt);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2000, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.jgss;
+
+import javax.security.auth.Subject;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.GSSCredential;
+
+/**
+ * GSS-API Utilities for using in conjunction with Sun Microsystem's
+ * implementation of Java GSS-API.
+ */
+@jdk.Exported
+public class GSSUtil {
+
+    /**
+     * Use this method to convert a GSSName and GSSCredential into a
+     * Subject. Typically this would be done by a server that wants to
+     * impersonate a client thread at the Java level by setting a client
+     * Subject in the current access control context. If the server is merely
+     * interested in using a principal based policy in its local JVM, then
+     * it only needs to provide the GSSName of the client.
+     *
+     * The elements from the GSSName are placed in the principals set of this
+     * Subject and those from the GSSCredential are placed in the private
+     * credentials set of the Subject. Any Kerberos specific elements that
+     * are added to the subject will be instances of the standard Kerberos
+     * implementation classes defined in javax.security.auth.kerberos.
+     *
+     * @return a Subject with the entries that contain elements from the
+     * given GSSName and GSSCredential.
+     *
+     * @param principals a GSSName containing one or more mechanism specific
+     * representations of the same entity. These mechanism specific
+     * representations will be populated in the returned Subject's principal
+     * set.
+     *
+     * @param credentials a GSSCredential containing one or more mechanism
+     * specific credentials for the same entity. These mechanism specific
+     * credentials will be populated in the returned Subject's private
+     * credential set. Passing in a value of null will imply that the private
+     * credential set should be left empty.
+     */
+    public static Subject createSubject(GSSName principals,
+                                     GSSCredential credentials) {
+
+        return  sun.security.jgss.GSSUtil.getSubject(principals,
+                                                     credentials);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.jgss;
+
+import java.security.BasicPermission;
+
+/**
+ * This class is used to protect various attributes of an established
+ * GSS security context that can be accessed using the
+ * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext}
+ * method.
+ *
+ * <p>The target name is the {@link InquireType} allowed.
+ */
+@jdk.Exported
+public final class InquireSecContextPermission extends BasicPermission {
+    private static final long serialVersionUID = -7131173349668647297L;
+
+    /**
+     * Constructs a new {@code InquireSecContextPermission} object with
+     * the specified name. The name is the symbolic name of the
+     * {@link InquireType} allowed.
+     *
+     * @param name the {@link InquireType} allowed by this
+     * permission. "*" means all {@link InquireType}s are allowed.
+     *
+     * @throws NullPointerException if <code>name</code> is <code>null</code>.
+     * @throws IllegalArgumentException if <code>name</code> is empty.
+     */
+    public InquireSecContextPermission(String name) {
+        super(name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireType.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2009, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.jgss;
+
+/**
+ * Attribute types that can be specified as an argument of
+ * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext}
+ */
+@jdk.Exported
+public enum InquireType {
+    /**
+     * Attribute type for retrieving the session key of an established
+     * Kerberos 5 security context. The returned object is an instance of
+     * {@link java.security.Key}, which has the following properties:
+     *    <ul>
+     *    <li>Algorithm: enctype as a string, where
+     *        enctype is defined in RFC 3961, section 8.
+     *    <li>Format: "RAW"
+     *    <li>Encoded form: the raw key bytes, not in any ASN.1 encoding
+     *    </ul>
+     * @deprecated as of 1.9, replaced by {@link #KRB5_GET_SESSION_KEY_EX}
+     * which returns an instance of
+     * {@link javax.security.auth.kerberos.EncryptionKey}
+     * that implements the {@link javax.crypto.SecretKey} interface and
+     * has similar methods with {@link javax.security.auth.kerberos.KerberosKey}.
+     */
+    @Deprecated
+    KRB5_GET_SESSION_KEY,
+    /**
+     * Attribute type for retrieving the session key of an
+     * established Kerberos 5 security context. The return value is an
+     * instance of {@link javax.security.auth.kerberos.EncryptionKey}.
+     *
+     * @since 1.9
+     */
+    KRB5_GET_SESSION_KEY_EX,
+    /**
+     * Attribute type for retrieving the service ticket flags of an
+     * established Kerberos 5 security context. The returned object is
+     * a boolean array for the service ticket flags, which is long enough
+     * to contain all true bits. This means if the user wants to get the
+     * <em>n</em>'th bit but the length of the returned array is less than
+     * <em>n</em>, it is regarded as false.
+     */
+    KRB5_GET_TKT_FLAGS,
+    /**
+     * Attribute type for retrieving the authorization data in the
+     * service ticket of an established Kerberos 5 security context.
+     * Only supported on the acceptor side.
+     */
+    KRB5_GET_AUTHZ_DATA,
+    /**
+     * Attribute type for retrieving the authtime in the service ticket
+     * of an established Kerberos 5 security context. The returned object
+     * is a String object in the standard KerberosTime format defined in
+     * RFC 4120 Section 5.2.3.
+     */
+    KRB5_GET_AUTHTIME,
+    /**
+     * Attribute type for retrieving the KRB_CRED message that an initiator
+     * is about to send to an acceptor. The return type is an instance of
+     * {@link javax.security.auth.kerberos.KerberosCredMessage}.
+     *
+     * @since 1.9
+     */
+    KRB5_GET_KRB_CRED,
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/package-info.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+@jdk.Exported
+package com.sun.security.jgss;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2000, 2006, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.sasl.gsskerb;
+
+import javax.security.sasl.*;
+import com.sun.security.sasl.util.PolicyUtils;
+
+import java.util.Map;
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+  * Client/server factory for GSSAPI (Kerberos V5) SASL client/server mechs.
+  * See GssKrb5Client/GssKrb5Server for input requirements.
+  *
+  * @author Rosanna Lee
+  */
+public final class FactoryImpl implements SaslClientFactory, SaslServerFactory {
+    private static final String myMechs[] = {
+        "GSSAPI"};
+
+    private static final int mechPolicies[] = {
+        PolicyUtils.NOPLAINTEXT|PolicyUtils.NOANONYMOUS|PolicyUtils.NOACTIVE
+    };
+
+    private static final int GSS_KERB_V5 = 0;
+
+    public FactoryImpl() {
+    }
+
+    public SaslClient createSaslClient(String[] mechs,
+        String authorizationId,
+        String protocol,
+        String serverName,
+        Map<String,?> props,
+        CallbackHandler cbh) throws SaslException {
+
+            for (int i = 0; i < mechs.length; i++) {
+                if (mechs[i].equals(myMechs[GSS_KERB_V5])
+                    && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) {
+                    return new GssKrb5Client(
+                        authorizationId,
+                        protocol,
+                        serverName,
+                        props,
+                        cbh);
+                }
+            }
+            return null;
+    };
+
+    public SaslServer createSaslServer(String mech,
+        String protocol,
+        String serverName,
+        Map<String,?> props,
+        CallbackHandler cbh) throws SaslException {
+            if (mech.equals(myMechs[GSS_KERB_V5])
+                && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) {
+                if (cbh == null) {
+                    throw new SaslException(
+                "Callback handler with support for AuthorizeCallback required");
+                }
+                return new GssKrb5Server(
+                    protocol,
+                    serverName,
+                    props,
+                    cbh);
+            }
+            return null;
+    };
+
+    public String[] getMechanismNames(Map<String,?> props) {
+        return PolicyUtils.filterMechs(myMechs, mechPolicies, props);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+
+package com.sun.security.sasl.gsskerb;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.logging.Level;
+import javax.security.sasl.*;
+import com.sun.security.sasl.util.AbstractSaslImpl;
+import org.ietf.jgss.*;
+import com.sun.security.jgss.ExtendedGSSContext;
+import com.sun.security.jgss.InquireType;
+
+abstract class GssKrb5Base extends AbstractSaslImpl {
+
+    private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2";
+    protected static Oid KRB5_OID;
+    protected static final byte[] EMPTY = new byte[0];
+
+    static {
+        try {
+            KRB5_OID = new Oid(KRB5_OID_STR);
+        } catch (GSSException ignore) {}
+    }
+
+    protected GSSContext secCtx = null;
+    protected static final int JGSS_QOP = 0;    // unrelated to SASL QOP mask
+
+    protected GssKrb5Base(Map<String, ?> props, String className)
+        throws SaslException {
+        super(props, className);
+    }
+
+    /**
+     * Retrieves this mechanism's name.
+     *
+     * @return  The string "GSSAPI".
+     */
+    public String getMechanismName() {
+        return "GSSAPI";
+    }
+
+    @Override
+    public Object getNegotiatedProperty(String propName) {
+        if (!completed) {
+            throw new IllegalStateException("Authentication incomplete");
+        }
+        String xprefix = "com.sun.security.jgss.inquiretype.";
+        if (propName.startsWith(xprefix)) {
+            String type = propName.substring(xprefix.length());
+            if (logger.isLoggable(Level.FINEST)) {
+                logger.logp(Level.FINE, "GssKrb5Base",
+                        "getNegotiatedProperty", propName);
+            }
+            for (InquireType t: InquireType.values()) {
+                if (t.name().toLowerCase(Locale.US).equals(type)) {
+                    try {
+                        return ((ExtendedGSSContext)secCtx).inquireSecContext(t);
+                    } catch (GSSException e) {
+                        if (logger.isLoggable(Level.FINEST)) {
+                            logger.log(Level.WARNING, "inquireSecContext error", e);
+                        }
+                        return null;
+                    }
+                }
+            }
+            // No such InquireType. Although not likely to be defined
+            // as a property in a parent class, still try it.
+        }
+        return super.getNegotiatedProperty(propName);
+    }
+
+    public byte[] unwrap(byte[] incoming, int start, int len)
+        throws SaslException {
+        if (!completed) {
+            throw new IllegalStateException("GSSAPI authentication not completed");
+        }
+
+        // integrity will be true if either privacy or integrity negotiated
+        if (!integrity) {
+            throw new IllegalStateException("No security layer negotiated");
+        }
+
+        try {
+            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
+            byte[] answer = secCtx.unwrap(incoming, start, len, msgProp);
+            if (logger.isLoggable(Level.FINEST)) {
+                traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
+                    incoming, start, len);
+                traceOutput(myClassName, "KRB502:Unwrap", "unwrapped: ",
+                    answer, 0, answer.length);
+            }
+            return answer;
+        } catch (GSSException e) {
+            throw new SaslException("Problems unwrapping SASL buffer", e);
+        }
+    }
+
+    public byte[] wrap(byte[] outgoing, int start, int len) throws SaslException {
+        if (!completed) {
+            throw new IllegalStateException("GSSAPI authentication not completed");
+        }
+
+        // integrity will be true if either privacy or integrity negotiated
+        if (!integrity) {
+            throw new IllegalStateException("No security layer negotiated");
+        }
+
+        // Generate GSS token
+        try {
+            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
+            byte[] answer = secCtx.wrap(outgoing, start, len, msgProp);
+            if (logger.isLoggable(Level.FINEST)) {
+                traceOutput(myClassName, "KRB503:Wrap", "outgoing: ",
+                    outgoing, start, len);
+                traceOutput(myClassName, "KRB504:Wrap", "wrapped: ",
+                    answer, 0, answer.length);
+            }
+            return answer;
+
+        } catch (GSSException e) {
+            throw new SaslException("Problem performing GSS wrap", e);
+        }
+    }
+
+    public void dispose() throws SaslException {
+        if (secCtx != null) {
+            try {
+                secCtx.dispose();
+            } catch (GSSException e) {
+                throw new SaslException("Problem disposing GSS context", e);
+            }
+            secCtx = null;
+        }
+    }
+
+    protected void finalize() throws Throwable {
+        dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2000, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.sasl.gsskerb;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.logging.Level;
+import javax.security.sasl.*;
+
+// JAAS
+import javax.security.auth.callback.CallbackHandler;
+
+// JGSS
+import org.ietf.jgss.*;
+
+/**
+  * Implements the GSSAPI SASL client mechanism for Kerberos V5.
+  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
+  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-04.txt">draft-ietf-cat-sasl-gssapi-04.txt</a>).
+  * It uses the Java Bindings for GSSAPI
+  * (<A HREF="http://www.ietf.org/rfc/rfc2853.txt">RFC 2853</A>)
+  * for getting GSSAPI/Kerberos V5 support.
+  *
+  * The client/server interactions are:
+  * C0: bind (GSSAPI, initial response)
+  * S0: sasl-bind-in-progress, challenge 1 (output of accept_sec_context or [])
+  * C1: bind (GSSAPI, response 1 (output of init_sec_context or []))
+  * S1: sasl-bind-in-progress challenge 2 (security layer, server max recv size)
+  * C2: bind (GSSAPI, response 2 (security layer, client max recv size, authzid))
+  * S2: bind success response
+  *
+  * Expects the client's credentials to be supplied from the
+  * javax.security.sasl.credentials property or from the thread's Subject.
+  * Otherwise the underlying KRB5 mech will attempt to acquire Kerberos creds
+  * by logging into Kerberos (via default TextCallbackHandler).
+  * These creds will be used for exchange with server.
+  *
+  * Required callbacks: none.
+  *
+  * Environment properties that affect behavior of implementation:
+  *
+  * javax.security.sasl.qop
+  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
+  * javax.security.sasl.maxbuf
+  * - max receive buffer size; default is 65536
+  * javax.security.sasl.sendmaxbuffer
+  * - max send buffer size; default is 65536; (min with server max recv size)
+  *
+  * javax.security.sasl.server.authentication
+  * - "true" means require mutual authentication; default is "false"
+  *
+  * javax.security.sasl.credentials
+  * - an {@link org.ietf.jgss.GSSCredential} used for delegated authentication.
+  *
+  * @author Rosanna Lee
+  */
+
+final class GssKrb5Client extends GssKrb5Base implements SaslClient {
+    // ---------------- Constants -----------------
+    private static final String MY_CLASS_NAME = GssKrb5Client.class.getName();
+
+    private boolean finalHandshake = false;
+    private boolean mutual = false;       // default false
+    private byte[] authzID;
+
+    /**
+     * Creates a SASL mechanism with client credentials that it needs
+     * to participate in GSS-API/Kerberos v5 authentication exchange
+     * with the server.
+     */
+    GssKrb5Client(String authzID, String protocol, String serverName,
+        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
+
+        super(props, MY_CLASS_NAME);
+
+        String service = protocol + "@" + serverName;
+        logger.log(Level.FINE, "KRB5CLNT01:Requesting service name: {0}",
+            service);
+
+        try {
+            GSSManager mgr = GSSManager.getInstance();
+
+            // Create the name for the requested service entity for Krb5 mech
+            GSSName acceptorName = mgr.createName(service,
+                GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
+
+            // Parse properties to check for supplied credentials
+            GSSCredential credentials = null;
+            if (props != null) {
+                Object prop = props.get(Sasl.CREDENTIALS);
+                if (prop != null && prop instanceof GSSCredential) {
+                    credentials = (GSSCredential) prop;
+                    logger.log(Level.FINE,
+                        "KRB5CLNT01:Using the credentials supplied in " +
+                        "javax.security.sasl.credentials");
+                }
+            }
+
+            // Create a context using credentials for Krb5 mech
+            secCtx = mgr.createContext(acceptorName,
+                KRB5_OID,   /* mechanism */
+                credentials, /* credentials */
+                GSSContext.INDEFINITE_LIFETIME);
+
+            // Request credential delegation when credentials have been supplied
+            if (credentials != null) {
+                secCtx.requestCredDeleg(true);
+            }
+
+            // Parse properties  to set desired context options
+            if (props != null) {
+                // Mutual authentication
+                String prop = (String)props.get(Sasl.SERVER_AUTH);
+                if (prop != null) {
+                    mutual = "true".equalsIgnoreCase(prop);
+                }
+            }
+            secCtx.requestMutualAuth(mutual);
+
+            // Always specify potential need for integrity and confidentiality
+            // Decision will be made during final handshake
+            secCtx.requestConf(true);
+            secCtx.requestInteg(true);
+
+        } catch (GSSException e) {
+            throw new SaslException("Failure to initialize security context", e);
+        }
+
+        if (authzID != null && authzID.length() > 0) {
+            try {
+                this.authzID = authzID.getBytes("UTF8");
+            } catch (IOException e) {
+                throw new SaslException("Cannot encode authorization ID", e);
+            }
+        }
+    }
+
+    public boolean hasInitialResponse() {
+        return true;
+    }
+
+    /**
+     * Processes the challenge data.
+     *
+     * The server sends a challenge data using which the client must
+     * process using GSS_Init_sec_context.
+     * As per RFC 2222, when GSS_S_COMPLETE is returned, we do
+     * an extra handshake to determine the negotiated security protection
+     * and buffer sizes.
+     *
+     * @param challengeData A non-null byte array containing the
+     * challenge data from the server.
+     * @return A non-null byte array containing the response to be
+     * sent to the server.
+     */
+    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {
+        if (completed) {
+            throw new IllegalStateException(
+                "GSSAPI authentication already complete");
+        }
+
+        if (finalHandshake) {
+            return doFinalHandshake(challengeData);
+        } else {
+
+            // Security context not established yet; continue with init
+
+            try {
+                byte[] gssOutToken = secCtx.initSecContext(challengeData,
+                    0, challengeData.length);
+                if (logger.isLoggable(Level.FINER)) {
+                    traceOutput(MY_CLASS_NAME, "evaluteChallenge",
+                        "KRB5CLNT02:Challenge: [raw]", challengeData);
+                    traceOutput(MY_CLASS_NAME, "evaluateChallenge",
+                        "KRB5CLNT03:Response: [after initSecCtx]", gssOutToken);
+                }
+
+                if (secCtx.isEstablished()) {
+                    finalHandshake = true;
+                    if (gssOutToken == null) {
+                        // RFC 2222 7.2.1:  Client responds with no data
+                        return EMPTY;
+                    }
+                }
+
+                return gssOutToken;
+            } catch (GSSException e) {
+                throw new SaslException("GSS initiate failed", e);
+            }
+        }
+    }
+
+    private byte[] doFinalHandshake(byte[] challengeData) throws SaslException {
+        try {
+            // Security context already established. challengeData
+            // should contain security layers and server's maximum buffer size
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
+                    "KRB5CLNT04:Challenge [raw]:", challengeData);
+            }
+
+            if (challengeData.length == 0) {
+                // Received S0, should return []
+                return EMPTY;
+            }
+
+            // Received S1 (security layer, server max recv size)
+
+            byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
+                challengeData.length, new MessageProp(0, false));
+
+            // First octet is a bit-mask specifying the protections
+            // supported by the server
+            if (logger.isLoggable(Level.FINE)) {
+                if (logger.isLoggable(Level.FINER)) {
+                    traceOutput(MY_CLASS_NAME, "doFinalHandshake",
+                        "KRB5CLNT05:Challenge [unwrapped]:", gssOutToken);
+                }
+                logger.log(Level.FINE, "KRB5CLNT06:Server protections: {0}",
+                    gssOutToken[0]);
+            }
+
+            // Client selects preferred protection
+            // qop is ordered list of qop values
+            byte selectedQop = findPreferredMask(gssOutToken[0], qop);
+            if (selectedQop == 0) {
+                throw new SaslException(
+                    "No common protection layer between client and server");
+            }
+
+            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
+                privacy = true;
+                integrity = true;
+            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
+                integrity = true;
+            }
+
+            // 2nd-4th octets specifies maximum buffer size expected by
+            // server (in network byte order)
+            int srvMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
+
+            // Determine the max send buffer size based on what the
+            // server is able to receive and our specified max
+            sendMaxBufSize = (sendMaxBufSize == 0) ? srvMaxBufSize :
+                Math.min(sendMaxBufSize, srvMaxBufSize);
+
+            // Update context to limit size of returned buffer
+            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
+                sendMaxBufSize);
+
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE,
+"KRB5CLNT07:Client max recv size: {0}; server max recv size: {1}; rawSendSize: {2}",
+                    new Object[] {recvMaxBufSize,
+                                  srvMaxBufSize,
+                                  rawSendSize});
+            }
+
+            // Construct negotiated security layers and client's max
+            // receive buffer size and authzID
+            int len = 4;
+            if (authzID != null) {
+                len += authzID.length;
+            }
+
+            byte[] gssInToken = new byte[len];
+            gssInToken[0] = selectedQop;
+
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE,
+            "KRB5CLNT08:Selected protection: {0}; privacy: {1}; integrity: {2}",
+                    new Object[]{selectedQop,
+                                 Boolean.valueOf(privacy),
+                                 Boolean.valueOf(integrity)});
+            }
+
+            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
+            if (authzID != null) {
+                // copy authorization id
+                System.arraycopy(authzID, 0, gssInToken, 4, authzID.length);
+                logger.log(Level.FINE, "KRB5CLNT09:Authzid: {0}", authzID);
+            }
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
+                    "KRB5CLNT10:Response [raw]", gssInToken);
+            }
+
+            gssOutToken = secCtx.wrap(gssInToken,
+                0, gssInToken.length,
+                new MessageProp(0 /* qop */, false /* privacy */));
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
+                    "KRB5CLNT11:Response [after wrap]", gssOutToken);
+            }
+
+            completed = true;  // server authenticated
+
+            return gssOutToken;
+        } catch (GSSException e) {
+            throw new SaslException("Final handshake failed", e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java	Wed Sep 17 13:55:30 2014 +0800
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2000, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.security.sasl.gsskerb;
+
+import javax.security.sasl.*;
+import java.io.*;
+import java.util.Map;
+import java.util.logging.Level;
+
+// JAAS
+import javax.security.auth.callback.*;
+
+// JGSS
+import org.ietf.jgss.*;
+
+/**
+  * Implements the GSSAPI SASL server mechanism for Kerberos V5.
+  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
+  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-00.txt">draft-ietf-cat-sasl-gssapi-00.txt</a>).
+  *
+  * Expects thread's Subject to contain server's Kerberos credentials
+  * - If not, underlying KRB5 mech will attempt to acquire Kerberos creds
+  *   by logging into Kerberos (via default TextCallbackHandler).
+  * - These creds will be used for exchange with client.
+  *
+  * Required callbacks:
+  * - AuthorizeCallback
+  *      handler must verify that authid/authzids are allowed and set
+  *      authorized ID to be the canonicalized authzid (if applicable).
+  *
+  * Environment properties that affect behavior of implementation:
+  *
+  * javax.security.sasl.qop
+  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
+  * javax.security.sasl.maxbuf
+  * - max receive buffer size; default is 65536
+  * javax.security.sasl.sendmaxbuffer
+  * - max send buffer size; default is 65536; (min with client max recv size)
+  *
+  * @author Rosanna Lee
+  */
+final class GssKrb5Server extends GssKrb5Base implements SaslServer {
+    private static final String MY_CLASS_NAME = GssKrb5Server.class.getName();
+
+    private int handshakeStage = 0;
+    private String peer;
+    private String me;
+    private String authzid;
+    private CallbackHandler cbh;
+
+    // When serverName is null, the server will be unbound. We need to save and
+    // check the protocol name after the context is established. This value
+    // will be null if serverName is not null.
+    private final String protocolSaved;
+    /**
+     * Creates a SASL mechanism with server credentials that it needs
+     * to participate in GSS-API/Kerberos v5 authentication exchange
+     * with the client.
+     */
+    GssKrb5Server(String protocol, String serverName,
+        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
+
+        super(props, MY_CLASS_NAME);
+
+        this.cbh = cbh;
+
+        String service;
+        if (serverName == null) {
+            protocolSaved = protocol;
+            service = null;
+        } else {
+            protocolSaved = null;
+            service = protocol + "@" + serverName;
+        }
+
+        logger.log(Level.FINE, "KRB5SRV01:Using service name: {0}", service);
+
+        try {
+            GSSManager mgr = GSSManager.getInstance();
+
+            // Create the name for the requested service entity for Krb5 mech
+            GSSName serviceName = service == null ? null:
+                    mgr.createName(service, GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
+
+            GSSCredential cred = mgr.createCredential(serviceName,
+                GSSCredential.INDEFINITE_LIFETIME,
+                KRB5_OID, GSSCredential.ACCEPT_ONLY);
+
+            // Create a context using the server's credentials
+            secCtx = mgr.createContext(cred);
+
+            if ((allQop&INTEGRITY_ONLY_PROTECTION) != 0) {
+                // Might need integrity
+                secCtx.requestInteg(true);
+            }
+
+            if ((allQop&PRIVACY_PROTECTION) != 0) {
+                // Might need privacy
+                secCtx.requestConf(true);
+            }
+        } catch (GSSException e) {
+            throw new SaslException("Failure to initialize security context", e);
+        }
+        logger.log(Level.FINE, "KRB5SRV02:Initialization complete");
+    }
+
+
+    /**
+     * Processes the response data.
+     *
+     * The client sends response data to which the server must
+     * process using GSS_accept_sec_context.
+     * As per RFC 2222, the GSS authenication completes (GSS_S_COMPLETE)
+     * we do an extra hand shake to determine the negotiated security protection
+     * and buffer sizes.
+     *
+     * @param responseData A non-null but possible empty byte array containing the
+     * response data from the client.
+     * @return A non-null byte array containing the challenge to be
+     * sent to the client, or null when no more data is to be sent.
+     */
+    public byte[] evaluateResponse(byte[] responseData) throws SaslException {
+        if (completed) {
+            throw new SaslException(
+                "SASL authentication already complete");
+        }
+
+        if (logger.isLoggable(Level.FINER)) {
+            traceOutput(MY_CLASS_NAME, "evaluateResponse",
+                "KRB5SRV03:Response [raw]:", responseData);
+        }
+
+        switch (handshakeStage) {
+        case 1:
+            return doHandshake1(responseData);
+
+        case 2:
+            return doHandshake2(responseData);
+
+        default:
+            // Security context not established yet; continue with accept
+
+            try {
+                byte[] gssOutToken = secCtx.acceptSecContext(responseData,
+                    0, responseData.length);
+
+                if (logger.isLoggable(Level.FINER)) {
+                    traceOutput(MY_CLASS_NAME, "evaluateResponse",
+                        "KRB5SRV04:Challenge: [after acceptSecCtx]", gssOutToken);
+                }
+
+                if (secCtx.isEstablished()) {
+                    handshakeStage = 1;
+
+                    peer = secCtx.getSrcName().toString();
+                    me = secCtx.getTargName().toString();
+
+                    logger.log(Level.FINE,
+                            "KRB5SRV05:Peer name is : {0}, my name is : {1}",
+                            new Object[]{peer, me});
+
+                    // me might take the form of proto@host or proto/host
+                    if (protocolSaved != null &&
+                            !protocolSaved.equalsIgnoreCase(me.split("[/@]")[0])) {
+                        throw new SaslException(
+                                "GSS context targ name protocol error: " + me);
+                    }
+
+                    if (gssOutToken == null) {
+                        return doHandshake1(EMPTY);
+                    }
+                }
+
+                return gssOutToken;
+            } catch (GSSException e) {
+                throw new SaslException("GSS initiate failed", e);
+            }
+        }
+    }
+
+    private byte[] doHandshake1(byte[] responseData) throws SaslException {
+        try {
+            // Security context already established. responseData
+            // should contain no data
+            if (responseData != null && responseData.length > 0) {
+                throw new SaslException(
+                    "Handshake expecting no response data from server");
+            }
+
+            // Construct 4 octets of data:
+            // First octet contains bitmask specifying protections supported
+            // 2nd-4th octets contains max receive buffer of server
+
+            byte[] gssInToken = new byte[4];
+            gssInToken[0] = allQop;
+            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
+
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE,
+                    "KRB5SRV06:Supported protections: {0}; recv max buf size: {1}",
+                    new Object[]{allQop,
+                                 recvMaxBufSize});
+            }
+
+            handshakeStage = 2;  // progress to next stage
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doHandshake1",
+                    "KRB5SRV07:Challenge [raw]", gssInToken);
+            }
+
+            byte[] gssOutToken = secCtx.wrap(gssInToken, 0, gssInToken.length,
+                new MessageProp(0 /* gop */, false /* privacy */));
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doHandshake1",
+                    "KRB5SRV08:Challenge [after wrap]", gssOutToken);
+            }
+            return gssOutToken;
+
+        } catch (GSSException e) {
+            throw new SaslException("Problem wrapping handshake1", e);
+        }
+    }
+
+    private byte[] doHandshake2(byte[] responseData) throws SaslException {
+        try {
+            // Expecting 4 octets from client selected protection
+            // and client's receive buffer size
+            byte[] gssOutToken = secCtx.unwrap(responseData, 0,
+                responseData.length, new MessageProp(0, false));
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doHandshake2",
+                    "KRB5SRV09:Response [after unwrap]", gssOutToken);
+            }
+
+            // First octet is a bit-mask specifying the selected protection
+            byte selectedQop = gssOutToken[0];
+            if ((selectedQop&allQop) == 0) {
+                throw new SaslException("Client selected unsupported protection: "
+                    + selectedQop);
+            }
+            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
+                privacy = true;
+                integrity = true;
+            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
+                integrity = true;
+            }
+
+            // 2nd-4th octets specifies maximum buffer size expected by
+            // client (in network byte order). This is the server's send
+            // buffer maximum.
+            int clntMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
+
+            // Determine the max send buffer size based on what the
+            // client is able to receive and our specified max
+            sendMaxBufSize = (sendMaxBufSize == 0) ? clntMaxBufSize :
+                Math.min(sendMaxBufSize, clntMaxBufSize);
+
+            // Update context to limit size of returned buffer
+            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
+                sendMaxBufSize);
+
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE,
+            "KRB5SRV10:Selected protection: {0}; privacy: {1}; integrity: {2}",
+                    new Object[]{selectedQop,
+                                 Boolean.valueOf(privacy),
+                                 Boolean.valueOf(integrity)});
+                logger.log(Level.FINE,
+"KRB5SRV11:Client max recv size: {0}; server max send size: {1}; rawSendSize: {2}",
+                    new Object[] {clntMaxBufSize,
+                                  sendMaxBufSize,
+                                  rawSendSize});
+            }
+
+            // Get authorization identity, if any
+            if (gssOutToken.length > 4) {
+                try {
+                    authzid = new String(gssOutToken, 4,
+                        gssOutToken.length - 4, "UTF-8");
+                } catch (UnsupportedEncodingException uee) {
+                    throw new SaslException ("Cannot decode authzid", uee);
+                }
+            } else {
+                authzid = peer;
+            }
+            logger.log(Level.FINE, "KRB5SRV12:Authzid: {0}", authzid);
+
+            AuthorizeCallback acb = new AuthorizeCallback(peer, authzid);
+
+            // In Kerberos, realm is embedded in peer name
+            cbh.handle(new Callback[] {acb});
+            if (acb.isAuthorized()) {
+                authzid = acb.getAuthorizedID();
+                completed = true;
+            } else {
+                // Authorization failed
+                throw new SaslException(peer +
+                    " is not authorized to connect as " + authzid);
+            }
+
+            return null;
+        } catch (GSSException e) {
+            throw new SaslException("Final handshake step failed", e);
+        } catch (IOException e) {
+            throw new SaslException("Problem with callback handler", e);
+        } catch (UnsupportedCallbackException e) {
+            throw new SaslException("Problem with callback handler", e);
+        }
+    }
+
+    public String getAuthorizationID() {
+        if (completed) {
+            return authzid;
+        } else {
+            throw new IllegalStateException("Authentication incomplete");
+        }
+    }
+
+    public Object getNegotiatedProperty(String propName) {
+        if (!completed) {
+            throw new IllegalStateException("Authentication incomplete");
+        }
+
+        Object result;
+        switch (propName) {
+            case Sasl.BOUND_SERVER_NAME:
+                try {
+                    // me might take the form of proto@host or proto/host
+                    result = me.split("[/@]")[1];
+                } catch (Exception e) {
+                    result = null;
+                }
+                break;
+            default:
+                result = super.getNegotiatedProperty(propName);
+        }
+        return result;
+    }
+}