001    /**
002     *
003     * Copyright 2003-2004 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.security.jaas;
019    
020    import java.util.Collection;
021    import java.util.Collections;
022    import java.util.Hashtable;
023    import java.util.Iterator;
024    import java.util.Map;
025    import javax.security.auth.login.AppConfigurationEntry;
026    import javax.security.auth.login.Configuration;
027    
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.geronimo.gbean.GBeanInfo;
031    import org.apache.geronimo.gbean.GBeanInfoBuilder;
032    import org.apache.geronimo.gbean.GBeanLifecycle;
033    import org.apache.geronimo.gbean.ReferenceCollection;
034    import org.apache.geronimo.gbean.ReferenceCollectionEvent;
035    import org.apache.geronimo.gbean.ReferenceCollectionListener;
036    import org.apache.geronimo.security.SecurityServiceImpl;
037    import org.apache.geronimo.security.jaas.server.JaasLoginModuleConfiguration;
038    
039    
040    /**
041     * A JAAS configuration mechanism (associating JAAS configuration names with
042     * specific LoginModule configurations).  This is a drop-in replacement for the
043     * normal file-reading JAAS configuration mechanism.  Instead of getting
044     * its configuration from its file, it gets its configuration from other
045     * GBeans running in Geronimo.
046     *
047     * @version $Rev: 386763 $ $Date: 2006-03-17 15:15:27 -0800 (Fri, 17 Mar 2006) $
048     */
049    public class GeronimoLoginConfiguration extends Configuration implements GBeanLifecycle, ReferenceCollectionListener {
050    
051        private final Log log = LogFactory.getLog(GeronimoLoginConfiguration.class);
052        private static Map entries = new Hashtable();
053        private Configuration oldConfiguration;
054        private Collection configurations = Collections.EMPTY_SET;
055    
056    
057        public Collection getConfigurations() {
058            SecurityManager sm = System.getSecurityManager();
059            if (sm != null) sm.checkPermission(SecurityServiceImpl.CONFIGURE);
060    
061            return configurations;
062        }
063    
064        public void setConfigurations(Collection configurations) {
065            SecurityManager sm = System.getSecurityManager();
066            if (sm != null) sm.checkPermission(SecurityServiceImpl.CONFIGURE);
067    
068            if (configurations instanceof ReferenceCollection) {
069                ReferenceCollection ref = (ReferenceCollection) configurations;
070                ref.addReferenceCollectionListener(this);
071            }
072    
073            this.configurations = configurations;
074    
075            for (Iterator iter = configurations.iterator(); iter.hasNext();) {
076                addConfiguration((ConfigurationEntryFactory) iter.next());
077            }
078        }
079    
080        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
081            AppConfigurationEntry entry = (AppConfigurationEntry) entries.get(name);
082    
083            if (entry == null) return null;
084    
085            return new AppConfigurationEntry[]{entry};
086        }
087    
088        public void refresh() {
089        }
090    
091        public void memberAdded(ReferenceCollectionEvent event) {
092            SecurityManager sm = System.getSecurityManager();
093            if (sm != null) sm.checkPermission(SecurityServiceImpl.CONFIGURE);
094    
095            ConfigurationEntryFactory factory = (ConfigurationEntryFactory) event.getMember();
096            addConfiguration(factory);
097        }
098    
099        public void memberRemoved(ReferenceCollectionEvent event) {
100            SecurityManager sm = System.getSecurityManager();
101            if (sm != null) sm.checkPermission(SecurityServiceImpl.CONFIGURE);
102    
103            ConfigurationEntryFactory factory = (ConfigurationEntryFactory) event.getMember();
104    
105            entries.remove(factory.getConfigurationName());
106            log.debug("Removed Application Configuration Entry " + factory.getConfigurationName());
107        }
108    
109        private final void addConfiguration(ConfigurationEntryFactory factory) {
110            JaasLoginModuleConfiguration config = factory.generateConfiguration();
111            if(config.getLoginDomainName() == null) {
112                throw new IllegalArgumentException("A login module to be registered standalone must have a domain name!");
113            }
114            if (entries.containsKey(factory.getConfigurationName())) {
115                throw new java.lang.IllegalArgumentException("ConfigurationEntry already registered");
116            }
117            AppConfigurationEntry ace = new AppConfigurationEntry(config.getLoginModuleClassName(), config.getFlag().getFlag(), config.getOptions());
118    
119            entries.put(factory.getConfigurationName(), ace);
120            log.debug("Added Application Configuration Entry " + factory.getConfigurationName());
121        }
122    
123        public void doStart() throws Exception {
124            try {
125                oldConfiguration = Configuration.getConfiguration();
126            } catch (SecurityException e) {
127                oldConfiguration = null;
128            }
129            Configuration.setConfiguration(this);
130            log.debug("Installed Geronimo login configuration");
131        }
132    
133        public void doStop() throws Exception {
134            Configuration.setConfiguration(oldConfiguration);
135    
136            for (Iterator iter = entries.keySet().iterator(); iter.hasNext();){
137                log.debug("Removed Application Configuration Entry " + iter.next());
138            }
139            entries.clear();
140    
141            log.debug("Uninstalled Geronimo login configuration");
142        }
143    
144        public void doFail() {
145            Configuration.setConfiguration(oldConfiguration);
146            log.debug("Uninstalled Geronimo login configuration");
147        }
148    
149        public static GBeanInfo getGBeanInfo() {
150            return GBEAN_INFO;
151        }
152    
153        private static final GBeanInfo GBEAN_INFO;
154    
155        static {
156            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(GeronimoLoginConfiguration.class); //just a gbean
157            infoFactory.addReference("Configurations", ConfigurationEntryFactory.class, null);
158    
159            GBEAN_INFO = infoFactory.getBeanInfo();
160        }
161    
162    }