6578647: Undefined requesting URL in java.net.Authenticator.getPasswordAuthentication()

Reviewed-by: chegar, valeriep
This commit is contained in:
Weijun Wang 2009-06-09 14:17:05 +08:00
parent 105735aeb6
commit 8a52d1a9d5
28 changed files with 717 additions and 218 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -81,8 +81,7 @@ public class AuthenticationHeader {
MessageHeader rsp; // the response to be parsed
HeaderParser preferred;
String preferred_r; // raw Strings
String host = null; // the hostname for server,
// used in checking the availability of Negotiate
private final HttpCallerInfo hci; // un-schemed, need check
// When set true, do not use Negotiate even if the response
// headers suggest so.
@ -113,24 +112,13 @@ public class AuthenticationHeader {
String hdrname; // Name of the header to look for
/**
* parse a set of authentication headers and choose the preferred scheme
* that we support
*/
public AuthenticationHeader (String hdrname, MessageHeader response) {
rsp = response;
this.hdrname = hdrname;
schemes = new HashMap();
parse();
}
/**
* parse a set of authentication headers and choose the preferred scheme
* that we support for a given host
*/
public AuthenticationHeader (String hdrname, MessageHeader response,
String host, boolean dontUseNegotiate) {
this.host = host;
HttpCallerInfo hci, boolean dontUseNegotiate) {
this.hci = hci;
this.dontUseNegotiate = dontUseNegotiate;
rsp = response;
this.hdrname = hdrname;
@ -138,6 +126,9 @@ public class AuthenticationHeader {
parse();
}
public HttpCallerInfo getHttpCallerInfo() {
return hci;
}
/* we build up a map of scheme names mapped to SchemeMapValue objects */
static class SchemeMapValue {
SchemeMapValue (HeaderParser h, String r) {raw=r; parser=h;}
@ -186,7 +177,7 @@ public class AuthenticationHeader {
if(v == null && !dontUseNegotiate) {
SchemeMapValue tmp = (SchemeMapValue)schemes.get("negotiate");
if(tmp != null) {
if(host == null || !NegotiateAuthentication.isSupported(host, "Negotiate")) {
if(hci == null || !NegotiateAuthentication.isSupported(new HttpCallerInfo(hci, "Negotiate"))) {
tmp = null;
}
v = tmp;
@ -206,7 +197,7 @@ public class AuthenticationHeader {
//
// The only chance this line get executed is that the server
// only suggest the Kerberos scheme.
if(host == null || !NegotiateAuthentication.isSupported(host, "Kerberos")) {
if(hci == null || !NegotiateAuthentication.isSupported(new HttpCallerInfo(hci, "Kerberos"))) {
tmp = null;
}
v = tmp;

View File

@ -0,0 +1,108 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.net.www.protocol.http;
import java.net.Authenticator.RequestorType;
import java.net.InetAddress;
import java.net.URL;
/**
* Used in HTTP/Negotiate, to feed HTTP request info into JGSS as a HttpCaller,
* so that special actions can be taken, including special callback handler,
* special useSubjectCredsOnly value.
*
* This is an immutable class. It can be instantiated in two styles;
*
* 1. Un-schemed: Create at the beginning before the preferred scheme is
* determined. This object can be fed into AuthenticationHeader to check
* for the preference.
*
* 2. Schemed: With the scheme field filled, can be used in JGSS-API calls.
*/
final public class HttpCallerInfo {
// All info that an Authenticator needs.
final public URL url;
final public String host, protocol, prompt, scheme;
final public int port;
final public InetAddress addr;
final public RequestorType authType;
/**
* Create a schemed object based on an un-schemed one.
*/
public HttpCallerInfo(HttpCallerInfo old, String scheme) {
this.url = old.url;
this.host = old.host;
this.protocol = old.protocol;
this.prompt = old.prompt;
this.port = old.port;
this.addr = old.addr;
this.authType = old.authType;
this.scheme = scheme;
}
/**
* Constructor an un-schemed object for site access.
*/
public HttpCallerInfo(URL url) {
this.url= url;
prompt = "";
host = url.getHost();
int p = url.getPort();
if (p == -1) {
port = url.getDefaultPort();
} else {
port = p;
}
InetAddress ia;
try {
ia = InetAddress.getByName(url.getHost());
} catch (Exception e) {
ia = null;
}
addr = ia;
protocol = url.getProtocol();
authType = RequestorType.SERVER;
scheme = "";
}
/**
* Constructor an un-schemed object for proxy access.
*/
public HttpCallerInfo(URL url, String host, int port) {
this.url= url;
this.host = host;
this.port = port;
prompt = "";
addr = null;
protocol = url.getProtocol();
authType = RequestorType.PROXY;
scheme = "";
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1165,7 +1165,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
AuthenticationHeader authhdr = new AuthenticationHeader (
"Proxy-Authenticate", responses,
http.getProxyHostUsed(), dontUseNegotiate
new HttpCallerInfo(url, http.getProxyHostUsed(),
http.getProxyPortUsed()),
dontUseNegotiate
);
if (!doingNTLMp2ndStage) {
@ -1230,7 +1232,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
srvHdr = new AuthenticationHeader (
"WWW-Authenticate", responses,
url.getHost().toLowerCase(), dontUseNegotiate
new HttpCallerInfo(url),
dontUseNegotiate
);
String raw = srvHdr.raw();
@ -1595,7 +1598,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
AuthenticationHeader authhdr = new AuthenticationHeader (
"Proxy-Authenticate", responses,
http.getProxyHostUsed(), dontUseNegotiate
new HttpCallerInfo(url, http.getProxyHostUsed(),
http.getProxyPortUsed()),
dontUseNegotiate
);
if (!doingNTLMp2ndStage) {
proxyAuthentication =
@ -1811,9 +1816,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
tryTransparentNTLMProxy = false;
} else if (schemeID == NegotiateAuthentication.NEGOTIATE_AUTH) {
ret = new NegotiateAuthentication(true, host, port, null, "Negotiate");
ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate"));
} else if (schemeID == NegotiateAuthentication.KERBEROS_AUTH) {
ret = new NegotiateAuthentication(true, host, port, null, "Kerberos");
ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos"));
}
}
// For backwards compatibility, we also try defaultAuth
@ -1897,7 +1902,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
} catch (Exception e) {
url1 = url;
}
ret = new NegotiateAuthentication(false, url1, null, "Kerberos");
ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos"));
}
if (schemeID == NegotiateAuthentication.NEGOTIATE_AUTH) {
URL url1;
@ -1906,7 +1911,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
} catch (Exception e) {
url1 = url;
}
ret = new NegotiateAuthentication(false, url1, null, "Negotiate");
ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate"));
}
if (schemeID == BasicAuthentication.BASIC_AUTH) {
PasswordAuthentication a =

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,17 +25,15 @@
package sun.net.www.protocol.http;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import sun.net.www.HeaderParser;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.net.URL;
import java.net.PasswordAuthentication;
import java.io.IOException;
import java.net.Authenticator.RequestorType;
/**
@ -49,7 +47,7 @@ class NegotiateAuthentication extends AuthenticationInfo {
private static final long serialVersionUID = 100L;
private String scheme = null;
final private HttpCallerInfo hci;
static final char NEGOTIATE_AUTH = 'S';
static final char KERBEROS_AUTH = 'K';
@ -66,25 +64,16 @@ class NegotiateAuthentication extends AuthenticationInfo {
private Negotiator negotiator = null;
/**
* Constructor used for WWW entries. <code>pw</code> is not used because
* for GSS there is only one single PasswordAuthentication which is
* independant of host/port/... info.
* Constructor used for both WWW and proxy entries.
* @param hci a schemed object.
*/
public NegotiateAuthentication(boolean isProxy, URL url,
PasswordAuthentication pw, String scheme) {
super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION,
NEGOTIATE_AUTH, url, "");
this.scheme = scheme;
}
/**
* Constructor used for proxy entries
*/
public NegotiateAuthentication(boolean isProxy, String host, int port,
PasswordAuthentication pw, String scheme) {
super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION,
NEGOTIATE_AUTH,host, port, "");
this.scheme = scheme;
public NegotiateAuthentication(HttpCallerInfo hci) {
super(RequestorType.PROXY==hci.authType?
PROXY_AUTHENTICATION:SERVER_AUTHENTICATION,
hci.scheme.equalsIgnoreCase("Negotiate")?
NEGOTIATE_AUTH:KERBEROS_AUTH,
hci.url, "");
this.hci = hci;
}
/**
@ -95,32 +84,29 @@ class NegotiateAuthentication extends AuthenticationInfo {
}
/**
* Find out if a hostname supports Negotiate protocol. In order to find
* out yes or no, an initialization of a Negotiator object against
* hostname and scheme is tried. The generated object will be cached
* under the name of hostname at a success try.<br>
* Find out if the HttpCallerInfo supports Negotiate protocol. In order to
* find out yes or no, an initialization of a Negotiator object against it
* is tried. The generated object will be cached under the name of ths
* hostname at a success try.<br>
*
* If this method is called for the second time on a hostname, the answer is
* already saved in <code>supported</code>, so no need to try again.
* If this method is called for the second time on an HttpCallerInfo with
* the same hostname, the answer is retrieved from cache.
*
* @param hostname hostname to test
* @param scheme scheme to test
* @return true if supported
*/
synchronized public static boolean isSupported(String hostname,
String scheme) {
synchronized public static boolean isSupported(HttpCallerInfo hci) {
if (supported == null) {
supported = new HashMap <String, Boolean>();
cache = new HashMap <String, Negotiator>();
}
String hostname = hci.host;
hostname = hostname.toLowerCase();
if (supported.containsKey(hostname)) {
return supported.get(hostname);
}
try {
Negotiator neg = Negotiator.getSupported(hostname, scheme);
Negotiator neg = Negotiator.getSupported(hci);
supported.put(hostname, true);
// the only place cache.put is called. here we can make sure
// the object is valid and the oneToken inside is not null
@ -179,7 +165,7 @@ class NegotiateAuthentication extends AuthenticationInfo {
if (parts.length > 1) {
incoming = new BASE64Decoder().decodeBuffer(parts[1]);
}
response = scheme + " " + new B64Encoder().encode(
response = hci.scheme + " " + new B64Encoder().encode(
incoming==null?firstToken():nextToken(incoming));
conn.setAuthenticationProperty(getHeaderName(), response);
@ -207,7 +193,7 @@ class NegotiateAuthentication extends AuthenticationInfo {
}
if (negotiator == null) {
try {
negotiator = Negotiator.getSupported(getHost(), scheme);
negotiator = Negotiator.getSupported(hci);
} catch(Exception e) {
IOException ioe = new IOException("Cannot initialize Negotiator");
ioe.initCause(e);
@ -255,18 +241,18 @@ class NegotiateAuthentication extends AuthenticationInfo {
* NegotiatorImpl, so that JAAS and JGSS calls can be made
*/
abstract class Negotiator {
static Negotiator getSupported(String hostname, String scheme)
static Negotiator getSupported(HttpCallerInfo hci)
throws Exception {
// These lines are equivalent to
// return new NegotiatorImpl(hostname, scheme);
// return new NegotiatorImpl(hci);
// The current implementation will make sure NegotiatorImpl is not
// directly referenced when compiling, thus smooth the way of building
// the J2SE platform where HttpURLConnection is a bootstrap class.
Class clazz = Class.forName("sun.net.www.protocol.http.NegotiatorImpl");
java.lang.reflect.Constructor c = clazz.getConstructor(String.class, String.class);
return (Negotiator) (c.newInstance(hostname, scheme));
java.lang.reflect.Constructor c = clazz.getConstructor(HttpCallerInfo.class);
return (Negotiator) (c.newInstance(hci));
}
abstract byte[] firstToken() throws IOException;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -36,12 +36,19 @@ import javax.security.auth.callback.UnsupportedCallbackException;
/**
* @since 1.6
* Special callback handler used in JGSS for the HttpCaller.
*/
public class NegotiateCallbackHandler implements CallbackHandler {
private String username;
private char[] password;
private final HttpCallerInfo hci;
public NegotiateCallbackHandler(HttpCallerInfo hci) {
this.hci = hci;
}
public void handle(Callback[] callbacks) throws
UnsupportedCallbackException, IOException {
for (int i=0; i<callbacks.length; i++) {
@ -51,8 +58,8 @@ public class NegotiateCallbackHandler implements CallbackHandler {
if (username == null) {
PasswordAuthentication passAuth =
Authenticator.requestPasswordAuthentication(
null, null, 0, null,
null, "Negotiate");
hci.host, hci.addr, hci.port, hci.protocol,
hci.prompt, hci.scheme, hci.url, hci.authType);
username = passAuth.getUserName();
password = passAuth.getPassword();
}
@ -66,8 +73,8 @@ public class NegotiateCallbackHandler implements CallbackHandler {
if (password == null) {
PasswordAuthentication passAuth =
Authenticator.requestPasswordAuthentication(
null, null, 0, null,
null, "Negotiate");
hci.host, hci.addr, hci.port, hci.protocol,
hci.prompt, hci.scheme, hci.url, hci.authType);
username = passAuth.getUserName();
password = passAuth.getPassword();
}
@ -76,7 +83,7 @@ public class NegotiateCallbackHandler implements CallbackHandler {
} else {
throw new UnsupportedCallbackException(callBack,
"Call back not supported");
}//else
}//for
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,9 +34,10 @@ import org.ietf.jgss.Oid;
import sun.security.jgss.GSSManagerImpl;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.HttpCaller;
/**
* This class encapsulates all JAAS and JGSS API calls in a seperate class
* This class encapsulates all JAAS and JGSS API calls in a separate class
* outside NegotiateAuthentication.java so that J2SE build can go smoothly
* without the presence of it.
*
@ -54,21 +55,16 @@ public class NegotiatorImpl extends Negotiator {
/**
* Initialize the object, which includes:<ul>
* <li>Find out what GSS mechanism to use from <code>http.negotiate.mechanism.oid</code>,
* defaults SPNEGO
* <li>Find out what GSS mechanism to use from the system property
* <code>http.negotiate.mechanism.oid</code>, defaults SPNEGO
* <li>Creating the GSSName for the target host, "HTTP/"+hostname
* <li>Creating GSSContext
* <li>A first call to initSecContext</ul>
* @param hostname name of peer server
* @param scheme auth scheme requested, Negotiate ot Kerberos
* @throws GSSException if any JGSS-API call fails
*/
private void init(final String hostname, String scheme) throws GSSException {
// "1.2.840.113554.1.2.2" Kerberos
// "1.3.6.1.5.5.2" SPNEGO
private void init(HttpCallerInfo hci) throws GSSException {
final Oid oid;
if (scheme.equalsIgnoreCase("Kerberos")) {
if (hci.scheme.equalsIgnoreCase("Kerberos")) {
// we can only use Kerberos mech when the scheme is kerberos
oid = GSSUtil.GSS_KRB5_MECH_OID;
} else {
@ -89,9 +85,11 @@ public class NegotiatorImpl extends Negotiator {
}
GSSManagerImpl manager = new GSSManagerImpl(
GSSUtil.CALLER_HTTP_NEGOTIATE);
new HttpCaller(hci));
String peerName = "HTTP@" + hostname;
// RFC 4559 4.1 uses uppercase service name "HTTP".
// RFC 4120 6.2.1 demands the host be lowercase
String peerName = "HTTP@" + hci.host.toLowerCase();
GSSName serverName = manager.createName(peerName,
GSSName.NT_HOSTBASED_SERVICE);
@ -114,16 +112,15 @@ public class NegotiatorImpl extends Negotiator {
/**
* Constructor
* @param hostname name of peer server
* @param scheme auth scheme requested, Negotiate ot Kerberos
* @throws java.io.IOException If negotiator cannot be constructed
*/
public NegotiatorImpl(String hostname, String scheme) throws IOException {
public NegotiatorImpl(HttpCallerInfo hci) throws IOException {
try {
init(hostname, scheme);
init(hci);
} catch (GSSException e) {
if (DEBUG) {
System.out.println("Negotiate support not initiated, will fallback to other scheme if allowed. Reason:");
System.out.println("Negotiate support not initiated, will " +
"fallback to other scheme if allowed. Reason:");
e.printStackTrace();
}
IOException ioe = new IOException("Negotiate support not initiated");

View File

@ -0,0 +1,40 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.security.jgss;
/**
* Denotes what client is calling the JGSS-API. The object can be sent deep
* into the mechanism level so that special actions can be performed for
* different callers.
*/
public class GSSCaller {
public static final GSSCaller CALLER_UNKNOWN = new GSSCaller();
public static final GSSCaller CALLER_INITIATE = new GSSCaller();
public static final GSSCaller CALLER_ACCEPT = new GSSCaller();
public static final GSSCaller CALLER_SSL_CLIENT = new GSSCaller();
public static final GSSCaller CALLER_SSL_SERVER = new GSSCaller();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,8 +27,6 @@ package sun.security.jgss;
import org.ietf.jgss.*;
import sun.security.jgss.spi.*;
import java.io.*;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -63,17 +61,17 @@ public class GSSManagerImpl extends GSSManager {
private ProviderList list;
// Used by java SPNEGO impl to make sure native is disabled
public GSSManagerImpl(int caller, boolean useNative) {
public GSSManagerImpl(GSSCaller caller, boolean useNative) {
list = new ProviderList(caller, useNative);
}
// Used by HTTP/SPNEGO NegotiatorImpl
public GSSManagerImpl(int caller) {
public GSSManagerImpl(GSSCaller caller) {
list = new ProviderList(caller, USE_NATIVE);
}
public GSSManagerImpl() {
list = new ProviderList(GSSUtil.CALLER_UNKNOWN, USE_NATIVE);
list = new ProviderList(GSSCaller.CALLER_UNKNOWN, USE_NATIVE);
}
public Oid[] getMechs(){

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -72,13 +72,6 @@ public class GSSUtil {
private static final String DEFAULT_HANDLER =
"auth.login.defaultCallbackHandler";
public static final int CALLER_UNKNOWN = -1;
public static final int CALLER_INITIATE = 1;
public static final int CALLER_ACCEPT = 2;
public static final int CALLER_SSL_CLIENT = 3;
public static final int CALLER_SSL_SERVER = 4;
public static final int CALLER_HTTP_NEGOTIATE = 5;
static final boolean DEBUG;
static {
DEBUG = (AccessController.doPrivileged
@ -240,11 +233,12 @@ public class GSSUtil {
* @param mech the mech to be used
* @return the authenticated subject
*/
public static Subject login(int caller, Oid mech) throws LoginException {
public static Subject login(GSSCaller caller, Oid mech) throws LoginException {
CallbackHandler cb = null;
if (caller == GSSUtil.CALLER_HTTP_NEGOTIATE) {
cb = new sun.net.www.protocol.http.NegotiateCallbackHandler();
if (caller instanceof HttpCaller) {
cb = new sun.net.www.protocol.http.NegotiateCallbackHandler(
((HttpCaller)caller).info());
} else {
String defaultHandler =
java.security.Security.getProperty(DEFAULT_HANDLER);
@ -274,12 +268,12 @@ public class GSSUtil {
* The application indicates this by explicitly setting the system
* property javax.security.auth.useSubjectCredsOnly to false.
*/
public static boolean useSubjectCredsOnly(int caller) {
public static boolean useSubjectCredsOnly(GSSCaller caller) {
// HTTP/SPNEGO doesn't use the standard JAAS framework. Instead, it
// uses the java.net.Authenticator style, therefore always return
// false here.
if (caller == CALLER_HTTP_NEGOTIATE) {
if (caller instanceof HttpCaller) {
return false;
}
/*

View File

@ -0,0 +1,45 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.security.jgss;
import sun.net.www.protocol.http.HttpCallerInfo;
/**
* A special kind of GSSCaller, which origins from HTTP/Negotiate and contains
* info about what triggers the JGSS calls.
*/
public class HttpCaller extends GSSCaller {
final private HttpCallerInfo hci;
public HttpCaller(HttpCallerInfo hci) {
this.hci = hci;
}
public HttpCallerInfo info() {
return hci;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -39,7 +39,7 @@ import org.ietf.jgss.Oid;
public class LoginConfigImpl extends Configuration {
private final Configuration config;
private final int caller;
private final GSSCaller caller;
private final String mechName;
private static final sun.security.util.Debug debug =
sun.security.util.Debug.getInstance("gssloginconfig", "\t[GSS LoginConfigImpl]");
@ -50,7 +50,7 @@ public class LoginConfigImpl extends Configuration {
* @param caller defined in GSSUtil as CALLER_XXX final fields
* @param oid defined in GSSUtil as XXX_MECH_OID final fields
*/
public LoginConfigImpl(int caller, Oid mech) {
public LoginConfigImpl(GSSCaller caller, Oid mech) {
this.caller = caller;
@ -88,40 +88,31 @@ public class LoginConfigImpl extends Configuration {
// entry name is not provided.
if ("krb5".equals(mechName)) {
switch (caller) {
case GSSUtil.CALLER_INITIATE:
if (caller == GSSCaller.CALLER_INITIATE) {
alts = new String[] {
"com.sun.security.jgss.krb5.initiate",
"com.sun.security.jgss.initiate",
};
break;
case GSSUtil.CALLER_ACCEPT:
} else if (caller == GSSCaller.CALLER_ACCEPT) {
alts = new String[] {
"com.sun.security.jgss.krb5.accept",
"com.sun.security.jgss.accept",
};
break;
case GSSUtil.CALLER_SSL_CLIENT:
} else if (caller == GSSCaller.CALLER_SSL_CLIENT) {
alts = new String[] {
"com.sun.security.jgss.krb5.initiate",
"com.sun.net.ssl.client",
};
break;
case GSSUtil.CALLER_SSL_SERVER:
} else if (caller == GSSCaller.CALLER_SSL_SERVER) {
alts = new String[] {
"com.sun.security.jgss.krb5.accept",
"com.sun.net.ssl.server",
};
break;
case GSSUtil.CALLER_HTTP_NEGOTIATE:
} else if (caller instanceof HttpCaller) {
alts = new String[] {
"com.sun.security.jgss.krb5.initiate",
};
break;
case GSSUtil.CALLER_UNKNOWN:
// should never use
throw new AssertionError("caller cannot be unknown");
default:
} else if (caller == GSSCaller.CALLER_UNKNOWN) {
throw new AssertionError("caller not defined");
}
} else {
@ -199,8 +190,8 @@ public class LoginConfigImpl extends Configuration {
return null;
}
private static boolean isServerSide (int caller) {
return GSSUtil.CALLER_ACCEPT == caller ||
GSSUtil.CALLER_SSL_SERVER == caller;
private static boolean isServerSide (GSSCaller caller) {
return GSSCaller.CALLER_ACCEPT == caller ||
GSSCaller.CALLER_SSL_SERVER == caller;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,8 +28,6 @@ package sun.security.jgss;
import java.lang.reflect.InvocationTargetException;
import org.ietf.jgss.*;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
@ -37,7 +35,6 @@ import java.util.HashSet;
import java.util.HashMap;
import java.util.Enumeration;
import java.util.Iterator;
import javax.security.auth.Subject;
import sun.security.jgss.spi.*;
import sun.security.jgss.wrapper.NativeGSSFactory;
import sun.security.jgss.wrapper.SunNativeProvider;
@ -124,9 +121,9 @@ public final class ProviderList {
new HashMap<PreferencesEntry, MechanismFactory>(5);
private HashSet<Oid> mechs = new HashSet<Oid>(5);
final private int caller;
final private GSSCaller caller;
public ProviderList(int caller, boolean useNative) {
public ProviderList(GSSCaller caller, boolean useNative) {
this.caller = caller;
Provider[] provList;
if (useNative) {
@ -274,7 +271,7 @@ public final class ProviderList {
private static MechanismFactory getMechFactoryImpl(Provider p,
String className,
Oid mechOid,
int caller)
GSSCaller caller)
throws GSSException {
try {
@ -301,7 +298,7 @@ public final class ProviderList {
if (baseClass.isAssignableFrom(implClass)) {
java.lang.reflect.Constructor<?> c =
implClass.getConstructor(Integer.TYPE);
implClass.getConstructor(GSSCaller.class);
MechanismFactory mf = (MechanismFactory) (c.newInstance(caller));
if (mf instanceof NativeGSSFactory) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,7 +34,7 @@ import java.net.Inet6Address;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.security.krb5.*;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.HttpCaller;
import sun.security.krb5.internal.Krb5;
abstract class InitialToken extends Krb5Token {
@ -85,7 +85,7 @@ abstract class InitialToken extends Krb5Token {
CHECKSUM_FLAGS_SIZE;
if (context.getCredDelegState()) {
if (context.getCaller() == GSSUtil.CALLER_HTTP_NEGOTIATE &&
if (context.getCaller() instanceof HttpCaller &&
!serviceTicket.getFlags()[Krb5.TKT_OPTS_DELEGATE]) {
// When the caller is HTTP/SPNEGO and OK-AS-DELEGATE
// is not present in the service ticket, delegation

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,11 +26,10 @@
package sun.security.jgss.krb5;
import org.ietf.jgss.*;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import sun.security.jgss.spi.*;
import sun.security.krb5.*;
import javax.security.auth.kerberos.*;
import java.io.IOException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.AccessController;
@ -80,7 +79,7 @@ public class Krb5AcceptCredential
}
}
static Krb5AcceptCredential getInstance(final int caller, Krb5NameElement name)
static Krb5AcceptCredential getInstance(final GSSCaller caller, Krb5NameElement name)
throws GSSException {
final String serverPrinc = (name == null? null:
@ -93,7 +92,7 @@ public class Krb5AcceptCredential
new PrivilegedExceptionAction<KerberosKey[]>() {
public KerberosKey[] run() throws Exception {
return Krb5Util.getKeys(
caller == GSSUtil.CALLER_UNKNOWN ? GSSUtil.CALLER_ACCEPT: caller,
caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller,
serverPrinc, acc);
}});
} catch (PrivilegedActionException e) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@ package sun.security.jgss.krb5;
import org.ietf.jgss.*;
import sun.misc.HexDumpEncoder;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import sun.security.jgss.spi.*;
import sun.security.jgss.TokenTracker;
import sun.security.krb5.*;
@ -37,8 +38,6 @@ import java.io.IOException;
import java.security.Provider;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.GeneralSecurityException;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import javax.crypto.Cipher;
@ -113,14 +112,14 @@ class Krb5Context implements GSSContextSpi {
// stored elsewhere
private Credentials serviceCreds;
private KrbApReq apReq;
final private int caller;
final private GSSCaller caller;
private static final boolean DEBUG = Krb5Util.DEBUG;
/**
* Constructor for Krb5Context to be called on the context initiator's
* side.
*/
Krb5Context(int caller, Krb5NameElement peerName, Krb5CredElement myCred,
Krb5Context(GSSCaller caller, Krb5NameElement peerName, Krb5CredElement myCred,
int lifetime)
throws GSSException {
@ -138,7 +137,7 @@ class Krb5Context implements GSSContextSpi {
* Constructor for Krb5Context to be called on the context acceptor's
* side.
*/
Krb5Context(int caller, Krb5CredElement myCred)
Krb5Context(GSSCaller caller, Krb5CredElement myCred)
throws GSSException {
this.caller = caller;
this.myCred = myCred;
@ -148,7 +147,7 @@ class Krb5Context implements GSSContextSpi {
/**
* Constructor for Krb5Context to import a previously exported context.
*/
public Krb5Context(int caller, byte [] interProcessToken)
public Krb5Context(GSSCaller caller, byte [] interProcessToken)
throws GSSException {
throw new GSSException(GSSException.UNAVAILABLE,
-1, "GSS Import Context not available");
@ -573,7 +572,7 @@ class Krb5Context implements GSSContextSpi {
// SubjectComber.find
// instead of Krb5Util.getTicket
return Krb5Util.getTicket(
GSSUtil.CALLER_UNKNOWN,
GSSCaller.CALLER_UNKNOWN,
// since it's useSubjectCredsOnly here,
// don't worry about the null
myName.getKrb5PrincipalName().getName(),
@ -1280,7 +1279,7 @@ class Krb5Context implements GSSContextSpi {
}
}
int getCaller() {
GSSCaller getCaller() {
// Currently used by InitialToken only
return caller;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,7 +26,7 @@
package sun.security.jgss.krb5;
import org.ietf.jgss.*;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import sun.security.jgss.spi.*;
import sun.security.krb5.*;
import sun.security.krb5.Config;
@ -138,7 +138,7 @@ public class Krb5InitCredential
this.krb5Credentials = delegatedCred;
}
static Krb5InitCredential getInstance(int caller, Krb5NameElement name,
static Krb5InitCredential getInstance(GSSCaller caller, Krb5NameElement name,
int initLifetime)
throws GSSException {
@ -305,7 +305,7 @@ public class Krb5InitCredential
// XXX call to this.destroy() should destroy the locally cached copy
// of krb5Credentials and then call super.destroy().
private static KerberosTicket getTgt(int caller, Krb5NameElement name,
private static KerberosTicket getTgt(GSSCaller caller, Krb5NameElement name,
int initLifetime)
throws GSSException {
@ -337,8 +337,8 @@ public class Krb5InitCredential
final AccessControlContext acc = AccessController.getContext();
try {
final int realCaller = (caller == GSSUtil.CALLER_UNKNOWN)
? GSSUtil.CALLER_INITIATE
final GSSCaller realCaller = (caller == GSSCaller.CALLER_UNKNOWN)
? GSSCaller.CALLER_INITIATE
: caller;
return AccessController.doPrivileged(
new PrivilegedExceptionAction<KerberosTicket>() {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,12 +27,10 @@ package sun.security.jgss.krb5;
import org.ietf.jgss.*;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import sun.security.jgss.spi.*;
import javax.security.auth.kerberos.ServicePermission;
import java.security.Provider;
import sun.security.util.DerOutputStream;
import sun.security.util.ObjectIdentifier;
import java.io.IOException;
import java.util.Vector;
/**
@ -62,7 +60,7 @@ public final class Krb5MechFactory implements MechanismFactory {
GSSName.NT_EXPORT_NAME,
NT_GSS_KRB5_PRINCIPAL};
final private int caller;
final private GSSCaller caller;
private static Krb5CredElement getCredFromSubject(GSSNameSpi name,
boolean initiate)
@ -88,7 +86,7 @@ public final class Krb5MechFactory implements MechanismFactory {
return result;
}
public Krb5MechFactory(int caller) {
public Krb5MechFactory(GSSCaller caller) {
this.caller = caller;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,7 @@ import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import java.security.AccessControlContext;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import sun.security.krb5.Credentials;
import sun.security.krb5.EncryptionKey;
@ -67,7 +68,7 @@ public class Krb5Util {
*
* NOTE: This method is used by JSSE Kerberos Cipher Suites
*/
public static KerberosTicket getTicketFromSubjectAndTgs(int caller,
public static KerberosTicket getTicketFromSubjectAndTgs(GSSCaller caller,
String clientPrincipal, String serverPrincipal, String tgsPrincipal,
AccessControlContext acc)
throws LoginException, KrbException, IOException {
@ -138,7 +139,7 @@ public class Krb5Util {
* useSubjectCredsOnly is false, then obtain ticket from
* a LoginContext.
*/
static KerberosTicket getTicket(int caller,
static KerberosTicket getTicket(GSSCaller caller,
String clientPrincipal, String serverPrincipal,
AccessControlContext acc) throws LoginException {
@ -168,7 +169,7 @@ public class Krb5Util {
*
* NOTE: This method is used by JSSE Kerberos Cipher Suites
*/
public static Subject getSubject(int caller,
public static Subject getSubject(GSSCaller caller,
AccessControlContext acc) throws LoginException {
// Try to get the Subject from acc
@ -190,7 +191,7 @@ public class Krb5Util {
*
* NOTE: This method is used by JSSE Kerberos Cipher Suites
*/
public static KerberosKey[] getKeys(int caller,
public static KerberosKey[] getKeys(GSSCaller caller,
String serverPrincipal, AccessControlContext acc)
throws LoginException {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -90,7 +90,7 @@ public final class SpNegoMechFactory implements MechanismFactory {
return result;
}
public SpNegoMechFactory(int caller) {
public SpNegoMechFactory(GSSCaller caller) {
manager = new GSSManagerImpl(caller, false);
Oid[] mechs = manager.getMechs();
availableMechs = new Oid[mechs.length-1];

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,17 +26,11 @@
package sun.security.jgss.wrapper;
import java.io.UnsupportedEncodingException;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.util.Set;
import java.util.Vector;
import java.util.Iterator;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.*;
import org.ietf.jgss.*;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import sun.security.jgss.GSSExceptionImpl;
import sun.security.jgss.spi.*;
@ -49,7 +43,7 @@ import sun.security.jgss.spi.*;
public final class NativeGSSFactory implements MechanismFactory {
GSSLibStub cStub = null;
private final int caller;
private final GSSCaller caller;
private GSSCredElement getCredFromSubject(GSSNameElement name,
boolean initiate)
@ -74,7 +68,7 @@ public final class NativeGSSFactory implements MechanismFactory {
return result;
}
public NativeGSSFactory(int caller) {
public NativeGSSFactory(GSSCaller caller) {
this.caller = caller;
// Have to call setMech(Oid) explicitly before calling other
// methods. Otherwise, NPE may be thrown unexpectantly

View File

@ -1,5 +1,5 @@
/*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -46,13 +46,12 @@ import javax.net.ssl.*;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosPrincipal;
import sun.security.jgss.krb5.Krb5Util;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
import sun.security.ssl.HandshakeMessage.*;
import sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.KeyExchange.*;
/**
@ -364,7 +363,7 @@ final class ClientHandshaker extends Handshaker {
new PrivilegedExceptionAction<Subject>() {
public Subject run() throws Exception {
return Krb5Util.getSubject(
GSSUtil.CALLER_SSL_CLIENT,
GSSCaller.CALLER_SSL_CLIENT,
getAccSE());
}});
} catch (PrivilegedActionException e) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,19 +34,16 @@ import java.security.PrivilegedActionException;
import java.security.SecureRandom;
import java.net.InetAddress;
import javax.net.ssl.SSLException;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.ServicePermission;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import sun.security.krb5.Config;
import sun.security.krb5.EncryptionKey;
import sun.security.krb5.EncryptedData;
import sun.security.krb5.PrincipalName;
import sun.security.krb5.Realm;
import sun.security.krb5.KrbException;
import sun.security.krb5.internal.Ticket;
import sun.security.krb5.internal.EncTicketPart;
import sun.security.krb5.internal.crypto.KeyUsage;
@ -310,7 +307,7 @@ final class KerberosClientKeyExchange extends HandshakeMessage {
new PrivilegedExceptionAction<KerberosTicket>() {
public KerberosTicket run() throws Exception {
return Krb5Util.getTicketFromSubjectAndTgs(
GSSUtil.CALLER_SSL_CLIENT,
GSSCaller.CALLER_SSL_CLIENT,
clientPrincipal, serverPrincipal,
tgsPrincipal, acc);
}});

View File

@ -1,5 +1,5 @@
/*
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -43,7 +43,7 @@ import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.ServicePermission;
import sun.security.jgss.krb5.Krb5Util;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
@ -367,7 +367,7 @@ final class ServerHandshaker extends Handshaker {
new PrivilegedExceptionAction<Subject>() {
public Subject run() throws Exception {
return Krb5Util.getSubject(
GSSUtil.CALLER_SSL_SERVER,
GSSCaller.CALLER_SSL_SERVER,
getAccSE());
}});
} catch (PrivilegedActionException e) {
@ -918,7 +918,7 @@ final class ServerHandshaker extends Handshaker {
public KerberosKey[] run() throws Exception {
// get kerberos key for the default principal
return Krb5Util.getKeys(
GSSUtil.CALLER_SSL_SERVER, null, acc);
GSSCaller.CALLER_SSL_SERVER, null, acc);
}});
// check permission to access and use the secret key of the

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2006-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.URIParameter;
import javax.security.auth.login.Configuration;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSCaller;
import sun.security.jgss.LoginConfigImpl;
public class DefaultGssConfig {
@ -56,11 +57,11 @@ public class DefaultGssConfig {
Configuration.getConfiguration();
// 3. Make sure there're default entries for GSS krb5 client/server
LoginConfigImpl lc = new LoginConfigImpl(GSSUtil.CALLER_INITIATE, GSSUtil.GSS_KRB5_MECH_OID);
LoginConfigImpl lc = new LoginConfigImpl(GSSCaller.CALLER_INITIATE, GSSUtil.GSS_KRB5_MECH_OID);
if (lc.getAppConfigurationEntry("").length == 0) {
throw new Exception("No default config for GSS krb5 client");
}
lc = new LoginConfigImpl(GSSUtil.CALLER_ACCEPT, GSSUtil.GSS_KRB5_MECH_OID);
lc = new LoginConfigImpl(GSSCaller.CALLER_ACCEPT, GSSUtil.GSS_KRB5_MECH_OID);
if (lc.getAppConfigurationEntry("").length == 0) {
throw new Exception("No default config for GSS krb5 server");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,6 @@
* @summary GSS throws NPE when the JAAS config file does not exist
*/
import org.ietf.jgss.*;
import sun.security.jgss.*;
public class GssNPE {
@ -40,7 +39,7 @@ public class GssNPE {
// not exist. New caller-enabled JGSS changed this. this bug fix will
// revert to the old behavior.
try {
GSSUtil.login(GSSUtil.CALLER_INITIATE, GSSUtil.GSS_KRB5_MECH_OID);
GSSUtil.login(GSSCaller.CALLER_INITIATE, GSSUtil.GSS_KRB5_MECH_OID);
} catch (SecurityException se) {
if (se.getCause() instanceof java.io.IOException) {
// what had been and should be...

View File

@ -0,0 +1,341 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6578647
* @summary Undefined requesting URL in java.net.Authenticator.getPasswordAuthentication()
* @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock HttpNegotiateServer
*/
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpPrincipal;
import com.sun.security.auth.module.Krb5LoginModule;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.InetAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.security.PrivilegedExceptionAction;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.Subject;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSManager;
import sun.security.jgss.GSSUtil;
import sun.net.spi.nameservice.NameService;
import sun.net.spi.nameservice.NameServiceDescriptor;
import sun.security.krb5.Config;
/**
* Basic JGSS/krb5 test with 3 parties: client, server, backend server. Each
* party uses JAAS login to get subjects and executes JGSS calls using
* Subject.doAs.
*/
public class HttpNegotiateServer implements NameServiceDescriptor {
// Two realm, web server in one, proxy server in another
final static String REALM_WEB = "WEB.DOMAIN";
final static String REALM_PROXY = "PROXY.DOMAIN";
final static String KRB5_CONF = "web.conf";
final static String KRB5_TAB = "web.ktab";
// user principals
final static String WEB_USER = "web";
final static char[] WEB_PASS = "webby".toCharArray();
final static String PROXY_USER = "pro";
final static char[] PROXY_PASS = "proxy".toCharArray();
final static int WEB_PORT = 17840;
final static String WEB_HOST = "host.web.domain";
final static String PROXY_HOST = "host.proxy.domain";
final static int PROXY_PORT = 17841;
// web page content
final static String CONTENT = "Hello, World!";
// URLs for web test, proxy test. The proxy server is not a real proxy
// since it fakes the same content for any URL. :)
final static URL webUrl, proxyUrl;
static {
URL u1 = null, u2 = null;
try {
u1 = new URL("http://" + WEB_HOST +":" + WEB_PORT + "/a/b/c");
u2 = new URL("http://nosuchplace/a/b/c");
} catch (Exception e) {
}
webUrl = u1; proxyUrl = u2;
}
/**
* This Authenticator checks everything:
* scheme, protocol, requestor type, host, port, and url
*/
static class KnowAllAuthenticator extends java.net.Authenticator {
public PasswordAuthentication getPasswordAuthentication () {
if (!getRequestingScheme().equalsIgnoreCase("Negotiate")) {
throw new RuntimeException("Bad scheme");
}
if (!getRequestingProtocol().equalsIgnoreCase("HTTP")) {
throw new RuntimeException("Bad protocol");
}
if (getRequestorType() == RequestorType.SERVER) {
if (!this.getRequestingHost().equalsIgnoreCase(webUrl.getHost())) {
throw new RuntimeException("Bad host");
}
if (this.getRequestingPort() != webUrl.getPort()) {
throw new RuntimeException("Bad port");
}
if (!this.getRequestingURL().equals(webUrl)) {
throw new RuntimeException("Bad url");
}
return new PasswordAuthentication(
WEB_USER+"@"+REALM_WEB, WEB_PASS);
} else if (getRequestorType() == RequestorType.PROXY) {
if (!this.getRequestingHost().equalsIgnoreCase(PROXY_HOST)) {
throw new RuntimeException("Bad host");
}
if (this.getRequestingPort() != PROXY_PORT) {
throw new RuntimeException("Bad port");
}
if (!this.getRequestingURL().equals(proxyUrl)) {
throw new RuntimeException("Bad url");
}
return new PasswordAuthentication(
PROXY_USER+"@"+REALM_PROXY, PROXY_PASS);
} else {
throw new RuntimeException("Bad requster type");
}
}
}
public static void main(String[] args)
throws Exception {
KDC kdcw = new KDC(REALM_WEB, 0, true);
kdcw.addPrincipal(WEB_USER, WEB_PASS);
kdcw.addPrincipalRandKey("krbtgt/" + REALM_WEB);
kdcw.addPrincipalRandKey("HTTP/" + WEB_HOST);
KDC kdcp = new KDC(REALM_PROXY, 0, true);
kdcp.addPrincipal(PROXY_USER, PROXY_PASS);
kdcp.addPrincipalRandKey("krbtgt/" + REALM_PROXY);
kdcp.addPrincipalRandKey("HTTP/" + PROXY_HOST);
KDC.writeMultiKtab(KRB5_TAB, kdcw, kdcp);
KDC.saveConfig(KRB5_CONF, kdcw, kdcp,
"default_keytab_name = " + KRB5_TAB,
"[domain_realm]",
"",
".web.domain="+REALM_WEB,
".proxy.domain="+REALM_PROXY);
System.setProperty("java.security.krb5.conf", KRB5_CONF);
Config.refresh();
HttpServer h1 = httpd(WEB_PORT, "Negotiate", false,
"HTTP/" + WEB_HOST + "@" + REALM_WEB, KRB5_TAB);
HttpServer h2 = httpd(PROXY_PORT, "Negotiate", true,
"HTTP/" + PROXY_HOST + "@" + REALM_PROXY, KRB5_TAB);
try {
BufferedReader reader;
java.net.Authenticator.setDefault(new KnowAllAuthenticator());
reader = new BufferedReader(new InputStreamReader(
webUrl.openConnection().getInputStream()));
if (!reader.readLine().equals(CONTENT)) {
throw new RuntimeException("Bad content");
}
reader = new BufferedReader(new InputStreamReader(
proxyUrl.openConnection(
new Proxy(Proxy.Type.HTTP,
new InetSocketAddress(PROXY_HOST, PROXY_PORT)))
.getInputStream()));
if (!reader.readLine().equals(CONTENT)) {
throw new RuntimeException("Bad content");
}
} finally {
// Must stop. Seems there's no HttpServer.startAsDaemon()
if (h1 != null) h1.stop(0);
if (h2 != null) h2.stop(0);
}
}
/**
* Creates and starts an HTTP or proxy server that requires
* Negotiate authentication.
* @param scheme "Negotiate" or "Kerberos"
* @param principal the krb5 service principal the server runs with
* @return the server
*/
public static HttpServer httpd(int port, String scheme, boolean proxy,
String principal, String ktab) throws Exception {
MyHttpHandler h = new MyHttpHandler();
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
HttpContext hc = server.createContext("/", h);
hc.setAuthenticator(new MyServerAuthenticator(
proxy, scheme, principal, ktab));
server.start();
return server;
}
static class MyHttpHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
t.sendResponseHeaders(200, 0);
t.getResponseBody().write(CONTENT.getBytes());
t.close();
}
}
static class MyServerAuthenticator
extends com.sun.net.httpserver.Authenticator {
Subject s = new Subject();
GSSManager m = null;
GSSCredential cred = null;
String scheme = null;
String reqHdr = "WWW-Authenticate";
String respHdr = "Authorization";
int err = HttpURLConnection.HTTP_UNAUTHORIZED;
public MyServerAuthenticator(boolean proxy, String scheme,
String principal, String ktab) throws Exception {
this.scheme = scheme;
if (proxy) {
reqHdr = "Proxy-Authenticate";
respHdr = "Proxy-Authorization";
err = HttpURLConnection.HTTP_PROXY_AUTH;
}
Krb5LoginModule krb5 = new Krb5LoginModule();
Map<String, String> map = new HashMap<String, String>();
Map<String, Object> shared = new HashMap<String, Object>();
map.put("storeKey", "true");
map.put("isInitiator", "false");
map.put("useKeyTab", "true");
map.put("keyTab", ktab);
map.put("principal", principal);
krb5.initialize(s, null, shared, map);
krb5.login();
krb5.commit();
m = GSSManager.getInstance();
cred = Subject.doAs(s, new PrivilegedExceptionAction<GSSCredential>() {
@Override
public GSSCredential run() throws Exception {
System.err.println("Creating GSSCredential");
return m.createCredential(
null,
GSSCredential.INDEFINITE_LIFETIME,
MyServerAuthenticator.this.scheme.equalsIgnoreCase("Negotiate")?
GSSUtil.GSS_SPNEGO_MECH_OID:
GSSUtil.GSS_KRB5_MECH_OID,
GSSCredential.ACCEPT_ONLY);
}
});
}
@Override
public Result authenticate(HttpExchange exch) {
// The GSContext is stored in an HttpContext attribute named
// "GSSContext" and is created at the first request.
GSSContext c = null;
String auth = exch.getRequestHeaders().getFirst(respHdr);
try {
c = (GSSContext)exch.getHttpContext().getAttributes().get("GSSContext");
if (auth == null) { // First request
Headers map = exch.getResponseHeaders();
map.set (reqHdr, scheme); // Challenge!
c = Subject.doAs(s, new PrivilegedExceptionAction<GSSContext>() {
@Override
public GSSContext run() throws Exception {
return m.createContext(cred);
}
});
exch.getHttpContext().getAttributes().put("GSSContext", c);
return new com.sun.net.httpserver.Authenticator.Retry(err);
} else { // Later requests
byte[] token = new sun.misc.BASE64Decoder()
.decodeBuffer(auth.split(" ")[1]);
token = c.acceptSecContext(token, 0, token.length);
Headers map = exch.getResponseHeaders();
map.set (reqHdr, scheme + " " + new sun.misc.BASE64Encoder()
.encode(token).replaceAll("\\s", ""));
if (c.isEstablished()) {
return new com.sun.net.httpserver.Authenticator.Success(
new HttpPrincipal(c.getSrcName().toString(), ""));
} else {
return new com.sun.net.httpserver.Authenticator.Retry(err);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Override
public NameService createNameService() throws Exception {
NameService ns = new NameService() {
@Override
public InetAddress[] lookupAllHostAddr(String host)
throws UnknownHostException {
// Everything is localhost
return new InetAddress[]{
InetAddress.getByAddress(host, new byte[]{127,0,0,1})
};
}
@Override
public String getHostByAddr(byte[] addr)
throws UnknownHostException {
// No reverse lookup
throw new UnknownHostException();
}
};
return ns;
}
@Override
public String getProviderName() {
return "mock";
}
@Override
public String getType() {
return "ns";
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -201,14 +201,14 @@ public class KDC {
}
/**
* Write all principals' keys into a keytab file. Note that the keys for
* the krbtgt principal for this realm will not be written.
* Write all principals' keys from multiple KDCsinto one keytab file.
* Note that the keys for the krbtgt principals will not be written.
* <p>
* Attention: This method references krb5.conf settings. If you need to
* setup krb5.conf later, please call <code>Config.refresh()</code> after
* the new setting. For example:
* <pre>
* kdc.writeKtab("/etc/kdc/ktab"); // Config is initialized,
* KDC.writeKtab("/etc/kdc/ktab", kdc); // Config is initialized,
* System.setProperty("java.security.krb5.conf", "/home/mykrb5.conf");
* Config.refresh();
* </pre>
@ -223,20 +223,31 @@ public class KDC {
* @throws sun.security.krb5.KrbException for any realm and/or principal
* name error.
*/
public void writeKtab(String tab) throws IOException, KrbException {
public static void writeMultiKtab(String tab, KDC... kdcs)
throws IOException, KrbException {
KeyTab ktab = KeyTab.create(tab);
for (String name : passwords.keySet()) {
if (name.equals("krbtgt/" + realm)) {
continue;
for (KDC kdc: kdcs) {
for (String name : kdc.passwords.keySet()) {
if (name.equals("krbtgt/" + kdc.realm)) {
continue;
}
ktab.addEntry(new PrincipalName(name + "@" + kdc.realm,
name.indexOf('/') < 0 ?
PrincipalName.KRB_NT_UNKNOWN :
PrincipalName.KRB_NT_SRV_HST),
kdc.passwords.get(name));
}
ktab.addEntry(new PrincipalName(name + "@" + realm,
name.indexOf('/') < 0 ?
PrincipalName.KRB_NT_UNKNOWN :
PrincipalName.KRB_NT_SRV_HST), passwords.get(name));
}
ktab.save();
}
/**
* Write a ktab for this KDC.
*/
public void writeKtab(String tab) throws IOException, KrbException {
KDC.writeMultiKtab(tab, this);
}
/**
* Adds a new principal to this realm with a given password.
* @param user the principal's name. For a service principal, use the