You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by ca...@apache.org on 2013/09/11 22:44:15 UTC
svn commit: r1522029 - in /zookeeper/trunk: CHANGES.txt
src/java/main/org/apache/zookeeper/client/ZooKeeperSaslClient.java
src/java/main/org/apache/zookeeper/server/ZooKeeperSaslServer.java
Author: camille
Date: Wed Sep 11 20:44:15 2013
New Revision: 1522029
URL: http://svn.apache.org/r1522029
Log:
ZOOKEEPER-1664. Kerberos auth doesn't work with native platform GSS integration. (Boaz Kelmer via camille)
Modified:
zookeeper/trunk/CHANGES.txt
zookeeper/trunk/src/java/main/org/apache/zookeeper/client/ZooKeeperSaslClient.java
zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperSaslServer.java
Modified: zookeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/trunk/CHANGES.txt?rev=1522029&r1=1522028&r2=1522029&view=diff
==============================================================================
--- zookeeper/trunk/CHANGES.txt (original)
+++ zookeeper/trunk/CHANGES.txt Wed Sep 11 20:44:15 2013
@@ -374,6 +374,8 @@ BUGFIXES:
ZOOKEEPER-1448. Node+Quota creation in transaction log can crash leader startup (Botond Hejj via fpj)
+ ZOOKEEPER-1664. Kerberos auth doesn't work with native platform GSS integration. (Boaz Kelmer via camille)
+
IMPROVEMENTS:
ZOOKEEPER-1170. Fix compiler (eclipse) warnings: unused imports,
Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/client/ZooKeeperSaslClient.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/client/ZooKeeperSaslClient.java?rev=1522029&r1=1522028&r2=1522029&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/client/ZooKeeperSaslClient.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/client/ZooKeeperSaslClient.java Wed Sep 11 20:44:15 2013
@@ -18,23 +18,11 @@
package org.apache.zookeeper.client;
-import org.apache.zookeeper.AsyncCallback;
-import org.apache.zookeeper.ClientCnxn;
-import org.apache.zookeeper.Login;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.Environment;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.proto.GetSASLRequest;
-import org.apache.zookeeper.proto.SetSASLResponse;
-import org.apache.zookeeper.server.auth.KerberosName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.IOException;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
@@ -50,6 +38,24 @@ import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.ClientCnxn;
+import org.apache.zookeeper.Environment;
+import org.apache.zookeeper.Login;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.proto.GetSASLRequest;
+import org.apache.zookeeper.proto.SetSASLResponse;
+import org.apache.zookeeper.server.auth.KerberosName;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.Oid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* This class manages SASL authentication for the client. It
* allows ClientCnxn to authenticate using SASL with a Zookeeper server.
@@ -213,6 +219,33 @@ public class ZooKeeperSaslClient {
return saslClient;
}
else { // GSSAPI.
+ boolean usingNativeJgss =
+ Boolean.getBoolean("sun.security.jgss.native");
+ if (usingNativeJgss) {
+ // http://docs.oracle.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
+ // """
+ // In addition, when performing operations as a particular
+ // Subject, e.g. Subject.doAs(...) or Subject.doAsPrivileged(...),
+ // the to-be-used GSSCredential should be added to Subject's
+ // private credential set. Otherwise, the GSS operations will
+ // fail since no credential is found.
+ // """
+ try {
+ GSSManager manager = GSSManager.getInstance();
+ Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
+ GSSCredential cred = manager.createCredential(null,
+ GSSContext.DEFAULT_LIFETIME,
+ krb5Mechanism,
+ GSSCredential.INITIATE_ONLY);
+ subject.getPrivateCredentials().add(cred);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Added private credential to subject: " + cred);
+ }
+ } catch (GSSException ex) {
+ LOG.warn("Cannot add private credential to subject; " +
+ "authentication at the server may fail", ex);
+ }
+ }
final Object[] principals = subject.getPrincipals().toArray();
// determine client principal from subject.
final Principal clientPrincipal = (Principal)principals[0];
@@ -237,7 +270,7 @@ public class ZooKeeperSaslClient {
return saslClient;
}
catch (Exception e) {
- LOG.error("Error creating SASL client:" + e);
+ LOG.error("Exception while trying to create SASL client", e);
e.printStackTrace();
return null;
}
Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperSaslServer.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperSaslServer.java?rev=1522029&r1=1522028&r2=1522029&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperSaslServer.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperSaslServer.java Wed Sep 11 20:44:15 2013
@@ -21,13 +21,21 @@ package org.apache.zookeeper.server;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
import javax.security.auth.Subject;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+
import org.apache.zookeeper.Login;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ZooKeeperSaslServer {
public static final String LOGIN_CONTEXT_NAME_KEY = "zookeeper.sasl.serverconfig";
@@ -68,9 +76,40 @@ public class ZooKeeperSaslServer {
final String mech = "GSSAPI"; // TODO: should depend on zoo.cfg specified mechs, but if subject is non-null, it can be assumed to be GSSAPI.
LOG.debug("serviceHostname is '"+ serviceHostname + "'");
- LOG.debug("servicePrincipalName is "+ servicePrincipalName + "'");
- LOG.debug("SASL mechanism(mech) is "+ mech +"'");
+ LOG.debug("servicePrincipalName is '"+ servicePrincipalName + "'");
+ LOG.debug("SASL mechanism(mech) is '"+ mech +"'");
+ boolean usingNativeJgss =
+ Boolean.getBoolean("sun.security.jgss.native");
+ if (usingNativeJgss) {
+ // http://docs.oracle.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
+ // """
+ // In addition, when performing operations as a particular
+ // Subject, e.g. Subject.doAs(...) or
+ // Subject.doAsPrivileged(...), the to-be-used
+ // GSSCredential should be added to Subject's
+ // private credential set. Otherwise, the GSS operations
+ // will fail since no credential is found.
+ // """
+ try {
+ GSSManager manager = GSSManager.getInstance();
+ Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
+ GSSName gssName = manager.createName(
+ servicePrincipalName + "@" + serviceHostname,
+ GSSName.NT_HOSTBASED_SERVICE);
+ GSSCredential cred = manager.createCredential(gssName,
+ GSSContext.DEFAULT_LIFETIME,
+ krb5Mechanism,
+ GSSCredential.ACCEPT_ONLY);
+ subject.getPrivateCredentials().add(cred);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Added private credential to subject: " + cred);
+ }
+ } catch (GSSException ex) {
+ LOG.warn("Cannot add private credential to subject; " +
+ "clients authentication may fail", ex);
+ }
+ }
try {
return Subject.doAs(subject,new PrivilegedExceptionAction<SaslServer>() {
public SaslServer run() {
@@ -94,8 +133,8 @@ public class ZooKeeperSaslServer {
e.printStackTrace();
}
}
- catch (Exception e) {
- LOG.error("server principal name/hostname determination error: " + e);
+ catch (IndexOutOfBoundsException e) {
+ LOG.error("server principal name/hostname determination error: ", e);
}
}
else {
@@ -106,7 +145,7 @@ public class ZooKeeperSaslServer {
return saslServer;
}
catch (SaslException e) {
- LOG.error("Zookeeper Quorum member failed to create a SaslServer to interact with a client during session initiation: " + e);
+ LOG.error("Zookeeper Quorum member failed to create a SaslServer to interact with a client during session initiation", e);
}
}
}