001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.activemq.jaas;
019
020 import java.io.File;
021 import java.io.IOException;
022 import java.util.Enumeration;
023 import java.util.HashSet;
024 import java.util.Map;
025 import java.util.Properties;
026 import java.util.Set;
027
028 import javax.security.auth.Subject;
029 import javax.security.auth.callback.Callback;
030 import javax.security.auth.callback.CallbackHandler;
031 import javax.security.auth.callback.NameCallback;
032 import javax.security.auth.callback.PasswordCallback;
033 import javax.security.auth.callback.UnsupportedCallbackException;
034 import javax.security.auth.login.LoginException;
035 import javax.security.auth.login.FailedLoginException;
036 import javax.security.auth.spi.LoginModule;
037
038 import org.apache.commons.logging.Log;
039 import org.apache.commons.logging.LogFactory;
040
041
042 /**
043 * @version $Rev: $ $Date: $
044 */
045 public class PropertiesLoginModule implements LoginModule {
046
047 private final String USER_FILE = "org.apache.activemq.jaas.properties.user";
048 private final String GROUP_FILE = "org.apache.activemq.jaas.properties.group";
049
050 private static final Log log = LogFactory.getLog(PropertiesLoginModule.class);
051
052 private Subject subject;
053 private CallbackHandler callbackHandler;
054
055 private boolean debug;
056 private String usersFile;
057 private String groupsFile;
058 private Properties users = new Properties();
059 private Properties groups = new Properties();
060 private String user;
061 private Set principals = new HashSet();
062 private File baseDir;
063
064 public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
065 this.subject = subject;
066 this.callbackHandler = callbackHandler;
067
068 if( System.getProperty("java.security.auth.login.config")!=null ) {
069 baseDir=new File(System.getProperty("java.security.auth.login.config")).getParentFile();
070 } else {
071 baseDir = new File(".");
072 }
073
074 debug = "true".equalsIgnoreCase((String) options.get("debug"));
075 usersFile = (String) options.get(USER_FILE)+"";
076 groupsFile = (String) options.get(GROUP_FILE)+"";
077
078 if (debug) {
079 log.debug("Initialized debug=" + debug + " usersFile=" + usersFile + " groupsFile=" + groupsFile+" basedir="+baseDir);
080 }
081 }
082
083 public boolean login() throws LoginException {
084 File f = new File(baseDir,usersFile);
085 try {
086 users.load(new java.io.FileInputStream(f));
087 } catch (IOException ioe) {
088 throw new LoginException("Unable to load user properties file " + f);
089 }
090 f = new File(baseDir, groupsFile);
091 try {
092 groups.load(new java.io.FileInputStream(f));
093 } catch (IOException ioe) {
094 throw new LoginException("Unable to load group properties file " + f);
095 }
096
097 Callback[] callbacks = new Callback[2];
098
099 callbacks[0] = new NameCallback("Username: ");
100 callbacks[1] = new PasswordCallback("Password: ", false);
101 try {
102 callbackHandler.handle(callbacks);
103 } catch (IOException ioe) {
104 throw new LoginException(ioe.getMessage());
105 } catch (UnsupportedCallbackException uce) {
106 throw new LoginException(uce.getMessage() + " not available to obtain information from user");
107 }
108 user = ((NameCallback) callbacks[0]).getName();
109 char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
110 if (tmpPassword == null) tmpPassword = new char[0];
111
112 String password = users.getProperty(user);
113
114 if (password == null) throw new FailedLoginException("User does exist");
115 if (!password.equals(new String(tmpPassword))) throw new FailedLoginException("Password does not match");
116
117 users.clear();
118
119 if (debug) {
120 log.debug("login " + user);
121 }
122 return true;
123 }
124
125 public boolean commit() throws LoginException {
126 principals.add(new UserPrincipal(user));
127
128 for (Enumeration enumeration = groups.keys(); enumeration.hasMoreElements();) {
129 String name = (String) enumeration.nextElement();
130 String[] userList = ((String) groups.getProperty(name) + "").split(",");
131 for (int i = 0; i < userList.length; i++) {
132 if (user.equals(userList[i])) {
133 principals.add(new GroupPrincipal(name));
134 break;
135 }
136 }
137 }
138
139 subject.getPrincipals().addAll(principals);
140
141 clear();
142
143 if (debug) {
144 log.debug("commit");
145 }
146 return true;
147 }
148
149 public boolean abort() throws LoginException {
150 clear();
151
152 if (debug) {
153 log.debug("abort");
154 }
155 return true;
156 }
157
158 public boolean logout() throws LoginException {
159 subject.getPrincipals().removeAll(principals);
160 principals.clear();
161
162 if (debug) {
163 log.debug("logout");
164 }
165 return true;
166 }
167
168 private void clear() {
169 groups.clear();
170 user = null;
171 }
172 }