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    package org.apache.geronimo.security.jaas;
018    
019    import java.util.HashMap;
020    import java.util.List;
021    import java.util.Map;
022    import java.util.Set;
023    
024    import org.apache.geronimo.gbean.GBeanInfo;
025    import org.apache.geronimo.gbean.GBeanInfoBuilder;
026    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
027    import org.apache.geronimo.kernel.Kernel;
028    import org.apache.geronimo.system.serverinfo.ServerInfo;
029    import org.apache.geronimo.security.jaas.server.JaasLoginModuleConfiguration;
030    
031    
032    /**
033     * Holds a reference to a login module and the control flag.  A linked list of these forms the list of login modules
034     * in a GenericSecurityRealm.
035     *
036     * @version $Rev: 391894 $ $Date: 2006-04-05 21:00:33 -0700 (Wed, 05 Apr 2006) $
037     */
038    public class JaasLoginModuleUse implements JaasLoginModuleChain {
039        // See also http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html for more standard login module option keys
040        public final static String KERNEL_NAME_LM_OPTION = "org.apache.geronimo.security.realm.GenericSecurityRealm.KERNEL";
041        public final static String SERVERINFO_LM_OPTION = "org.apache.geronimo.security.realm.GenericSecurityRealm.SERVERINFO";
042        public final static String CLASSLOADER_LM_OPTION = "org.apache.geronimo.security.realm.GenericSecurityRealm.CLASSLOADER";
043    
044        private final LoginModuleSettings loginModule;
045        private final JaasLoginModuleUse next;
046        private LoginModuleControlFlag controlFlag;
047        private final Kernel kernel;
048    
049        //for reference.
050        public JaasLoginModuleUse() {
051            loginModule = null;
052            next = null;
053            controlFlag = null;
054            kernel = null;
055        }
056    
057        public JaasLoginModuleUse(LoginModuleSettings loginModule, JaasLoginModuleUse next, String controlFlag, Kernel kernel) {
058            this.loginModule = loginModule;
059            this.next = next;
060            LoginModuleControlFlagEditor editor = new LoginModuleControlFlagEditor();
061            editor.setAsText(controlFlag);
062            this.controlFlag = (LoginModuleControlFlag) editor.getValue();
063            this.kernel = kernel;
064        }
065    
066        public LoginModuleSettings getLoginModule() {
067            return loginModule;
068        }
069    
070        public JaasLoginModuleChain getNext() {
071            return next;
072        }
073    
074        public String getLoginModuleName() {
075            //TODO configId which is correct?
076    //        return kernel.getAbstractNameFor(loginModule).getObjectName().getCanonicalName();
077            return kernel.getAbstractNameFor(loginModule).toURI().toString();
078        }
079    
080        public String getNextName() {
081            if(next == null) {
082                return null;
083            }
084            //TODO configId which is correct?
085    //        return kernel.getAbstractNameFor(next).getObjectName().getCanonicalName();
086            return kernel.getAbstractNameFor(next).toURI().toString();
087        }
088    
089        public String getControlFlag() {
090            return controlFlag.toString();
091        }
092    
093        public void setControlFlag(String controlFlag) {
094            LoginModuleControlFlagEditor ed = new LoginModuleControlFlagEditor();
095            ed.setAsText(controlFlag);
096            this.controlFlag = (LoginModuleControlFlag) ed.getValue();
097        }
098    
099        public void configure(Set domainNames, List loginModuleConfigurations, Kernel kernel, ServerInfo serverInfo, ClassLoader classLoader) {
100            Map options = loginModule.getOptions();
101            if (options != null) {
102                options = new HashMap(options);
103            } else {
104                options = new HashMap();
105            }
106            if (kernel != null && !options.containsKey(KERNEL_NAME_LM_OPTION)) {
107                options.put(KERNEL_NAME_LM_OPTION, kernel.getKernelName());
108            }
109            if (serverInfo != null && !options.containsKey(SERVERINFO_LM_OPTION)) {
110                options.put(SERVERINFO_LM_OPTION, serverInfo);
111            }
112            if (classLoader != null && !options.containsKey(CLASSLOADER_LM_OPTION)) {
113                options.put(CLASSLOADER_LM_OPTION, classLoader);
114            }
115            if (loginModule.getLoginDomainName() != null) {
116                if (domainNames.contains(loginModule.getLoginDomainName())) {
117                    throw new IllegalStateException("Error in realm: one security realm cannot contain multiple login modules for the same login domain");
118                } else {
119                    domainNames.add(loginModule.getLoginDomainName());
120                }
121            }
122            JaasLoginModuleConfiguration config = new JaasLoginModuleConfiguration(loginModule.getLoginModuleClass(), controlFlag, options, loginModule.isServerSide(), loginModule.getLoginDomainName(), loginModule.isWrapPrincipals(), loginModule.getClassLoader());
123            loginModuleConfigurations.add(config);
124    
125            if (next != null) {
126                next.configure(domainNames, loginModuleConfigurations, kernel, serverInfo, classLoader);
127            }
128        }
129    
130        public static final GBeanInfo GBEAN_INFO;
131    
132        static {
133            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JaasLoginModuleUse.class, "LoginModuleUse");
134            infoBuilder.addAttribute("controlFlag", String.class, true);
135            infoBuilder.addAttribute("kernel", Kernel.class, false, false);
136            infoBuilder.addReference("LoginModule", LoginModuleSettings.class, NameFactory.LOGIN_MODULE);
137            infoBuilder.addReference("Next", JaasLoginModuleUse.class);
138    
139            infoBuilder.addOperation("configure", new Class[]{Set.class, List.class, Kernel.class, ServerInfo.class, ClassLoader.class});
140            infoBuilder.addInterface(JaasLoginModuleChain.class);
141            infoBuilder.setConstructor(new String[]{"LoginModule", "Next", "controlFlag", "kernel"});
142            GBEAN_INFO = infoBuilder.getBeanInfo();
143        }
144    
145        public static GBeanInfo getGBeanInfo() {
146            return GBEAN_INFO;
147        }
148    }