From 68b6f72bbb671ffaedcbe0e4f77a6661450e385c Mon Sep 17 00:00:00 2001 From: Matt Murphy Date: Wed, 7 Jun 2017 13:44:10 -0400 Subject: [PATCH 1/2] sast scanmanager --- pom.xml | 2 +- .../plugin/core/scanners/messages.properties | 3 +- .../core/scanners/sast/SASTScanManager.java | 87 ++++++ .../core/scanners/sast/target/CppTarget.java | 22 ++ .../scanners/sast/target/DefaultTarget.java | 35 +++ .../scanners/sast/target/DotNetTarget.java | 21 ++ .../core/scanners/sast/target/ICppTarget.java | 26 ++ .../scanners/sast/target/IDotNetTarget.java | 21 ++ .../core/scanners/sast/target/IJEETarget.java | 16 ++ .../scanners/sast/target/IJavaTarget.java | 21 ++ .../scanners/sast/target/ISASTTarget.java | 46 ++++ .../core/scanners/sast/target/JEETarget.java | 15 ++ .../core/scanners/sast/target/JavaTarget.java | 17 ++ .../core/scanners/sast/xml/DOMWriter.java | 255 ++++++++++++++++++ .../scanners/sast/xml/IModelXMLConstants.java | 39 +++ .../core/scanners/sast/xml/ModelWriter.java | 123 +++++++++ .../core/scanners/sast/xml/XmlWriter.java | 95 +++++++ 17 files changed, 842 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/CppTarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DefaultTarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DotNetTarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ICppTarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IDotNetTarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJEETarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJavaTarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ISASTTarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JEETarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JavaTarget.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/DOMWriter.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/ModelWriter.java create mode 100644 src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/XmlWriter.java diff --git a/pom.xml b/pom.xml index 0a628aa..c645906 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ com.github.AppSecDev asoc-core - 1.0.2 + scan_manager-SNAPSHOT diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/messages.properties b/src/main/java/com/ibm/appscan/plugin/core/scanners/messages.properties index fc31099..c83490c 100644 --- a/src/main/java/com/ibm/appscan/plugin/core/scanners/messages.properties +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/messages.properties @@ -23,4 +23,5 @@ error.running.scan=An error occurred running the scan. {0} error.scan.failed=The security analysis process failed. {0} error.target.invalid=The scan target {0} is invalid. error.creating.scan=An error occurred initiating the scan. - +error.delete=Failed to delete {0}. +error.dom.state=Bad DOM state. \ No newline at end of file diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java new file mode 100644 index 0000000..6ba59ef --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java @@ -0,0 +1,87 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.xml.transform.TransformerException; + +import com.ibm.appscan.plugin.core.CoreConstants; +import com.ibm.appscan.plugin.core.error.AppScanException; +import com.ibm.appscan.plugin.core.error.InvalidTargetException; +import com.ibm.appscan.plugin.core.error.ScannerException; +import com.ibm.appscan.plugin.core.logging.IProgress; +import com.ibm.appscan.plugin.core.scan.IScanManager; +import com.ibm.appscan.plugin.core.scan.IScanServiceProvider; +import com.ibm.appscan.plugin.core.scan.ITarget; +import com.ibm.appscan.plugin.core.scanners.sast.SASTConstants; +import com.ibm.appscan.plugin.core.scanners.sast.SASTScan; +import com.ibm.appscan.plugin.core.scanners.sast.target.ISASTTarget; +import com.ibm.appscan.plugin.core.scanners.sast.xml.ModelWriter; +import com.ibm.appscan.plugin.core.scanners.sast.xml.XmlWriter; + +public class SASTScanManager implements IScanManager{ + + private List m_targets; + private SASTScan m_scan; + private String m_workingDirectory; + + public SASTScanManager(String workingDir) { + m_workingDirectory = workingDir; + m_targets = new ArrayList(); + } + + @Override + public void prepare(IProgress progress, Map properties) throws AppScanException { + createConfig(); + properties.put(CoreConstants.TARGET, m_workingDirectory); + properties.put(SASTConstants.PREPARE_ONLY, Boolean.toString(true)); + run(progress, properties, null); + } + + @Override + public void analyze(IProgress progress, Map properties, IScanServiceProvider provider) throws AppScanException { + if(m_scan == null || m_scan.getIrx() == null) { + createConfig(); + properties.put(CoreConstants.TARGET, m_workingDirectory); + } + else + properties.put(CoreConstants.TARGET, m_scan.getIrx().getAbsolutePath()); + + run(progress, properties, provider); + } + + @Override + public void addScanTarget(ITarget target) { + if(target instanceof ISASTTarget) + m_targets.add((ISASTTarget)target); + } + + private void run(IProgress progress,Map properties, IScanServiceProvider provider) throws AppScanException { + try { + m_scan = new SASTScan(properties, progress, provider); + m_scan.run(); + } catch (InvalidTargetException | ScannerException e) { + throw new AppScanException(e.getLocalizedMessage()); + } + } + + private String createConfig() throws AppScanException { + try { + ModelWriter writer = new XmlWriter(); + writer.initWriters(new File(m_workingDirectory)); + writer.visit(m_targets); + writer.write(); + return writer.getOutputLocation(); + } catch (IOException | TransformerException e) { + throw new AppScanException(e.getLocalizedMessage()); + } + } +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/CppTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/CppTarget.java new file mode 100644 index 0000000..e7ee2cb --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/CppTarget.java @@ -0,0 +1,22 @@ +/* + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.target; + +import java.util.HashMap; +import java.util.Map; + +import com.ibm.appscan.plugin.core.scanners.sast.xml.IModelXMLConstants; + +public abstract class CppTarget extends DefaultTarget implements ICppTarget { + + @Override + public Map getProperties() { + HashMap buildInfos = new HashMap(); + buildInfos.put(IModelXMLConstants.A_ADDITIONAL_CLASSPATH, getCompilerOptions()); + buildInfos.put(IModelXMLConstants.A_MACROS, getMacros()); + buildInfos.put(IModelXMLConstants.A_INCLUDE_PATHS, getIncludeDirs()); + return buildInfos; + } +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DefaultTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DefaultTarget.java new file mode 100644 index 0000000..a6eb060 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DefaultTarget.java @@ -0,0 +1,35 @@ +package com.ibm.appscan.plugin.core.scanners.sast.target; + +import java.util.HashSet; +import java.util.Set; + +public abstract class DefaultTarget implements ISASTTarget { + + Set m_exclusionPatterns; + Set m_inclusionPatterns; + + public DefaultTarget() { + m_exclusionPatterns = new HashSet(); + m_inclusionPatterns = new HashSet(); + } + + @Override + public String getTarget() { + return getTargetFile().getAbsolutePath(); + } + + @Override + public Set getExclusionPatterns() { + return m_exclusionPatterns; + } + + @Override + public Set getInclusionPatterns() { + return m_inclusionPatterns; + } + + @Override + public boolean outputsOnly() { + return false; + } +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DotNetTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DotNetTarget.java new file mode 100644 index 0000000..4cbdd94 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DotNetTarget.java @@ -0,0 +1,21 @@ +/* + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.target; + +import java.util.HashMap; +import java.util.Map; + +import com.ibm.appscan.plugin.core.scanners.sast.xml.IModelXMLConstants; + +public abstract class DotNetTarget extends DefaultTarget implements IDotNetTarget { + + @Override + public Map getProperties() { + HashMap buildInfos = new HashMap(); + buildInfos.put(IModelXMLConstants.A_REFERENCES, getReferences()); + buildInfos.put(IModelXMLConstants.A_FRAMEWORK, getFrameworkVersion()); + return buildInfos; + } +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ICppTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ICppTarget.java new file mode 100644 index 0000000..ee0aea0 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ICppTarget.java @@ -0,0 +1,26 @@ +/* + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.target; + +public interface ICppTarget extends ISASTTarget { + + /** + * Gets the compiler options used to build the target. + * @return + */ + String getCompilerOptions(); + + /** + * Gets the macros defined for the target. + * @return + */ + String getMacros(); + + /** + * Gets the include directories for the target. + * @return + */ + String getIncludeDirs(); +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IDotNetTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IDotNetTarget.java new file mode 100644 index 0000000..7d1e0a9 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IDotNetTarget.java @@ -0,0 +1,21 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.target; + +public interface IDotNetTarget extends ISASTTarget { + + /** + * Gets the dependencies of this target as a string. + * @return + */ + String getReferences(); + + /** + * Gets the targeted framework version of this target. + * @return + */ + String getFrameworkVersion(); +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJEETarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJEETarget.java new file mode 100644 index 0000000..e302bd2 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJEETarget.java @@ -0,0 +1,16 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.target; + +public interface IJEETarget extends IJavaTarget { + + /** + * Gets the jsp compiler that should be used for this target. + * @return + */ + String getJSPCompiler(); + +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJavaTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJavaTarget.java new file mode 100644 index 0000000..e2f6d81 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJavaTarget.java @@ -0,0 +1,21 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.target; + +public interface IJavaTarget extends ISASTTarget { + + /** + * Gets the classpath for this target as a String. + * @return + */ + String getClasspath(); + + /** + * Gets the jre/jdk associated with this target. + * @return + */ + String getJava(); +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ISASTTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ISASTTarget.java new file mode 100644 index 0000000..58a2077 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ISASTTarget.java @@ -0,0 +1,46 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.target; + + +import java.io.File; +import java.util.Map; +import java.util.Set; + +import com.ibm.appscan.plugin.core.scan.ITarget; + +public interface ISASTTarget extends ITarget{ + + /** + * Gets the target file. + * @return The target file. + */ + File getTargetFile(); + + /** + * Gets a map of properties associated with the target. + * @return The Map of properties. + */ + Map getProperties(); + + /** + * Gets a list of exclusion patterns for this target. + * @return A list of patterns to exclude. + */ + Set getExclusionPatterns(); + + /** + * Gets a list of inclusion patterns for this target. + * @return A list of patterns to include. + */ + Set getInclusionPatterns(); + + /** + * Whether this target is only associated with build output files (e.g. .jar, .dll, etc.) + * @return false if this target includes non-build outputs. + */ + boolean outputsOnly(); +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JEETarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JEETarget.java new file mode 100644 index 0000000..5cf6186 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JEETarget.java @@ -0,0 +1,15 @@ +package com.ibm.appscan.plugin.core.scanners.sast.target; + +import java.util.Map; + +import com.ibm.appscan.plugin.core.scanners.sast.xml.IModelXMLConstants; + +public abstract class JEETarget extends JavaTarget implements IJEETarget { + + @Override + public Map getProperties() { + Map buildInfos = super.getProperties(); + buildInfos.put(IModelXMLConstants.A_JSP_COMPILER, getJSPCompiler()); + return buildInfos; + } +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JavaTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JavaTarget.java new file mode 100644 index 0000000..f155cff --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JavaTarget.java @@ -0,0 +1,17 @@ +package com.ibm.appscan.plugin.core.scanners.sast.target; + +import java.util.HashMap; +import java.util.Map; + +import com.ibm.appscan.plugin.core.scanners.sast.xml.IModelXMLConstants; + +public abstract class JavaTarget extends DefaultTarget implements IJavaTarget { + + @Override + public Map getProperties() { + HashMap buildInfos = new HashMap(); + buildInfos.put(IModelXMLConstants.A_ADDITIONAL_CLASSPATH, getClasspath()); + buildInfos.put(IModelXMLConstants.A_JDK_PATH, getJava()); + return buildInfos; + } +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/DOMWriter.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/DOMWriter.java new file mode 100644 index 0000000..7d8a40f --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/DOMWriter.java @@ -0,0 +1,255 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.xml; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.ibm.appscan.plugin.core.scanners.Messages; + +/** + * Helper class for constructing and writing a DOM document. + */ +public final class DOMWriter { + + private File m_file; + private DocumentBuilder m_builder; + private Document m_doc; + private OutputStream m_stream; + private Element m_current = null; + + /** + * Constructor. + * + * @param file The file to write. + * @param builder A document builder. + * @param append If file exist, setting this to true appends to the file. + * @throws IOException If the file already exists, append is false, and the file could not be deleted. + * Or if file already exists, append is true, but there is an error parsing the existing file. + */ + public DOMWriter(File file, DocumentBuilder builder, boolean append) throws IOException { + m_file = file; + m_builder = builder; + + if (m_file.exists()) { + + if (append) { + try { + m_doc = builder.parse(file); + m_current = m_doc.getDocumentElement(); + return; + } + catch (SAXException e) { + throw new IOException(e); + } + } + + if (!m_file.delete()) + throw new IOException(Messages.getMessage("error.delete", m_file)); //$NON-NLS-1$ + } + else + m_file.getParentFile().mkdirs(); + + m_doc = builder.newDocument(); + } + + /** + * Constructor. + * + * @param file The file to write. + * @param builder A document builder. + * @throws IOException If the file already exists and could not be deleted. + */ + public DOMWriter(File file, DocumentBuilder builder) throws IOException { + this(file, builder, false); + } + + /** + * Constructor. + * + * @param directory Directory to contain the written file. + * @param file The name of the file to write. + * @param builder A document builder. + * @throws IOException If the file already exists and could not be deleted. + */ + public DOMWriter(File directory, String file, DocumentBuilder builder) throws IOException { + this(new File(directory, file), builder, false); + } + + /** + * Constructor. + * Makes a new DOMWriter + */ + public DOMWriter(OutputStream stream,DocumentBuilder builder) { + m_stream=stream; + m_builder = builder; + m_doc = builder.newDocument(); + } + + /** + * Create an attribute for the current element. + * + * @param name The attribute name. + * @param value The attribute value. + */ + //@SuppressSecurityTrace + public void setAttribute(String name, String value) { + try { + m_current.setAttribute(name, value); + } + catch (DOMException e) { + if (e.code != DOMException.INVALID_CHARACTER_ERR) + throw e; + } + } + + /** + * Append a document fragment to the current element. + * + * @param fragment The document fragment to append. + */ + public void appendFragment(DocumentFragment fragment) { + if (fragment != null) { + Node newFragment = m_doc.importNode(fragment, true); + m_current.appendChild(newFragment); + } + } + + /** + * Append the XML string as a document fragment to the current element. + * + * @param xml The XML string. + * @throws IOException If any IO errors occur. + * @throws SAXException If any parse errors occur. + */ + public void appendFragment(String xml) throws IOException, SAXException { + if (xml != null) { + Document document = m_builder.parse(new InputSource(new StringReader(xml))); + DocumentFragment fragment = document.createDocumentFragment(); + fragment.appendChild(document.getDocumentElement()); + appendFragment(fragment); + } + } + + /** + * Append a DOM node to the current element. + * + * @param node The DOM node to append. + */ + public void appendNode(Node node) { + if (node != null) { + m_current.appendChild(node); + } + } + + /** + * Begin a new element. + * + * @param name The name of the element. + */ + public void beginElement(String name) { + Element child = m_doc.createElement(name); + if (m_current == null) + m_doc.appendChild(child); + else + m_current.appendChild(child); + m_current = child; + } + + /** + * Close off the current element. + */ + public void endElement() { + Node parent = m_current.getParentNode(); + if (parent instanceof Element) + m_current = (Element) parent; + } + + /** + * Write some data and close off the element. The data is treated as + * CData if {@code isCData} is true. An IllegalStateException is thrown + * if the current element has child elements. + * + * @param data The text. + * @param isCData True if the data is CData. + */ + public void endElement(String data, boolean isCData) { + if (data != null) { + if (m_current.hasChildNodes()) + throw new IllegalStateException(Messages.getMessage("error.dom.state")); //$NON-NLS-1$ + m_current.appendChild(isCData ? m_doc.createCDATASection(data) : m_doc.createTextNode(data)); + } + endElement(); + } + + /** + * Write some text data and close off the element. An + * IllegalStateException is thrown if the current element + * has child elements. + * + * @param data The text. + */ + public void endElement(String data) { + endElement(data, false); + } + + /** + * Write the document to disk. + * + * @param transformer A transformer. + * @throws TransformerException If an error occurs during the write operation. + */ + public void write(Transformer transformer) throws TransformerException { + DOMSource source = new DOMSource(m_doc); + boolean shouldCloseAfter = false; + try { + StreamResult result; + if (m_stream==null) { + m_stream = new FileOutputStream(m_file); + shouldCloseAfter = true; + } + result = new StreamResult(m_stream); + transformer.transform(source, result); + } catch (IOException e) { + throw new TransformerException(e); + } finally { + if (m_stream!=null && shouldCloseAfter) { + try { + m_stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + m_stream = null; + } + } + } + + /** + * Returns the Document object. + * + * @return The Document object. + */ + public Document getDocument() { + return m_doc; + } +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java new file mode 100644 index 0000000..1523ae7 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java @@ -0,0 +1,39 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.xml; + +public interface IModelXMLConstants { + + String E_CONFIGURATION = "Configuration"; //$NON-NLS-1$ + String E_TARGETS = "Targets"; //$NON-NLS-1$ + String E_TARGET = "Target"; //$NON-NLS-1$ + String E_TARGET_SETTINGS = "TargetSettings"; //$NON-NLS-1$ + String E_CUSTOM_BUILD_INFO = "CustomBuildInfo"; //$NON-NLS-1$ + String E_INCLUDE = "Include"; //$NON-NLS-1$ + String E_EXCLUDE = "Exclude"; //$NON-NLS-1$ + + //Java + String A_PATH = "path"; //$NON-NLS-1$ + String A_SRC_PATH = "src_path"; //$NON-NLS-1$ + String A_SRC_ROOT = "src_root"; //$NON-NLS-1$ + String A_JDK_PATH = "jdk_path"; //$NON-NLS-1$ + String A_JSP_COMPILER = "jsp_compiler"; //$NON-NLS-1$ + String A_ADDITIONAL_CLASSPATH = "additional_classpath"; //$NON-NLS-1$ + String A_OUTPUTS_ONLY = "outputs-only"; //$NON-NLS-1$ + + //C++ + String A_COMPILER_OPTS = "compiler_opts"; + String A_MACROS = "macros"; + String A_INCLUDE_PATHS = "include_paths"; + String A_BUILD_CONFIG = "build_configuration"; + + String APPSCAN_CONFIG = "appscan-config"; //$NON-NLS-1$ + String DOT_XML = ".xml"; //$NON-NLS-1$ + + //.NET + String A_REFERENCES = "references"; //$NON-NLS-1$ + String A_FRAMEWORK = "framework_version"; //$NON-NLS-1$ +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/ModelWriter.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/ModelWriter.java new file mode 100644 index 0000000..82a0a3b --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/ModelWriter.java @@ -0,0 +1,123 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.xml; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; + +import com.ibm.appscan.plugin.core.scanners.sast.target.ISASTTarget; + + +/** + * Base implementation of a model writer. Subclasses define the logic to write + * specific fragments of the scan model to disk. + */ +public abstract class ModelWriter { + /** + * Instance of a document builder, initialized only after {@link #initialize(File)} is called. + */ + protected DocumentBuilder m_builder; + + /** + * Instance of a transformer, initialized only after {@link #initialize(File)} is called. + */ + protected Transformer m_transformer; + + /** + * Initializes this model writer. + * + * @param directory The directory where the scan is stored. + * @throws ParserConfigurationException If a problem occurs initializing the document builder + * @throws TransformerConfigurationException If a problem occurs initializing the transformer + * @throws IOException If a problem occurs initializing the internal writers. + */ + public final void initialize(File directory) + throws ParserConfigurationException , TransformerConfigurationException, IOException { + + initDocumentBuilder(); + initTransformer(); + //initWriters(directory); + } + /** + * Subclasses can override this to configure the document builder factory. + * The default implementation does nothing. + * + * @param factory The document builder factory. + */ + protected void configureDocumentBuilderFactory(DocumentBuilderFactory factory) { + // subclass to override + } + + + /** + * Subclasses can override this to configure the transformer factory. + * The default implementation does nothing. + * + * @param factory The transformer factory. + */ + protected void configureTransformerFactory(TransformerFactory factory) { + // subclass to override + } + + /** + * Subclasses can override this to configure the transformer. + */ + protected void configureTransformer() { + m_transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$ + m_transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + m_transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /* + * Initializes the transformer. + */ + private void initTransformer() throws TransformerConfigurationException { + TransformerFactory factory = TransformerFactory.newInstance(); + configureTransformerFactory(factory); + m_transformer = factory.newTransformer(); + configureTransformer(); + } + + /* + * Initializes the document builder. + */ + private void initDocumentBuilder() throws ParserConfigurationException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + configureDocumentBuilderFactory(factory); + m_builder = factory.newDocumentBuilder(); + } + + + /** + * Initializes the internal writers typically there is one writer for each fragment of the + * scan model to write. + * + * @param directory The directory where the model files are. + * @throws IOException If a problem occurs initializing the internal writers. + */ + public abstract void initWriters(File directory) throws IOException; + + /** + * Write out to disk. + * + * @throws TransformerException If a problem occurs during the write. + */ + public abstract void write() throws TransformerException; + + public abstract String getOutputLocation() ; + + public abstract void visit(List targets) ; +} diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/XmlWriter.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/XmlWriter.java new file mode 100644 index 0000000..b28bae3 --- /dev/null +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/XmlWriter.java @@ -0,0 +1,95 @@ +/* + * (c) Copyright IBM Corp. 2016. + * (c) Copyright HCL Technologies Ltd. 2017. +*/ + +package com.ibm.appscan.plugin.core.scanners.sast.xml; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map.Entry; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; + +import com.ibm.appscan.plugin.core.scanners.sast.target.ISASTTarget; + +public class XmlWriter extends ModelWriter +implements IModelXMLConstants +{ + + private DOMWriter m_config; + private String m_configOutputDirectory = null; + private String m_configFileName = APPSCAN_CONFIG + DOT_XML; + + @Override + public void initWriters(File directory) throws IOException { + m_configOutputDirectory = directory.getCanonicalPath(); + try { + initialize(directory); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + m_config = new DOMWriter(directory, m_configFileName, m_builder); + } + + @Override + public void visit(List targets) { + m_config.beginElement(E_CONFIGURATION); + m_config.beginElement(E_TARGETS); + + for (ISASTTarget target: targets){ + //Add Target + m_config.beginElement(E_TARGET); + m_config.setAttribute(A_PATH, target.getTargetFile().getAbsolutePath()); + if(target.outputsOnly()) + m_config.setAttribute(A_OUTPUTS_ONLY, "true"); + + //Add CustomBuildInfo + if(target.getProperties().size() > 0) { + m_config.beginElement(E_CUSTOM_BUILD_INFO); + + for (Entry buildInfo : target.getProperties().entrySet()) + m_config.setAttribute(buildInfo.getKey(), buildInfo.getValue()); + + m_config.endElement(); + } + + //Add Include patterns + for(String include : target.getInclusionPatterns()) { + m_config.beginElement(E_INCLUDE); + m_config.endElement(include); + } + + //Add Exclude patterns + for(String exclude : target.getExclusionPatterns()) { + m_config.beginElement(E_EXCLUDE); + m_config.endElement(exclude); + } + + m_config.endElement(); // + } + + m_config.endElement(); // + } + + @Override + public void write() throws TransformerException { + m_transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); //$NON-NLS-1$ + m_config.write(m_transformer); + } + + /** + * Returns the location of the generated configuration file. + * @return + */ + @Override + public String getOutputLocation() { + return m_configOutputDirectory+File.separator+m_configFileName; + } +} From 9d384609de649c9123c4ae0be63ee7a283023c31 Mon Sep 17 00:00:00 2001 From: Matt Murphy Date: Thu, 8 Jun 2017 09:36:45 -0400 Subject: [PATCH 2/2] sast scan manager update --- .../plugin/core/scanners/sast/SASTScan.java | 3 +++ .../plugin/core/scanners/sast/SASTScanManager.java | 2 +- .../core/scanners/sast/xml/IModelXMLConstants.java | 14 +++++++------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScan.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScan.java index bf80e6e..adfdca7 100644 --- a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScan.java +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScan.java @@ -17,6 +17,9 @@ import com.ibm.appscan.plugin.core.scanners.ASoCScan; import com.ibm.appscan.plugin.core.scanners.Messages; +/** + * A class for running static scans. For greater control over what gets scanned a {@link SASTScanManager} should be used. + */ public class SASTScan extends ASoCScan implements SASTConstants { private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java index 6ba59ef..40b77ef 100644 --- a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java @@ -81,7 +81,7 @@ private String createConfig() throws AppScanException { writer.write(); return writer.getOutputLocation(); } catch (IOException | TransformerException e) { - throw new AppScanException(e.getLocalizedMessage()); + throw new AppScanException(e.getLocalizedMessage(), e); } } } diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java index 1523ae7..ef2f98e 100644 --- a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java +++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java @@ -7,6 +7,9 @@ public interface IModelXMLConstants { + String APPSCAN_CONFIG = "appscan-config"; //$NON-NLS-1$ + String DOT_XML = ".xml"; //$NON-NLS-1$ + String E_CONFIGURATION = "Configuration"; //$NON-NLS-1$ String E_TARGETS = "Targets"; //$NON-NLS-1$ String E_TARGET = "Target"; //$NON-NLS-1$ @@ -25,13 +28,10 @@ public interface IModelXMLConstants { String A_OUTPUTS_ONLY = "outputs-only"; //$NON-NLS-1$ //C++ - String A_COMPILER_OPTS = "compiler_opts"; - String A_MACROS = "macros"; - String A_INCLUDE_PATHS = "include_paths"; - String A_BUILD_CONFIG = "build_configuration"; - - String APPSCAN_CONFIG = "appscan-config"; //$NON-NLS-1$ - String DOT_XML = ".xml"; //$NON-NLS-1$ + String A_COMPILER_OPTS = "compiler_opts"; //$NON-NLS-1$ + String A_MACROS = "macros"; //$NON-NLS-1$ + String A_INCLUDE_PATHS = "include_paths"; //$NON-NLS-1$ + String A_BUILD_CONFIG = "build_configuration"; //$NON-NLS-1$ //.NET String A_REFERENCES = "references"; //$NON-NLS-1$