8056141: Move com.sun.security.jgss into a new module
Reviewed-by: alanb, chegar, mchung
--- a/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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/jdk/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;
+ }
+}