6578647: Undefined requesting URL in java.net.Authenticator.getPasswordAuthentication()
Reviewed-by: chegar, valeriep
diff --git a/src/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java b/src/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java
index 8eb05bf..6826244 100644
--- a/src/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java
+++ b/src/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java
@@ -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 @@
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.
@@ -115,22 +114,11 @@
/**
* 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 @@
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 @@
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 @@
//
// 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;
diff --git a/src/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java b/src/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java
new file mode 100644
index 0000000..3aeba81
--- /dev/null
+++ b/src/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java
@@ -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 = "";
+ }
+}
diff --git a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
index 770ffba..aacab5f 100644
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
@@ -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 @@
AuthenticationHeader authhdr = new AuthenticationHeader (
"Proxy-Authenticate", responses,
- http.getProxyHostUsed(), dontUseNegotiate
+ new HttpCallerInfo(url, http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate
);
if (!doingNTLMp2ndStage) {
@@ -1230,7 +1232,8 @@
srvHdr = new AuthenticationHeader (
"WWW-Authenticate", responses,
- url.getHost().toLowerCase(), dontUseNegotiate
+ new HttpCallerInfo(url),
+ dontUseNegotiate
);
String raw = srvHdr.raw();
@@ -1595,7 +1598,9 @@
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 @@
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 @@
} 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 @@
} 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 =
diff --git a/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java b/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java
index 81353fc..db5d509 100644
--- a/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java
+++ b/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java
@@ -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 @@
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 @@
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 @@
}
/**
- * 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 @@
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 @@
}
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 @@
* 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;
diff --git a/src/share/classes/sun/net/www/protocol/http/NegotiateCallbackHandler.java b/src/share/classes/sun/net/www/protocol/http/NegotiateCallbackHandler.java
index 8ab6eb6..7ac2593 100644
--- a/src/share/classes/sun/net/www/protocol/http/NegotiateCallbackHandler.java
+++ b/src/share/classes/sun/net/www/protocol/http/NegotiateCallbackHandler.java
@@ -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 @@
/**
* @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 @@
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 @@
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 @@
} else {
throw new UnsupportedCallbackException(callBack,
"Call back not supported");
- }//else
- }//for
+ }
+ }
}
}
diff --git a/src/share/classes/sun/net/www/protocol/http/NegotiatorImpl.java b/src/share/classes/sun/net/www/protocol/http/NegotiatorImpl.java
index 6252517..2c195e4 100644
--- a/src/share/classes/sun/net/www/protocol/http/NegotiatorImpl.java
+++ b/src/share/classes/sun/net/www/protocol/http/NegotiatorImpl.java
@@ -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 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 @@
/**
* 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 @@
}
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 @@
/**
* 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");
diff --git a/src/share/classes/sun/security/jgss/GSSCaller.java b/src/share/classes/sun/security/jgss/GSSCaller.java
new file mode 100644
index 0000000..e38c348
--- /dev/null
+++ b/src/share/classes/sun/security/jgss/GSSCaller.java
@@ -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();
+}
+
diff --git a/src/share/classes/sun/security/jgss/GSSManagerImpl.java b/src/share/classes/sun/security/jgss/GSSManagerImpl.java
index a886b87..eeb23fc 100644
--- a/src/share/classes/sun/security/jgss/GSSManagerImpl.java
+++ b/src/share/classes/sun/security/jgss/GSSManagerImpl.java
@@ -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 @@
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 @@
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(){
diff --git a/src/share/classes/sun/security/jgss/GSSUtil.java b/src/share/classes/sun/security/jgss/GSSUtil.java
index 4c161b2..12a791d 100644
--- a/src/share/classes/sun/security/jgss/GSSUtil.java
+++ b/src/share/classes/sun/security/jgss/GSSUtil.java
@@ -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 @@
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 @@
* @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 @@
* 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;
}
/*
diff --git a/src/share/classes/sun/security/jgss/HttpCaller.java b/src/share/classes/sun/security/jgss/HttpCaller.java
new file mode 100644
index 0000000..4ec4398
--- /dev/null
+++ b/src/share/classes/sun/security/jgss/HttpCaller.java
@@ -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;
+ }
+}
+
diff --git a/src/share/classes/sun/security/jgss/LoginConfigImpl.java b/src/share/classes/sun/security/jgss/LoginConfigImpl.java
index a421e51..7262965 100644
--- a/src/share/classes/sun/security/jgss/LoginConfigImpl.java
+++ b/src/share/classes/sun/security/jgss/LoginConfigImpl.java
@@ -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 @@
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 @@
* @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 @@
// 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 @@
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;
}
}
diff --git a/src/share/classes/sun/security/jgss/ProviderList.java b/src/share/classes/sun/security/jgss/ProviderList.java
index 8df718c..45e69b2 100644
--- a/src/share/classes/sun/security/jgss/ProviderList.java
+++ b/src/share/classes/sun/security/jgss/ProviderList.java
@@ -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 @@
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.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 @@
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 @@
private static MechanismFactory getMechFactoryImpl(Provider p,
String className,
Oid mechOid,
- int caller)
+ GSSCaller caller)
throws GSSException {
try {
@@ -301,7 +298,7 @@
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) {
diff --git a/src/share/classes/sun/security/jgss/krb5/InitialToken.java b/src/share/classes/sun/security/jgss/krb5/InitialToken.java
index 4533813..7ce0b44 100644
--- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java
+++ b/src/share/classes/sun/security/jgss/krb5/InitialToken.java
@@ -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.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 @@
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
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java b/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java
index 3fb4835..ddbd48b 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java
@@ -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 @@
}
}
- 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 @@
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) {
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5Context.java b/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
index 9e92a6f..f2ef7d5 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
@@ -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 @@
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.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 @@
// 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 @@
* 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 @@
/**
* 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 @@
// 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 @@
}
}
- int getCaller() {
+ GSSCaller getCaller() {
// Currently used by InitialToken only
return caller;
}
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java b/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
index 8e9cd1b..1aac872 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
@@ -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 @@
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 @@
// 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 @@
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>() {
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java b/src/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java
index 3977777..5e32977 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java
@@ -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 @@
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 @@
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 @@
return result;
}
- public Krb5MechFactory(int caller) {
+ public Krb5MechFactory(GSSCaller caller) {
this.caller = caller;
}
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5Util.java b/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
index 62b5795..849dbc4 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
@@ -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.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 @@
*
* 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 @@
* 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 @@
*
* 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 @@
*
* 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 {
diff --git a/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java b/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java
index d782967..ae12d6b 100644
--- a/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java
+++ b/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java
@@ -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 @@
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];
diff --git a/src/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java b/src/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java
index 315e560..7e2146c 100644
--- a/src/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java
+++ b/src/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java
@@ -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 @@
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 @@
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
diff --git a/src/share/classes/sun/security/ssl/ClientHandshaker.java b/src/share/classes/sun/security/ssl/ClientHandshaker.java
index f29397d..08877ba 100644
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java
+++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java
@@ -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.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 @@
new PrivilegedExceptionAction<Subject>() {
public Subject run() throws Exception {
return Krb5Util.getSubject(
- GSSUtil.CALLER_SSL_CLIENT,
+ GSSCaller.CALLER_SSL_CLIENT,
getAccSE());
}});
} catch (PrivilegedActionException e) {
diff --git a/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java b/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java
index cb7543b..e79026e 100644
--- a/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java
+++ b/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java
@@ -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.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 @@
new PrivilegedExceptionAction<KerberosTicket>() {
public KerberosTicket run() throws Exception {
return Krb5Util.getTicketFromSubjectAndTgs(
- GSSUtil.CALLER_SSL_CLIENT,
+ GSSCaller.CALLER_SSL_CLIENT,
clientPrincipal, serverPrincipal,
tgsPrincipal, acc);
}});
diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java
index ab2ebd3..772cdb6 100644
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java
@@ -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.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 @@
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 @@
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
diff --git a/test/sun/security/jgss/DefaultGssConfig.java b/test/sun/security/jgss/DefaultGssConfig.java
index 5959f8e..672be74 100644
--- a/test/sun/security/jgss/DefaultGssConfig.java
+++ b/test/sun/security/jgss/DefaultGssConfig.java
@@ -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.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 @@
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");
}
diff --git a/test/sun/security/jgss/GssNPE.java b/test/sun/security/jgss/GssNPE.java
index 9d9b144..815e248 100644
--- a/test/sun/security/jgss/GssNPE.java
+++ b/test/sun/security/jgss/GssNPE.java
@@ -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 @@
// 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...
diff --git a/test/sun/security/krb5/auto/HttpNegotiateServer.java b/test/sun/security/krb5/auto/HttpNegotiateServer.java
new file mode 100644
index 0000000..9505455
--- /dev/null
+++ b/test/sun/security/krb5/auto/HttpNegotiateServer.java
@@ -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";
+ }
+}
+
diff --git a/test/sun/security/krb5/auto/KDC.java b/test/sun/security/krb5/auto/KDC.java
index 3e6a779..14767c4 100644
--- a/test/sun/security/krb5/auto/KDC.java
+++ b/test/sun/security/krb5/auto/KDC.java
@@ -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 @@
}
/**
- * 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,21 +223,32 @@
* @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
* form of host/f.q.d.n
diff --git a/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
new file mode 100644
index 0000000..32f3a09
--- /dev/null
+++ b/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
@@ -0,0 +1 @@
+HttpNegotiateServer