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    }