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: SecurityPlugin.java,v 1.2 2007/08/01 11:08:18 ashutoshshahi Exp $
022: */
023:
024: /*
025: * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
026: * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
027: */
028:
029: package com.sun.xml.rpc.plugins;
030:
031: import java.io.File;
032: import java.io.IOException;
033: import java.io.InputStream;
034: import java.io.PrintStream;
035: import java.io.FileInputStream;
036: import java.io.DataInputStream;
037: import java.io.ByteArrayInputStream;
038:
039: import java.util.StringTokenizer;
040:
041: import com.sun.xml.rpc.tools.plugin.ToolPlugin;
042: import com.sun.xml.rpc.tools.wscompile.UsageIf;
043: import com.sun.xml.rpc.tools.wscompile.ModelIf;
044: import com.sun.xml.rpc.tools.wscompile.TieHooksIf;
045: import com.sun.xml.rpc.tools.wscompile.StubHooksIf;
046: import com.sun.xml.rpc.tools.wscompile.ModelIf.ModelProperty;
047:
048: import com.sun.xml.rpc.util.localization.Localizable;
049: import com.sun.xml.rpc.util.localization.LocalizableMessageFactory;
050:
051: import com.sun.xml.rpc.processor.model.Port;
052: import com.sun.xml.rpc.processor.model.Model;
053: import com.sun.xml.rpc.processor.util.IndentingWriter;
054:
055: import javax.xml.parsers.DocumentBuilder;
056: import javax.xml.parsers.DocumentBuilderFactory;
057:
058: import org.xml.sax.SAXException;
059: import org.xml.sax.SAXParseException;
060: import org.xml.sax.helpers.DefaultHandler;
061:
062: public class SecurityPlugin extends ToolPlugin implements UsageIf,
063: ModelIf, StubHooksIf, TieHooksIf {
064:
065: private File securityFile = null;
066: private LocalizableMessageFactory messageFactory;
067:
068: private static final String sec_util = "secPgUtil";
069: private static final String sec_util_pkg = "com.sun.xml.rpc.security";
070: private static final String SECURITY_PROPERTY = "com.sun.xml.rpc.security";
071:
072: public SecurityPlugin() {
073: messageFactory = new LocalizableMessageFactory(
074: "com.sun.xml.rpc.plugins.sec");
075: }
076:
077: public Localizable getOptionsUsage() {
078: return messageFactory.getMessage("sec.usage.options",
079: (Object[]) null);
080: }
081:
082: public Localizable getFeaturesUsage() {
083: return null;
084: }
085:
086: public Localizable getInternalUsage() {
087: return null;
088: }
089:
090: public Localizable getExamplesUsage() {
091: return null;
092: }
093:
094: public boolean parseArguments(String[] args, UsageError err) {
095: securityFile = null;
096:
097: for (int i = 0; i < args.length; i++) {
098: if (args[i] != null && args[i].equals("-security")) {
099: if ((i + 1) < args.length) {
100: if (securityFile != null) {
101: err.msg = messageFactory.getMessage(
102: "sec.duplicateOption",
103: new Object[] { "-security" });
104: return false;
105: }
106: args[i] = null;
107: securityFile = new File(args[++i]);
108: args[i] = null;
109: } else {
110: err.msg = messageFactory.getMessage(
111: "sec.missingOptionArgument",
112: new Object[] { "-security" });
113: return false;
114: }
115: }
116: }
117:
118: return true;
119: }
120:
121: public void updateModel(ModelProperty property) {
122: if (securityFile != null) {
123: property.attr = SECURITY_PROPERTY;
124: try {
125: DataInputStream in = new DataInputStream(
126: new FileInputStream(securityFile));
127: byte[] xmlBytes = new byte[(int) securityFile.length()];
128: in.readFully(xmlBytes);
129: in.close();
130:
131: /* validate security configuration */
132: DocumentBuilderFactory factory = new com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl();
133: factory
134: .setAttribute(
135: "http://apache.org/xml/features/validation/dynamic",
136: Boolean.FALSE);
137: factory
138: .setAttribute(
139: "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
140: "http://www.w3.org/2001/XMLSchema");
141: InputStream is = SecurityPlugin.class
142: .getResourceAsStream("xwssconfig.xsd");
143:
144: boolean validate = true;
145: try {
146: InputStream isV = SecurityPlugin.class
147: .getResourceAsStream("disablevalidation.xml");
148: if (isV != null)
149: validate = false;
150: } catch (Exception e) {
151: //ignore
152: }
153:
154: if (validate) {
155: factory
156: .setAttribute(
157: "http://java.sun.com/xml/jaxp/properties/schemaSource",
158: is);
159: factory.setValidating(true);
160: factory.setIgnoringComments(true);
161: factory.setNamespaceAware(true);
162: DocumentBuilder builder = factory
163: .newDocumentBuilder();
164: builder
165: .setErrorHandler(new ErrorHandler(
166: System.out));
167: ByteArrayInputStream inputStream = new ByteArrayInputStream(
168: xmlBytes);
169: builder.parse(inputStream);
170: }
171:
172: property.value = processString(new String(xmlBytes));
173: } catch (Exception e) {
174: throw new RuntimeException(e);
175: }
176: }
177: }
178:
179: public void _preHandlingHook(Model model, IndentingWriter p,
180: StubHooksState state) throws IOException {
181: String config = (String) model.getProperty(SECURITY_PROPERTY);
182: if (config != null) {
183: p.pln("//Generated by security plugin");
184: writeCheckMustUnderstandInStub(p);
185: p.pln(sec_util + "._preHandlingHook(state);");
186: p.pln("super._preHandlingHook(state);");
187: p.flush();
188: state.super Done = true;
189: }
190: }
191:
192: public void _preRequestSendingHook(Model model, IndentingWriter p,
193: StubHooksState state) throws IOException {
194: String config = (String) model.getProperty(SECURITY_PROPERTY);
195: if (config != null) {
196: p.pln("//Generated by security plugin");
197: p.pln("super._preRequestSendingHook(state);");
198: p.pln("bool = " + sec_util
199: + "._preRequestSendingHook(state);");
200: p.flush();
201: state.super Done = true;
202: }
203: }
204:
205: public void preHandlingHook(Model model, IndentingWriter p,
206: TieHooksState state) throws IOException {
207: String config = (String) model.getProperty(SECURITY_PROPERTY);
208: if (config != null) {
209: p.pln("//Generated by security plugin");
210: writeCheckMustUnderstandInTie(p);
211: p.plnI("try {");
212: p.pln("if (!" + sec_util
213: + ".preHandlingHook(state)) return false;");
214: p
215: .pOlnI("} catch (javax.xml.rpc.soap.SOAPFaultException sfe) {");
216: p
217: .pln("SOAPFaultInfo fault = new SOAPFaultInfo(sfe.getFaultCode(), sfe.getFaultString(), sfe.getFaultActor());");
218: p.pln("reportFault(fault, state);");
219: p.pln("return false;");
220: p.pOln("}");
221: p.pln("bool = super.preHandlingHook(state);");
222: p.flush();
223: state.super Done = true;
224: }
225: }
226:
227: public void postResponseWritingHook(Model model, IndentingWriter p,
228: TieHooksState state) throws IOException {
229: String config = (String) model.getProperty(SECURITY_PROPERTY);
230: if (config != null) {
231: p.pln("//Generated by security plugin");
232: p.pln("super.postResponseWritingHook(state);");
233: p.pln(sec_util + ".postResponseWritingHook(state);");
234: p.flush();
235: state.super Done = true;
236: }
237: }
238:
239: public void writeStubStatic(Model model, IndentingWriter p)
240: throws IOException {
241: // nop
242: }
243:
244: public void writeTieStatic(Model model, IndentingWriter p)
245: throws IOException {
246: // nop
247: }
248:
249: public void writeStubStatic(Model model, Port port,
250: IndentingWriter p) throws IOException {
251: writeStatics(model, port, p, true);
252: }
253:
254: public void writeTieStatic(Model model, Port port, IndentingWriter p)
255: throws IOException {
256: writeStatics(model, port, p, false);
257: }
258:
259: private void writeStatics(Model model, Port port,
260: IndentingWriter p, boolean isStub) throws IOException {
261: String config = (String) model.getProperty(SECURITY_PROPERTY);
262: if (config != null) {
263: config = "\"[version 1.0 FCS]" + config + "\"";
264:
265: String decl = "private static " + sec_util_pkg
266: + ".SecurityPluginUtil " + sec_util + ";";
267: String block_begin = "static {";
268: String block_body1 = "try {";
269: String block_body2 = sec_util + " = new " + sec_util_pkg
270: + ".SecurityPluginUtil(" + config + ", \""
271: + port.getName() + "\"" + ", "
272: + Boolean.valueOf(isStub) + ");";
273: String block_body3 = "} catch (Exception e) {";
274: String block_body4 = "e.printStackTrace();";
275: String block_body5 = "throw new RuntimeException(e);";
276: String block_body6 = "}";
277: String block_end = "}";
278:
279: p.pln(decl);
280: p.pln();
281: p.plnI(block_begin);
282: p.plnI(block_body1);
283: p.flush();
284: char[] array = block_body2.toCharArray();
285: for (int i = 0; i < array.length; i++)
286: p.write(array[i]);
287: p.newLine();
288: p.flush();
289: p.pOlnI(block_body3);
290: p.pln(block_body4);
291: p.pOln(block_body5);
292: p.pOln(block_body6);
293: p.pOln(block_end);
294: p.flush();
295: }
296: }
297:
298: private void writeCheckMustUnderstandInStub(IndentingWriter p)
299: throws IOException {
300: p.pln("// prepare message for check");
301: p
302: .pln(sec_util
303: + ".prepareMessageForMUCheck(state.getResponse().getMessage());");
304: p.pln();
305: p
306: .pln("com.sun.xml.rpc.client.HandlerChainImpl handlerChain = (com.sun.xml.rpc.client.HandlerChainImpl) state.getHandlerChain();");
307: p
308: .plnI("if (handlerChain != null && !handlerChain.isEmpty()) {");
309: p
310: .pln("boolean allUnderstood = handlerChain.checkMustUnderstand(state.getMessageContext());");
311: p.plnI("if (allUnderstood == false) {");
312: p
313: .pln("throw new javax.xml.rpc.soap.SOAPFaultException("
314: + "com.sun.xml.rpc.encoding.soap.SOAPConstants.FAULT_CODE_MUST_UNDERSTAND,"
315: + "\"SOAP must understand error\","
316: + "_getActor()," + "null);");
317: p.pOln("}");
318: p.pOln("}");
319: p.pln();
320: p.pln("// restore message after check");
321: p
322: .pln(sec_util
323: + ".restoreMessageAfterMUCheck(state.getResponse().getMessage());");
324: p.flush();
325: }
326:
327: private void writeCheckMustUnderstandInTie(IndentingWriter p)
328: throws IOException {
329: p.pln("// prepare message for check");
330: p
331: .pln(sec_util
332: + ".prepareMessageForMUCheck(state.getRequest().getMessage());");
333: p.pln();
334: p
335: .pln("com.sun.xml.rpc.client.HandlerChainImpl handlerChain = getHandlerChain();");
336: p
337: .plnI("if (handlerChain != null && !handlerChain.isEmpty()) {");
338: p
339: .pln("boolean allUnderstood = handlerChain.checkMustUnderstand(state.getMessageContext());");
340: p.plnI("if (allUnderstood == false) {");
341: p
342: .pln("com.sun.xml.rpc.soap.message.SOAPFaultInfo fault = new "
343: + "com.sun.xml.rpc.soap.message.SOAPFaultInfo(com.sun.xml.rpc.encoding.soap.SOAPConstants.FAULT_CODE_MUST_UNDERSTAND,"
344: + "\"SOAP must understand error\", getActor());");
345: p.pln("reportFault(fault, state);");
346: p.pln("state.getRequest().setHeaderNotUnderstood(true);");
347: p
348: .pln("state.setHandlerFlag(StreamingHandlerState.CALL_NO_HANDLERS);");
349: p.pln("return false;");
350: p.pOln("}");
351: p.pOln("}");
352: p.pln();
353: p.pln("// restore message after check");
354: p
355: .pln(sec_util
356: + ".restoreMessageAfterMUCheck(state.getRequest().getMessage());");
357: p.flush();
358: }
359:
360: private String processString(String config) {
361: return replaceOthers(replaceOthers(replaceNewLine(config),
362: "\"", "\\\""), " ", " ");
363:
364: }
365:
366: private String replaceNewLine(String config) {
367: return config.replace('\r', ' ').replace('\n', ' ');
368: }
369:
370: private String replaceOthers(String config, String delim,
371: String append) {
372: StringTokenizer strTokenizer = new StringTokenizer(config,
373: delim);
374: StringBuffer sbuf = new StringBuffer();
375: while (strTokenizer.hasMoreTokens()) {
376: String tok = strTokenizer.nextToken();
377: sbuf.append(tok);
378: // Assuming the string is regular xml -
379: if (strTokenizer.hasMoreTokens()) {
380: sbuf.append(append);
381: }
382: }
383: return sbuf.toString();
384: }
385:
386: private static class ErrorHandler extends DefaultHandler {
387: PrintStream out;
388:
389: public ErrorHandler(PrintStream out) {
390: this .out = out;
391: }
392:
393: public void error(SAXParseException e) throws SAXException {
394: if (out != null)
395: out.println(e);
396: throw e;
397: }
398:
399: public void warning(SAXParseException e) throws SAXException {
400: if (out != null)
401: out.println(e);
402: else
403: ;// log
404: }
405:
406: public void fatalError(SAXParseException e) throws SAXException {
407: if (out != null)
408: out.println(e);
409: throw e;
410: }
411: }
412:
413: }
|