001: /*
002: * $Id: NewSecurityRecipient.java,v 1.14 2007/01/08 09:28:50 ashutoshshahi Exp $
003: */
004:
005: /*
006: * The contents of this file are subject to the terms
007: * of the Common Development and Distribution License
008: * (the License). You may not use this file except in
009: * compliance with the License.
010: *
011: * You can obtain a copy of the license at
012: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
013: * See the License for the specific language governing
014: * permissions and limitations under the License.
015: *
016: * When distributing Covered Code, include this CDDL
017: * Header Notice in each file and include the License file
018: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
019: * If applicable, add the following below the CDDL Header,
020: * with the fields enclosed by brackets [] replaced by
021: * you own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
025: */
026:
027: package com.sun.xml.wss.impl;
028:
029: import com.sun.xml.wss.impl.policy.verifier.MessagePolicyVerifier;
030: import com.sun.xml.wss.impl.policy.verifier.TargetResolver;
031: import java.util.Iterator;
032: import java.util.ArrayList;
033: import java.util.List;
034: import java.util.logging.Level;
035: import java.util.logging.Logger;
036: import javax.xml.soap.SOAPElement;
037: import javax.xml.soap.SOAPFactory;
038:
039: import com.sun.xml.wss.core.SecurityHeader;
040: import com.sun.xml.wss.impl.filter.DumpFilter;
041: import com.sun.xml.wss.impl.filter.TimestampFilter;
042: import com.sun.xml.wss.impl.filter.SignatureFilter;
043: import com.sun.xml.wss.impl.filter.EncryptionFilter;
044: import com.sun.xml.wss.impl.filter.SignatureConfirmationFilter;
045: import com.sun.xml.wss.impl.filter.AuthenticationTokenFilter;
046: import com.sun.xml.wss.impl.policy.mls.MessagePolicy;
047: import com.sun.xml.wss.logging.LogDomainConstants;
048: import com.sun.xml.wss.*;
049:
050: /**
051: * This class exports a static Security Service for Verifying/Validating Security in an Inbound SOAPMessage.
052: * The policy to be applied for Verifying the Message and the SOAPMessage itself are
053: * supplied in an instance of a com.sun.xml.wss.ProcessingContext
054: * @see ProcessingContext
055: */
056: public class NewSecurityRecipient {
057:
058: private static Logger log = Logger.getLogger(
059: LogDomainConstants.WSS_API_DOMAIN,
060: LogDomainConstants.WSS_API_DOMAIN_BUNDLE);
061:
062: private static SOAPFactory sFactory = null;
063:
064: static {
065: try {
066: sFactory = SOAPFactory.newInstance();
067: } catch (Exception ex) {
068: log.log(Level.SEVERE, "WSS0397.soap.factory.exception", ex);
069: throw new RuntimeException(ex);
070: }
071: }
072:
073: /**
074: * Validate security in an Inbound SOAPMessage.
075: * <P>
076: * Calling code should create com.sun.xml.wss.ProcessingContext object with
077: * runtime properties. Specifically, it should set SecurityPolicy, application
078: * CallbackHandler Or a SecurityEnvironment
079: * The SecurityPolicy instance can be of the following types:
080: * <UL>
081: * <LI> A MessagePolicy
082: * </UL>
083: *
084: * @param context an instance of com.sun.xml.wss.ProcessingContext
085: * @exception com.sun.xml.wss.XWSSecurityException if there was an unexpected error
086: * while verifying the message. OR if the security in the incoming
087: * message violates the Security policy that was applied to the message.
088: * @exception WssSoapFaultException when security in the incoming message
089: * is in direct violation of the OASIS WSS specification.
090: * When a WssSoapFaultException is thrown the getFaultCode() method on the WssSoapFaultException
091: * will return a <code>QName</code> which would correspond to the WSS defined fault.
092: */
093: public static void validateMessage(ProcessingContext context)
094: throws XWSSecurityException {
095:
096: HarnessUtil.validateContext(context);
097: FilterProcessingContext fpContext = new FilterProcessingContext(
098: context);
099: fpContext.isInboundMessage(true);
100:
101: MessagePolicy msgPolicy = (MessagePolicy) fpContext
102: .getSecurityPolicy();
103: if ((msgPolicy != null) && (msgPolicy.dumpMessages())) {
104: DumpFilter.process(fpContext);
105: }
106:
107: //unconditionally set these since the policy is unknown
108: fpContext.setExtraneousProperty("EnableWSS11PolicyReceiver",
109: "true");
110: List scList = new ArrayList();
111: fpContext.setExtraneousProperty("receivedSignValues", scList);
112: fpContext.setMode(FilterProcessingContext.WSDL_POLICY);
113:
114: pProcess(fpContext);
115:
116: boolean isTrust = fpContext.isTrustMessage();
117: //TODO: Venu this is a workaround for PROTOCOL Messages
118: //To be removed after resolveOperationPolicy starts returning correct policy for
119: //protocol messages.
120: if (msgPolicy == null || msgPolicy.size() <= 0) {
121: PolicyResolver opResolver = (PolicyResolver) fpContext
122: .getExtraneousProperty(fpContext.OPERATION_RESOLVER);
123: if (opResolver != null && !isTrust)
124: msgPolicy = opResolver.resolvePolicy(fpContext);
125: }
126: //TODO: this is a workaround for PROTOCOL Message
127: try {
128: if ((msgPolicy == null)
129: || (msgPolicy.size() == 0 && fpContext
130: .getSOAPMessage().getSOAPBody().hasFault())) {
131:
132: fpContext.getSecurableSoapMessage()
133: .deleteSecurityHeader();
134: fpContext.getSOAPMessage().saveChanges();
135: return;
136: }
137: } catch (Exception ex) {
138: log.log(Level.SEVERE, "WSS0370.error.deleting.secheader",
139: ex);
140: throw new XWSSecurityException(ex);
141: }
142:
143: // for Policy verfication
144: TargetResolver targetResolver = new TargetResolverImpl(context);
145: MessagePolicyVerifier mpv = new MessagePolicyVerifier(context,
146: targetResolver);
147: /*
148: try{
149: System.out.println("Inferred Security Policy");
150: mpv.printInferredSecurityPolicy(fpContext.getInferredSecurityPolicy());
151: } catch(Exception e){
152: throw new XWSSecurityException(e);
153: }
154: System.out.println("==================================");
155:
156:
157: try{
158: System.out.println("Actual SecurityPolicy");
159: mpv.printInferredSecurityPolicy(msgPolicy);
160: } catch(Exception e){
161: throw new XWSSecurityException(e);
162: }
163: */
164:
165: if (!isTrust) {
166: mpv.verifyPolicy(fpContext.getInferredSecurityPolicy(),
167: msgPolicy);
168: }
169:
170: try {
171: fpContext.getSecurableSoapMessage().deleteSecurityHeader();
172: fpContext.getSOAPMessage().saveChanges();
173: } catch (Exception ex) {
174: log.log(Level.SEVERE, "WSS0370.error.deleting.secheader",
175: ex);
176: throw new XWSSecurityException(ex);
177: }
178: }
179:
180: /*
181: * @param fpContext com.sun.xml.wss.FilterProcessingContext
182: * @param isSecondary boolean
183: *
184: * @return boolean
185: *
186: * @see pProcess
187: *
188: * @throws com.sun.xml.wss.XWSSecurityException
189: */
190: private static void processCurrentHeader(
191: FilterProcessingContext fpContext, SOAPElement current,
192: boolean isSecondary) throws XWSSecurityException {
193:
194: String elementName = current.getLocalName();
195:
196: if (isSecondary) {
197: if (MessageConstants.USERNAME_TOKEN_LNAME
198: .equals(elementName)) {
199: AuthenticationTokenFilter
200: .processUserNameToken(fpContext);
201: } else if (MessageConstants.TIMESTAMP_LNAME
202: .equals(elementName)) {
203: TimestampFilter.process(fpContext);
204: } else if (MessageConstants.SIGNATURE_CONFIRMATION_LNAME
205: .equals(elementName)) {
206: SignatureConfirmationFilter.process(fpContext);
207: } else if (MessageConstants.WSSE_BINARY_SECURITY_TOKEN_LNAME
208: .equals(elementName)) {
209: //ignore
210: } else if (MessageConstants.SAML_ASSERTION_LNAME
211: .equals(elementName)) {
212: AuthenticationTokenFilter.processSamlToken(fpContext);
213: } else if (MessageConstants.WSSE_SECURITY_TOKEN_REFERENCE_LNAME
214: .equals(elementName)) {
215: //ignore
216: } else if (MessageConstants.SECURITY_CONTEXT_TOKEN_LNAME
217: .equals(elementName)) {
218: // ignore
219: }
220: } else {
221: if (MessageConstants.DS_SIGNATURE_LNAME.equals(elementName)) {
222: SignatureFilter.process(fpContext);
223: } else if (MessageConstants.XENC_ENCRYPTED_KEY_LNAME
224: .equals(elementName)) {
225: Iterator iter = null;
226: try {
227: iter = current
228: .getChildElements(sFactory
229: .createName(
230: MessageConstants.XENC_REFERENCE_LIST_LNAME,
231: MessageConstants.XENC_PREFIX,
232: MessageConstants.XENC_NS));
233: } catch (Exception e) {
234: log.log(Level.SEVERE,
235: "WSS0252.failedto.getChildElement", e);
236: throw new XWSSecurityException(e);
237: }
238: if (iter.hasNext()) {
239: EncryptionFilter.process(fpContext);
240: }
241:
242: } else if (MessageConstants.XENC_REFERENCE_LIST_LNAME
243: .equals(elementName)) {
244: EncryptionFilter.process(fpContext);
245:
246: } else if (MessageConstants.ENCRYPTED_DATA_LNAME
247: .equals(elementName)) {
248: EncryptionFilter.process(fpContext);
249: } else {
250: if (!HarnessUtil.isSecondaryHeaderElement(current)) {
251: log
252: .log(Level.SEVERE,
253: "WSS0204.illegal.header.block",
254: elementName);
255: HarnessUtil
256: .throwWssSoapFault("Unrecognized header block: "
257: + elementName);
258: }
259: }
260: }
261:
262: }
263:
264: /*
265: * Validation of wsse:UsernameToken/wsu:Timestamp protected by
266: * signature/encryption should follow post verification of
267: * signature/encryption.
268: *
269: * A two-pass processing model is implemented, the first pass
270: * verifies signature/encryption, while the second, the token/
271: * timestamp.
272: *
273: * Note: Can be specification documented
274: *
275: * @param fpContext com.sun.xml.wss.FilterProcessingContext
276: *
277: * @throws com.sun.xml.wss.XWSSecurityException
278: */
279: private static void pProcess(FilterProcessingContext fpContext)
280: throws XWSSecurityException {
281:
282: SecurityHeader header = fpContext.getSecurableSoapMessage()
283: .findSecurityHeader();
284: MessagePolicy policy = (MessagePolicy) fpContext
285: .getSecurityPolicy();
286:
287: if (header == null) {
288: if (policy != null) {
289: if (PolicyTypeUtil.messagePolicy(policy)) {
290: if (!((MessagePolicy) policy).isEmpty()) {
291: log
292: .log(Level.SEVERE,
293: "WSS0253.invalid.Message");
294: throw new XWSSecurityException(
295: "Message does not conform to configured policy: "
296: + "No Security Header found in incoming message");
297:
298: }
299: } else {
300: log.log(Level.SEVERE, "WSS0253.invalid.Message");
301: throw new XWSSecurityException(
302: "Message does not conform to configured policy: "
303: + "No Security Header found in incoming message");
304: }
305: }
306:
307: return;
308: }
309:
310: if ((policy != null) && policy.dumpMessages()) {
311: DumpFilter.process(fpContext);
312: }
313: SOAPElement current = header.getCurrentHeaderBlockElement();
314: SOAPElement first = current;
315:
316: while (current != null) {
317: processCurrentHeader(fpContext, current, false);
318: current = header.getCurrentHeaderBlockElement();
319: }
320:
321: current = first;
322: header.setCurrentHeaderElement(current);
323:
324: while (current != null) {
325: processCurrentHeader(fpContext, current, true);
326: current = header.getCurrentHeaderBlockElement();
327: }
328:
329: }
330:
331: /*
332: * @param context Processing Context
333: */
334: public static void handleFault(ProcessingContext context) {
335: }
336:
337: }
|