1
2
3
4
5
6
7
8
9
10
11 package org.mule.extras.wssecurity.handlers;
12
13 import org.mule.MuleManager;
14 import org.mule.providers.soap.xfire.XFireConnector;
15 import org.mule.umo.security.SecurityException;
16
17 import java.security.cert.X509Certificate;
18 import java.util.Map;
19 import java.util.Properties;
20 import java.util.Vector;
21
22 import javax.security.auth.callback.CallbackHandler;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.ws.security.WSConstants;
27 import org.apache.ws.security.WSSecurityEngineResult;
28 import org.apache.ws.security.WSSecurityException;
29 import org.apache.ws.security.handler.RequestData;
30 import org.apache.ws.security.handler.WSHandlerConstants;
31 import org.apache.ws.security.handler.WSHandlerResult;
32 import org.apache.ws.security.util.WSSecurityUtil;
33 import org.codehaus.xfire.MessageContext;
34 import org.codehaus.xfire.XFireRuntimeException;
35 import org.codehaus.xfire.exchange.AbstractMessage;
36 import org.codehaus.xfire.fault.XFireFault;
37 import org.codehaus.xfire.handler.Handler;
38 import org.codehaus.xfire.handler.Phase;
39 import org.codehaus.xfire.security.wss4j.AbstractWSS4JHandler;
40 import org.codehaus.xfire.soap.handler.ReadHeadersHandler;
41 import org.codehaus.xfire.util.dom.DOMInHandler;
42 import org.w3c.dom.Document;
43
44 public class MuleWSSInHandler extends AbstractWSS4JHandler implements Handler
45 {
46
47
48
49 protected static final Log log = LogFactory.getLog(MuleWSSInHandler.class);
50
51 public MuleWSSInHandler()
52 {
53 super();
54 setPhase(Phase.PARSE);
55 getBefore().add(ReadHeadersHandler.class.getName());
56 getAfter().add(DOMInHandler.class.getName());
57 }
58
59 public MuleWSSInHandler(Properties properties)
60 {
61 this();
62 setProperties(properties);
63 }
64
65
66
67
68
69 public void invoke(MessageContext msgContext)
70 throws SecurityException, XFireFault, WSSecurityException
71 {
72 boolean doDebug = log.isDebugEnabled();
73
74 if (doDebug)
75 {
76 log.debug("MuleWSSInSecurityHandler: enter invoke()");
77 }
78
79 RequestData reqData = new RequestData();
80
81 try
82 {
83 reqData.setMsgContext(msgContext);
84
85 Vector actions = new Vector();
86 String action;
87
88
89
90 if ((action = (String)getOption(WSHandlerConstants.ACTION)) == null)
91 {
92 action = getString(WSHandlerConstants.ACTION, msgContext);
93 }
94
95 if (action == null)
96 {
97 Map connectors = MuleManager.getInstance().getConnectors();
98 Object[] arr = connectors.values().toArray();
99 for (int i =0; i < arr.length; i++)
100 {
101 Object c = arr[i];
102 if (c instanceof XFireConnector)
103 {
104 action = (String)((XFireConnector)c).getExtraProperties().get(WSHandlerConstants.ACTION);
105 if (action != null)
106 {
107 break;
108 }
109 }
110 }
111 }
112 if (action == null)
113 {
114 throw new XFireRuntimeException("MuleWSSInHandler: No action defined");
115 }
116
117 int doAction = WSSecurityUtil.decodeAction(action, actions);
118
119 String actor = (String)getOption(WSHandlerConstants.ACTOR);
120
121 AbstractMessage sm = msgContext.getCurrentMessage();
122 Document doc = (Document)sm.getProperty(DOMInHandler.DOM_MESSAGE);
123
124 if (doc == null)
125 throw new XFireRuntimeException("DOMInHandler must be enabled for WS-Security!");
126
127
128 if (sm.getBody() instanceof XFireFault) return;
129
130
131 CallbackHandler cbHandler = null;
132 if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0)
133 {
134 cbHandler = getPasswordCB(reqData);
135 }
136
137
138
139 doReceiverAction(doAction, reqData);
140
141
142
143 if (action.equals(WSHandlerConstants.SAML_TOKEN_SIGNED))
144 {
145 reqData.setSigCrypto(loadSignatureCrypto(reqData));
146 }
147
148 Vector wsResult;
149
150
151 try
152 {
153 wsResult = secEngine.processSecurityHeader(doc, actor, cbHandler, reqData
154 .getSigCrypto(), reqData.getDecCrypto());
155 }
156 catch (WSSecurityException ex)
157 {
158 throw new XFireFault("MuleWSSInHandler: security processing failed: " + ex.toString(), ex,
159 XFireFault.SENDER);
160 }
161
162
163
164 if (wsResult == null)
165 {
166 if (doAction == WSConstants.NO_SECURITY)
167 {
168 return;
169 }
170 else
171 {
172 throw new XFireFault(
173 "MuleWSSInHandler: Request does not contain required Security header",
174 XFireFault.SENDER);
175 }
176 }
177
178
179 if (reqData.getWssConfig().isEnableSignatureConfirmation())
180 {
181 checkSignatureConfirmation(reqData, wsResult);
182 }
183
184
185 WSSecurityEngineResult actionResult = WSSecurityUtil.fetchActionResult(wsResult,
186 WSConstants.SIGN);
187
188 if (actionResult != null)
189 {
190 X509Certificate returnCert = actionResult.getCertificate();
191
192 if (returnCert != null)
193 {
194 if (!verifyTrust(returnCert, reqData))
195 {
196 throw new XFireFault(
197 "MuleWSSInHandler: The certificate used for the signature is not trusted",
198 XFireFault.SENDER);
199 }
200 }
201 }
202
203 if (actions.elementAt(0).equals(new Integer(16)))
204 {
205 actions.clear();
206 actions.add(new Integer(2));
207 actions.add(new Integer(8));
208 }
209
210
211 if (!checkReceiverResults(wsResult, actions))
212 {
213 throw new XFireFault(
214 "MuleWSSInHandler: security processing failed (actions mismatch)",
215 XFireFault.SENDER);
216
217 }
218
219
220
221
222 Vector results;
223 if ((results = (Vector)msgContext.getProperty(WSHandlerConstants.RECV_RESULTS)) == null)
224 {
225 results = new Vector();
226 msgContext.setProperty(WSHandlerConstants.RECV_RESULTS, results);
227 }
228 WSHandlerResult rResult = new WSHandlerResult(actor, wsResult);
229 results.add(0, rResult);
230
231 if (doDebug)
232 {
233 log.debug("MuleWSSInHandler: exit invoke()");
234 }
235 }
236 catch (WSSecurityException e)
237 {
238 throw new WSSecurityException(e.getErrorCode());
239 }
240 finally
241 {
242 reqData.clear();
243 reqData = null;
244 }
245 }
246 }