diff -r 904e243eac08 -r 7146fad1804a jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java Wed Sep 17 08:04:31 2014 +0200
+++ /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.
- * (RFC 2222,
- * draft-ietf-cat-sasl-gssapi-04.txt).
- * It uses the Java Bindings for GSSAPI
- * (RFC 2853)
- * 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 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);
- }
- }
-}