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    package org.apache.geronimo.corba;
018    
019    import java.net.URI;
020    
021    import javax.transaction.TransactionManager;
022    
023    import org.apache.commons.logging.Log;
024    import org.apache.commons.logging.LogFactory;
025    import org.apache.geronimo.gbean.AbstractName;
026    import org.apache.geronimo.gbean.GBeanLifecycle;
027    import org.apache.geronimo.gbean.InvalidConfigurationException; 
028    import org.apache.geronimo.corba.security.config.ConfigAdapter;
029    import org.apache.geronimo.corba.security.config.css.CSSConfig;
030    import org.apache.geronimo.corba.security.config.ssl.SSLConfig;
031    import org.apache.geronimo.corba.security.config.tss.TSSConfig;
032    import org.apache.geronimo.corba.security.ClientPolicy;
033    import org.apache.geronimo.corba.transaction.ClientTransactionPolicyConfig;
034    import org.apache.geronimo.corba.transaction.ClientTransactionPolicy;
035    import org.apache.geronimo.corba.transaction.nodistributedtransactions.NoDTxClientTransactionPolicyConfig;
036    import org.apache.geronimo.corba.util.Util;
037    import org.omg.CORBA.ORB;
038    import org.omg.CORBA.UserException;
039    import org.omg.CORBA.PolicyManager;
040    import org.omg.CORBA.Policy;
041    import org.omg.CORBA.SetOverrideType;
042    import org.omg.CosNaming.NameComponent;
043    import org.omg.CosNaming.NamingContextExt;
044    import org.omg.CosNaming.NamingContextExtHelper;
045    
046    
047    /**
048     * A CSSBean is an ORB instance configured for
049     * accessing EJBs using a specific security profile.  A single
050     * CSSBean can be referenced by multiple ejb-refs that share a
051     * common security profile.
052     *
053     * For each CSSBean instance, there will be a backing
054     * ORB configured with the appropriate interceptors and
055     * principal information to access the target object.
056     * @version $Revision: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
057     */
058    public class CSSBean implements GBeanLifecycle, ORBConfiguration {
059    
060        private final static Log log = LogFactory.getLog(CSSBean.class);
061    
062        private final ClassLoader classLoader;
063        private final ConfigAdapter configAdapter;
064        private final TransactionManager transactionManager;
065        private String description;
066        private CSSConfig cssConfig;
067        private SSLConfig sslConfig;
068        // ORB used for activating and accessing the target bean.
069        private ORB cssORB;
070        // ORB used for nameservice lookups.
071        private ORB nssORB;
072        private AbstractName abstractName;
073    
074        public CSSBean() {
075            this.classLoader = null;
076            this.configAdapter = null;
077            this.transactionManager = null;
078            this.abstractName = null;
079            this.sslConfig = null;
080            this.cssConfig = null;
081        }
082    
083        public CSSBean(ConfigAdapter configAdapter, TransactionManager transactionManager, SSLConfig ssl, AbstractName abstractName, ClassLoader classLoader) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
084            this.abstractName = abstractName;
085            this.classLoader = classLoader;
086            this.transactionManager = transactionManager;
087            this.configAdapter = configAdapter;
088            this.sslConfig = ssl;
089        }
090    
091        public String getDescription() {
092            return description;
093        }
094    
095        public void setDescription(String description) {
096            this.description = description;
097        }
098    
099        public CSSConfig getCssConfig() {
100            return cssConfig;
101        }
102    
103        public void setCssConfig(CSSConfig config) {
104            if (config == null) config = new CSSConfig();
105            this.cssConfig = config;
106        }
107    
108        public TSSConfig getTssConfig() {
109            // just return a default no security one.
110            return new TSSConfig();
111        }
112    
113        /**
114         * Return the SSLConfig used for this ORB instance.
115         * if one has not been configured, this returns
116         * a default configuration.
117         *
118         * @return The SSLConfig object use to manage transport-level
119         *         security.
120         */
121        public SSLConfig getSslConfig() {
122            if (sslConfig == null) {
123                sslConfig = new SSLConfig();
124            }
125            return sslConfig;
126        }
127    
128        public ORB getORB() {
129            return cssORB;
130        }
131    
132        /**
133         * Return the retrieval URI for this bean.
134         *
135         * @return The URI for the bean AbstractName;
136         */
137        public String getURI() {
138            return abstractName.toString();
139        }
140    
141        public org.omg.CORBA.Object getHome(URI nsURI, String name) {
142    
143            if (log.isDebugEnabled())
144                log.debug(description + " - Looking up home from " + nsURI.toString() + " at " + name);
145    
146            try {
147                // The following may seem unncecessary, but it isn't.  We need to use one ORB to
148                // retrieve the object reference from the NameService because the SecurityInterceptor
149                // attached to the main ORB instance may add additional service contexts to the
150                // NameService request that will cause failures.  We use one configuration to access
151                // the server, and the activate the object on the real one.
152                org.omg.CORBA.Object ref = nssORB.string_to_object(nsURI.toString());
153                NamingContextExt ic = NamingContextExtHelper.narrow(ref);
154    
155                NameComponent[] nameComponent = ic.to_name(name);
156                org.omg.CORBA.Object bean = ic.resolve(nameComponent);
157    
158                // Ok, now we have an object reference from the naming service, but we need to 
159                // activate that object on the cssORB instance before we hand it out.  Activating it 
160                // on the cssORB will ensure that all of the interceptors and policies we define on the 
161                // cssORB will get used for all requests involving this bean. 
162                String beanIOR = nssORB.object_to_string(bean);
163                bean = cssORB.string_to_object(beanIOR);
164    
165                return bean;
166            } catch (NoSuchMethodError e) {
167                log.error("Incorrect level of org.omg.CORBA classes found.\nLikely cause is an incorrect java.endorsed.dirs configuration"); 
168                throw new InvalidConfigurationException("CORBA usage requires Yoko CORBA spec classes in java.endorsed.dirs classpath", e); 
169            } catch (UserException ue) {
170                log.error(description + " - Looking up home", ue);
171                throw new RuntimeException(description + " - Looking up home", ue);
172            }
173        }
174    
175        /**
176         * Start this GBean instance, which essentially
177         * sets up an ORB and configures a client context
178         * for handling requests.
179         *
180         * @exception Exception
181         */
182        public void doStart() throws Exception {
183    
184            // we create a dummy CSSConfig if one has not be specified prior to this.
185            if (cssConfig == null) {
186                cssConfig = new CSSConfig();
187            }
188    
189            ClassLoader savedLoader = Thread.currentThread().getContextClassLoader();
190            try {
191                log.debug("Starting CSS ORB " + getURI());
192    
193                Thread.currentThread().setContextClassLoader(classLoader);
194                // register this so we can retrieve this in the interceptors 
195                Util.registerORB(getURI(), this); 
196    
197                // create an ORB using the name service.
198                nssORB = configAdapter.createNameServiceClientORB(this);
199                // the configAdapter creates the ORB instance for us.
200                cssORB = configAdapter.createClientORB(this);
201                PolicyManager policyManager = (PolicyManager) cssORB.resolve_initial_references("ORBPolicyManager");
202                Policy[] policies = new Policy[] {new ClientPolicy(cssConfig), new ClientTransactionPolicy(buildClientTransactionPolicyConfig())};
203                policyManager.set_policy_overrides(policies, SetOverrideType.ADD_OVERRIDE);
204            } finally {
205                Thread.currentThread().setContextClassLoader(savedLoader);
206            }
207    
208            log.debug("Started CORBA Client Security Server - " + description);
209        }
210    
211        private ClientTransactionPolicyConfig buildClientTransactionPolicyConfig() {
212            return new NoDTxClientTransactionPolicyConfig(transactionManager);
213        }
214    
215        public void doStop() throws Exception {
216            cssORB.destroy();
217            nssORB.destroy();
218            // remove this from the registry 
219            Util.unregisterORB(getURI()); 
220            cssORB = null;
221            nssORB = null;
222            log.debug("Stopped CORBA Client Security Server - " + description);
223        }
224    
225        public void doFail() {
226            log.debug("Failed CORBA Client Security Server " + description);
227        }
228    
229    }