JDK-7112336 : Request is for enhancements to the GSS API implementation and code paths
  • Type: Enhancement
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 7
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_10
  • CPU: sparc
  • Submitted: 2011-11-16
  • Updated: 2012-12-05
  • Resolved: 2012-12-05
Related Reports
Duplicate :  
Description
Request is for enhancements to the GSS API implementation and code paths leading from javax.security.sasl.Sasl.createSaslServer, to allow for not providing a server name argument and instead using the DefaultAcceptorCredential to dynamically select the appropriate key from the key tab.  This would allow for clients to connect to our server to using FQDN or shortname interchangably and get the approproate key when both entries exist in the keytab.

The underlying implementation changes are descibed below:
====
jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java

where we find this:

66 final class GssKrb5Server extends GssKrb5Base implements SaslServer {
67 private static final String MY_CLASS_NAME = GssKrb5Server.class.getName();
68
69 private int handshakeStage = 0;
70 private String peer;
71 private String authzid;
72 private CallbackHandler cbh;
73
74 /**
75 * Creates a SASL mechanism with server credentials that it needs
76 * to participate in GSS-API/Kerberos v5 authentication exchange
77 * with the client.
78 */
79 GssKrb5Server(String protocol, String serverName,
80 Map props, CallbackHandler cbh) throws SaslException {
81
82 super(props, MY_CLASS_NAME);
83
84 this.cbh = cbh;
--->85 String service = protocol + "@" + serverName;
86
87 logger.log(Level.FINE, "KRB5SRV01:Using service name: {0}", service);

That's the only place that serverName is referenced. The we have this:

88
89 try {
90 GSSManager mgr = GSSManager.getInstance();
91
92 // Create the name for the requested service entity for Krb5 mech
--->93 GSSName serviceName = mgr.createName(service,
94 GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
95
--->96 GSSCredential cred = mgr.createCredential(serviceName,
97 GSSCredential.INDEFINITE_LIFETIME,
98 KRB5_OID, GSSCredential.ACCEPT_ONLY);
99
100 // Create a context using the server's credentials
-->101 secCtx = mgr.createContext(cred);

Exactly as I'd predicted. This should all be changed to be something
like:

79 GssKrb5Server(String protocol, String serverName,
80 Map props, CallbackHandler cbh) throws SaslException {
81
82 super(props, MY_CLASS_NAME);
+83 String service = null
84
85 this.cbh = cbh;
86
+87 if (serverName != null)
88 service = protocol + "@" + serverName;
89
90 logger.log(Level.FINE, "KRB5SRV01:Using service name: {0}", service);
91
92 try {
93 GSSManager mgr = GSSManager.getInstance();
94 GSSCredential cred = null;
95
+96 if (service != null) {
97 // Create the name for the requested service entity for Krb5 mech
98 GSSName serviceName = mgr.createName(service,
99 GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
100
101 GSSCredential cred = mgr.createCredential(serviceName,
102 GSSCredential.INDEFINITE_LIFETIME,
103 KRB5_OID, GSSCredential.ACCEPT_ONLY);
+104 }
105
106 // Create a context using the server's credentials
107 secCtx = mgr.createContext(cred);

However, I'm sure the maintainer will want to retain <protocol> (really, the service name) for checking later, when acceptSecContext() completes they can then call the getTargName() method of the context and check that the target's name matches the given <protocol>, if one was given.
====