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.service;
023:
024: import java.io.FileNotFoundException;
025: import java.io.InputStream;
026: import java.io.IOException;
027: import java.math.BigInteger;
028: import java.net.URL;
029: import java.security.KeyException;
030: import java.util.HashMap;
031: import java.util.Iterator;
032: import java.util.Properties;
033: import javax.naming.InitialContext;
034: import javax.naming.Name;
035:
036: import org.jboss.naming.NonSerializableFactory;
037: import org.jboss.security.Util;
038: import org.jboss.security.srp.SRPConf;
039: import org.jboss.security.srp.SRPVerifierStore;
040: import org.jboss.security.srp.SRPVerifierStore.VerifierInfo;
041: import org.jboss.system.ServiceMBeanSupport;
042:
043: /** The PropertiesVerifierStore service is a SRPVerifierStore implementation
044: that obtains the username and password info from a properties file and then
045: creates an in memory SRPVerifierStore.
046:
047: @author Scott.Stark@jboss.org
048: @version $Revision: 57211 $
049: */
050: public class PropertiesVerifierStore extends ServiceMBeanSupport
051: implements PropertiesVerifierStoreMBean, SRPVerifierStore {
052: private String jndiName = "srp/DefaultVerifierSource";
053: private HashMap storeMap = new HashMap();
054: private Thread addUserThread;
055:
056: /** Creates a new instance of PropertiesVerifierStore */
057: public PropertiesVerifierStore() {
058: }
059:
060: /** Get the jndi name for the SRPVerifierSource implementation binding.
061: */
062: public String getJndiName() {
063: return jndiName;
064: }
065:
066: /** set the jndi name for the SRPVerifierSource implementation binding.
067: */
068: public void setJndiName(String jndiName) {
069: this .jndiName = jndiName;
070: }
071:
072: protected void startService() throws Exception {
073: // Make sure the security utility class is initialized
074: Util.init();
075:
076: // Find the users.properties file
077: ClassLoader loader = Thread.currentThread()
078: .getContextClassLoader();
079: URL users = loader.getResource("users.properties");
080: if (users == null)
081: throw new FileNotFoundException(
082: "Failed to find users.properties resource");
083: InputStream is = users.openStream();
084: final Properties userPasswords = new Properties();
085: userPasswords.load(is);
086: is.close();
087: addUserThread = new Thread("AddUsers") {
088: public void run() {
089: Iterator keys = userPasswords.keySet().iterator();
090: while (keys.hasNext()) {
091: String username = (String) keys.next();
092: char[] password = userPasswords.getProperty(
093: username).toCharArray();
094: String cipherAlgorithm = "Blowfish";
095: String hashAlgorithm = "SHA_Interleave";
096: addUser(username, password, cipherAlgorithm,
097: hashAlgorithm);
098: log.info("Added user: " + username);
099: }
100: }
101: };
102: addUserThread.start();
103:
104: // Bind a reference to the SRPVerifierStore using NonSerializableFactory
105: InitialContext ctx = new InitialContext();
106: Name name = ctx.getNameParser("").parse(jndiName);
107: NonSerializableFactory.rebind(name, this , true);
108: log.debug("Bound SRPVerifierStore at " + jndiName);
109: }
110:
111: protected void stopService() throws Exception {
112: InitialContext ctx = new InitialContext();
113: NonSerializableFactory.unbind(jndiName);
114: ctx.unbind(jndiName);
115: log.debug("Unbound SRPVerifierStore at " + jndiName);
116: }
117:
118: public VerifierInfo getUserVerifier(String username)
119: throws KeyException, IOException {
120: if (addUserThread != null) {
121: try {
122: addUserThread.join();
123: addUserThread = null;
124: } catch (InterruptedException e) {
125: }
126: }
127: VerifierInfo info = (VerifierInfo) storeMap.get(username);
128: return info;
129: }
130:
131: public void setUserVerifier(String username, VerifierInfo info)
132: throws IOException {
133: throw new IOException("PropertiesVerifierStore is read only");
134: }
135:
136: public void verifyUserChallenge(String username, Object auxChallenge)
137: throws SecurityException {
138: }
139:
140: private void addUser(String username, char[] password,
141: String cipherAlgorithm, String hashAlgorithm) {
142: VerifierInfo info = new VerifierInfo();
143: info.username = username;
144: // Create a random salt
145: long r = Util.nextLong();
146: String rs = Long.toHexString(r);
147: info.salt = rs.getBytes();
148: BigInteger g = SRPConf.getDefaultParams().g();
149: BigInteger N = SRPConf.getDefaultParams().N();
150: info.cipherAlgorithm = cipherAlgorithm;
151: info.hashAlgorithm = hashAlgorithm;
152:
153: info.verifier = Util.calculateVerifier(username, password,
154: info.salt, N, g);
155: info.g = g.toByteArray();
156: info.N = N.toByteArray();
157: storeMap.put(username, info);
158: }
159: }
|