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 org.apache.commons.logging.Log;
020 import org.apache.commons.logging.LogFactory;
021 import org.apache.geronimo.gbean.GBeanLifecycle;
022 import org.apache.geronimo.gbean.InvalidConfigurationException;
023 import org.omg.CORBA.Any;
024 import org.omg.CORBA.ORB;
025 import org.omg.CORBA.Policy;
026 import org.omg.CosNaming.NamingContextExt;
027 import org.omg.CosNaming.NamingContextExtHelper;
028 import org.omg.PortableServer.IdAssignmentPolicyValue;
029 import org.omg.PortableServer.ImplicitActivationPolicyValue;
030 import org.omg.PortableServer.LifespanPolicyValue;
031 import org.omg.PortableServer.POA;
032 import org.omg.PortableServer.RequestProcessingPolicyValue;
033 import org.omg.PortableServer.ServantRetentionPolicyValue;
034 import org.apache.geronimo.corba.security.ServerPolicy;
035 import org.apache.geronimo.corba.security.ServerPolicyFactory;
036 import org.apache.geronimo.corba.security.config.tss.TSSConfig;
037 import org.apache.geronimo.corba.security.config.tss.TSSNULLTransportConfig;
038
039 import java.util.HashMap;
040 import java.util.Map;
041
042 /**
043 * A TSSBean represents a transport-level security profile for exported EJB objects. An
044 * exported object is attached to a TSSBean-created named POA. The TSSBean POA
045 * is created in the context of the ORB controlled by a CORBABean instance.
046 * The parent CORBABean controls the transport-level security of the host connection and
047 * defines the endpoint connnection for the object (host and listener port).
048 * TSSBean may then define additional characteristics that
049 * get encoded in the IOR of the connection.
050 * @version $Revision: 497125 $ $Date: 2007-01-17 10:51:30 -0800 (Wed, 17 Jan 2007) $
051 */
052 public class TSSBean implements GBeanLifecycle {
053
054 private final Log log = LogFactory.getLog(TSSBean.class);
055
056 private final ClassLoader classLoader;
057 private final String POAName;
058 private final CORBABean server;
059 private POA localPOA;
060 private NamingContextExt initialContext;
061 private TSSConfig tssConfig;
062 private final Map adapters = new HashMap();
063 private Policy securityPolicy;
064
065 /**
066 * gbean endpoint constructor
067 */
068 public TSSBean() {
069 classLoader = null;
070 POAName = null;
071 server = null;
072 }
073
074 public TSSBean(ClassLoader classLoader, String POAName, CORBABean server) {
075 this.classLoader = classLoader;
076 this.POAName = POAName;
077 this.server = server;
078 }
079
080 public CORBABean getServer() {
081 return server;
082 }
083
084 public String getPOAName() {
085 return POAName;
086 }
087
088 public TSSConfig getTssConfig() {
089 return tssConfig;
090 }
091
092 public void setTssConfig(TSSConfig tssConfig) {
093 if (tssConfig == null) tssConfig = new TSSConfig();
094 this.tssConfig = tssConfig;
095 }
096
097 /**
098 * TODO: Security policy really shouldn't be inserted if there is not CSI
099 * config to put into it.
100 *
101 * @throws Exception
102 */
103 public void doStart() throws Exception {
104 ClassLoader savedLoader = Thread.currentThread().getContextClassLoader();
105 try {
106 Thread.currentThread().setContextClassLoader(classLoader);
107
108 ORB orb = server.getORB();
109 POA rootPOA = server.getRootPOA();
110
111 Any any = orb.create_any();
112 any.insert_Value(new ServerPolicy.Config(createCSIv2Config(), classLoader));
113
114 securityPolicy = orb.create_policy(ServerPolicyFactory.POLICY_TYPE, any);
115 Policy[] policies = new Policy[]{
116 securityPolicy,
117 rootPOA.create_lifespan_policy(LifespanPolicyValue.TRANSIENT),
118 rootPOA.create_request_processing_policy(RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY),
119 rootPOA.create_servant_retention_policy(ServantRetentionPolicyValue.RETAIN),
120 rootPOA.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID),
121 rootPOA.create_implicit_activation_policy(ImplicitActivationPolicyValue.NO_IMPLICIT_ACTIVATION),
122 };
123 // there may be ORB-specific policy overrides required.
124 policies = server.addPolicyOverrides(policies);
125
126 localPOA = rootPOA.create_POA(POAName, rootPOA.the_POAManager(), policies);
127
128 localPOA.the_POAManager().activate();
129
130 org.omg.CORBA.Object obj = server.getORB().resolve_initial_references("NameService");
131 // NB: This is initial context is never used by the TSSBean, but we request it here
132 // to verify that the server ORB is correctly configured and our target server is accessible.
133 initialContext = NamingContextExtHelper.narrow(obj);
134 } catch (NoSuchMethodError e) {
135 log.error("Incorrect level of org.omg.CORBA classes found.\nLikely cause is an incorrect java.endorsed.dirs configuration");
136 throw new InvalidConfigurationException("CORBA usage requires Yoko CORBA spec classes in java.endorsed.dirs classpath", e);
137 } finally {
138 Thread.currentThread().setContextClassLoader(savedLoader);
139 }
140
141 log.debug("Started CORBA Target Security Service in POA " + POAName);
142 }
143
144 public void doStop() throws Exception {
145 if (localPOA != null) {
146 // make sure this POA is destroyed so the bean can be potentially restarted.
147 // NOTE: we do NOT deactivate() the poa manager, as that will take down any
148 // other POAs attached to the same manager. Just destroying this POA is sufficient.
149 localPOA.destroy(true, false);
150 localPOA = null;
151 }
152 log.debug("Stopped CORBA Target Security Service in POA " + POAName);
153 }
154
155 public void doFail() {
156 log.warn("Failed CORBA Target Security Service in POA " + POAName);
157 }
158
159 private TSSConfig createCSIv2Config() {
160 if (tssConfig == null) return null;
161 if (tssConfig.isInherit()) return server.getTssConfig();
162
163 TSSConfig config = new TSSConfig();
164
165 if (server.getTssConfig() != null) {
166 config.setTransport_mech(server.getTssConfig().getTransport_mech());
167 } else {
168 config.setTransport_mech(new TSSNULLTransportConfig());
169 }
170
171 config.getMechListConfig().setStateful(tssConfig.getMechListConfig().isStateful());
172 for (int i = 0; i < tssConfig.getMechListConfig().size(); i++) {
173 config.getMechListConfig().add(tssConfig.getMechListConfig().mechAt(i));
174 }
175
176 return config;
177 }
178
179 public void registerContainer(TSSLink tssLink) throws CORBAException {
180 AdapterWrapper adapterWrapper = new AdapterWrapper(tssLink);
181
182 adapterWrapper.start(server.getORB(), localPOA, securityPolicy);
183 adapters.put(tssLink.getContainerId(), adapterWrapper);
184
185 log.debug(POAName + " - Linked container " + tssLink.getContainerId());
186 }
187
188 public void unregisterContainer(TSSLink tssLink) {
189 AdapterWrapper adapterWrapper = (AdapterWrapper) adapters.remove(tssLink.getContainerId());
190 if (adapterWrapper != null) {
191 try {
192 adapterWrapper.stop();
193 log.debug(POAName + " - Unlinked container " + tssLink.getContainerId());
194 } catch (CORBAException e) {
195 log.error(POAName + " - Error unlinking container " + tssLink.getContainerId(), e);
196 }
197 }
198 }
199
200 /**
201 * Add the policy overrides (if any) to the list
202 * of policies used to create a POA instance.
203 *
204 * @param policies The base set of policies.
205 *
206 * @return A new Policy array with the overrides added. Returns
207 * the same array if no overrides are required.
208 */
209 public Policy[] addPolicyOverrides(Policy[] policies) {
210 return server.addPolicyOverrides(policies);
211 }
212 }