001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020: /**
021: * $Id: SecurityPluginUtil.java,v 1.3 2007/08/24 09:12:49 kumarjayanti Exp $
022: *
023: * Copyright 2004 Sun Microsystems, Inc. All rights reserved. SUN
024: * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
025: */package com.sun.xml.rpc.security;
026:
027: import java.util.Iterator;
028:
029: import org.w3c.dom.Attr;
030: import org.w3c.dom.Node;
031: import org.w3c.dom.NodeList;
032:
033: import javax.xml.soap.Name;
034: import javax.xml.soap.SOAPBody;
035: import javax.xml.soap.SOAPPart;
036: import javax.xml.soap.SOAPHeader;
037: import javax.xml.soap.SOAPMessage;
038: import javax.xml.soap.SOAPElement;
039: import javax.xml.soap.SOAPEnvelope;
040:
041: import javax.xml.namespace.QName;
042:
043: import java.io.ByteArrayInputStream;
044:
045: import javax.security.auth.callback.CallbackHandler;
046:
047: import javax.xml.rpc.JAXRPCException;
048: import javax.xml.rpc.soap.SOAPFaultException;
049: import javax.xml.rpc.handler.soap.SOAPMessageContext;
050:
051: import com.sun.xml.wss.impl.MessageConstants;
052: import com.sun.xml.wss.ProcessingContext;
053: import com.sun.xml.wss.impl.SecurityAnnotator;
054: import com.sun.xml.wss.impl.SecurityRecipient;
055: import com.sun.xml.wss.impl.SecurableSoapMessage;
056: import com.sun.xml.wss.XWSSecurityException;
057: import com.sun.xml.wss.XWSSecurityException;
058: import com.sun.xml.wss.impl.WssSoapFaultException;
059: import com.sun.xml.wss.impl.PolicyViolationException;
060: import com.sun.xml.wss.impl.PolicyTypeUtil;
061:
062: import com.sun.xml.wss.impl.filter.DumpFilter;
063:
064: import com.sun.xml.rpc.client.StreamingSenderState;
065: import com.sun.xml.rpc.server.StreamingHandlerState;
066:
067: import com.sun.xml.wss.impl.policy.SecurityPolicy;
068:
069: import com.sun.xml.wss.impl.policy.mls.DynamicSecurityPolicy;
070: import com.sun.xml.wss.impl.configuration.StaticApplicationContext;
071: import com.sun.xml.wss.impl.config.SecurityConfigurationXmlReader;
072: import com.sun.xml.wss.impl.config.ApplicationSecurityConfiguration;
073: import com.sun.xml.wss.impl.config.DeclarativeSecurityConfiguration;
074:
075: import com.sun.xml.wss.SecurityEnvironment;
076: import com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl;
077:
078: public class SecurityPluginUtil {
079:
080: String port = null;
081:
082: private CallbackHandler _callbackHandler = null;
083: private SecurityEnvironment _securityEnvironment = null;
084:
085: private ApplicationSecurityConfiguration _sConfig = null;
086:
087: private static final String CONTEXT_OPERATION = "context.operation.name";
088:
089: public SecurityPluginUtil(String config, String port, boolean isStub)
090: throws Exception {
091: if (config != null) {
092: // look for and remove version tag
093: int versionStart = config.indexOf('[');
094: if (versionStart != -1) {
095: int versionEnd = config.indexOf(']');
096: // versionEnd better not be -1!
097: // In future versions we can treat
098: // the config string differently depending
099: // on the version string.
100: config = config.substring(versionEnd + 1);
101: }
102:
103: this .port = port;
104:
105: _sConfig = SecurityConfigurationXmlReader
106: .createApplicationSecurityConfiguration(new ByteArrayInputStream(
107: config.getBytes()));
108:
109: _callbackHandler = (CallbackHandler) Class.forName(
110: _sConfig.getSecurityEnvironmentHandler(), true,
111: Thread.currentThread().getContextClassLoader())
112: .newInstance();
113: _securityEnvironment = new DefaultSecurityEnvironmentImpl(
114: _callbackHandler);
115:
116: }
117: }
118:
119: private void copyToMessageContext(
120: SOAPMessageContext messageContext, ProcessingContext context)
121: throws Exception {
122: messageContext.setMessage(context.getSOAPMessage());
123:
124: Iterator i = context.getExtraneousProperties().keySet()
125: .iterator();
126: while (i.hasNext()) {
127: String name = (String) i.next();
128: Object value = context.getExtraneousProperties().get(name);
129: messageContext.setProperty(name, value);
130: }
131: }
132:
133: private void copyToProcessingContext(ProcessingContext context,
134: SOAPMessageContext messageContext) throws Exception {
135: context.setSOAPMessage(messageContext.getMessage());
136:
137: Iterator i = messageContext.getPropertyNames();
138: while (i.hasNext()) {
139: String name = (String) i.next();
140: Object value = messageContext.getProperty(name);
141:
142: context.setExtraneousProperty(name, value);
143: }
144: }
145:
146: private StaticApplicationContext getPolicyContext() {
147: // assumed to contain single nested container
148: ApplicationSecurityConfiguration config = (ApplicationSecurityConfiguration) _sConfig
149: .getAllTopLevelApplicationSecurityConfigurations()
150: .iterator().next();
151:
152: StaticApplicationContext iContext = (StaticApplicationContext) config
153: .getAllContexts().next();
154:
155: StaticApplicationContext sContext = new StaticApplicationContext(
156: iContext);
157: sContext.setPortIdentifier(port);
158:
159: return sContext;
160: }
161:
162: public void _preHandlingHook(StreamingSenderState state)
163: throws Exception {
164: try {
165: SOAPMessageContext messageContext = state
166: .getMessageContext();
167: SOAPMessage message = state.getResponse().getMessage();
168:
169: String operation = (String) messageContext
170: .getProperty(CONTEXT_OPERATION);
171:
172: StaticApplicationContext sContext = getPolicyContext();
173: sContext.setOperationIdentifier(operation);
174:
175: SecurityPolicy policy = _sConfig
176: .getSecurityConfiguration(sContext);
177:
178: ProcessingContext context = new ProcessingContext();
179: copyToProcessingContext(context, messageContext);
180:
181: context.setPolicyContext(sContext);
182:
183: if (PolicyTypeUtil.declarativeSecurityConfiguration(policy)) {
184: context
185: .setSecurityPolicy(((DeclarativeSecurityConfiguration) policy)
186: .receiverSettings());
187: } else {
188: context.setSecurityPolicy(policy);
189: }
190:
191: context.setSecurityEnvironment(_securityEnvironment);
192: context.isInboundMessage(true);
193:
194: if (_sConfig.retainSecurityHeader()) {
195: context.retainSecurityHeader(true);
196: }
197:
198: SecurityRecipient.validateMessage(context);
199:
200: copyToMessageContext(messageContext, context);
201:
202: } catch (com.sun.xml.wss.impl.WssSoapFaultException soapFaultException) {
203: throw getSOAPFaultException(soapFaultException);
204: } catch (com.sun.xml.wss.XWSSecurityException xwse) {
205: QName qname = null;
206:
207: if (xwse.getCause() instanceof PolicyViolationException)
208: qname = MessageConstants.WSSE_RECEIVER_POLICY_VIOLATION;
209: else
210: qname = MessageConstants.WSSE_FAILED_AUTHENTICATION;
211:
212: com.sun.xml.wss.impl.WssSoapFaultException wsfe = SecurableSoapMessage
213: .newSOAPFaultException(qname, xwse.getMessage(),
214: xwse);
215: throw getSOAPFaultException(wsfe);
216: }
217: }
218:
219: public boolean _preRequestSendingHook(StreamingSenderState state)
220: throws Exception {
221: try {
222: SOAPMessageContext messageContext = state
223: .getMessageContext();
224: SOAPMessage message = state.getRequest().getMessage();
225:
226: String operation = getOperationName(message);
227: messageContext.setProperty(CONTEXT_OPERATION, operation);
228:
229: StaticApplicationContext sContext = getPolicyContext();
230: sContext.setOperationIdentifier(operation);
231:
232: SecurityPolicy policy = _sConfig
233: .getSecurityConfiguration(sContext);
234:
235: ProcessingContext context = new ProcessingContext();
236: copyToProcessingContext(context, messageContext);
237:
238: context.setPolicyContext(sContext);
239:
240: if (PolicyTypeUtil.declarativeSecurityConfiguration(policy)) {
241: context
242: .setSecurityPolicy(((DeclarativeSecurityConfiguration) policy)
243: .senderSettings());
244: } else {
245: context.setSecurityPolicy(policy);
246: }
247:
248: context.setSecurityEnvironment(_securityEnvironment);
249: context.isInboundMessage(false);
250:
251: SecurityAnnotator.secureMessage(context);
252:
253: copyToMessageContext(messageContext, context);
254: } catch (com.sun.xml.wss.impl.WssSoapFaultException soapFaultException) {
255: throw getSOAPFaultException(soapFaultException);
256: } catch (com.sun.xml.wss.XWSSecurityException xwse) {
257: // log the exception here
258: throw new JAXRPCException(xwse);
259: }
260:
261: return true;
262: }
263:
264: private static final String ENCRYPTED_BODY_QNAME = "{"
265: + MessageConstants.XENC_NS + "}"
266: + MessageConstants.ENCRYPTED_DATA_LNAME;
267:
268: public boolean preHandlingHook(StreamingHandlerState state)
269: throws Exception {
270: try {
271: SOAPMessageContext messageContext = state
272: .getMessageContext();
273: SOAPMessage message = state.getRequest().getMessage();
274:
275: StaticApplicationContext sContext = new StaticApplicationContext(
276: getPolicyContext());
277: ProcessingContext context = new ProcessingContext();
278:
279: copyToProcessingContext(context, messageContext);
280: String operation = getOperationName(message);
281:
282: if (operation.equals(ENCRYPTED_BODY_QNAME)
283: && _sConfig.hasOperationPolicies()) {
284:
285: // get enclosing port level configuration
286: if (MessageConstants.debug) {
287: System.out.println("context in plugin= "
288: + sContext.toString());
289: }
290: ApplicationSecurityConfiguration config = (ApplicationSecurityConfiguration) _sConfig
291: .getSecurityPolicies(sContext).next();
292:
293: if (config != null) {
294: context.setPolicyContext(sContext);
295: context.setSecurityPolicy(config);
296: } else {
297: ApplicationSecurityConfiguration config0 = (ApplicationSecurityConfiguration) _sConfig
298: .getAllTopLevelApplicationSecurityConfigurations()
299: .iterator().next();
300:
301: //sContext.setPortIdentifier ("");
302: context.setPolicyContext(sContext);
303: context.setSecurityPolicy(config0);
304: }
305: } else {
306: sContext.setOperationIdentifier(operation);
307: messageContext
308: .setProperty(CONTEXT_OPERATION, operation);
309: SecurityPolicy policy = _sConfig
310: .getSecurityConfiguration(sContext);
311:
312: context.setPolicyContext(sContext);
313:
314: if (PolicyTypeUtil
315: .declarativeSecurityConfiguration(policy)) {
316: context
317: .setSecurityPolicy(((DeclarativeSecurityConfiguration) policy)
318: .receiverSettings());
319: } else {
320: context.setSecurityPolicy(policy);
321: }
322: }
323:
324: context.setSecurityEnvironment(_securityEnvironment);
325: context.isInboundMessage(true);
326:
327: if (_sConfig.retainSecurityHeader()) {
328: context.retainSecurityHeader(true);
329: }
330:
331: SecurityRecipient.validateMessage(context);
332:
333: messageContext.setProperty(CONTEXT_OPERATION,
334: getOperationName(message));
335:
336: copyToMessageContext(messageContext, context);
337: } catch (com.sun.xml.wss.impl.WssSoapFaultException soapFaultException) {
338: state.getResponse().setFailure(true);
339: throw getSOAPFaultException(soapFaultException);
340:
341: } catch (com.sun.xml.wss.XWSSecurityException xwse) {
342: QName qname = null;
343:
344: if (xwse.getCause() instanceof PolicyViolationException)
345: qname = MessageConstants.WSSE_RECEIVER_POLICY_VIOLATION;
346: else
347: qname = MessageConstants.WSSE_FAILED_AUTHENTICATION;
348:
349: com.sun.xml.wss.impl.WssSoapFaultException wsfe = SecurableSoapMessage
350: .newSOAPFaultException(qname, xwse.getMessage(),
351: xwse);
352:
353: state.getResponse().setFailure(true);
354:
355: throw getSOAPFaultException(wsfe);
356: }
357:
358: return true;
359: }
360:
361: public void postResponseWritingHook(StreamingHandlerState state)
362: throws Exception {
363: try {
364: SOAPMessageContext messageContext = state
365: .getMessageContext();
366: SOAPMessage message = state.getResponse().getMessage();
367:
368: ProcessingContext context = new ProcessingContext();
369:
370: copyToProcessingContext(context, messageContext);
371:
372: if (state.getResponse().isFailure()) {
373: DumpFilter.process(context);
374: return;
375: }
376:
377: String operation = (String) messageContext
378: .getProperty(CONTEXT_OPERATION);
379:
380: StaticApplicationContext sContext = new StaticApplicationContext(
381: getPolicyContext());
382: sContext.setOperationIdentifier(operation);
383:
384: SecurityPolicy policy = _sConfig
385: .getSecurityConfiguration(sContext);
386: context.setPolicyContext(sContext);
387:
388: if (PolicyTypeUtil.declarativeSecurityConfiguration(policy)) {
389: context
390: .setSecurityPolicy(((DeclarativeSecurityConfiguration) policy)
391: .senderSettings());
392: } else {
393: context.setSecurityPolicy(policy);
394: }
395:
396: context.setSecurityEnvironment(_securityEnvironment);
397: context.isInboundMessage(false);
398:
399: SecurityAnnotator.secureMessage(context);
400:
401: copyToMessageContext(messageContext, context);
402: } catch (com.sun.xml.wss.impl.WssSoapFaultException soapFaultException) {
403: throw getSOAPFaultException(soapFaultException);
404: } catch (com.sun.xml.wss.XWSSecurityException xwse) {
405: com.sun.xml.wss.impl.WssSoapFaultException wsfe = SecurableSoapMessage
406: .newSOAPFaultException(
407: MessageConstants.WSSE_INTERNAL_SERVER_ERROR,
408: xwse.getMessage(), xwse);
409: throw getSOAPFaultException(wsfe);
410: }
411: }
412:
413: public void prepareMessageForMUCheck(SOAPMessage message)
414: throws Exception {
415: setMUValue(message, "0");
416: }
417:
418: public void restoreMessageAfterMUCheck(SOAPMessage message)
419: throws Exception {
420: setMUValue(message, "1");
421: }
422:
423: private void setMUValue(SOAPMessage message, String value)
424: throws Exception {
425: SOAPPart sp = message.getSOAPPart();
426: SOAPEnvelope se = sp.getEnvelope();
427: SOAPHeader sh = se.getHeader();
428:
429: if (sh != null) {
430:
431: SOAPElement secHeader = null;
432: Node currentChild = sh.getFirstChild();
433:
434: while (currentChild != null
435: && !(currentChild.getNodeType() == Node.ELEMENT_NODE)) {
436: currentChild = currentChild.getNextSibling();
437: }
438:
439: if (currentChild != null /* && currentChild instanceof SOAPElement*/) {
440: if (MessageConstants.WSSE_SECURITY_LNAME
441: .equals(currentChild.getLocalName())
442: && MessageConstants.WSSE_NS.equals(currentChild
443: .getNamespaceURI())) {
444:
445: secHeader = (SOAPElement) currentChild;
446: }
447: }
448:
449: if (secHeader != null) {
450: // change the mustUnderstand value to false
451: Attr attr = secHeader.getAttributeNodeNS(
452: MessageConstants.SOAP_1_1_NS, "mustUnderstand");
453:
454: if (attr != null)
455: secHeader.setAttributeNS(attr.getNamespaceURI(),
456: attr.getName(), value);
457: }
458: }
459: }
460:
461: public SOAPFaultException getSOAPFaultException(
462: WssSoapFaultException sfe) {
463: return new SOAPFaultException(sfe.getFaultCode(), sfe
464: .getFaultString(), sfe.getFaultActor(), sfe.getDetail());
465: }
466:
467: /**
468: * Handles rpc-lit, rpc-encoded, doc-lit wrap/non-wrap, doc-encoded modes as follows:
469: *
470: * (1) rpc-lit, rpc-enc, doc-lit (wrap), doc-enc: First child of SOAPBody to contain Operation Identifier
471: * (2) doc-lit (non-wrap): Operation Identifier constructed as concatenated string
472: * of tag names of childs of SOAPBody
473: */
474: private String getOperationName(SOAPMessage message)
475: throws Exception {
476: Node node = null;
477: String key = null;
478: SOAPBody body = null;
479:
480: if (message != null)
481: body = message.getSOAPBody();
482: else
483: throw new XWSSecurityException(
484: "SOAPMessage in message context is null");
485:
486: if (body != null)
487: node = body.getFirstChild();
488: else
489: throw new XWSSecurityException(
490: "No body element identifying an operation is found");
491:
492: StringBuffer tmp = new StringBuffer("");
493: String operation = "";
494:
495: for (; node != null; node = node.getNextSibling())
496: tmp.append("{" + node.getNamespaceURI() + "}"
497: + node.getLocalName() + ":");
498: operation = tmp.toString();
499:
500: return operation.substring(0, operation.length() - 1);
501: }
502: }
|