Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

indention fixed

  • Loading branch information...
commit c75b0c95289abfe2844095dd21777faf5fc3a91f 1 parent 43bd28b
afeng authored
190 src/jvm/backtype/storm/security/auth/AnonymousAuthenticationProvider.java
View
@@ -2,114 +2,140 @@
import java.io.IOException;
import java.util.Map;
-
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslClientFactory;
import javax.security.sasl.SaslServerFactory;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
-
import com.google.common.annotations.VisibleForTesting;
public class AnonymousAuthenticationProvider extends java.security.Provider {
- public AnonymousAuthenticationProvider() {
- super("ThriftSaslAnonymous", 1.0, "Thrift Anonymous SASL provider");
- put("SaslClientFactory.ANONYMOUS", SaslAnonymousFactory.class.getName());
- put("SaslServerFactory.ANONYMOUS", SaslAnonymousFactory.class.getName());
- }
-
- public static class SaslAnonymousFactory implements SaslClientFactory, SaslServerFactory {
-
- @Override
- public SaslClient createSaslClient(
- String[] mechanisms, String authorizationId, String protocol,
- String serverName, Map<String,?> props, CallbackHandler cbh)
- {
- for (String mech : mechanisms) {
- if ("ANONYMOUS".equals(mech)) {
- return new AnonymousClient(authorizationId);
- }
- }
- return null;
+ public AnonymousAuthenticationProvider() {
+ super("ThriftSaslAnonymous", 1.0, "Thrift Anonymous SASL provider");
+ put("SaslClientFactory.ANONYMOUS", SaslAnonymousFactory.class.getName());
+ put("SaslServerFactory.ANONYMOUS", SaslAnonymousFactory.class.getName());
+ }
+
+ public static class SaslAnonymousFactory implements SaslClientFactory, SaslServerFactory {
+ @Override
+ public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol,
+ String serverName, Map<String,?> props, CallbackHandler cbh)
+ {
+ for (String mech : mechanisms) {
+ if ("ANONYMOUS".equals(mech)) {
+ return new AnonymousClient(authorizationId);
}
+ }
+ return null;
+ }
- @Override
- public SaslServer createSaslServer(
- String mechanism, String protocol, String serverName, Map<String,?> props, CallbackHandler cbh)
- {
- if ("ANONYMOUS".equals(mechanism)) {
- return new AnonymousServer();
- }
- return null;
- }
- public String[] getMechanismNames(Map<String, ?> props) {
- return new String[] { "ANONYMOUS" };
- }
+ @Override
+ public SaslServer createSaslServer(String mechanism, String protocol,
+ String serverName, Map<String,?> props, CallbackHandler cbh)
+ {
+ if ("ANONYMOUS".equals(mechanism)) {
+ return new AnonymousServer();
+ }
+ return null;
+ }
+ public String[] getMechanismNames(Map<String, ?> props) {
+ return new String[] { "ANONYMOUS" };
}
+ }
}
class AnonymousClient implements SaslClient {
- @VisibleForTesting
- final String username;
- private boolean hasProvidedInitialResponse;
-
- public AnonymousClient(String username) {
- if (username == null) {
- this.username = "anonymous";
- } else {
- this.username = username;
- }
+ @VisibleForTesting
+ final String username;
+ private boolean hasProvidedInitialResponse;
+
+ public AnonymousClient(String username) {
+ if (username == null) {
+ this.username = "anonymous";
+ } else {
+ this.username = username;
}
+ }
- public String getMechanismName() { return "ANONYMOUS"; }
- public boolean hasInitialResponse() { return true; }
- public byte[] evaluateChallenge(byte[] challenge) throws SaslException {
- if (hasProvidedInitialResponse) {
- throw new SaslException("Already complete!");
- }
+ public String getMechanismName() {
+ return "ANONYMOUS";
+ }
- try {
- hasProvidedInitialResponse = true;
- return username.getBytes("UTF-8");
- } catch (IOException e) {
- throw new SaslException(e.toString());
- }
- }
- public boolean isComplete() { return hasProvidedInitialResponse; }
- public byte[] unwrap(byte[] incoming, int offset, int len) {
- throw new UnsupportedOperationException();
+ public boolean hasInitialResponse() {
+ return true;
+ }
+
+ public byte[] evaluateChallenge(byte[] challenge) throws SaslException {
+ if (hasProvidedInitialResponse) {
+ throw new SaslException("Already complete!");
}
- public byte[] wrap(byte[] outgoing, int offset, int len) {
- throw new UnsupportedOperationException();
+
+ try {
+ hasProvidedInitialResponse = true;
+ return username.getBytes("UTF-8");
+ } catch (IOException e) {
+ throw new SaslException(e.toString());
}
- public Object getNegotiatedProperty(String propName) { return null; }
- public void dispose() {}
+ }
+
+ public boolean isComplete() {
+ return hasProvidedInitialResponse;
+ }
+
+ public byte[] unwrap(byte[] incoming, int offset, int len) {
+ throw new UnsupportedOperationException();
+ }
+
+ public byte[] wrap(byte[] outgoing, int offset, int len) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getNegotiatedProperty(String propName) {
+ return null;
+ }
+
+ public void dispose() {}
}
class AnonymousServer implements SaslServer {
- private String user;
- public String getMechanismName() { return "ANONYMOUS"; }
- public byte[] evaluateResponse(byte[] response) throws SaslException {
- try {
- this.user = new String(response, "UTF-8");
- } catch (IOException e) {
- throw new SaslException(e.toString());
- }
- return null;
- }
- public boolean isComplete() { return user != null; }
- public String getAuthorizationID() { return user; }
- public byte[] unwrap(byte[] incoming, int offset, int len) {
- throw new UnsupportedOperationException();
- }
- public byte[] wrap(byte[] outgoing, int offset, int len) {
- throw new UnsupportedOperationException();
+ private String user;
+
+ public String getMechanismName() {
+ return "ANONYMOUS";
+ }
+
+ public byte[] evaluateResponse(byte[] response) throws SaslException {
+ try {
+ this.user = new String(response, "UTF-8");
+ } catch (IOException e) {
+ throw new SaslException(e.toString());
}
- public Object getNegotiatedProperty(String propName) { return null; }
- public void dispose() {}
+ return null;
+ }
+
+ public boolean isComplete() {
+ return user != null;
+ }
+
+ public String getAuthorizationID() {
+ return user;
+ }
+
+ public byte[] unwrap(byte[] incoming, int offset, int len) {
+ throw new UnsupportedOperationException();
+ }
+
+ public byte[] wrap(byte[] outgoing, int offset, int len) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getNegotiatedProperty(String propName) {
+ return null;
+ }
+ public void dispose() {}
}
48 src/jvm/backtype/storm/security/auth/AuthUtils.java
View
@@ -2,38 +2,34 @@
import javax.security.auth.login.Configuration;
import javax.security.auth.login.AppConfigurationEntry;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-
import java.io.IOException;
public class AuthUtils {
- public static String LoginContextServer = "StormServer";
- public static String LoginContextClient = "StormClient";
-
- static public final String DIGEST = "DIGEST-MD5";
- static public final String ANONYMOUS = "ANONYMOUS";
- static public final String KERBEROS = "GSSAPI";
- static public final String SERVICE = "storm_thrift_server";
-
- private static final Logger LOG = LoggerFactory.getLogger(AuthUtils.class);
-
- public static String get(Configuration configuration, String section, String key) throws IOException {
- AppConfigurationEntry configurationEntries[] = configuration.getAppConfigurationEntry(section);
- if (configurationEntries == null) {
- String errorMessage = "Could not find a '"+ section + "' entry in this configuration.";
- LOG.error(errorMessage);
- throw new IOException(errorMessage);
- }
+ public static String LoginContextServer = "StormServer";
+ public static String LoginContextClient = "StormClient";
+ public static final String DIGEST = "DIGEST-MD5";
+ public static final String ANONYMOUS = "ANONYMOUS";
+ public static final String KERBEROS = "GSSAPI";
+ public static final String SERVICE = "storm_thrift_server";
+ private static final Logger LOG = LoggerFactory.getLogger(AuthUtils.class);
+
+
+ public static String get(Configuration configuration, String section, String key) throws IOException {
+ AppConfigurationEntry configurationEntries[] = configuration.getAppConfigurationEntry(section);
+ if (configurationEntries == null) {
+ String errorMessage = "Could not find a '"+ section + "' entry in this configuration.";
+ LOG.error(errorMessage);
+ throw new IOException(errorMessage);
+ }
- for(AppConfigurationEntry entry: configurationEntries) {
- Object val = entry.getOptions().get(key);
- if (val != null)
- return (String)val;
- }
- return null;
+ for(AppConfigurationEntry entry: configurationEntries) {
+ Object val = entry.getOptions().get(key);
+ if (val != null)
+ return (String)val;
}
+ return null;
+ }
}
43 src/jvm/backtype/storm/security/auth/DenyAuthorizer.java
View
@@ -1,7 +1,6 @@
package backtype.storm.security.auth;
import backtype.storm.Config;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -9,27 +8,25 @@
* An authorization implementation that denies everything, for testing purposes
*/
public class DenyAuthorizer implements IAuthorization {
- private static final Logger LOG =
- LoggerFactory.getLogger(DenyAuthorizer.class);
+ private static final Logger LOG = LoggerFactory.getLogger(DenyAuthorizer.class);
- /**
- * permit() method is invoked for each incoming Thrift request
- * @param contrext request context includes info about
- * (1) remote address/subject,
- * (2) operation
- * (3) configuration of targeted topology
- * @return true if the request is authorized, false if reject
- */
- public boolean permit(ReqContext context) {
- LOG.info("Access "
- + " from: " +
- (context.remoteAddress() == null
- ? "null" : context.remoteAddress().toString())
- + " principal:"+ (context.principal() == null
- ? "null" : context.principal())
- +" op:"+context.operation()
- + " topoology:"+context.topologyConf().get(Config.TOPOLOGY_NAME)
- );
- return false;
- }
+ /**
+ * permit() method is invoked for each incoming Thrift request
+ * @param contrext request context includes info about
+ * (1) remote address/subject,
+ * (2) operation
+ * (3) configuration of targeted topology
+ * @return true if the request is authorized, false if reject
+ */
+ public boolean permit(ReqContext context) {
+ LOG.info("Access "
+ + " from: " +
+ (context.remoteAddress() == null
+ ? "null" : context.remoteAddress().toString())
+ + " principal:"+ (context.principal() == null
+ ? "null" : context.principal())
+ +" op:"+context.operation()
+ + " topoology:"+context.topologyConf().get(Config.TOPOLOGY_NAME));
+ return false;
+ }
}
18 src/jvm/backtype/storm/security/auth/IAuthorization.java
View
@@ -11,13 +11,13 @@
* nimbus.authorization.classname: backtype.storm.security.auth.DefaultAuthorizer
*/
public interface IAuthorization {
- /**
- * permit() method is invoked for each incoming Thrift request.
- * @param contrext request context includes info about
- * (1) remote address/subject,
- * (2) operation
- * (3) configuration of targeted topology
- * @return true if the request is authorized, false if reject
- */
- public boolean permit(ReqContext context);
+ /**
+ * permit() method is invoked for each incoming Thrift request.
+ * @param contrext request context includes info about
+ * (1) remote address/subject,
+ * (2) operation
+ * (3) configuration of targeted topology
+ * @return true if the request is authorized, false if reject
+ */
+ public boolean permit(ReqContext context);
}
39 src/jvm/backtype/storm/security/auth/NoopAuthorizer.java
View
@@ -1,7 +1,6 @@
package backtype.storm.security.auth;
import backtype.storm.Config;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -9,24 +8,24 @@
* A no-op authorization implementation that illustrate info available for authorization decisions.
*/
public class NoopAuthorizer implements IAuthorization {
- private static final Logger LOG = LoggerFactory.getLogger(NoopAuthorizer.class);
+ private static final Logger LOG = LoggerFactory.getLogger(NoopAuthorizer.class);
- /**
- * permit() method is invoked for each incoming Thrift request
- * @param contrext request context includes info about
- * (1) remote address/subject,
- * (2) operation
- * (3) configuration of targeted topology
- * @return true if the request is authorized, false if reject
- */
- public boolean permit(ReqContext context) {
- LOG.info("Access "
- + " from: " + context.remoteAddress() == null
- ? "null" : context.remoteAddress().toString()
- + " principal:"+context.principal() == null
- ? "null" : context.principal()
- +" op:"+context.operation()
- + " topoology:"+ context.topologyConf().get(Config.TOPOLOGY_NAME));
- return true;
- }
+ /**
+ * permit() method is invoked for each incoming Thrift request
+ * @param contrext request context includes info about
+ * (1) remote address/subject,
+ * (2) operation
+ * (3) configuration of targeted topology
+ * @return true if the request is authorized, false if reject
+ */
+ public boolean permit(ReqContext context) {
+ LOG.info("Access "
+ + " from: " + context.remoteAddress() == null
+ ? "null" : context.remoteAddress().toString()
+ + " principal:"+context.principal() == null
+ ? "null" : context.principal()
+ +" op:"+context.operation()
+ + " topoology:"+ context.topologyConf().get(Config.TOPOLOGY_NAME));
+ return true;
+ }
}
48 src/jvm/backtype/storm/security/auth/ReqContext.java
View
@@ -1,56 +1,52 @@
package backtype.storm.security.auth;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.net.InetAddress;
import com.google.common.annotations.VisibleForTesting;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Principal;
import javax.security.auth.Subject;
-
import backtype.storm.scheduler.TopologyDetails;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.net.InetAddress;
-
/**
* context request context includes info about
- * (1) remote address/subject,
+ * (1) remote address/subject,
* (2) operation
* (3) configuration of targeted topology
*/
public class ReqContext {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
-
public enum OperationType { SUBMIT_TOPOLOGY, KILL_TOPOLOGY, REBALANCE_TOPOLOGY, ACTIVATE_TOPOLOGY, DEACTIVATE_TOPOLOGY };
-
private Subject _subject;
private InetAddress _remoteAddr;
private Integer _reqID;
private Map _storm_conf;
- private OperationType _operation;
+ private OperationType _operation;
/**
* Get a request context associated with current thread
* @return
*/
public static ReqContext context() {
- return ctxt.get();
- }
+ return ctxt.get();
+ }
//each thread will have its own request context
private static final ThreadLocal < ReqContext > ctxt =
new ThreadLocal < ReqContext > () {
- @Override protected ReqContext initialValue() {
- return new ReqContext(AccessController.getContext());
+ @Override protected ReqContext initialValue() {
+ return new ReqContext(AccessController.getContext());
}
};
//private constructor
- @VisibleForTesting
+ @VisibleForTesting
ReqContext(AccessControlContext acl_ctxt) {
- _subject = Subject.getSubject(acl_ctxt);
- _reqID = uniqueId.incrementAndGet();
+ _subject = Subject.getSubject(acl_ctxt);
+ _reqID = uniqueId.incrementAndGet();
}
/**
@@ -72,23 +68,21 @@ public void setSubject(Subject subject) {
}
/**
- * Client subject associated with this request context
- * @return
+ * Retrieve client subject associated with this request context
*/
public Subject subject() {
- return _subject;
- }
+ return _subject;
+ }
/**
* The primary principal associated current subject
- * @return
*/
public Principal principal() {
- if (_subject == null) return null;
- Set<Principal> princs = _subject.getPrincipals();
- if (princs.size()==0) return null;
- return (Principal) (princs.toArray()[0]);
- }
+ if (_subject == null) return null;
+ Set<Principal> princs = _subject.getPrincipals();
+ if (princs.size()==0) return null;
+ return (Principal) (princs.toArray()[0]);
+ }
/**
* Topology that this request is against
162 src/jvm/backtype/storm/security/auth/SaslClientCallbackHandler.java
View
@@ -2,7 +2,6 @@
import java.io.IOException;
import java.util.Map;
-
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
@@ -12,7 +11,6 @@
import javax.security.sasl.RealmCallback;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,90 +18,90 @@
* SASL client side callback handler.
*/
public class SaslClientCallbackHandler implements CallbackHandler {
- private static final String USERNAME = "username";
- private static final String PASSWORD = "password";
- private static final Logger LOG = LoggerFactory.getLogger(SaslClientCallbackHandler.class);
- private String _username = null;
- private String _password = null;
+ private static final String USERNAME = "username";
+ private static final String PASSWORD = "password";
+ private static final Logger LOG = LoggerFactory.getLogger(SaslClientCallbackHandler.class);
+ private String _username = null;
+ private String _password = null;
- /**
- * Constructor based on a JAAS configuration
- *
- * For digest, you should have a pair of user name and password defined in this figgure.
- *
- * @param configuration
- * @throws IOException
- */
- public SaslClientCallbackHandler(Configuration configuration) throws IOException {
- if (configuration == null) return;
- AppConfigurationEntry configurationEntries[] = configuration.getAppConfigurationEntry(AuthUtils.LoginContextClient);
- if (configurationEntries == null) {
- String errorMessage = "Could not find a '"+AuthUtils.LoginContextClient
- + "' entry in this configuration: Client cannot start.";
- LOG.error(errorMessage);
- throw new IOException(errorMessage);
- }
+ /**
+ * Constructor based on a JAAS configuration
+ *
+ * For digest, you should have a pair of user name and password defined in this figgure.
+ *
+ * @param configuration
+ * @throws IOException
+ */
+ public SaslClientCallbackHandler(Configuration configuration) throws IOException {
+ if (configuration == null) return;
+ AppConfigurationEntry configurationEntries[] = configuration.getAppConfigurationEntry(AuthUtils.LoginContextClient);
+ if (configurationEntries == null) {
+ String errorMessage = "Could not find a '"+AuthUtils.LoginContextClient
+ + "' entry in this configuration: Client cannot start.";
+ LOG.error(errorMessage);
+ throw new IOException(errorMessage);
+ }
- for(AppConfigurationEntry entry: configurationEntries) {
- if (entry.getOptions().get(USERNAME) != null) {
- _username = (String)entry.getOptions().get(USERNAME);
- }
- if (entry.getOptions().get(PASSWORD) != null) {
- _password = (String)entry.getOptions().get(PASSWORD);
- }
- }
+ for(AppConfigurationEntry entry: configurationEntries) {
+ if (entry.getOptions().get(USERNAME) != null) {
+ _username = (String)entry.getOptions().get(USERNAME);
+ }
+ if (entry.getOptions().get(PASSWORD) != null) {
+ _password = (String)entry.getOptions().get(PASSWORD);
+ }
}
+ }
- /**
- * This method is invoked by SASL for authentication challenges
- * @param callbacks a collection of challenge callbacks
- */
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
- for (Callback c : callbacks) {
- if (c instanceof NameCallback) {
- LOG.debug("name callback");
- NameCallback nc = (NameCallback) c;
- nc.setName(_username);
- } else if (c instanceof PasswordCallback) {
- LOG.debug("pwd callback");
- PasswordCallback pc = (PasswordCallback)c;
- if (_password != null) {
- pc.setPassword(_password.toCharArray());
- } else {
- LOG.warn("Could not login: the client is being asked for a password, but the " +
- " client code does not currently support obtaining a password from the user." +
- " Make sure that the client is configured to use a ticket cache (using" +
- " the JAAS configuration setting 'useTicketCache=true)' and restart the client. If" +
- " you still get this message after that, the TGT in the ticket cache has expired and must" +
- " be manually refreshed. To do so, first determine if you are using a password or a" +
- " keytab. If the former, run kinit in a Unix shell in the environment of the user who" +
- " is running this client using the command" +
- " 'kinit <princ>' (where <princ> is the name of the client's Kerberos principal)." +
- " If the latter, do" +
- " 'kinit -k -t <keytab> <princ>' (where <princ> is the name of the Kerberos principal, and" +
- " <keytab> is the location of the keytab file). After manually refreshing your cache," +
- " restart this client. If you continue to see this message after manually refreshing" +
- " your cache, ensure that your KDC host's clock is in sync with this host's clock.");
- }
- } else if (c instanceof AuthorizeCallback) {
- LOG.debug("authorization callback");
- AuthorizeCallback ac = (AuthorizeCallback) c;
- String authid = ac.getAuthenticationID();
- String authzid = ac.getAuthorizationID();
- if (authid.equals(authzid)) {
- ac.setAuthorized(true);
- } else {
- ac.setAuthorized(false);
- }
- if (ac.isAuthorized()) {
- ac.setAuthorizedID(authzid);
- }
- } else if (c instanceof RealmCallback) {
- RealmCallback rc = (RealmCallback) c;
- ((RealmCallback) c).setText(rc.getDefaultText());
- } else {
- throw new UnsupportedCallbackException(c);
- }
+ /**
+ * This method is invoked by SASL for authentication challenges
+ * @param callbacks a collection of challenge callbacks
+ */
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (Callback c : callbacks) {
+ if (c instanceof NameCallback) {
+ LOG.debug("name callback");
+ NameCallback nc = (NameCallback) c;
+ nc.setName(_username);
+ } else if (c instanceof PasswordCallback) {
+ LOG.debug("pwd callback");
+ PasswordCallback pc = (PasswordCallback)c;
+ if (_password != null) {
+ pc.setPassword(_password.toCharArray());
+ } else {
+ LOG.warn("Could not login: the client is being asked for a password, but the " +
+ " client code does not currently support obtaining a password from the user." +
+ " Make sure that the client is configured to use a ticket cache (using" +
+ " the JAAS configuration setting 'useTicketCache=true)' and restart the client. If" +
+ " you still get this message after that, the TGT in the ticket cache has expired and must" +
+ " be manually refreshed. To do so, first determine if you are using a password or a" +
+ " keytab. If the former, run kinit in a Unix shell in the environment of the user who" +
+ " is running this client using the command" +
+ " 'kinit <princ>' (where <princ> is the name of the client's Kerberos principal)." +
+ " If the latter, do" +
+ " 'kinit -k -t <keytab> <princ>' (where <princ> is the name of the Kerberos principal, and" +
+ " <keytab> is the location of the keytab file). After manually refreshing your cache," +
+ " restart this client. If you continue to see this message after manually refreshing" +
+ " your cache, ensure that your KDC host's clock is in sync with this host's clock.");
+ }
+ } else if (c instanceof AuthorizeCallback) {
+ LOG.debug("authorization callback");
+ AuthorizeCallback ac = (AuthorizeCallback) c;
+ String authid = ac.getAuthenticationID();
+ String authzid = ac.getAuthorizationID();
+ if (authid.equals(authzid)) {
+ ac.setAuthorized(true);
+ } else {
+ ac.setAuthorized(false);
+ }
+ if (ac.isAuthorized()) {
+ ac.setAuthorizedID(authzid);
}
+ } else if (c instanceof RealmCallback) {
+ RealmCallback rc = (RealmCallback) c;
+ ((RealmCallback) c).setText(rc.getDefaultText());
+ } else {
+ throw new UnsupportedCallbackException(c);
+ }
}
+ }
}
190 src/jvm/backtype/storm/security/auth/SaslServerCallbackHandler.java
View
@@ -3,7 +3,6 @@
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.security.auth.callback.Callback;
@@ -15,114 +14,113 @@
import javax.security.auth.login.Configuration;
import javax.security.sasl.AuthorizeCallback;
import javax.security.sasl.RealmCallback;
-
import org.apache.zookeeper.server.auth.KerberosName;
/**
* SASL server side collback handler
*/
public class SaslServerCallbackHandler implements CallbackHandler {
- private static final String USER_PREFIX = "user_";
- private static final Logger LOG = LoggerFactory.getLogger(SaslServerCallbackHandler.class);
- private static final String SYSPROP_SUPER_PASSWORD = "storm.SASLAuthenticationProvider.superPassword";
- private static final String SYSPROP_REMOVE_HOST = "storm.kerberos.removeHostFromPrincipal";
- private static final String SYSPROP_REMOVE_REALM = "storm.kerberos.removeRealmFromPrincipal";
-
- private String userName;
- private final Map<String,String> credentials = new HashMap<String,String>();
-
- public SaslServerCallbackHandler(Configuration configuration) throws IOException {
- if (configuration==null) return;
-
- AppConfigurationEntry configurationEntries[] = configuration.getAppConfigurationEntry(AuthUtils.LoginContextServer);
- if (configurationEntries == null) {
- String errorMessage = "Could not find a '"+AuthUtils.LoginContextServer+"' entry in this configuration: Server cannot start.";
- LOG.error(errorMessage);
- throw new IOException(errorMessage);
- }
- credentials.clear();
- for(AppConfigurationEntry entry: configurationEntries) {
- Map<String,?> options = entry.getOptions();
- // Populate DIGEST-MD5 user -> password map with JAAS configuration entries from the "Server" section.
- // Usernames are distinguished from other options by prefixing the username with a "user_" prefix.
- for(Map.Entry<String, ?> pair : options.entrySet()) {
- String key = pair.getKey();
- if (key.startsWith(USER_PREFIX)) {
- String userName = key.substring(USER_PREFIX.length());
- credentials.put(userName,(String)pair.getValue());
- }
- }
- }
+ private static final String USER_PREFIX = "user_";
+ private static final Logger LOG = LoggerFactory.getLogger(SaslServerCallbackHandler.class);
+ private static final String SYSPROP_SUPER_PASSWORD = "storm.SASLAuthenticationProvider.superPassword";
+ private static final String SYSPROP_REMOVE_HOST = "storm.kerberos.removeHostFromPrincipal";
+ private static final String SYSPROP_REMOVE_REALM = "storm.kerberos.removeRealmFromPrincipal";
+
+ private String userName;
+ private final Map<String,String> credentials = new HashMap<String,String>();
+
+ public SaslServerCallbackHandler(Configuration configuration) throws IOException {
+ if (configuration==null) return;
+
+ AppConfigurationEntry configurationEntries[] = configuration.getAppConfigurationEntry(AuthUtils.LoginContextServer);
+ if (configurationEntries == null) {
+ String errorMessage = "Could not find a '"+AuthUtils.LoginContextServer+"' entry in this configuration: Server cannot start.";
+ LOG.error(errorMessage);
+ throw new IOException(errorMessage);
}
-
- public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
- for (Callback callback : callbacks) {
- if (callback instanceof NameCallback) {
- handleNameCallback((NameCallback) callback);
- } else if (callback instanceof PasswordCallback) {
- handlePasswordCallback((PasswordCallback) callback);
- } else if (callback instanceof RealmCallback) {
- handleRealmCallback((RealmCallback) callback);
- } else if (callback instanceof AuthorizeCallback) {
- handleAuthorizeCallback((AuthorizeCallback) callback);
- }
+ credentials.clear();
+ for(AppConfigurationEntry entry: configurationEntries) {
+ Map<String,?> options = entry.getOptions();
+ // Populate DIGEST-MD5 user -> password map with JAAS configuration entries from the "Server" section.
+ // Usernames are distinguished from other options by prefixing the username with a "user_" prefix.
+ for(Map.Entry<String, ?> pair : options.entrySet()) {
+ String key = pair.getKey();
+ if (key.startsWith(USER_PREFIX)) {
+ String userName = key.substring(USER_PREFIX.length());
+ credentials.put(userName,(String)pair.getValue());
}
+ }
}
-
- private void handleNameCallback(NameCallback nc) {
- userName = nc.getDefaultName();
- nc.setName(nc.getDefaultName());
+ }
+
+ public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
+ for (Callback callback : callbacks) {
+ if (callback instanceof NameCallback) {
+ handleNameCallback((NameCallback) callback);
+ } else if (callback instanceof PasswordCallback) {
+ handlePasswordCallback((PasswordCallback) callback);
+ } else if (callback instanceof RealmCallback) {
+ handleRealmCallback((RealmCallback) callback);
+ } else if (callback instanceof AuthorizeCallback) {
+ handleAuthorizeCallback((AuthorizeCallback) callback);
+ }
}
-
- private void handlePasswordCallback(PasswordCallback pc) {
- if ("super".equals(this.userName) && System.getProperty(SYSPROP_SUPER_PASSWORD) != null) {
- // superuser: use Java system property for password, if available.
- pc.setPassword(System.getProperty(SYSPROP_SUPER_PASSWORD).toCharArray());
- } else if (credentials.containsKey(userName) ) {
- pc.setPassword(credentials.get(userName).toCharArray());
- } else {
- LOG.warn("No password found for user: " + userName);
- }
+ }
+
+ private void handleNameCallback(NameCallback nc) {
+ userName = nc.getDefaultName();
+ nc.setName(nc.getDefaultName());
+ }
+
+ private void handlePasswordCallback(PasswordCallback pc) {
+ if ("super".equals(this.userName) && System.getProperty(SYSPROP_SUPER_PASSWORD) != null) {
+ // superuser: use Java system property for password, if available.
+ pc.setPassword(System.getProperty(SYSPROP_SUPER_PASSWORD).toCharArray());
+ } else if (credentials.containsKey(userName) ) {
+ pc.setPassword(credentials.get(userName).toCharArray());
+ } else {
+ LOG.warn("No password found for user: " + userName);
}
-
- private void handleRealmCallback(RealmCallback rc) {
- LOG.debug("handleRealmCallback: "+ rc.getDefaultText());
- rc.setText(rc.getDefaultText());
+ }
+
+ private void handleRealmCallback(RealmCallback rc) {
+ LOG.debug("handleRealmCallback: "+ rc.getDefaultText());
+ rc.setText(rc.getDefaultText());
+ }
+
+ private void handleAuthorizeCallback(AuthorizeCallback ac) {
+ String authenticationID = ac.getAuthenticationID();
+ LOG.debug("Successfully authenticated client: authenticationID=" + authenticationID);
+ ac.setAuthorized(true);
+
+ // canonicalize authorization id according to system properties:
+ // storm.kerberos.removeRealmFromPrincipal(={true,false})
+ // storm.kerberos.removeHostFromPrincipal(={true,false})
+ KerberosName kerberosName = new KerberosName(authenticationID);
+ try {
+ StringBuilder userNameBuilder = new StringBuilder(kerberosName.getShortName());
+ if (shouldAppendHost(kerberosName)) {
+ userNameBuilder.append("/").append(kerberosName.getHostName());
+ }
+ if (shouldAppendRealm(kerberosName)) {
+ userNameBuilder.append("@").append(kerberosName.getRealm());
+ }
+ LOG.debug("Setting authorizedID: " + userNameBuilder);
+ ac.setAuthorizedID(userNameBuilder.toString());
+ } catch (IOException e) {
+ LOG.error("Failed to set name based on Kerberos authentication rules.");
}
+ }
- private void handleAuthorizeCallback(AuthorizeCallback ac) {
- String authenticationID = ac.getAuthenticationID();
- LOG.debug("Successfully authenticated client: authenticationID=" + authenticationID);
- ac.setAuthorized(true);
+ private boolean shouldAppendRealm(KerberosName kerberosName) {
+ return !isSystemPropertyTrue(SYSPROP_REMOVE_REALM) && kerberosName.getRealm() != null;
+ }
- // canonicalize authorization id according to system properties:
- // storm.kerberos.removeRealmFromPrincipal(={true,false})
- // storm.kerberos.removeHostFromPrincipal(={true,false})
- KerberosName kerberosName = new KerberosName(authenticationID);
- try {
- StringBuilder userNameBuilder = new StringBuilder(kerberosName.getShortName());
- if (shouldAppendHost(kerberosName)) {
- userNameBuilder.append("/").append(kerberosName.getHostName());
- }
- if (shouldAppendRealm(kerberosName)) {
- userNameBuilder.append("@").append(kerberosName.getRealm());
- }
- LOG.debug("Setting authorizedID: " + userNameBuilder);
- ac.setAuthorizedID(userNameBuilder.toString());
- } catch (IOException e) {
- LOG.error("Failed to set name based on Kerberos authentication rules.");
- }
- }
+ private boolean shouldAppendHost(KerberosName kerberosName) {
+ return !isSystemPropertyTrue(SYSPROP_REMOVE_HOST) && kerberosName.getHostName() != null;
+ }
- private boolean shouldAppendRealm(KerberosName kerberosName) {
- return !isSystemPropertyTrue(SYSPROP_REMOVE_REALM) && kerberosName.getRealm() != null;
- }
-
- private boolean shouldAppendHost(KerberosName kerberosName) {
- return !isSystemPropertyTrue(SYSPROP_REMOVE_HOST) && kerberosName.getHostName() != null;
- }
-
- private boolean isSystemPropertyTrue(String propertyName) {
- return "true".equals(System.getProperty(propertyName));
- }
+ private boolean isSystemPropertyTrue(String propertyName) {
+ return "true".equals(System.getProperty(propertyName));
+ }
}
11 src/jvm/backtype/storm/security/auth/ThriftClient.java
View
@@ -1,19 +1,15 @@
package backtype.storm.security.auth;
-import backtype.storm.utils.Utils;
-
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-
import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.login.Configuration;
import javax.security.sasl.Sasl;
-
import org.apache.thrift7.protocol.TBinaryProtocol;
import org.apache.thrift7.protocol.TProtocol;
import org.apache.thrift7.transport.TSocket;
@@ -21,10 +17,9 @@
import org.apache.thrift7.transport.TSaslClientTransport;
import org.apache.zookeeper.Login;
import org.apache.zookeeper.server.auth.KerberosName;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
+import backtype.storm.utils.Utils;
public class ThriftClient {
private static final Logger LOG = LoggerFactory.getLogger(ThriftClient.class);
@@ -118,14 +113,14 @@ public Void run() {
_transport.open();
}
catch (Exception e) {
- LOG.error("Nimbus client failed to open SaslClientTransport to interact with a server during session initiation: " + e);
+ LOG.error("Nimbus client failed to open SaslClientTransport to interact with a server during session initiation: " + e, e);
e.printStackTrace();
}
return null;
}
});
} catch (PrivilegedActionException e) {
- LOG.error("Nimbus client experienced a PrivilegedActionException exception while creating a TSaslClientTransport using a JAAS principal context:" + e);
+ LOG.error("Nimbus client experienced a PrivilegedActionException exception while creating a TSaslClientTransport using a JAAS principal context:" + e, e);
e.printStackTrace();
}
}
12 src/jvm/backtype/storm/security/auth/ThriftServer.java
View
@@ -3,14 +3,12 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslServer;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.login.Configuration;
import javax.security.auth.Subject;
-
import java.io.IOException;
import java.net.Socket;
import java.security.Principal;
@@ -18,7 +16,6 @@
import java.security.PrivilegedActionException;
import org.apache.zookeeper.Login;
import org.apache.zookeeper.server.auth.KerberosName;
-
import org.apache.thrift7.TException;
import org.apache.thrift7.TProcessor;
import org.apache.thrift7.server.TServer;
@@ -33,8 +30,6 @@
import org.apache.thrift7.transport.TTransportFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-
import backtype.storm.security.auth.*;
import backtype.storm.utils.Utils;
@@ -128,7 +123,6 @@ public void serve() {
transportFactory(factory).
protocolFactory(new TBinaryProtocol.Factory()));
}
-
}
_server.serve();
@@ -196,7 +190,7 @@ public String getName() {
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
@@ -207,7 +201,7 @@ public boolean equals(Object o) {
}
@Override
- public int hashCode() {
+ public int hashCode() {
return name.hashCode();
}
@@ -237,7 +231,7 @@ public TUGIAssumingTransportFactory(TTransportFactory wrapped, Subject subject)
}
@Override
- public TTransport getTransport(final TTransport trans) {
+ public TTransport getTransport(final TTransport trans) {
try {
return Subject.doAs(subject,
new PrivilegedExceptionAction<TTransport>() {
Please sign in to comment.
Something went wrong with that request. Please try again.