You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2006/09/19 00:43:25 UTC
svn commit: r447608 [2/2] - in /incubator/activemq/trunk:
activemq-core/src/main/java/org/apache/activemq/
activemq-core/src/main/java/org/apache/activemq/broker/
activemq-core/src/main/java/org/apache/activemq/security/
activemq-core/src/main/java/org...
Added: incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubSSLSocketFactory.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubSSLSocketFactory.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubSSLSocketFactory.java (added)
+++ incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubSSLSocketFactory.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,59 @@
+/**
+ *
+ * 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.activemq.transport.tcp;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import javax.net.ssl.SSLServerSocketFactory;
+
+public class StubSSLSocketFactory extends SSLServerSocketFactory {
+
+ private final ServerSocket retServerSocket;
+
+ public StubSSLSocketFactory(ServerSocket returnServerSocket) {
+ retServerSocket = returnServerSocket;
+ }
+
+ public ServerSocket createServerSocket(int arg0) throws IOException {
+ return retServerSocket;
+ }
+
+ public ServerSocket createServerSocket(int arg0, int arg1)
+ throws IOException {
+ return retServerSocket;
+ }
+
+ public ServerSocket createServerSocket(int arg0, int arg1, InetAddress arg2)
+ throws IOException {
+ return retServerSocket;
+ }
+
+ // --- Stubbed Methods ---
+
+ public String[] getDefaultCipherSuites() {
+ return null;
+ }
+
+ public String[] getSupportedCipherSuites() {
+ return null;
+ }
+}
Added: incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubSslTransport.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubSslTransport.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubSslTransport.java (added)
+++ incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubSslTransport.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,52 @@
+/**
+ *
+ * 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.activemq.transport.tcp;
+
+import javax.net.ssl.SSLSocket;
+
+import org.apache.activemq.wireformat.WireFormat;
+
+public class StubSslTransport extends SslTransport {
+ public static final int UNTOUCHED = -1;
+ public static final int FALSE = 0;
+ public static final int TRUE = 1;
+
+ private int wantClientAuthStatus = UNTOUCHED;
+ private int needClientAuthStatus = UNTOUCHED;
+
+ public StubSslTransport(WireFormat wireFormat, SSLSocket socket) throws Exception {
+ super(wireFormat, socket);
+ }
+
+ public void setWantClientAuth(boolean arg0) {
+ this.wantClientAuthStatus = (arg0 ? TRUE : FALSE);
+ }
+
+ public void setNeedClientAuth(boolean arg0) {
+ this.needClientAuthStatus = (arg0 ? TRUE : FALSE);
+ }
+
+ public int getWantClientAuthStatus() {
+ return wantClientAuthStatus;
+ }
+
+ public int getNeedClientAuthStatus() {
+ return needClientAuthStatus;
+ }
+}
Added: incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubX509Certificate.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubX509Certificate.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubX509Certificate.java (added)
+++ incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/tcp/StubX509Certificate.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,166 @@
+/**
+ *
+ * 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.activemq.transport.tcp;
+
+import java.math.BigInteger;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.util.Date;
+import java.util.Set;
+
+import java.security.cert.X509Certificate;
+
+public class StubX509Certificate extends X509Certificate {
+ public StubX509Certificate(Principal id) {
+ this.id = id;
+ }
+
+ public Principal getSubjectDN() {
+ return this.id;
+ }
+
+ private final Principal id;
+
+ // --- Stubbed Methods ---
+ public void checkValidity() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void checkValidity(Date arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public int getVersion() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public BigInteger getSerialNumber() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Principal getIssuerDN() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Date getNotBefore() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Date getNotAfter() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public byte[] getTBSCertificate() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public byte[] getSignature() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getSigAlgName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getSigAlgOID() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public byte[] getSigAlgParams() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean[] getIssuerUniqueID() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean[] getSubjectUniqueID() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean[] getKeyUsage() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public int getBasicConstraints() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public byte[] getEncoded() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void verify(PublicKey arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void verify(PublicKey arg0, String arg1) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public String toString() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public PublicKey getPublicKey() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean hasUnsupportedCriticalExtension() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public Set getCriticalExtensionOIDs() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Set getNonCriticalExtensionOIDs() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public byte[] getExtensionValue(String arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
\ No newline at end of file
Added: incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateCallback.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateCallback.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateCallback.java (added)
+++ incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateCallback.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,52 @@
+/**
+ *
+ * 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.activemq.jaas;
+
+import javax.security.auth.callback.Callback;
+import java.security.cert.X509Certificate;
+
+/**
+ * A Callback for SSL certificates.
+ *
+ * Will return a certificate chain to its client.
+ *
+ * @author sepandm@gmail.com (Sepand)
+ *
+ */
+public class CertificateCallback implements Callback {
+ X509Certificate certificates[] = null;
+
+ /**
+ * Setter for certificate chain.
+ *
+ * @param certs The certificates to be returned.
+ */
+ public void setCertificates(X509Certificate certs[]) {
+ certificates = certs;
+ }
+
+ /**
+ * Getter for certificate chain.
+ *
+ * @return The certificates being carried.
+ */
+ public X509Certificate[] getCertificates() {
+ return certificates;
+ }
+}
Added: incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateLoginModule.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateLoginModule.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateLoginModule.java (added)
+++ incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateLoginModule.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,191 @@
+/**
+ *
+ * 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.activemq.jaas;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.Subject;
+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.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A LoginModule that allows for authentication based on SSL certificates.
+ *
+ * Allows for subclasses to define methods used to verify user certificates and find user groups.
+ * Uses CertificateCallbacks to retrieve certificates.
+ *
+ * @author sepandm@gmail.com (Sepand)
+ *
+ */
+public abstract class CertificateLoginModule implements LoginModule {
+
+ private CallbackHandler callbackHandler;
+ private Subject subject;
+
+ private X509Certificate certificates[];
+ private String username = null;
+ private Set groups = null;
+
+ private Set principals = new HashSet();
+
+ private static final Log log = LogFactory.getLog(CertificateLoginModule.class);
+ private boolean debug;
+
+ /**
+ * Overriding to allow for proper initialization.
+ *
+ * Standard JAAS.
+ */
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+
+ debug = "true".equalsIgnoreCase((String) options.get("debug"));
+
+ if (debug) {
+ log.debug("Initialized debug");
+ }
+ }
+
+ /**
+ * Overriding to allow for certificate-based login.
+ *
+ * Standard JAAS.
+ */
+ public boolean login() throws LoginException {
+ Callback[] callbacks = new Callback[1];
+
+ callbacks[0] = new CertificateCallback();
+ try {
+ callbackHandler.handle(callbacks);
+ } catch (IOException ioe) {
+ throw new LoginException(ioe.getMessage());
+ } catch (UnsupportedCallbackException uce) {
+ throw new LoginException(uce.getMessage() + " Unable to obtain client certificates.");
+ }
+ certificates = ((CertificateCallback) callbacks[0]).getCertificates();
+
+ username = getUserNameForCertificates(certificates);
+ if ( username == null )
+ throw new FailedLoginException("Unable to verify client certificates.");
+
+ groups = getUserGroups(username);
+
+ if (debug) {
+ log.debug("Certificate for user: " + username);
+ }
+ return true;
+ }
+
+ /**
+ * Overriding to complete login process.
+ *
+ * Standard JAAS.
+ */
+ public boolean commit() throws LoginException {
+ principals.add(new UserPrincipal(username));
+
+ String currentGroup = null;
+ for (Iterator iter = groups.iterator(); iter.hasNext(); ) {
+ currentGroup = (String)iter.next();
+ principals.add(new GroupPrincipal(currentGroup));
+ }
+
+ subject.getPrincipals().addAll(principals);
+
+ clear();
+
+ if (debug) {
+ log.debug("commit");
+ }
+ return true;
+ }
+
+ /**
+ * Standard JAAS override.
+ */
+ public boolean abort() throws LoginException {
+ clear();
+
+ if (debug) {
+ log.debug("abort");
+ }
+ return true;
+ }
+
+ /**
+ * Standard JAAS override.
+ */
+ public boolean logout() {
+ subject.getPrincipals().removeAll(principals);
+ principals.clear();
+
+ if (debug) {
+ log.debug("logout");
+ }
+ return true;
+ }
+
+ /**
+ * Helper method.
+ */
+ private void clear() {
+ groups.clear();
+ certificates = null;
+ }
+
+ /**
+ * Should return a unique name corresponding to the certificates given.
+ *
+ * The name returned will be used to look up access levels as well as
+ * group associations.
+ *
+ * @param dn The distinguished name.
+ * @return The unique name if the certificate is recognized, null otherwise.
+ */
+ protected abstract String getUserNameForCertificates(final X509Certificate[] certs) throws LoginException;
+
+ /**
+ * Should return a set of the groups this user belongs to.
+ *
+ * The groups returned will be added to the user's credentials.
+ *
+ * @param username The username of the client. This is the same name that
+ * getUserNameForDn returned for the user's DN.
+ * @return A Set of the names of the groups this user belongs to.
+ */
+ protected abstract Set getUserGroups(final String username) throws LoginException;
+
+}
Added: incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/JaasCertificateCallbackHandler.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/JaasCertificateCallbackHandler.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/JaasCertificateCallbackHandler.java (added)
+++ incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/JaasCertificateCallbackHandler.java Mon Sep 18 15:43:24 2006
@@ -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.activemq.jaas;
+
+
+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 java.io.IOException;
+import java.security.cert.X509Certificate;
+
+/**
+ * A Standard JAAS callback handler for SSL certificate requests.
+ *
+ * Will only handle callbacks of type CertificateCallback.
+ *
+ * @author sepandm@gmail.com (Sepand)
+ *
+ */
+public class JaasCertificateCallbackHandler implements CallbackHandler {
+ final X509Certificate certificates[];
+
+ /**
+ * Basic constructor.
+ *
+ * @param cert The certificate returned when calling back.
+ */
+ public JaasCertificateCallbackHandler(X509Certificate certs[]) {
+ certificates = certs;
+ }
+
+ /**
+ * Overriding handle method to handle certificates.
+ *
+ * @param callbacks The callbacks requested.
+ * @throws IOException
+ * @throws UnsupportedCallbackException Thrown if an unkown Callback type is encountered.
+ */
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (callback instanceof CertificateCallback) {
+ CertificateCallback certCallback = (CertificateCallback) callback;
+
+ certCallback.setCertificates(certificates);
+
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ }
+}
Added: incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/JassCredentialCallback.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/JassCredentialCallback.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/JassCredentialCallback.java (added)
+++ incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/JassCredentialCallback.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,63 @@
+/**
+ *
+ * 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.activemq.jaas;
+
+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 java.io.IOException;
+
+
+/**
+ * A JASS username password CallbackHandler.
+ */
+public class JassCredentialCallback implements CallbackHandler {
+
+ private final String username;
+ private final String password;
+
+ public JassCredentialCallback(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (callback instanceof PasswordCallback) {
+ PasswordCallback passwordCallback = (PasswordCallback) callback;
+ if (password == null) {
+ passwordCallback.setPassword(null);
+ }
+ else {
+ passwordCallback.setPassword(password.toCharArray());
+ }
+ } else if (callback instanceof NameCallback) {
+ NameCallback nameCallback = (NameCallback) callback;
+ if (username == null) {
+ nameCallback.setName(null);
+ }
+ else {
+ nameCallback.setName(username);
+ }
+ }
+ }
+ }
+}
Added: incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/TextFileCertificateLoginModule.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/TextFileCertificateLoginModule.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/TextFileCertificateLoginModule.java (added)
+++ incubator/activemq/trunk/activemq-jaas/src/main/java/org/apache/activemq/jaas/TextFileCertificateLoginModule.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,140 @@
+/**
+ *
+ * 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.activemq.jaas;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+/**
+ * A LoginModule allowing for SSL certificate based authentication based on Distinguished Names (DN) stored in text
+ * files.
+ *
+ * The DNs are parsed using a Properties class where each line is <user_name>=<user_DN>.
+ * This class also uses a group definition file where each line is <group_name>=<user_name_1>,<user_name_2>,etc.
+ * The user and group files' locations must be specified in the org.apache.activemq.jaas.textfiledn.user and
+ * org.apache.activemq.jaas.textfiledn.user properties respectively.
+ *
+ * NOTE: This class will re-read user and group files for every authentication (i.e it does live updates of allowed
+ * groups and users).
+ *
+ * @author sepandm@gmail.com (Sepand)
+ */
+public class TextFileCertificateLoginModule extends CertificateLoginModule {
+
+ private final String USER_FILE = "org.apache.activemq.jaas.textfiledn.user";
+ private final String GROUP_FILE = "org.apache.activemq.jaas.textfiledn.group";
+
+ private File baseDir;
+ private String usersFilePathname;
+ private String groupsFilePathname;
+
+ /**
+ * Performs initialization of file paths.
+ *
+ * A standard JAAS override.
+ */
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
+ super.initialize(subject, callbackHandler, sharedState, options);
+ if (System.getProperty("java.security.auth.login.config") != null) {
+ baseDir = new File(System.getProperty("java.security.auth.login.config")).getParentFile();
+ } else {
+ baseDir = new File(".");
+ }
+
+ usersFilePathname = (String) options.get(USER_FILE)+"";
+ groupsFilePathname = (String) options.get(GROUP_FILE)+"";
+ }
+
+ /**
+ * Overriding to allow DN authorization based on DNs specified in text files.
+ *
+ * @param certs The certificate the incoming connection provided.
+ * @return The user's authenticated name or null if unable to authenticate the user.
+ * @throws LoginException Thrown if unable to find user file or connection certificate.
+ */
+ protected String getUserNameForCertificates(final X509Certificate[] certs) throws LoginException {
+ if (certs == null) {
+ throw new LoginException("Client certificates not found. Cannot authenticate.");
+ }
+
+ File usersFile = new File(baseDir,usersFilePathname);
+
+ Properties users = new Properties();
+
+ try {
+ users.load(new java.io.FileInputStream(usersFile));
+ } catch (IOException ioe) {
+ throw new LoginException("Unable to load user properties file " + usersFile);
+ }
+
+ String dn = certs[0].getSubjectDN().getName();
+
+ for(Enumeration vals = users.elements(), keys = users.keys(); vals.hasMoreElements(); ) {
+ if ( ((String)vals.nextElement()).equals(dn) ) {
+ return (String)keys.nextElement();
+ } else {
+ keys.nextElement();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Overriding to allow for group discovery based on text files.
+ *
+ * @param username The name of the user being examined. This is the same name returned by
+ * getUserNameForCertificates.
+ * @return A Set of name Strings for groups this user belongs to.
+ * @throws LoginException Thrown if unable to find group definition file.
+ */
+ protected Set getUserGroups(String username) throws LoginException {
+ File groupsFile = new File(baseDir, groupsFilePathname);
+
+ Properties groups = new Properties();
+ try {
+ groups.load(new java.io.FileInputStream(groupsFile));
+ } catch (IOException ioe) {
+ throw new LoginException("Unable to load group properties file " + groupsFile);
+ }
+ Set userGroups = new HashSet();
+ for (Enumeration enumeration = groups.keys(); enumeration.hasMoreElements();) {
+ String groupName = (String) enumeration.nextElement();
+ String[] userList = (groups.getProperty(groupName) + "").split(",");
+ for (int i = 0; i < userList.length; i++) {
+ if (username.equals(userList[i])) {
+ userGroups.add(groupName);
+ break;
+ }
+ }
+ }
+
+ return userGroups;
+ }
+}
Added: incubator/activemq/trunk/activemq-jaas/src/test/java/org/apache/activemq/jaas/CertificateLoginModuleTest.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jaas/src/test/java/org/apache/activemq/jaas/CertificateLoginModuleTest.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-jaas/src/test/java/org/apache/activemq/jaas/CertificateLoginModuleTest.java (added)
+++ incubator/activemq/trunk/activemq-jaas/src/test/java/org/apache/activemq/jaas/CertificateLoginModuleTest.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,144 @@
+/**
+ *
+ * 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.activemq.jaas;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+public class CertificateLoginModuleTest extends TestCase {
+ private final String userName = "testUser";
+ private final List groupNames = new Vector();
+ private StubCertificateLoginModule loginModule;
+
+ private Subject subject;
+
+ public CertificateLoginModuleTest() {
+ groupNames.add("testGroup1");
+ groupNames.add("testGroup2");
+ groupNames.add("testGroup3");
+ groupNames.add("testGroup4");
+ }
+
+ protected void setUp() throws Exception {
+ subject = new Subject();
+ }
+
+ protected void tearDown() throws Exception {
+ }
+
+ private void loginWithCredentials(String userName, Set groupNames) throws LoginException {
+ loginModule = new StubCertificateLoginModule(userName, new HashSet(groupNames));
+ JaasCertificateCallbackHandler callbackHandler = new JaasCertificateCallbackHandler(null);
+
+ loginModule.initialize(subject, callbackHandler, null, new HashMap());
+
+ loginModule.login();
+ loginModule.commit();
+ }
+
+ private void checkPrincipalsMatch(Subject subject) {
+ boolean nameFound = false;
+ boolean groupsFound[] = new boolean[groupNames.size()];
+ for (int i = 0; i < groupsFound.length; ++i) {
+ groupsFound[i] = false;
+ }
+
+ for (Iterator iter = subject.getPrincipals().iterator(); iter.hasNext(); ) {
+ Principal currentPrincipal = (Principal) iter.next();
+
+ if (currentPrincipal instanceof UserPrincipal) {
+ if (((UserPrincipal)currentPrincipal).getName().equals(userName)) {
+ if (nameFound == false) {
+ nameFound = true;
+ } else {
+ fail("UserPrincipal found twice.");
+ }
+
+ } else {
+ fail("Unknown UserPrincipal found.");
+ }
+
+ } else if (currentPrincipal instanceof GroupPrincipal) {
+ int principalIdx = groupNames.indexOf(((GroupPrincipal)currentPrincipal).getName());
+
+ if (principalIdx < 0) {
+ fail("Unknown GroupPrincipal found.");
+ }
+
+ if (groupsFound[principalIdx] == false) {
+ groupsFound[principalIdx] = true;
+ } else {
+ fail("GroupPrincipal found twice.");
+ }
+ } else {
+ fail("Unknown Principal type found.");
+ }
+ }
+ }
+
+ public void testLoginSuccess() throws IOException {
+ try {
+ loginWithCredentials(userName, new HashSet(groupNames));
+ } catch (Exception e) {
+ fail("Unable to login: " + e.getMessage());
+ }
+
+ checkPrincipalsMatch(subject);
+ }
+
+ public void testLoginFailure() throws IOException {
+ boolean loginFailed = false;
+
+ try {
+ loginWithCredentials(null, new HashSet());
+ } catch (LoginException e) {
+ loginFailed = true;
+ }
+
+ if (!loginFailed) {
+ fail("Logged in with unknown certificate.");
+ }
+ }
+
+ public void testLogOut() throws IOException {
+ try {
+ loginWithCredentials(userName, new HashSet(groupNames));
+ } catch (Exception e) {
+ fail("Unable to login: " + e.getMessage());
+ }
+
+ loginModule.logout();
+
+ assertEquals("logout should have cleared Subject principals.", 0, subject.getPrincipals().size());
+ }
+}
+
Added: incubator/activemq/trunk/activemq-jaas/src/test/java/org/apache/activemq/jaas/StubCertificateLoginModule.java
URL: http://svn.apache.org/viewvc/incubator/activemq/trunk/activemq-jaas/src/test/java/org/apache/activemq/jaas/StubCertificateLoginModule.java?view=auto&rev=447608
==============================================================================
--- incubator/activemq/trunk/activemq-jaas/src/test/java/org/apache/activemq/jaas/StubCertificateLoginModule.java (added)
+++ incubator/activemq/trunk/activemq-jaas/src/test/java/org/apache/activemq/jaas/StubCertificateLoginModule.java Mon Sep 18 15:43:24 2006
@@ -0,0 +1,48 @@
+/**
+ *
+ * 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.activemq.jaas;
+
+import java.security.cert.X509Certificate;
+import java.util.Set;
+
+import javax.security.auth.login.LoginException;
+
+public class StubCertificateLoginModule extends CertificateLoginModule {
+ final String userName;
+ final Set groupNames;
+
+ String lastUserName = null;
+ X509Certificate[] lastCertChain = null;
+
+ public StubCertificateLoginModule(String userName, Set groupNames) {
+ this.userName = userName;
+ this.groupNames = groupNames;
+ }
+
+ protected String getUserNameForCertificates(X509Certificate[] certs)
+ throws LoginException {
+ lastCertChain = certs;
+ return userName;
+ }
+
+ protected Set getUserGroups(String username) throws LoginException {
+ lastUserName = username;
+ return this.groupNames;
+ }
+}