001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  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.Map;
024    
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    
038    
039    /**
040     * A JAAS configuration mechanism (associating JAAS configuration names with
041     * specific LoginModule configurations).  This is a drop-in replacement for the
042     * normal file-reading JAAS configuration mechanism.  Instead of getting
043     * its configuration from its file, it gets its configuration from other
044     * GBeans running in Geronimo.
045     *
046     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
047     */
048    public class GeronimoLoginConfiguration extends Configuration implements GBeanLifecycle, ReferenceCollectionListener {
049    
050        private final Log log = LogFactory.getLog(GeronimoLoginConfiguration.class);
051        private static Map<String, AppConfigurationEntry[]> entries = new Hashtable<String, AppConfigurationEntry[]>();
052        private Configuration oldConfiguration;
053        private Collection<ConfigurationEntryFactory> configurations = Collections.emptySet();
054    
055    
056        public Collection getConfigurations() {
057            SecurityManager sm = System.getSecurityManager();
058            if (sm != null) sm.checkPermission(SecurityServiceImpl.CONFIGURE);
059    
060            return configurations;
061        }
062    
063        public void setConfigurations(Collection<ConfigurationEntryFactory> configurations) {
064            SecurityManager sm = System.getSecurityManager();
065            if (sm != null) sm.checkPermission(SecurityServiceImpl.CONFIGURE);
066    
067            if (configurations instanceof ReferenceCollection) {
068                ReferenceCollection ref = (ReferenceCollection) configurations;
069                ref.addReferenceCollectionListener(this);
070            }
071    
072            this.configurations = configurations;
073    
074            for (ConfigurationEntryFactory configuration : configurations) {
075                addConfiguration(configuration);
076            }
077        }
078    
079        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
080            return entries.get(name);
081        }
082    
083        public void refresh() {
084        }
085    
086        public void memberAdded(ReferenceCollectionEvent event) {
087            SecurityManager sm = System.getSecurityManager();
088            if (sm != null) sm.checkPermission(SecurityServiceImpl.CONFIGURE);
089    
090            ConfigurationEntryFactory factory = (ConfigurationEntryFactory) event.getMember();
091            addConfiguration(factory);
092        }
093    
094        public void memberRemoved(ReferenceCollectionEvent event) {
095            SecurityManager sm = System.getSecurityManager();
096            if (sm != null) sm.checkPermission(SecurityServiceImpl.CONFIGURE);
097    
098            ConfigurationEntryFactory factory = (ConfigurationEntryFactory) event.getMember();
099    
100            entries.remove(factory.getConfigurationName());
101            log.debug("Removed Application Configuration Entry " + factory.getConfigurationName());
102        }
103    
104        private void addConfiguration(ConfigurationEntryFactory factory) {
105            if (entries.containsKey(factory.getConfigurationName())) {
106                throw new java.lang.IllegalArgumentException("ConfigurationEntry already registered");
107            }
108            AppConfigurationEntry[] ace = factory.getAppConfigurationEntries();
109            entries.put(factory.getConfigurationName(), ace);
110            log.debug("Added Application Configuration Entry " + factory.getConfigurationName());
111        }
112    
113        public void doStart() throws Exception {
114            try {
115                oldConfiguration = Configuration.getConfiguration();
116            } catch (SecurityException e) {
117                oldConfiguration = null;
118            }
119            Configuration.setConfiguration(this);
120            log.debug("Installed Geronimo login configuration");
121        }
122    
123        public void doStop() throws Exception {
124            Configuration.setConfiguration(oldConfiguration);
125    
126            for (String s : entries.keySet()) {
127                log.debug("Removed Application Configuration Entry " + s);
128            }
129            entries.clear();
130    
131            log.debug("Uninstalled Geronimo login configuration");
132        }
133    
134        public void doFail() {
135            Configuration.setConfiguration(oldConfiguration);
136            log.debug("Uninstalled Geronimo login configuration");
137        }
138    
139        public static GBeanInfo getGBeanInfo() {
140            return GBEAN_INFO;
141        }
142    
143        private static final GBeanInfo GBEAN_INFO;
144    
145        static {
146            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(GeronimoLoginConfiguration.class); //just a gbean
147            infoFactory.addReference("Configurations", ConfigurationEntryFactory.class, null);
148    
149            GBEAN_INFO = infoFactory.getBeanInfo();
150        }
151    
152    }