001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.security.test;
023:
024: import java.lang.reflect.UndeclaredThrowableException;
025: import java.rmi.RemoteException;
026: import javax.rmi.PortableRemoteObject;
027: import javax.security.auth.login.LoginContext;
028:
029: import junit.extensions.TestSetup;
030: import junit.framework.Test;
031: import junit.framework.TestSuite;
032:
033: import org.jboss.test.util.AppCallbackHandler;
034: import org.jboss.test.JBossTestCase;
035: import org.jboss.test.JBossTestSetup;
036: import org.jboss.test.security.interfaces.StatelessSession;
037: import org.jboss.test.security.interfaces.StatelessSessionHome;
038: import org.apache.log4j.Logger;
039:
040: /** Test of the secure remote password(SRP) session key to perform crypto
041: operations.
042:
043: @author Scott.Stark@jboss.org
044: @version $Revision: 57211 $
045: */
046: public class SRPUnitTestCase extends JBossTestCase {
047: static final String JAR = "security-srp.jar";
048: static String username = "scott";
049: static char[] password = "echoman".toCharArray();
050:
051: LoginContext lc;
052: boolean loggedIn;
053:
054: public SRPUnitTestCase(String name) {
055: super (name);
056: }
057:
058: /** Test that the echo method is secured by the SRPCacheLogin module
059: */
060: public void testEchoArgs() throws Exception {
061: log.debug("+++ testEchoArgs");
062: login("srp-test", username, password);
063: Object obj = getInitialContext().lookup(
064: "srp-jce.StatelessSession");
065: obj = PortableRemoteObject.narrow(obj,
066: StatelessSessionHome.class);
067: StatelessSessionHome home = (StatelessSessionHome) obj;
068: log.debug("Found StatelessSessionHome");
069: StatelessSession bean = home.create();
070: log.debug("Created srp-jce.StatelessSession");
071: try {
072: log.debug("Bean.echo('Hello') -> " + bean.echo("Hello"));
073: } catch (Exception e) {
074: Throwable t = e;
075: if (e instanceof UndeclaredThrowableException) {
076: UndeclaredThrowableException ex = (UndeclaredThrowableException) e;
077: t = ex.getUndeclaredThrowable();
078: } else if (e instanceof RemoteException) {
079: RemoteException ex = (RemoteException) e;
080: t = ex.detail;
081: }
082:
083: log.error("echo failed", t);
084: boolean failure = true;
085: if (t instanceof SecurityException) {
086: String msg = t.getMessage();
087: if (msg.startsWith("Unsupported keysize")) {
088: /* The size of the srp session key is bigger than the JCE version
089: in use supports. Most likely the unlimited strength policy is
090: not installed so don't fail the test.
091: */
092: failure = false;
093: log.info("Not failing test due to key size issue");
094: }
095: }
096:
097: if (failure)
098: fail("Call to echo failed: " + t.getMessage());
099: }
100:
101: logout();
102: }
103:
104: /** Test that the echo method is secured by the SRPCacheLogin module when
105: * using multi-session srp with two threads
106: */
107: public void testMultiUserEchoArgs() throws Exception {
108: log.debug("+++ testMultiUserEchoArgs");
109: UserThread ut0 = new UserThread(log);
110: UserThread ut1 = new UserThread(log);
111:
112: Thread t0 = new Thread(ut0, "UserThread#0");
113: t0.start();
114: Thread t1 = new Thread(ut1, "UserThread#1");
115: t1.start();
116:
117: // Release the ut0 thread and wait for it to finish the first ejb call
118: synchronized (ut0) {
119: ut0.semaphore = true;
120: ut0.notify();
121: ut0.wait();
122: }
123: // Release the ut1 thread and wait for it to finish the first ejb call
124: synchronized (ut1) {
125: ut1.semaphore = true;
126: ut1.notify();
127: ut1.wait();
128: }
129: // Release the ut1 thread and wait for it to finish the second ejb call
130: synchronized (ut1) {
131: ut1.semaphore = true;
132: ut1.notify();
133: ut1.wait();
134: }
135: // Release the ut0 thread and wait for it to finish the second ejb call
136: synchronized (ut0) {
137: ut0.semaphore = true;
138: ut0.notify();
139: ut0.wait();
140: }
141:
142: t0.join();
143: log.debug("UserThread0.ex", ut0.ex);
144: t1.join();
145: log.debug("UserThread1.ex", ut1.ex);
146: assertTrue("UserThread0.ex == null", ut0.ex == null);
147: assertTrue("UserThread1.ex == null", ut1.ex == null);
148: }
149:
150: /** Login using the given confName login configuration with the provided
151: username and password credential.
152: */
153: private void login(String confName, String username, char[] password)
154: throws Exception {
155: if (loggedIn)
156: return;
157:
158: lc = null;
159: AppCallbackHandler handler = new AppCallbackHandler(username,
160: password);
161: log.debug("Creating LoginContext(" + confName + ")");
162: lc = new LoginContext(confName, handler);
163: lc.login();
164: log.debug("Created LoginContext, subject=" + lc.getSubject());
165: loggedIn = true;
166: }
167:
168: private void logout() throws Exception {
169: if (loggedIn) {
170: loggedIn = false;
171: lc.logout();
172: }
173: }
174:
175: /**
176: * Setup the test suite.
177: */
178: public static Test suite() throws Exception {
179: TestSuite suite = new TestSuite();
180: suite.addTest(new TestSuite(SRPUnitTestCase.class));
181:
182: // Create an initializer for the test suite
183: TestSetup wrapper = new JBossTestSetup(suite) {
184: protected void setUp() throws Exception {
185: super .setUp();
186: deploy(JAR);
187: // Establish the JAAS login config
188: String authConfPath = super
189: .getResourceURL("security-srp/auth.conf");
190: System.setProperty("java.security.auth.login.config",
191: authConfPath);
192: }
193:
194: protected void tearDown() throws Exception {
195: undeploy(JAR);
196: super .tearDown();
197: }
198: };
199: return wrapper;
200: }
201:
202: class UserThread implements Runnable {
203: boolean semaphore;
204: Throwable ex;
205: Logger log;
206:
207: UserThread(Logger log) {
208: this .log = log;
209: }
210:
211: public void run() {
212: try {
213: internalTestEchoArgs();
214: } catch (Throwable t) {
215: this .ex = t;
216: t.printStackTrace();
217: }
218: }
219:
220: private synchronized void internalTestEchoArgs()
221: throws Exception {
222: log.debug("+++ internalTestEchoArgs");
223: AppCallbackHandler handler = new AppCallbackHandler(
224: username, password);
225: log.debug("Creating LoginContext(srp-test-multi)");
226: LoginContext lc = new LoginContext("srp-test-multi",
227: handler);
228: lc.login();
229: log.debug("Created LoginContext, subject="
230: + lc.getSubject());
231:
232: Object obj = getInitialContext().lookup(
233: "srp.StatelessSession");
234: obj = PortableRemoteObject.narrow(obj,
235: StatelessSessionHome.class);
236: StatelessSessionHome home = (StatelessSessionHome) obj;
237: // Wait for the test thread to tell use to continue
238: log.debug("Enter wait");
239: while (semaphore == false) {
240: wait(1000);
241: }
242: semaphore = false;
243: log.debug("Notified, Found StatelessSessionHome");
244: StatelessSession bean = home.create();
245: log.debug("Created srp.StatelessSession");
246: log.debug("Bean.echo('Hello') -> " + bean.echo("Hello"));
247: notifyAll();
248: log.debug("Enter wait#2");
249: while (semaphore == false) {
250: wait(1000);
251: }
252: log.debug("Notified, Bean.echo('Hello#2') -> "
253: + bean.echo("Hello#2"));
254: notifyAll();
255: lc.logout();
256: log.debug("Logout");
257: }
258: }
259: }
|