View Javadoc
1 /* 2 * $Header: /cvsroot/ebxmlrr/ebxmlrr/src/share/com/sun/ebxml/registry/interfaces/soap/RegistryJAXMServlet.java,v 1.55 2003/08/29 02:25:22 farrukh_najmi Exp $ 3 * 4 */ 5 6 package com.sun.ebxml.registry.interfaces.soap; 7 8 import com.sun.ebxml.registry.*; 9 import com.sun.ebxml.registry.interfaces.*; 10 import com.sun.ebxml.registry.util.*; 11 12 import org.oasis.ebxml.registry.bindings.query.*; 13 import org.oasis.ebxml.registry.bindings.query.types.*; 14 import org.oasis.ebxml.registry.bindings.rim.ObjectRefListItem; 15 import org.oasis.ebxml.registry.bindings.rim.User; 16 import org.oasis.ebxml.registry.bindings.rs.*; 17 import org.oasis.ebxml.registry.bindings.rs.types.*; 18 19 import com.sun.ebxml.registry.query.*; 20 import com.sun.ebxml.registry.lcm.*; 21 import com.sun.ebxml.registry.persistence.*; 22 import com.sun.ebxml.registry.security.*; 23 import com.sun.ebxml.registry.security.authentication.*; 24 import com.sun.ebxml.registry.repository.*; 25 26 27 import javax.xml.messaging.*; 28 import javax.xml.soap.*; 29 import javax.xml.transform.stream.StreamSource; 30 31 32 import java.util.*; 33 import java.io.*; 34 import java.security.*; 35 import java.security.cert.*; 36 37 import org.apache.xml.serialize.*; 38 39 import javax.mail.*; 40 import javax.mail.internet.*; 41 import javax.activation.*; 42 43 import javax.servlet.http.*; 44 import javax.servlet.*; 45 46 import org.apache.xml.security.signature.*; 47 48 import org.apache.commons.logging.Log; 49 import org.apache.commons.logging.LogFactory; 50 51 /*** 52 * The JAXMServlet for the OASIS ebXMl registry. It receives SOAP messages. 53 * 54 * @see com.sun.ebxml.registry.interfaces.soap.SOAPSender class under test tree to send SOAP messages to this servlet. 55 * @author Farrukh S. Najmi 56 */ 57 public class RegistryJAXMServlet extends JAXMServlet implements ReqRespListener { 58 59 private Log log = LogFactory.getLog(this.getClass()); 60 61 public void init(ServletConfig servletConfig) throws ServletException { 62 super.init( servletConfig ); 63 init(); 64 } 65 66 public void init() throws ServletException { 67 try { 68 log.info("init"); 69 XalanVersion.verifyVersion(); 70 //initialise XML Security library 71 org.apache.xml.security.Init.init(); 72 } catch (Exception ex) { 73 log.fatal("RegistryJAXMServlet Init Failed:", ex); 74 throw new ServletException("RegistryJAXMServlet Init Failed:"+ex); 75 } 76 } 77 78 public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 79 resp.setContentType("text/plain"); 80 PrintWriter wt = resp.getWriter(); 81 wt.print("Are you visiting this URL with Web browser? You should submit data or query to ebxml Registry/Repository with Registry Browser or SOAPSender."); 82 wt.flush(); 83 wt.close(); 84 } 85 86 public SOAPMessage onMessage(SOAPMessage msg) { 87 //System.err.println("onMessage called for RegistryJAXMServlet"); 88 89 SOAPMessage soapResponse = null; 90 91 try { 92 93 /* 94 Due to the suspected bugs in JAXM, we have to call writeTo method of the 95 input message that has been received from JAXMServlet to write the content 96 to a ByteArrayOutputStream and re-instantiate another SOAPMessage 97 to make the XML signature properly verified. 98 */ 99 100 //System.err.println("Getting any attachements."); 101 102 /* Firstly we put save the attached repository items in a map. Later 103 we will remove the attachments. 104 */ 105 HashMap idToRepositoryItemMap = new HashMap(); 106 107 //Now get any repository items that may be attached 108 Iterator apIter = msg.getAttachments(); 109 //Iterator apIter = attachments.iterator(); 110 while (apIter.hasNext()) { 111 AttachmentPart ap = (AttachmentPart)apIter.next(); 112 113 //Get the DSIG and content for the attachment 114 RepositoryItem ri = processAttachment(ap); 115 idToRepositoryItemMap.put(ri.getId(), ri); 116 } 117 118 119 /* 120 If we do not remove the attachment, the SOAPMessage.writeTo() mehtod 121 will output a MIME-encoded form of the message, not pure SOAP part. 122 */ 123 if (msg.countAttachments() > 0) { 124 msg.removeAllAttachments(); 125 if (msg.saveRequired()) { 126 msg.saveChanges(); 127 } 128 } 129 130 131 ByteArrayOutputStream msgOs = new ByteArrayOutputStream(); 132 msg.writeTo(msgOs); 133 msgOs.close(); 134 ByteArrayInputStream msgIs = new ByteArrayInputStream(msgOs.toByteArray()); 135 136 msg = Utility.getInstance().createSOAPMessageFromSOAPStream(msgIs); 137 138 SOAPPart sp = msg.getSOAPPart(); 139 SOAPEnvelope se = sp.getEnvelope(); //<------------------------------- 140 SOAPBody sb = se.getBody(); 141 SOAPHeader sh = se.getHeader(); 142 143 //System.err.println("Getting header signature"); 144 145 // Get the header signature (if any) from the SOAPHeader 146 147 XMLSignature headerSignature = SecurityUtil.getInstance().verifySOAPMessage(msg); 148 149 //System.err.println("Getting ebXML Registry request"); 150 151 //The ebXML registry request is the only element in the SOAPBody 152 StringWriter requestXML = new StringWriter(); //The request as an XML String 153 String requestRootElement = null; 154 Iterator iter = sb.getChildElements(); 155 int i=0; 156 while (iter.hasNext()) { 157 Object obj = iter.next(); 158 if (!(obj instanceof SOAPElement)) { 159 continue; 160 } 161 162 if (i++ == 0) { 163 SOAPElement elem = (SOAPElement)obj; 164 Name name = elem.getElementName(); 165 requestRootElement = name.getLocalName(); 166 167 OutputFormat of = new OutputFormat(); 168 of.setIndenting(true); 169 of.setPreserveSpace(true); 170 171 XMLSerializer serializer = new XMLSerializer(requestXML, 172 new OutputFormat()); 173 serializer.serialize(elem); 174 } 175 else { 176 throw new RegistryException("InvalidRequest: Cannot have more than one child element"); 177 } 178 } 179 180 if (requestRootElement == null) { 181 throw new RegistryException("The SOAP message does not contain an ebXML Registry Request."); 182 } 183 184 Request request = new Request(headerSignature, BindingUtility.getInstance().getRequestObject(requestRootElement, requestXML.toString()), idToRepositoryItemMap); 185 186 Response response = request.process(); 187 soapResponse = createResponseSOAPMessage(response); 188 if (request.getMessage() instanceof GetContentRequest && response.getMessage().getStatus().getType() == StatusType.SUCCESS_TYPE) { 189 190 ObjectRefListItem[] items = ((GetContentRequest) request.getMessage()).getObjectRefList().getObjectRefListItem(); 191 for (int j=0 ; j<items.length ; j++) { 192 String id = items[j].getObjectRef().getId(); 193 if (id.startsWith("urn:uuid:")) { 194 id = id.substring(9); 195 } 196 197 RepositoryItem repositoryItem = 198 RepositoryManagerFactory.getInstance() 199 .getRepositoryManager().getRepositoryItem(id); 200 201 DataHandler contentDataHandler = 202 repositoryItem.getDataHandler(); 203 204 String xmlsigStr = repositoryItem.signatureToString(); 205 206 MimeMultipart mp = new MimeMultipart(); 207 208 // Payload signature 209 MimeBodyPart bp1 = new MimeBodyPart(); 210 // Can't set 211 bp1.setHeader("Content-Type", "text/xml; charset=UTF-8"); 212 // Can't set 213 bp1.addHeader("Content-Transfer-Encoding", "8bit"); 214 bp1.setHeader("Content-ID", "payload1"); 215 bp1.setContent(xmlsigStr, "text/plain"); 216 mp.addBodyPart(bp1); 217 218 219 // Repository item 220 MimeBodyPart bp2 = new MimeBodyPart(); 221 bp2.setDataHandler(contentDataHandler); 222 bp2.setHeader("Content-Type", contentDataHandler.getContentType()); 223 bp2.setHeader("Content-ID", "payload2"); 224 mp.addBodyPart(bp2); 225 226 AttachmentPart ap = soapResponse.createAttachmentPart(mp, "multipart/related"); 227 // Can't add type=text/xml; start="urn:uuid:1234567" ?? 228 ap.setContentType(ap.getContentType() + "; type=text/xml; start=\"urn:uuid:" + id + "\""); 229 // Not in spec?? 230 ap.setContentId("urn:uuid:" + id); 231 232 ContentType contentTypeMP = new ContentType(mp.getContentType()); 233 234 String boundary = contentTypeMP.getParameter("boundary"); 235 ContentType contentType = new ContentType("multipart/related"); 236 contentType.setParameter("boundary", boundary); 237 ap.setContentType(contentType.toString()); 238 soapResponse.addAttachmentPart(ap); 239 } 240 } 241 242 soapResponse.saveChanges(); 243 } 244 catch (RegistryException e) { 245 log.error("Caught exception: "+e.getMessage(), e); 246 soapResponse = createResponseSOAPMessage(e); 247 } 248 catch (SOAPException e) { 249 log.error("Caught exception: "+e.getMessage(), e); 250 soapResponse = createResponseSOAPMessage(e); 251 } 252 catch (MessagingException e) { 253 log.error("Caught exception: "+e.getMessage(), e); 254 soapResponse = createResponseSOAPMessage(e); 255 } 256 catch (Exception e) { 257 log.error("Caught exception: "+e.getMessage(), e); 258 soapResponse = createResponseSOAPMessage(e); 259 } 260 catch (Throwable t) { 261 log.error("Caught exception: "+t.getMessage(), t); 262 soapResponse = createResponseSOAPMessage(t); 263 } 264 265 return soapResponse; 266 } 267 268 private SOAPMessage createResponseSOAPMessage(Object obj) { 269 SOAPMessage msg = null; 270 try { 271 msg = MessageFactory.newInstance().createMessage(); 272 273 RegistryResponse resp = null; 274 if (obj instanceof com.sun.ebxml.registry.interfaces.Response) { 275 Response r = (Response)obj; 276 resp = r.getMessage(); 277 } 278 else if (obj instanceof java.lang.Throwable) { 279 Throwable t = (Throwable)obj; 280 resp = Utility.getInstance().createRegistryResponseFromThrowable(t, "RegistryJAXMServlet", "Unknown"); 281 } 282 283 //Now add resp to SOAPMessage 284 StringWriter sw = new StringWriter(); 285 resp.marshal(sw); 286 287 //Now get the RegistryResponse as a String 288 String respStr = sw.toString(); 289 //System.err.println("respStr = " + respStr); 290 291 // Use Unicode (utf-8) to getBytes (server and client). Rely on platform default encoding is not safe. 292 InputStream soapStream = Utility.getInstance().createSOAPStreamFromRequestStream(new ByteArrayInputStream(respStr.getBytes("utf-8"))); 293 294 boolean signRequired = Boolean.valueOf(RegistryProperties.getInstance().getProperty("ebxmlrr.interfaces.soap.signedResponse")).booleanValue(); 295 296 if (signRequired) { 297 AuthenticationServiceImpl auService = AuthenticationServiceImpl.getInstance(); 298 PrivateKey privateKey = auService.getPrivateKey(AuthenticationServiceImpl. 299 ALIAS_REGISTRY_OPERATOR,AuthenticationServiceImpl.ALIAS_REGISTRY_OPERATOR); 300 java.security.cert.Certificate [] certs = auService.getCertificateChain(AuthenticationServiceImpl.ALIAS_REGISTRY_OPERATOR); 301 ByteArrayOutputStream os = new ByteArrayOutputStream(); 302 // File soapFile = new File("signedResponse.xml"); 303 // FileOutputStream os = new FileOutputStream(soapFile); 304 SecurityUtil.getInstance().signSOAPMessage(soapStream, os, privateKey, certs, 305 org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_DSA); 306 soapStream = new ByteArrayInputStream(os.toByteArray()); 307 } 308 309 msg = Utility.getInstance().createSOAPMessageFromSOAPStream(soapStream); 310 // msg.writeTo(new FileOutputStream(new File("signedResponse.xml"))); 311 soapStream.close(); 312 } 313 catch (IOException e) { 314 e.printStackTrace(); 315 } 316 catch (SOAPException e) { 317 e.printStackTrace(); 318 } 319 catch (org.exolab.castor.xml.MarshalException e) { 320 e.printStackTrace(); 321 } 322 catch (org.exolab.castor.xml.ValidationException e) { 323 e.printStackTrace(); 324 } 325 catch (ParseException e) { 326 e.printStackTrace(); 327 } 328 catch (RegistryException e) { 329 e.printStackTrace(); 330 } 331 332 return msg; 333 } 334 335 private RepositoryItem processAttachment(AttachmentPart ap) throws RegistryException { 336 RepositoryItem ri = null; 337 338 try { 339 //Make sure it is a multipart/related 340 //if (!(ap.getContentType().equalsIgnoreCase("multipart/related"))) { 341 // throw new RegistryException("Attachement's must have content type 'multipart/related'"); 342 //} 343 344 //ContentId is the id of the repositoryItem 345 String id = ap.getContentId(); 346 System.err.println("Processing attachment with contentId: '" + id + "'"); 347 348 Object obj = ap.getContent(); 349 350 if (!(obj instanceof javax.mail.internet.MimeMultipart)) { 351 throw new RegistryException("Expected javax.mail.internet.MimeMultipart got " + obj.getClass().getName()); 352 } 353 354 //The Multipart should have two BodyParts. First is the signature, second is the payload 355 MimeMultipart mp = (MimeMultipart)obj; 356 357 if (mp.getCount() != 2) { 358 throw new RegistryException("Found " + mp.getCount() + " BodyParts. A Multipart for a RepositoryItem must have exactly 2 BodyParts. First is the signature, second is the repository item."); 359 } 360 361 BodyPart bp1 = mp.getBodyPart(0); //The XMLSignature 362 BodyPart bp2 = mp.getBodyPart(1); //The repository item 363 //System.out.println("bp2.getContentType() =======> " + bp2.getContentType()); 364 365 //Need to populate the sig and dh from the bp1 and bp2 366 javax.xml.parsers.DocumentBuilderFactory dbf = 367 javax.xml.parsers.DocumentBuilderFactory.newInstance(); 368 369 dbf.setNamespaceAware(true); 370 javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); 371 org.w3c.dom.Document sigDoc = db.parse(bp1.getInputStream()); 372 373 374 /* 375 Here we create a XMLSignature object and Document just for the sake for saving the signature 376 to disk. It is inefficient why not we just get the bytes and save it directly???? It involves 377 some changes in RepositoryItem and RepositoryManager. 378 */ 379 XMLSignature payloadSignature = new XMLSignature(sigDoc.getDocumentElement(), ""); 380 381 //Verify that the repository item has not been tampered with during transit 382 System.err.println("Verifying payload signature for the payload with id ='" + id + "'"); 383 if (!SecurityUtil.getInstance().verifyPayloadSignature(id, mp)) { 384 throw new RegistryException("Failed to verify payload signature on incoming SOAP message" + 385 " for contentId = '" + id + "'."); 386 } 387 388 DataHandler dh = bp2.getDataHandler(); 389 //System.out.println("dh.getContentType() =======> " + dh.getContentType()); 390 391 ri = new RepositoryItem(id, payloadSignature, dh); 392 393 } 394 catch (SOAPException e) { 395 throw new RegistryException(e); 396 } 397 catch (MessagingException e) { 398 throw new RegistryException(e); 399 } 400 catch (javax.xml.parsers.ParserConfigurationException e) { 401 throw new RegistryException(e); 402 } 403 catch (IOException e) { 404 throw new RegistryException(e); 405 } 406 catch (org.xml.sax.SAXException e) { 407 throw new RegistryException(e); 408 } 409 410 catch (org.apache.xml.security.signature.XMLSignatureException e) { 411 throw new RegistryException(e); 412 } 413 414 catch (org.apache.xml.security.exceptions.XMLSecurityException e) { 415 throw new RegistryException(e); 416 } 417 418 return ri; 419 } 420 421 }

This page was automatically generated by Maven