storm-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bo...@apache.org
Subject [1/2] storm git commit: Merge branch 'storm1469' of https://github.com/kishorvpatil/incubator-storm into STORM-1469
Date Mon, 07 Mar 2016 20:30:04 GMT
Repository: storm
Updated Branches:
  refs/heads/1.x-branch 8679384f1 -> 23a539252


Merge branch 'storm1469' of https://github.com/kishorvpatil/incubator-storm into STORM-1469

STORM-1469: Adding Plain Sasl Transport Plugin


Project: http://git-wip-us.apache.org/repos/asf/storm/repo
Commit: http://git-wip-us.apache.org/repos/asf/storm/commit/a70e344a
Tree: http://git-wip-us.apache.org/repos/asf/storm/tree/a70e344a
Diff: http://git-wip-us.apache.org/repos/asf/storm/diff/a70e344a

Branch: refs/heads/1.x-branch
Commit: a70e344a3e3c7abc056bca0fa4d2d48f5d5a223f
Parents: 8679384
Author: Robert (Bobby) Evans <evans@yahoo-inc.com>
Authored: Mon Mar 7 13:58:03 2016 -0600
Committer: Robert (Bobby) Evans <evans@yahoo-inc.com>
Committed: Mon Mar 7 14:09:12 2016 -0600

----------------------------------------------------------------------
 .../auth/AbstractSaslClientCallbackHandler.java |  76 +++++++++
 .../auth/AbstractSaslServerCallbackHandler.java |  94 +++++++++++
 .../auth/digest/ClientCallbackHandler.java      |  60 +------
 .../auth/digest/ServerCallbackHandler.java      |  61 +------
 .../auth/plain/PlainClientCallbackHandler.java  |  31 ++++
 .../auth/plain/PlainSaslTransportPlugin.java    |  71 +++++++++
 .../auth/plain/PlainServerCallbackHandler.java  |  55 +++++++
 .../security/auth/plain/SaslPlainServer.java    | 158 +++++++++++++++++++
 8 files changed, 497 insertions(+), 109 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/storm/blob/a70e344a/storm-core/src/jvm/org/apache/storm/security/auth/AbstractSaslClientCallbackHandler.java
----------------------------------------------------------------------
diff --git a/storm-core/src/jvm/org/apache/storm/security/auth/AbstractSaslClientCallbackHandler.java
b/storm-core/src/jvm/org/apache/storm/security/auth/AbstractSaslClientCallbackHandler.java
new file mode 100644
index 0000000..04710ba
--- /dev/null
+++ b/storm-core/src/jvm/org/apache/storm/security/auth/AbstractSaslClientCallbackHandler.java
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.storm.security.auth;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.RealmCallback;
+import java.io.IOException;
+
+public abstract class AbstractSaslClientCallbackHandler implements CallbackHandler {
+    protected static final String USERNAME = "username";
+    protected static final String PASSWORD = "password";
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractSaslClientCallbackHandler.class);
+    protected String _username = null;
+    protected String _password = null;
+
+    /**
+     * 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("password callback");
+                PasswordCallback pc = (PasswordCallback)c;
+                if (_password != null) {
+                    pc.setPassword(_password.toCharArray());
+                }
+            } 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);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/storm/blob/a70e344a/storm-core/src/jvm/org/apache/storm/security/auth/AbstractSaslServerCallbackHandler.java
----------------------------------------------------------------------
diff --git a/storm-core/src/jvm/org/apache/storm/security/auth/AbstractSaslServerCallbackHandler.java
b/storm-core/src/jvm/org/apache/storm/security/auth/AbstractSaslServerCallbackHandler.java
new file mode 100644
index 0000000..ebbe2ea
--- /dev/null
+++ b/storm-core/src/jvm/org/apache/storm/security/auth/AbstractSaslServerCallbackHandler.java
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.storm.security.auth;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.RealmCallback;
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class AbstractSaslServerCallbackHandler implements CallbackHandler {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractSaslServerCallbackHandler.class);
+    protected final Map<String,String> credentials = new HashMap<>();
+    protected String userName;
+
+    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 handleNameCallback(NameCallback nc) {
+        LOG.debug("handleNameCallback");
+        userName = nc.getDefaultName();
+        nc.setName(nc.getDefaultName());
+    }
+
+    protected void handlePasswordCallback(PasswordCallback pc) {
+        LOG.debug("handlePasswordCallback");
+        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 handleAuthorizeCallback(AuthorizeCallback ac) {
+        String authenticationID = ac.getAuthenticationID();
+        LOG.info("Successfully authenticated client: authenticationID = {} authorizationID
= {}",
+            authenticationID, ac.getAuthorizationID());
+
+        //if authorizationId is not set, set it to authenticationId.
+        if(ac.getAuthorizationID() == null) {
+            ac.setAuthorizedID(authenticationID);
+        }
+
+        //When authNid and authZid are not equal , authNId is attempting to impersonate authZid,
We
+        //add the authNid as the real user in reqContext's subject which will be used during
authorization.
+        if(!authenticationID.equals(ac.getAuthorizationID())) {
+            LOG.info("Impersonation attempt  authenticationID = {} authorizationID = {}",
+                ac.getAuthenticationID(),  ac.getAuthorizationID());
+            ReqContext.context().setRealPrincipal(new SaslTransportPlugin.User(ac.getAuthenticationID()));
+        } else {
+            ReqContext.context().setRealPrincipal(null);
+        }
+
+        ac.setAuthorized(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/storm/blob/a70e344a/storm-core/src/jvm/org/apache/storm/security/auth/digest/ClientCallbackHandler.java
----------------------------------------------------------------------
diff --git a/storm-core/src/jvm/org/apache/storm/security/auth/digest/ClientCallbackHandler.java
b/storm-core/src/jvm/org/apache/storm/security/auth/digest/ClientCallbackHandler.java
index 013ce06..312e4ab 100644
--- a/storm-core/src/jvm/org/apache/storm/security/auth/digest/ClientCallbackHandler.java
+++ b/storm-core/src/jvm/org/apache/storm/security/auth/digest/ClientCallbackHandler.java
@@ -17,30 +17,17 @@
  */
 package org.apache.storm.security.auth.digest;
 
-import java.io.IOException;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.RealmCallback;
+import org.apache.storm.security.auth.AbstractSaslClientCallbackHandler;
+import org.apache.storm.security.auth.AuthUtils;
+
 import javax.security.auth.login.AppConfigurationEntry;
 import javax.security.auth.login.Configuration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.storm.security.auth.AuthUtils;
+import java.io.IOException;
 
 /**
  *  client side callback handler.
  */
-public class ClientCallbackHandler implements CallbackHandler {
-    private static final String USERNAME = "username";
-    private static final String PASSWORD = "password";
-    private static final Logger LOG = LoggerFactory.getLogger(ClientCallbackHandler.class);
-    private String _username = null;
-    private String _password = null;
+public class ClientCallbackHandler extends AbstractSaslClientCallbackHandler {
 
     /**
      * Constructor based on a JAAS configuration
@@ -68,41 +55,4 @@ public class ClientCallbackHandler implements CallbackHandler {
         }
     }
 
-    /**
-     * 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("password callback");
-                PasswordCallback pc = (PasswordCallback)c;
-                if (_password != null) {
-                    pc.setPassword(_password.toCharArray());
-                } 
-            } 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);
-            }
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/storm/blob/a70e344a/storm-core/src/jvm/org/apache/storm/security/auth/digest/ServerCallbackHandler.java
----------------------------------------------------------------------
diff --git a/storm-core/src/jvm/org/apache/storm/security/auth/digest/ServerCallbackHandler.java
b/storm-core/src/jvm/org/apache/storm/security/auth/digest/ServerCallbackHandler.java
index 4fe21c2..7c4414f 100644
--- a/storm-core/src/jvm/org/apache/storm/security/auth/digest/ServerCallbackHandler.java
+++ b/storm-core/src/jvm/org/apache/storm/security/auth/digest/ServerCallbackHandler.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.storm.security.auth.AbstractSaslServerCallbackHandler;
 import org.apache.storm.security.auth.ReqContext;
 import org.apache.storm.security.auth.SaslTransportPlugin;
 import org.slf4j.Logger;
@@ -41,13 +42,10 @@ import org.apache.storm.security.auth.AuthUtils;
 /**
  * SASL server side callback handler
  */
-public class ServerCallbackHandler implements CallbackHandler {
-    private static final String USER_PREFIX = "user_";
+public class ServerCallbackHandler extends AbstractSaslServerCallbackHandler {
     private static final Logger LOG = LoggerFactory.getLogger(ServerCallbackHandler.class);
-    private static final String SYSPROP_SUPER_PASSWORD = "storm.SASLAuthenticationProvider.superPassword";
-
-    private String userName;
-    private final Map<String,String> credentials = new HashMap<>();
+    private static final String USER_PREFIX = "user_";
+    public static final String SYSPROP_SUPER_PASSWORD = "storm.SASLAuthenticationProvider.superPassword";
 
     public ServerCallbackHandler(Configuration configuration) throws IOException {
         if (configuration==null) return;
@@ -72,61 +70,16 @@ public class ServerCallbackHandler implements CallbackHandler {
         }
     }
 
-    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 handleNameCallback(NameCallback nc) {
-        LOG.debug("handleNameCallback");
-        userName = nc.getDefaultName();
-        nc.setName(nc.getDefaultName());
-    }
-
-    private void handlePasswordCallback(PasswordCallback pc) {
+    @Override
+    protected void handlePasswordCallback(PasswordCallback pc) {
         LOG.debug("handlePasswordCallback");
         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);
+            super.handlePasswordCallback(pc);
         }
-    }
 
-    private void handleRealmCallback(RealmCallback rc) {
-        LOG.debug("handleRealmCallback: "+ rc.getDefaultText());
-        rc.setText(rc.getDefaultText());
     }
 
-    private void handleAuthorizeCallback(AuthorizeCallback ac) {
-        String authenticationID = ac.getAuthenticationID();
-        LOG.info("Successfully authenticated client: authenticationID = " + authenticationID
+ " authorizationID = " + ac.getAuthorizationID());
-
-        //if authorizationId is not set, set it to authenticationId.
-        if(ac.getAuthorizationID() == null) {
-            ac.setAuthorizedID(authenticationID);
-        }
-
-        //When authNid and authZid are not equal , authNId is attempting to impersonate authZid,
We
-        //add the authNid as the real user in reqContext's subject which will be used during
authorization.
-        if(!authenticationID.equals(ac.getAuthorizationID())) {
-            LOG.info("Impersonation attempt  authenticationID = " + ac.getAuthenticationID()
+ " authorizationID = " + ac.getAuthorizationID());
-            ReqContext.context().setRealPrincipal(new SaslTransportPlugin.User(ac.getAuthenticationID()));
-        } else {
-            ReqContext.context().setRealPrincipal(null);
-        }
-
-        ac.setAuthorized(true);
-    }
 }

http://git-wip-us.apache.org/repos/asf/storm/blob/a70e344a/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainClientCallbackHandler.java
----------------------------------------------------------------------
diff --git a/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainClientCallbackHandler.java
b/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainClientCallbackHandler.java
new file mode 100644
index 0000000..13340df
--- /dev/null
+++ b/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainClientCallbackHandler.java
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.storm.security.auth.plain;
+
+import org.apache.storm.security.auth.AbstractSaslClientCallbackHandler;
+
+public class PlainClientCallbackHandler extends AbstractSaslClientCallbackHandler {
+
+    /*
+     * For plain, using constants for a pair of user name and password.
+     */
+    public PlainClientCallbackHandler() {
+        _username = System.getProperty("user.name");
+        _password = PASSWORD;
+    }
+}

http://git-wip-us.apache.org/repos/asf/storm/blob/a70e344a/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainSaslTransportPlugin.java
----------------------------------------------------------------------
diff --git a/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainSaslTransportPlugin.java
b/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainSaslTransportPlugin.java
new file mode 100644
index 0000000..eaef91a
--- /dev/null
+++ b/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainSaslTransportPlugin.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.storm.security.auth.plain;
+
+import org.apache.storm.security.auth.AuthUtils;
+import org.apache.storm.security.auth.SaslTransportPlugin;
+import org.apache.thrift.transport.TSaslClientTransport;
+import org.apache.thrift.transport.TSaslServerTransport;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+import org.apache.thrift.transport.TTransportFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.callback.CallbackHandler;
+import java.io.IOException;
+import java.security.Security;
+
+public class PlainSaslTransportPlugin extends SaslTransportPlugin {
+    public static final String PLAIN = "PLAIN";
+    private static final Logger LOG = LoggerFactory.getLogger(PlainSaslTransportPlugin.class);
+
+    @Override
+    protected TTransportFactory getServerTransportFactory() throws IOException {
+        //create an authentication callback handler
+        CallbackHandler serverCallbackHandler = new PlainServerCallbackHandler();
+        if (Security.getProvider(SaslPlainServer.SecurityProvider.SASL_PLAIN_SERVER) == null)
{
+            Security.addProvider(new SaslPlainServer.SecurityProvider());
+        }
+        //create a transport factory that will invoke our auth callback for digest
+        TSaslServerTransport.Factory factory = new TSaslServerTransport.Factory();
+        factory.addServerDefinition(PLAIN, AuthUtils.SERVICE, "localhost", null, serverCallbackHandler);
+
+        LOG.info("SASL PLAIN transport factory will be used");
+        return factory;
+    }
+
+    @Override
+    public TTransport connect(TTransport transport, String serverHost, String asUser) throws
IOException, TTransportException {
+        PlainClientCallbackHandler clientCallbackHandler = new PlainClientCallbackHandler();
+        TSaslClientTransport wrapperTransport = new TSaslClientTransport(PLAIN,
+            null,
+            AuthUtils.SERVICE,
+            serverHost,
+            null,
+            clientCallbackHandler,
+            transport);
+
+        wrapperTransport.open();
+        LOG.debug("SASL PLAIN client transport has been established");
+
+        return wrapperTransport;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/storm/blob/a70e344a/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainServerCallbackHandler.java
----------------------------------------------------------------------
diff --git a/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainServerCallbackHandler.java
b/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainServerCallbackHandler.java
new file mode 100644
index 0000000..c646fc9
--- /dev/null
+++ b/storm-core/src/jvm/org/apache/storm/security/auth/plain/PlainServerCallbackHandler.java
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.storm.security.auth.plain;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.storm.security.auth.AbstractSaslServerCallbackHandler;
+import org.apache.storm.security.auth.ReqContext;
+import org.apache.storm.security.auth.SaslTransportPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.RealmCallback;
+
+/**
+ * SASL server side callback handler
+ */
+public class PlainServerCallbackHandler extends AbstractSaslServerCallbackHandler {
+    private static final Logger LOG = LoggerFactory.getLogger(PlainServerCallbackHandler.class);
+    public static final String PASSWORD = "password";
+
+    public PlainServerCallbackHandler() throws IOException {
+        userName=null;
+    }
+
+    protected void handlePasswordCallback(PasswordCallback pc) {
+        LOG.debug("handlePasswordCallback");
+        pc.setPassword(PASSWORD.toCharArray());
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/storm/blob/a70e344a/storm-core/src/jvm/org/apache/storm/security/auth/plain/SaslPlainServer.java
----------------------------------------------------------------------
diff --git a/storm-core/src/jvm/org/apache/storm/security/auth/plain/SaslPlainServer.java
b/storm-core/src/jvm/org/apache/storm/security/auth/plain/SaslPlainServer.java
new file mode 100644
index 0000000..c84ce77
--- /dev/null
+++ b/storm-core/src/jvm/org/apache/storm/security/auth/plain/SaslPlainServer.java
@@ -0,0 +1,158 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.storm.security.auth.plain;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslServerFactory;
+import java.security.Provider;
+import java.util.Map;
+
+public class SaslPlainServer implements SaslServer {
+  @SuppressWarnings("serial")
+  public static class SecurityProvider extends Provider {
+
+    public static final String SASL_PLAIN_SERVER = "SaslPlainServer";
+
+    public SecurityProvider() {
+      super(SASL_PLAIN_SERVER, 1.0, "SASL PLAIN Authentication Server");
+      put("SaslServerFactory.PLAIN",
+          SaslPlainServerFactory.class.getName());
+    }
+  }
+
+  public static class SaslPlainServerFactory implements SaslServerFactory {
+    @Override
+    public SaslServer createSaslServer(String mechanism, String protocol,
+        String serverName, Map<String,?> props, CallbackHandler cbh)
+            throws SaslException {
+      return "PLAIN".equals(mechanism) ? new SaslPlainServer(cbh) : null; 
+    }
+    @Override
+    public String[] getMechanismNames(Map<String,?> props){
+      return (props == null) || "false".equals(props.get(Sasl.POLICY_NOPLAINTEXT))
+          ? new String[]{"PLAIN"}
+          : new String[0];
+    }
+  }
+  
+  private CallbackHandler cbh;
+  private boolean completed;
+  private String authz;
+  
+  SaslPlainServer(CallbackHandler callback) {
+    this.cbh = callback;
+  }
+
+  @Override
+  public String getMechanismName() {
+    return "PLAIN";
+  }
+  
+  @Override
+  public byte[] evaluateResponse(byte[] response) throws SaslException {
+    if (completed) {
+      throw new IllegalStateException("PLAIN authentication has completed");
+    }
+    if (response == null) {
+      throw new IllegalArgumentException("Received null response");
+    }
+    try {
+      String payload;
+      try {
+        payload = new String(response, "UTF-8");
+      } catch (Exception e) {
+        throw new IllegalArgumentException("Received corrupt response", e);
+      }
+      // [ authz, authn, password ]
+      String[] parts = payload.split("\u0000", 3);
+      if (parts.length != 3) {
+        throw new IllegalArgumentException("Received corrupt response");
+      }
+      if (parts[0].isEmpty()) { // authz = authn
+        parts[0] = parts[1];
+      }
+      
+      NameCallback nc = new NameCallback("SASL PLAIN");
+      nc.setName(parts[1]);
+      PasswordCallback pc = new PasswordCallback("SASL PLAIN", false);
+      pc.setPassword(parts[2].toCharArray());
+      AuthorizeCallback ac = new AuthorizeCallback(parts[1], parts[0]);
+      cbh.handle(new Callback[]{nc, pc, ac});
+      if (ac.isAuthorized()) {
+        authz = ac.getAuthorizedID();
+      }
+    } catch (Exception e) {
+      throw new SaslException("PLAIN auth failed: " + e.toString(), e);
+    } finally {
+      completed = true;
+    }
+    return null;
+  }
+
+  private void throwIfNotComplete() {
+    if (!completed) {
+      throw new IllegalStateException("PLAIN authentication not completed");
+    }
+  }
+  
+  @Override
+  public boolean isComplete() {
+    return completed;
+  }
+
+  @Override
+  public String getAuthorizationID() {
+    throwIfNotComplete();
+    return authz;
+  }
+  
+  @Override
+  public Object getNegotiatedProperty(String propName) {
+    throwIfNotComplete();      
+    return Sasl.QOP.equals(propName) ? "auth" : null;
+  }
+  
+  @Override
+  public byte[] wrap(byte[] outgoing, int offset, int len)
+      throws SaslException {
+    throwIfNotComplete();
+    throw new IllegalStateException(
+        "PLAIN supports neither integrity nor privacy");      
+  }
+  
+  @Override
+  public byte[] unwrap(byte[] incoming, int offset, int len)
+      throws SaslException {
+    throwIfNotComplete();
+    throw new IllegalStateException(
+        "PLAIN supports neither integrity nor privacy");      
+  }
+  
+  @Override
+  public void dispose() throws SaslException {
+    cbh = null;
+    authz = null;
+  }
+}


Mime
View raw message