001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: Csiv2IorInterceptor.java 7963 2006-01-31 15:07:27Z pelletib $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas.security.iiop;
025:
026: import java.rmi.Remote;
027:
028: import javax.rmi.CORBA.Tie;
029:
030: import org.jacorb.orb.iiop.IIOPAddress;
031: import org.jacorb.orb.iiop.IIOPProfile;
032: import org.jacorb.poa.RequestProcessor;
033: import org.omg.CORBA.Any;
034: import org.omg.CORBA.INV_POLICY;
035: import org.omg.CSIIOP.AS_ContextSec;
036: import org.omg.CSIIOP.CompoundSecMech;
037: import org.omg.CSIIOP.CompoundSecMechList;
038: import org.omg.CSIIOP.CompoundSecMechListHelper;
039: import org.omg.CSIIOP.DetectMisordering;
040: import org.omg.CSIIOP.DetectReplay;
041: import org.omg.CSIIOP.Integrity;
042: import org.omg.CSIIOP.SAS_ContextSec;
043: import org.omg.CSIIOP.ServiceConfiguration;
044: import org.omg.CSIIOP.TAG_CSI_SEC_MECH_LIST;
045: import org.omg.CSIIOP.TAG_NULL_TAG;
046: import org.omg.CSIIOP.TAG_TLS_SEC_TRANS;
047: import org.omg.CSIIOP.TLS_SEC_TRANS;
048: import org.omg.CSIIOP.TLS_SEC_TRANSHelper;
049: import org.omg.IOP.Codec;
050: import org.omg.IOP.TAG_INTERNET_IOP;
051: import org.omg.IOP.TaggedComponent;
052: import org.omg.IOP.CodecPackage.InvalidTypeForEncoding;
053: import org.omg.PortableInterceptor.IORInfo;
054: import org.omg.PortableServer.Servant;
055: import org.omg.SSLIOP.SSL;
056: import org.omg.SSLIOP.SSLHelper;
057: import org.omg.SSLIOP.TAG_SSL_SEC_TRANS;
058:
059: import org.objectweb.carol.util.csiv2.SasComponent;
060: import org.objectweb.carol.util.csiv2.SasPolicy;
061: import org.objectweb.carol.util.csiv2.struct.AsStruct;
062: import org.objectweb.carol.util.csiv2.struct.SasStruct;
063: import org.objectweb.carol.util.csiv2.struct.TransportStruct;
064:
065: import org.objectweb.jonas_ejb.container.JHome;
066: import org.objectweb.jonas_ejb.container.JRemote;
067: import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
068:
069: import org.objectweb.util.monolog.api.BasicLevel;
070: import org.objectweb.util.monolog.api.Logger;
071:
072: /**
073: * IOR interceptor for the supports of CSiv2 level 0 as described by chapter
074: * 19.8.2.5 Stateful support is not require for level 0
075: * @author Florent Benoit
076: * @see Common Secure Interoperability V2 Specification (July 23,2001)
077: */
078: public class Csiv2IorInterceptor extends org.omg.CORBA.LocalObject
079: implements org.omg.PortableInterceptor.IORInterceptor {
080:
081: /**
082: * Name
083: */
084: private static final String NAME = "Csiv2IorInterceptor";
085:
086: /**
087: * Codec to use (when encoding Any object)
088: */
089: private Codec codec = null;
090:
091: /**
092: * Logger to use
093: */
094: private Logger logger = null;
095:
096: /**
097: * Logger details (On catching exception)
098: */
099: private Logger loggerDetails = null;
100:
101: /**
102: * Constructor
103: * @param codec used for encoding any objects
104: * @param logger used for logging useful information
105: * @param loggerDetails for all information (useless for most time :)
106: */
107: public Csiv2IorInterceptor(Codec codec, Logger logger,
108: Logger loggerDetails) {
109: this .codec = codec;
110: this .logger = logger;
111: this .loggerDetails = loggerDetails;
112: }
113:
114: /**
115: * Check if there is a CSI v2 policy and there is one add the csiv2
116: * component into the IOR. The tagged Component is built from information of
117: * csiv2 policy object
118: * @see org.omg.PortableInterceptor.IORInterceptorOperations#establish_components(org.omg.PortableInterceptor.IORInfo)
119: */
120: public void establish_components(IORInfo info) {
121: SasPolicy sasPolicy = null;
122: SasComponent sasComponent = null;
123:
124: try {
125: sasPolicy = (SasPolicy) info
126: .get_effective_policy(SasPolicy.POLICY_TYPE);
127:
128: // build CSiv2 tagged component as required by spec
129: // 16.3.1 compound mechnaisms [62] and 16.5.1 [132]
130: TaggedComponent taggedComponent = null;
131:
132: if (sasPolicy != null) {
133: sasComponent = sasPolicy.getSasComponent();
134: } else {
135: // It may be a remote interface
136: Thread currentThread = Thread.currentThread();
137: if (!(currentThread instanceof RequestProcessor)) {
138: return;
139: }
140: RequestProcessor rp = (RequestProcessor) currentThread;
141: Servant servant = rp.getServant();
142: if (servant == null) {
143: return;
144: }
145: Tie tie = null;
146: if (!(servant instanceof Tie)) {
147: return;
148: }
149: tie = (Tie) servant;
150: Remote target = tie.getTarget();
151: if (target == null) {
152: return;
153: }
154:
155: if (!(target instanceof JHome)
156: && !(target instanceof JRemote)) {
157: return;
158: }
159: BeanDesc bd = null;
160: if (target instanceof JHome) {
161: bd = ((JHome) target).getDd();
162: } else if (target instanceof JRemote) {
163: bd = ((JRemote) target).getBf()
164: .getDeploymentDescriptor();
165: }
166: sasComponent = bd.getSasComponent();
167: }
168:
169: if (sasComponent == null) {
170: if (loggerDetails.isLoggable(BasicLevel.DEBUG)) {
171: loggerDetails
172: .log(BasicLevel.DEBUG,
173: "No Sas component was found, will not write any infos into IOR.");
174: }
175: return;
176: }
177:
178: try {
179:
180: taggedComponent = buildCSIv2Component(sasComponent);
181:
182: // And add it into the ior
183: info.add_ior_component_to_profile(taggedComponent,
184: TAG_INTERNET_IOP.value);
185:
186: } catch (Csiv2InterceptorException cie) {
187: logger.log(BasicLevel.ERROR,
188: "Cannot build Csiv2 component, cannot add it. Component = "
189: + taggedComponent);
190: }
191:
192: } catch (INV_POLICY e) {
193: if (logger.isLoggable(BasicLevel.DEBUG)) {
194: logger.log(BasicLevel.DEBUG, "No policy found");
195: }
196:
197: } finally {
198:
199: // Add SSL
200: if (sasComponent != null) {
201: // Need to patch profile port if SSL (port should be 0)
202: TransportStruct transportStruct = sasComponent
203: .getTransport();
204: if (transportStruct.getTargetRequires() > 0) {
205: org.omg.ETF.Profile profile = ((org.jacorb.orb.portableInterceptor.IORInfoImpl) info)
206: .get_profile(0);
207: if (profile instanceof IIOPProfile) {
208: if (logger.isLoggable(BasicLevel.DEBUG)) {
209: logger.log(BasicLevel.DEBUG,
210: "Set port to 0");
211: }
212:
213: IIOPProfile iiopp = (IIOPProfile) profile;
214: IIOPAddress iiopa = (IIOPAddress) iiopp
215: .getAddress();
216: iiopa.setPort(0);
217: ((IIOPProfile) profile)
218: .patchPrimaryAddress(iiopa);
219:
220: }
221: }
222: }
223:
224: try {
225: info.add_ior_component_to_profile(
226: buildSslTaggedComponent(sasComponent),
227: TAG_INTERNET_IOP.value);
228: } catch (Csiv2InterceptorException cie) {
229: logger.log(BasicLevel.ERROR,
230: "Cannot add SSL tagged component"
231: + cie.getMessage(), cie);
232: }
233:
234: }
235:
236: }
237:
238: /**
239: * Provides an opportunity to destroy this interceptor.
240: */
241: public void destroy() {
242: }
243:
244: /**
245: * Returns the name of the interceptor.
246: * @return the name of the interceptor.
247: */
248: public String name() {
249: return NAME;
250: }
251:
252: /**
253: * CSIv2 component is built from info within sasComponent which was
254: * contained in the policy object during the bind of the object <br>
255: * 16.4.2 Transport Mechanism Configuration <br>
256: * [113] The configuration of transport-layer security mechanisms is
257: * specified in IORs. Support for CSI is indicated within an IOR profile by
258: * the presence of at most one TAG_CSI_SEC_MECH_LIST tagged component that
259: * defines the mechanism configuration pertaining to the profile. This
260: * component contains a list of one or more CompoundSecMech structures, each
261: * of which defines the layer-specific security mechanisms that comprise a
262: * compound mechanism that is supported by the target. This specification
263: * does not define support for CSI mechanisms in multiple-component IOR
264: * profiles. <br>
265: * [114] Each CompoundSecMech structure contains a transport_mech field that
266: * defines the transport-layer security mechanism of the compound mechanism.
267: * A compound mechanism that does not implement security functionality at
268: * the transport layer shall contain the TAG_NULL_TAG component in its
269: * transport_mech field. Otherwise, the transport_mech field shall contain a
270: * tagged component that defines a transport protocol and its configuration.
271: * Section , TAG_SSL_SEC_TRANS, on page 16-33 and Section ,
272: * TAG_SECIOP_SEC_TRANS, on page 16-34 define valid transportlayer
273: * components that can be used in the transport_mech field.
274: * @param sasComponent information to build component
275: * @return CSIv2 component to be put in IOR
276: * @throws Csiv2InterceptorException if there is a failure
277: */
278: private TaggedComponent buildCSIv2Component(
279: SasComponent sasComponent) throws Csiv2InterceptorException {
280: if (logger.isLoggable(BasicLevel.DEBUG)) {
281: logger.log(BasicLevel.DEBUG, "");
282: }
283:
284: // @see 16.5.1 [132] SecMechList
285: // build list of compound_sec_mech
286: CompoundSecMech[] mechanismList = buildCompoundSecMechs(sasComponent);
287: CompoundSecMechList compoundSecMechList = new CompoundSecMechList(
288: Csiv2Const.STATEFUL_MODE, mechanismList);
289:
290: // use Any object
291: Any pAny = ORBHelper.getOrb().create_any();
292: CompoundSecMechListHelper.insert(pAny, compoundSecMechList);
293: byte[] componentData = null;
294: try {
295: componentData = codec.encode_value(pAny);
296: } catch (InvalidTypeForEncoding itfe) {
297: throw new Csiv2InterceptorException(
298: "Cannot encode a given any corba object", itfe);
299: }
300:
301: // Create tagged component TAG_CSI_SEC_MECH_LIST
302: TaggedComponent taggedComponent = new TaggedComponent(
303: TAG_CSI_SEC_MECH_LIST.value, componentData);
304:
305: return taggedComponent;
306: }
307:
308: /**
309: * Build all CompoundSecMech objects for building TAG_CSI_SEC_MECH_LIST
310: * CompoundSecMech is composed of (see [132] 16.5.1 p16-35)
311: * <ul>
312: * <li>target_requires</li>
313: * <li>transport_mech</li>
314: * <li>as_context_mech</li>
315: * <li>sas_context_mech</li>
316: * </ul>
317: * @param sasComponent information to build component
318: * @return CompoundSecMech objects for building TAG_CSI_SEC_MECH_LIST
319: * @throws Csiv2InterceptorException if there is a failure
320: */
321: private CompoundSecMech[] buildCompoundSecMechs(
322: SasComponent sasComponent) throws Csiv2InterceptorException {
323: if (logger.isLoggable(BasicLevel.DEBUG)) {
324: logger.log(BasicLevel.DEBUG, "");
325: }
326:
327: // build transport_mech
328: TaggedComponent transportMech = buildTransportMech(sasComponent);
329:
330: // build as_context_mech
331: AS_ContextSec asContextMech = buildAsContextMech(sasComponent);
332:
333: // build sas_context_mech
334: SAS_ContextSec sasContextMech = buildSasContextMech(sasComponent);
335:
336: // See [135]
337: // The target_requires field of the CompoundSecMech structure is used to
338: // designate a required outcome that shall be satisfied by one or more
339: // supporting (but not requiring) layers. The target_requires field also
340: // represents all the options required independently by the various
341: // layers as defined within the mechanism.
342: short targetRequires = (short) (sasComponent.getTransport()
343: .getTargetRequires()
344: | asContextMech.target_requires | sasContextMech.target_requires);
345:
346: // Only one compound sec mech
347: CompoundSecMech[] compoundSecMechs = new CompoundSecMech[1];
348: compoundSecMechs[0] = new CompoundSecMech(targetRequires,
349: transportMech, asContextMech, sasContextMech);
350:
351: // return objects
352: return compoundSecMechs;
353: }
354:
355: /**
356: * Build the transport mech object of the Sas component
357: * @param sasComponent information to build component
358: * @return transport mech object
359: * @throws Csiv2InterceptorException if there is a failure
360: */
361: private TaggedComponent buildTransportMech(SasComponent sasComponent)
362: throws Csiv2InterceptorException {
363:
364: TaggedComponent taggedComponent = null;
365:
366: TransportStruct transportStruct = sasComponent.getTransport();
367:
368: if (transportStruct.getTargetSupports() == 0
369: && transportStruct.getTargetRequires() == 0) {
370: // TAG_NULL_TAG [150] This new tagged component is used in the
371: // transport_mech field of a CompoundSecMech structure to indicate that
372: // the compound mechanism does not implement security functionality at
373: // the transport layer.
374:
375: return new TaggedComponent(TAG_NULL_TAG.value,
376: Csiv2Const.EMPTY_BYTES);
377: }
378:
379: /**
380: * Tagged component for configuring TLS/SSL as a CSIv2 transport
381: * mechanism is the constant : IOP::ComponentId TAG_TLS_SEC_TRANS = 36;
382: */
383: TLS_SEC_TRANS tlsSecTrans = new TLS_SEC_TRANS(transportStruct
384: .getTargetSupports(), transportStruct
385: .getTargetRequires(), transportStruct
386: .getTransportAddress());
387:
388: // use Any object
389: Any pAny = ORBHelper.getOrb().create_any();
390: TLS_SEC_TRANSHelper.insert(pAny, tlsSecTrans);
391: byte[] componentData = null;
392: try {
393: componentData = codec.encode_value(pAny);
394: } catch (InvalidTypeForEncoding itfe) {
395: throw new Csiv2InterceptorException(
396: "Cannot encode a given any corba object", itfe);
397: }
398:
399: // Create tagged component TAG_CSI_SEC_MECH_LIST
400: taggedComponent = new TaggedComponent(TAG_TLS_SEC_TRANS.value,
401: componentData);
402:
403: return taggedComponent;
404: }
405:
406: /**
407: * Build SSL tagged component
408: * @param sasComponent information for build component
409: * @return SSL tagged component
410: * @throws Csiv2InterceptorException if the SSL tagged cannot be built
411: */
412: private TaggedComponent buildSslTaggedComponent(
413: SasComponent sasComponent) throws Csiv2InterceptorException {
414:
415: SSL ssl = null;
416: int minSSlOptions = Integrity.value | DetectReplay.value
417: | DetectMisordering.value;
418: if (sasComponent != null) {
419: TransportStruct transportStruct = sasComponent
420: .getTransport();
421:
422: ssl = new SSL(transportStruct.getTargetSupports(),
423: transportStruct.getTargetRequires(),
424: (short) TransportStruct.getSslPort());
425: } else {
426: ssl = new SSL((short) minSSlOptions, (short) 0,
427: (short) TransportStruct.getSslPort());
428: }
429:
430: // use Any object
431: Any pAny = ORBHelper.getOrb().create_any();
432: SSLHelper.insert(pAny, ssl);
433: byte[] componentData = null;
434: try {
435: componentData = codec.encode_value(pAny);
436: } catch (InvalidTypeForEncoding itfe) {
437: throw new Csiv2InterceptorException(
438: "Cannot encode a given any corba object", itfe);
439: }
440: return new TaggedComponent(TAG_SSL_SEC_TRANS.value,
441: componentData);
442:
443: }
444:
445: /**
446: * Build the Authentication service object of the Sas component
447: * @param sasComponent information to build component
448: * @return Authentication service object
449: */
450: private AS_ContextSec buildAsContextMech(SasComponent sasComponent) {
451:
452: AsStruct asStruct = sasComponent.getAs();
453:
454: // The asStruct object could be for authenticated or no authenticated
455: AS_ContextSec asContextMech = new AS_ContextSec(asStruct
456: .getTargetSupports(), asStruct.getTargetRequires(),
457: asStruct.getClientAuthenticationMech(), asStruct
458: .getTargetName());
459:
460: return asContextMech;
461:
462: }
463:
464: /**
465: * Build the Secure Authentication service object of the Sas component
466: * @param sasComponent information to build component
467: * @return Secure Authentication service
468: */
469: private SAS_ContextSec buildSasContextMech(SasComponent sasComponent) {
470:
471: SasStruct sasStruct = sasComponent.getSas();
472:
473: /**
474: * The privilege_authorities field contains a list of the names of 0 or
475: * more privilege authorities in decreasing order of target preference.
476: * A non-empty list indicates that the target supports authorization
477: * tokens provided by a CSS (in EstablishContext messages) and acquired
478: * from a named privilege authority. For us, always empty.
479: */
480: ServiceConfiguration[] privilegeAuthorities = new ServiceConfiguration[0];
481:
482: byte[][] supportedNamingMechanisms = sasStruct
483: .getSupportedNamingMechanisms();
484: if (logger.isLoggable(BasicLevel.DEBUG)) {
485: logger.log(BasicLevel.DEBUG, "supported mechanisms = "
486: + supportedNamingMechanisms + " and identity = "
487: + sasStruct.getSupportedIdentityTypes());
488: logger.log(BasicLevel.DEBUG, "supported mechanisms size= "
489: + supportedNamingMechanisms.length);
490: logger.log(BasicLevel.DEBUG, "target supports= "
491: + sasStruct.getTargetSupports());
492: }
493: /**
494: * A target that supports identity assertion shall include in its IORs
495: * the complete list of GSS mechanisms for which it supports identity
496: * assertions using an identity token of type ITTPrincipalName. A TSS
497: * shall reject requests that carry identity tokens of type
498: * ITTPrincipalName constructed using a GSS mechanism that is not among
499: * the GSS mechanisms supported by the target. The definition of a
500: * target s list of supported GSS naming mechanisms is defined in
501: * Section , struct SAS_ContextSec, on page 16-37.
502: */
503: // should be ITTPrincipalName if supported
504: int supportedIdentityTypes = sasStruct
505: .getSupportedIdentityTypes();
506:
507: // build sas context with info of the given object.
508: SAS_ContextSec sasContextMech = new SAS_ContextSec(sasStruct
509: .getTargetSupports(), sasStruct.getTargetRequires(),
510: privilegeAuthorities, supportedNamingMechanisms,
511: supportedIdentityTypes);
512:
513: return sasContextMech;
514: }
515:
516: }
|