as a new layer into {@link VulasConfiguration}.
+ * If no such element exists, e.g., because the POM file does not contain a plugin section for Vulas, default settings
+ * are established using {@link MavenProject} and {@link VulasConfiguration#setPropertyIfEmpty(String, Object)}.
+ *
+ * @throws Exception
+ */
+ public final void prepareConfiguration() throws Exception {
+
+ // Delete any transient settings that remaining from a previous goal execution (if any)
+ final boolean contained_values = VulasConfiguration.getGlobal().clearTransientProperties();
+ if (contained_values)
+ getLog().info("Transient configuration settings deleted");
+
+ // Get the configuration layer from the plugin configuration (can be null)
+ VulasConfiguration.getGlobal().addAfterSystemProperties("Plugin configuration", this.layeredConfiguration, null, true);
+
+ // Check whether the application context can be established
+ Application app = null;
+ try {
+ app = CoreConfiguration.getAppContext();
+ }
+ // In case the plugin is called w/o using the Vulas profile, project-specific settings are not set
+ // Set them using the project member
+ catch (ConfigurationException e) {
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.APP_CTX_GROUP, this.project.getGroupId());
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.APP_CTX_ARTIF, this.project.getArtifactId());
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.APP_CTX_VERSI, this.project.getVersion());
+ app = CoreConfiguration.getAppContext();
+ }
+
+ // Set defaults for all the paths
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(VulasConfiguration.TMP_DIR, Paths.get(this.project.getBuild().getDirectory(), "vulas", "tmp").toString());
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.UPLOAD_DIR, Paths.get(this.project.getBuild().getDirectory(), "vulas", "upload").toString());
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.INSTR_SRC_DIR, Paths.get(this.project.getBuild().getDirectory()).toString());
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.INSTR_TARGET_DIR, Paths.get(this.project.getBuild().getDirectory(), "vulas", "target").toString());
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.INSTR_INCLUDE_DIR, Paths.get(this.project.getBuild().getDirectory(), "vulas", "include").toString());
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.INSTR_LIB_DIR, Paths.get(this.project.getBuild().getDirectory(), "vulas", "lib").toString());
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.REP_DIR, Paths.get(this.project.getBuild().getDirectory(), "vulas", "report").toString());
+
+ // Read app constructs from src/main/java and target/classes
+ final String p = Paths.get(this.project.getBuild().getOutputDirectory()).toString() + "," + Paths.get(this.project.getBuild().getSourceDirectory()).toString();
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.APP_DIRS, p);
+
+ // Test how-to get the reactor POM in a reliable manner
+ // The following method call fails if Maven is called with option -pl
+ getLog().info("Top level project: " + this.session.getTopLevelProject());
+ getLog().info("Execution root dir: " + this.session.getExecutionRootDirectory());
+
+ // Includes, excludes and ignorePoms
+ this.includeArtifacts = new StringList(VulasConfiguration.getGlobal().getStringArray(INCLUDES, null));
+ this.excludeArtifacts = new StringList(VulasConfiguration.getGlobal().getStringArray(EXCLUDES, null));
+ this.ignorePoms = VulasConfiguration.getGlobal().getConfiguration().getBoolean(IGNORE_POMS, false);
+ }
+
+ /**
+ * This method, called by Maven, first invokes {@link AbstractVulasMojo#createGoal()} and then {@link AbstractVulasMojo#executeGoal()}.
+ */
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ try {
+ this.prepareConfiguration();
+
+ final boolean do_process = this instanceof MvnPluginReport || this.isPassingFilter(this.project);
+ if (do_process) {
+ // Create the goal
+ this.createGoal();
+ this.goal.setGoalClient(GoalClient.MAVEN_PLUGIN);
+ this.goal.setConfiguration(VulasConfiguration.getGlobal());
+
+ // Set the application paths
+ this.goal.addAppPaths(FileUtil.getPaths(VulasConfiguration.getGlobal().getStringArray(CoreConfiguration.APP_DIRS, null)));
+
+ // Set the dependency paths
+ this.setKnownDependencies();
+
+ // Execute the goal
+ this.executeGoal();
+ }
+ }
+ // Expected problems will be passed on as is
+ catch (MojoFailureException mfe) {
+ throw mfe;
+ }
+ // Unexpected problems (the goal execution terminates abnormally/unexpectedly)
+ catch (GoalExecutionException gee) {
+ throw new MojoExecutionException(gee.getMessage(), gee);
+ }
+ // Every other exception results in a MojoExecutionException (= unexpected)
+ catch (Exception e) {
+ throw new MojoExecutionException("Error during Vulas goal execution " + this.goal + ": ", e);
+ }
+ }
+
+ /**
+ * Evaluates the configuration settings {@link AbstractVulasMojo#INCLUDES}, {@link AbstractVulasMojo#EXCLUDES} and {@link #IGNORE_POMS} to
+ * determine whether the given {@link MavenProject} shall be processed.
+ *
+ * @param _prj
+ * @return
+ */
+ private boolean isPassingFilter(MavenProject _prj) {
+ boolean do_process = true;
+
+ // Only included ones
+ if (!this.includeArtifacts.isEmpty()) {
+ do_process = this.includeArtifacts.contains(_prj.getArtifactId(), ComparisonMode.EQUALS, CaseSensitivity.CASE_INSENSITIVE);
+ if (do_process)
+ this.getLog().info("Artifact [" + _prj.getArtifactId() + "] explicitly included for processing via configuration parameter [" + INCLUDES + "]");
+ else
+ this.getLog().warn("Artifact [" + _prj.getArtifactId() + "] will NOT be processed, it is not among those explicitly included for processing via configuration parameter [" + INCLUDES + "]");
+ }
+
+ // Excluded (explicitly or through packaging)
+ else {
+ if (!this.excludeArtifacts.isEmpty() && this.excludeArtifacts.contains(_prj.getArtifactId(), ComparisonMode.EQUALS, CaseSensitivity.CASE_INSENSITIVE)) {
+ this.getLog().warn("Artifact [" + _prj.getArtifactId() + "] explicitly excluded from processing via configuration parameter [" + EXCLUDES + "]");
+ do_process = false;
+ }
+ if (do_process && this.ignorePoms && "POM".equalsIgnoreCase(_prj.getPackaging())) {
+ this.getLog().warn("Artifact [" + _prj.getArtifactId() + "] excluded from processing via configuration parameter [" + IGNORE_POMS + "]");
+ do_process = false;
+ }
+ }
+
+ return do_process;
+ }
+
+ /**
+ * Creates the respective goal.
+ *
+ * MUST be overridden by subclasses.
+ *
+ * @return
+ */
+ protected abstract void createGoal();
+
+ /**
+ * Simply calls {@AbstractAnalysisGoal#execute}.
+ *
+ * CAN be overridden by subclasses.
+ *
+ * @return
+ */
+ protected void executeGoal() throws Exception {
+ this.goal.executeSync();
+ }
+
+ /**
+ * Identifies known dependencies and passes them to Mojos inheriting from {@link AbstractAppGoal}.
+ * Note that such subclasses should be annotated with "requiresDependencyResolution = ResolutionScope.TEST".
+ *
+ * @throws DependencyResolutionRequiredException
+ */
+ private final void setKnownDependencies() throws DependencyResolutionRequiredException {
+ if (this.goal != null && this.goal instanceof AbstractAppGoal) {
+
+ // ---- Determine dependencies (Vulas 2.x)
/*final Set runtime_system_classpath = new HashSet();
runtime_system_classpath.addAll(project.getRuntimeClasspathElements());
@@ -223,54 +228,53 @@ private final void setKnownDependencies() throws DependencyResolutionRequiredExc
//this.goal.addDepPath(Paths.get(resource));
getLog().info("Dependency [" + ++i + "]: " + resource);
}*/
-
- // ---- Determine dependencies (Vulas 3.x)
-
- // Not sure why this line existed, let's see what happens if I comment it out :)
- //final ClassLoader originalContextClassLoader = currentThread().getContextClassLoader();
-
- // Old way of learning about dependencies (getArtifacts seems much better)
- //for (final String resource : project.getRuntimeClasspathElements()) {
-
- // Path to dependency info
- final Map dep_for_path = new HashMap();
-
- // Dependencies (direct and transitive), including Maven ID and file system path
- @SuppressWarnings("deprecation")
- final Set direct_artifacts = project.getDependencyArtifacts(); // The artifact class does not seem to tell whether it is a direct or transitive dependency (hence we keep the call and suppress the warning)
- final Set artifacts = project.getArtifacts();
- int count = 0;
- Dependency dep = null;
- Library lib = null;
- for(Artifact a: artifacts) {
- // Create lib w/o SHA1
- lib = new Library();
- lib.setLibraryId(new LibraryId(a.getGroupId(), a.getArtifactId(), a.getVersion()));
-
- // Create dependency and put into map
- dep = new Dependency(this.goal.getGoalContext().getApplication(), lib, Scope.valueOf(a.getScope().toUpperCase()), !direct_artifacts.contains(a), null, a.getFile().toPath().toString());
- dep_for_path.put(a.getFile().toPath(), dep);
-
- getLog().info("Dependency [" + StringUtil.padLeft(++count, 4) + "]: Dependency [libid=" + dep.getLib().getLibraryId() + ", path " + a.getFile().getPath() + ", direct=" + direct_artifacts.contains(a) + ", scope=" + dep.getScope() + "] created for Maven artifact [g=" + a.getGroupId() + ", a=" + a.getArtifactId() + ", base version=" + a.getBaseVersion() +", version=" + a.getVersion() + ", classifier=" + a.getClassifier() + "]");
- getLog().info(" " + this.trailToString(a.getDependencyTrail(), " => "));
- }
-
- //TODO: Is it necessary to check whether the above dependency (via getArtifacts) is actually the one added to the classpath (via project.getRuntimeClasspathElements())?
- //TODO: It may be that a different version (file) is chosen due to conflict resolution. Still, those cases should also be visible in the frontend (archive view).
-
- ((AbstractAppGoal)this.goal).setKnownDependencies(dep_for_path);
- }
- }
-
- private final String trailToString(List _trail, String _sep) {
- final StringBuffer b = new StringBuffer();
- if(_trail!=null) {
- for(int i=0; i<_trail.size(); i++) {
- if(i>0)
- b.append(_sep);
- b.append(_trail.get(i));
- }
- }
- return b.toString();
- }
+
+ // ---- Determine dependencies (Vulas 3.x)
+
+ // Not sure why this line existed, let's see what happens if I comment it out :)
+ //final ClassLoader originalContextClassLoader = currentThread().getContextClassLoader();
+
+ // Old way of learning about dependencies (getArtifacts seems much better)
+ //for (final String resource : project.getRuntimeClasspathElements()) {
+
+ // Path to dependency info
+ final Map dep_for_path = new HashMap();
+
+ // Dependencies (direct and transitive), including Maven ID and file system path
+ @SuppressWarnings("deprecation") final Set direct_artifacts = project.getDependencyArtifacts(); // The artifact class does not seem to tell whether it is a direct or transitive dependency (hence we keep the call and suppress the warning)
+ final Set artifacts = project.getArtifacts();
+ int count = 0;
+ Dependency dep = null;
+ Library lib = null;
+ for (Artifact a : artifacts) {
+ // Create lib w/o SHA1
+ lib = new Library();
+ lib.setLibraryId(new LibraryId(a.getGroupId(), a.getArtifactId(), a.getVersion()));
+
+ // Create dependency and put into map
+ dep = new Dependency(this.goal.getGoalContext().getApplication(), lib, Scope.valueOf(a.getScope().toUpperCase()), !direct_artifacts.contains(a), null, a.getFile().toPath().toString());
+ dep_for_path.put(a.getFile().toPath(), dep);
+
+ getLog().info("Dependency [" + StringUtil.padLeft(++count, 4) + "]: Dependency [libid=" + dep.getLib().getLibraryId() + ", path " + a.getFile().getPath() + ", direct=" + direct_artifacts.contains(a) + ", scope=" + dep.getScope() + "] created for Maven artifact [g=" + a.getGroupId() + ", a=" + a.getArtifactId() + ", base version=" + a.getBaseVersion() + ", version=" + a.getVersion() + ", classifier=" + a.getClassifier() + "]");
+ getLog().info(" " + this.trailToString(a.getDependencyTrail(), " => "));
+ }
+
+ //TODO: Is it necessary to check whether the above dependency (via getArtifacts) is actually the one added to the classpath (via project.getRuntimeClasspathElements())?
+ //TODO: It may be that a different version (file) is chosen due to conflict resolution. Still, those cases should also be visible in the frontend (archive view).
+
+ ((AbstractAppGoal) this.goal).setKnownDependencies(dep_for_path);
+ }
+ }
+
+ private final String trailToString(List _trail, String _sep) {
+ final StringBuffer b = new StringBuffer();
+ if (_trail != null) {
+ for (int i = 0; i < _trail.size(); i++) {
+ if (i > 0)
+ b.append(_sep);
+ b.append(_trail.get(i));
+ }
+ }
+ return b.toString();
+ }
}
diff --git a/plugin-maven/src/main/java/com/sap/psr/vulas/mvn/VulasAgentMojo.java b/plugin-maven/src/main/java/com/sap/psr/vulas/mvn/VulasAgentMojo.java
new file mode 100644
index 000000000..5daa8b930
--- /dev/null
+++ b/plugin-maven/src/main/java/com/sap/psr/vulas/mvn/VulasAgentMojo.java
@@ -0,0 +1,271 @@
+package com.sap.psr.vulas.mvn;
+
+
+import com.sap.psr.vulas.core.util.CoreConfiguration;
+import com.sap.psr.vulas.shared.connectivity.Service;
+import com.sap.psr.vulas.shared.util.StringUtil;
+import com.sap.psr.vulas.shared.util.VulasConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Environment;
+
+import java.io.File;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.lang.String.format;
+
+@Mojo(name = "prepare-vulas-agent", defaultPhase = LifecyclePhase.INITIALIZE, requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true)
+public class VulasAgentMojo extends AbstractVulasMojo {
+
+
+ @Parameter(property = "vulas.agent.propertyName")
+ private String propertyName;
+
+ @Parameter(property = "plugin.artifactMap", required = true, readonly = true)
+ private Map pluginArtifactMap;
+
+
+ private static final String ECLIPSE_TEST_PLUGIN = "eclipse-test-plugin";
+
+
+ private static final String VULAS_AGENT_ARTIFACT_NAME = "com.sap.research.security.vulas:lang-java";
+ private static final String VULAS_AGENT_ARTIFACT_CLASSIFIER = "jar-with-dependencies";
+
+ /**
+ * Name of the property used in maven-osgi-test-plugin.
+ */
+ private static final String TYCHO_ARG_LINE = "tycho.testArgLine";
+ /**
+ * Name of the property used in maven-surefire-plugin.
+ */
+ private static final String SUREFIRE_ARG_LINE = "argLine";
+
+
+ protected final class VulasAgentOptions {
+
+ private final HashMap agentOptions = new HashMap<>();
+
+ /**
+ * Creates the options for Vuals' Java Agent and initializes them with reasonable defaults.
+ */
+ public VulasAgentOptions() {
+
+ //prepare vulas configuration
+ try {
+ VulasAgentMojo.this.prepareConfiguration();
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.MONI_PERIODIC_UPL_ENABLED, false);
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.INSTR_WRITE_CODE, false);
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.INSTR_MAX_STACKTRACES, 10);
+ VulasConfiguration.getGlobal().setPropertyIfEmpty(CoreConfiguration.INSTR_CHOOSEN_INSTR, "com.sap.psr.vulas.monitor.trace.SingleStackTraceInstrumentor");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Configuration configuration = VulasConfiguration.getGlobal().getConfiguration();
+
+ //shared properties
+ setTmpDir(configuration.getString(VulasConfiguration.TMP_DIR));
+
+ //backend
+ setBackendURL(VulasConfiguration.getGlobal().getServiceUrl(Service.BACKEND));
+ setBackendConnect(CoreConfiguration.ConnectType.READ_ONLY);
+
+ //core properties
+ setVulasDummy("dummy");
+ setUploadDir(configuration.getString(CoreConfiguration.UPLOAD_DIR));
+ setPeriodicUpload(configuration.getBoolean(CoreConfiguration.MONI_PERIODIC_UPL_ENABLED));
+
+ //space token
+ setSpaceToken(configuration.getString(CoreConfiguration.SPACE_TOKEN));
+
+ //app agentOptions
+ setAppCtxGroup(configuration.getString(CoreConfiguration.APP_CTX_GROUP));
+ setAppCtxArtifact(configuration.getString(CoreConfiguration.APP_CTX_ARTIF));
+ setAppCtxVersion(configuration.getString(CoreConfiguration.APP_CTX_VERSI));
+ //instrumentation config
+ setWriteCode(configuration.getBoolean(CoreConfiguration.INSTR_WRITE_CODE));
+ setMaxStackTraces(configuration.getInt(CoreConfiguration.INSTR_MAX_STACKTRACES));
+ setInstrumentors(configuration.getStringArray(CoreConfiguration.INSTR_CHOOSEN_INSTR));
+
+ }
+
+ void setVulasDummy(String dummy) {
+ this.agentOptions.put("vulas.core.dummy", dummy);
+ }
+
+ void setSpaceToken(String spaceToken) {
+ this.agentOptions.put(CoreConfiguration.SPACE_TOKEN, spaceToken);
+ }
+
+ void setBackendURL(String backendURL) {
+ this.agentOptions.put("vulas.shared.backend.serviceUrl", backendURL);
+ }
+
+ void setBackendConnect(CoreConfiguration.ConnectType connectType) {
+ this.agentOptions.put(CoreConfiguration.BACKEND_CONNECT, connectType.toString());
+ }
+
+ void setAppCtxGroup(String appCtxGroup) {
+ this.agentOptions.put(CoreConfiguration.APP_CTX_GROUP, appCtxGroup);
+ }
+
+ void setAppCtxArtifact(String appCtxArtifact) {
+ this.agentOptions.put(CoreConfiguration.APP_CTX_ARTIF, appCtxArtifact);
+ }
+
+ void setAppCtxVersion(String appCtxVersion) {
+ this.agentOptions.put(CoreConfiguration.APP_CTX_VERSI, appCtxVersion);
+ }
+
+ void setPeriodicUpload(boolean enabled) {
+ this.agentOptions.put(CoreConfiguration.MONI_PERIODIC_UPL_ENABLED, String.valueOf(enabled));
+ }
+
+
+ void setUploadDir(String uploadDir) {
+ this.agentOptions.put(CoreConfiguration.UPLOAD_DIR, uploadDir);
+ }
+
+ void setTmpDir(String tmpDir) {
+ this.agentOptions.put(VulasConfiguration.TMP_DIR, tmpDir);
+ }
+
+ void setWriteCode(boolean enable) {
+ this.agentOptions.put(CoreConfiguration.INSTR_WRITE_CODE, String.valueOf(enable));
+ }
+
+ void setMaxStackTraces(int maxNumberOfStackTraces) {
+ this.agentOptions.put(CoreConfiguration.INSTR_MAX_STACKTRACES, String.valueOf(maxNumberOfStackTraces));
+ }
+
+ void setInstrumentors(String[] vulasInstr) {
+ String selectedInstr = StringUtil.join(vulasInstr, ",");
+ this.agentOptions.put(CoreConfiguration.INSTR_CHOOSEN_INSTR, selectedInstr);
+ }
+
+
+ public String prependVMArguments(final String arguments, final File agentJarFile) {
+
+ CommandlineJava commandlineJava = new CommandlineJava() {
+ @Override
+ public void setVm(String vm) {
+ //do not set "**/java" as the first command
+ }
+ };
+
+ //add the javaagent
+ commandlineJava.createVmArgument().setLine(format("-javaagent:%s", agentJarFile));
+
+ //remove any javaagent with the same file name from the arguments
+ final String[] args = Commandline.translateCommandline(arguments);
+ // the new javaagent, as used by the prepare-vulas-agent goal
+ final String regexForCurrentVulasAgent = format("-javaagent:(\"?)%s(\"?)", Pattern.quote(agentJarFile.toString()));
+ // the default name of the original javaagent
+ final String regexForOldVulasAgent = format("-javaagent:(\"?).*%s(\"?)", Pattern.quote("/vulas/lib/vulas-core-latest-jar-with-dependencies.jar"));
+
+ ArrayList patterns = new ArrayList<>();
+ patterns.add(regexForCurrentVulasAgent);
+ patterns.add(regexForOldVulasAgent);
+ // go through the arguments to check for existing javaagents
+ argprocess: for (String arg : args) {
+
+ // check if one of vulas's agents is already defined as an arg
+ // if yes ignore the arg
+ for (String regExExp : patterns) {
+ if (arg.matches(regExExp)) {
+ continue argprocess;
+ }
+
+ }
+ commandlineJava.createArgument().setLine(arg);
+
+ }
+ //add my properties
+ for (final String key : this.agentOptions.keySet()) {
+ final String value = this.agentOptions.get(key);
+ if (value != null && !value.isEmpty()) {
+ Environment.Variable variable = new Environment.Variable();
+ variable.setKey(key);
+ variable.setValue(value);
+ commandlineJava.addSysproperty(variable);
+ }
+ }
+
+ //add -noverify
+ commandlineJava.createVmArgument().setValue("-noverify");
+
+ return commandlineJava.toString();
+ }
+
+
+ }
+
+ @Override
+ public void execute() throws MojoExecutionException {
+
+ final String name = getEffectivePropertyName();
+ final Properties projectProperties = this.project.getProperties();
+ final String oldValue = projectProperties.getProperty(name);
+
+ VulasAgentOptions vulasAgentOptions = createVulasAgentConfig();
+ final String newValue = vulasAgentOptions.prependVMArguments(
+ oldValue, getAgentJarFile());
+ getLog().info(name + " set to " + newValue);
+ projectProperties.setProperty(name, newValue);
+ }
+
+
+ File getAgentJarFile() throws MojoExecutionException {
+ final Artifact vulasAgentArtifact = pluginArtifactMap
+ .get(VULAS_AGENT_ARTIFACT_NAME);
+ if (vulasAgentArtifact == null || !vulasAgentArtifact.hasClassifier() || !vulasAgentArtifact.getClassifier().equals(VULAS_AGENT_ARTIFACT_CLASSIFIER)) {
+ throw new MojoExecutionException("Could not found " + VULAS_AGENT_ARTIFACT_NAME + ":" + VULAS_AGENT_ARTIFACT_CLASSIFIER);
+ }
+ return vulasAgentArtifact.getFile();
+ }
+
+
+ @Override
+ protected void createGoal() {
+ throw new RuntimeException("Create Goal not valid for Mojo: " + this.getClass().getName());
+
+ }
+
+ private VulasAgentOptions createVulasAgentConfig() {
+ return new VulasAgentOptions();
+ }
+
+ /**
+ * Same as done in jacoco
+ * checks which property should be modified
+ *
+ * @return the name of the property to modify
+ */
+ private String getEffectivePropertyName() {
+ if (isPropertyNameSpecified()) {
+ return propertyName;
+ }
+ if (isEclipseTestPluginPackaging()) {
+ return TYCHO_ARG_LINE;
+ }
+ return SUREFIRE_ARG_LINE;
+ }
+
+ private boolean isPropertyNameSpecified() {
+ return propertyName != null && !propertyName.isEmpty();
+ }
+
+ private boolean isEclipseTestPluginPackaging() {
+ return ECLIPSE_TEST_PLUGIN.equals(project.getPackaging());
+ }
+}
diff --git a/plugin-maven/src/test/java/com/sap/psr/vulas/mvn/TestProjectStub.java b/plugin-maven/src/test/java/com/sap/psr/vulas/mvn/TestProjectStub.java
new file mode 100644
index 000000000..e92cd3627
--- /dev/null
+++ b/plugin-maven/src/test/java/com/sap/psr/vulas/mvn/TestProjectStub.java
@@ -0,0 +1,91 @@
+package com.sap.psr.vulas.mvn;
+
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
+import org.apache.maven.shared.utils.ReaderFactory;
+
+import java.io.File;
+import java.util.*;
+
+public class TestProjectStub
+ extends MavenProjectStub {
+ private final String projectPath;
+ private Map/**/pluginArtifactMap = new HashMap/**/();
+
+ /**
+ * Default constructor
+ */
+ public TestProjectStub(String projectPath, String pomFile) {
+ this.projectPath = projectPath;
+
+ MavenXpp3Reader pomReader = new MavenXpp3Reader();
+ Model model;
+ try {
+ model = pomReader.read(ReaderFactory.newXmlReader(new File(getBasedir(), pomFile)));
+ setModel(model);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ setGroupId(model.getGroupId());
+ setArtifactId(model.getArtifactId());
+ setVersion(model.getVersion());
+ setName(model.getName());
+ setUrl(model.getUrl());
+ setPackaging(model.getPackaging());
+
+
+ Build build = new Build();
+ build.setFinalName(model.getArtifactId());
+ build.setDirectory(getBasedir() + "/target");
+ build.setSourceDirectory(getBasedir() + "/src/main/java");
+ build.setOutputDirectory(getBasedir() + "/target/classes");
+ build.setTestSourceDirectory(getBasedir() + "/src/test/java");
+ build.setTestOutputDirectory(getBasedir() + "/target/test-classes");
+ build.setPlugins(model.getBuild().getPlugins());
+ build.setExtensions(model.getBuild().getExtensions());
+ setBuild(build);
+
+
+ List compileSourceRoots = new ArrayList();
+ compileSourceRoots.add(getBasedir() + "/src/main/java");
+ setCompileSourceRoots(compileSourceRoots);
+
+ List testCompileSourceRoots = new ArrayList();
+ testCompileSourceRoots.add(getBasedir() + "/src/test/java");
+ setTestCompileSourceRoots(testCompileSourceRoots);
+
+
+
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public File getBasedir() {
+ return new File(super.getBasedir() + this.projectPath);
+ }
+
+
+ @Override
+ public Properties getProperties() {
+ return this.getModel().getProperties();
+ }
+
+ public Map/**/getPluginArtifactMap() {
+ return pluginArtifactMap;
+ }
+
+ public void setPluginArtifactMap(Map/**/pluginArtifactMap) {
+ this.pluginArtifactMap = pluginArtifactMap;
+ }
+}
+
diff --git a/plugin-maven/src/test/java/com/sap/psr/vulas/mvn/VulasAgentOptionsTests.java b/plugin-maven/src/test/java/com/sap/psr/vulas/mvn/VulasAgentOptionsTests.java
new file mode 100644
index 000000000..e3a65f899
--- /dev/null
+++ b/plugin-maven/src/test/java/com/sap/psr/vulas/mvn/VulasAgentOptionsTests.java
@@ -0,0 +1,113 @@
+package com.sap.psr.vulas.mvn;
+
+
+import com.sap.psr.vulas.mvn.VulasAgentMojo;
+import com.sap.psr.vulas.shared.util.VulasConfiguration;
+import org.apache.maven.plugin.testing.AbstractMojoTestCase;
+import org.apache.maven.plugin.testing.MojoRule;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test for the AgentOptions standalone
+ */
+public class VulasAgentOptionsTests {
+ @Rule
+ public MojoRule rule = new MojoRule();
+
+ @Test
+ public void testCreateCommandLineArgs() throws Exception {
+
+ TestProjectStub stub = new TestProjectStub("/target/test-classes/unitTestPom/", "pom.xml");
+
+ VulasAgentMojo myMojo = (VulasAgentMojo) rule.lookupConfiguredMojo(stub, "prepare-vulas-agent");
+ assertNotNull(myMojo);
+
+
+ VulasAgentMojo.VulasAgentOptions vulasAgentOptions = myMojo.new VulasAgentOptions();
+
+ assertNotNull(vulasAgentOptions);
+ String finalArg = vulasAgentOptions.prependVMArguments("", new File("myaggent"));
+ System.out.println(finalArg);
+ assertTrue(finalArg.contains("-javaagent:myaggent"));
+ assertTrue(finalArg.contains("-noverify"));
+
+ }
+
+ @Test
+ public void testPrependCommandLineArgs() throws Exception {
+
+ TestProjectStub stub = new TestProjectStub("/target/test-classes/unitTestPom/", "pom2.xml");
+
+ VulasAgentMojo myMojo = (VulasAgentMojo) rule.lookupConfiguredMojo(stub, "prepare-vulas-agent");
+ assertNotNull(myMojo);
+
+
+ VulasAgentMojo.VulasAgentOptions vulasAgentOptions = myMojo.new VulasAgentOptions();
+
+ assertNotNull(vulasAgentOptions);
+ String finalArg = vulasAgentOptions.prependVMArguments("-Djava.security.manager -Djava.security.policy=${basedir}/src/test/resources/java.policy", new File("myaggent"));
+ System.out.println(finalArg);
+ assertTrue(finalArg.contains("-javaagent:myaggent"));
+ assertTrue(finalArg.contains("-noverify"));
+ assertTrue(finalArg.contains("-Djava.security.manager"));
+ assertTrue(finalArg.contains("-Djava.security.policy=${basedir}/src/test/resources/java.policy"));
+
+ }
+
+
+ @Test
+ public void testRemoveDuplicateAgentCommandLineArgs() throws Exception {
+
+ TestProjectStub stub = new TestProjectStub("/target/test-classes/unitTestPom/", "pom2.xml");
+
+ VulasAgentMojo myMojo = (VulasAgentMojo) rule.lookupConfiguredMojo(stub, "prepare-vulas-agent");
+ assertNotNull(myMojo);
+
+ VulasAgentMojo.VulasAgentOptions vulasAgentOptions = myMojo.new VulasAgentOptions();
+ assertNotNull(vulasAgentOptions);
+
+ String finalArg = vulasAgentOptions.prependVMArguments("-javaagent:myaggent", new File("myaggent"));
+
+ assertNotNull(finalArg);
+
+ assertTrue(finalArg.contains("-javaagent:myaggent"));
+ assertTrue(finalArg.contains("-noverify"));
+
+
+ }
+
+ @Test
+ public void testRemoveOriginalAgentCommandLineArgs() throws Exception {
+
+ TestProjectStub stub = new TestProjectStub("/target/test-classes/unitTestPom/", "pom2.xml");
+
+ VulasAgentMojo myMojo = (VulasAgentMojo) rule.lookupConfiguredMojo(stub, "prepare-vulas-agent");
+ assertNotNull(myMojo);
+
+ VulasAgentMojo.VulasAgentOptions vulasAgentOptions = myMojo.new VulasAgentOptions();
+ assertNotNull(vulasAgentOptions);
+
+ String finalArg = vulasAgentOptions.prependVMArguments("-javaagent:/mnt/c/Users/myuser/testproject/vulas/lib/vulas-core-latest-jar-with-dependencies.jar -DfooProp=bar", new File("myaggent"));
+
+ assertNotNull(finalArg);
+
+ assertTrue(finalArg.contains("-javaagent:myaggent"));
+ assertTrue(!finalArg.contains("/vulas/lib/vulas-core-latest-jar-with-dependencies.jar"));
+
+ assertTrue(finalArg.contains("-noverify"));
+
+
+ }
+
+
+
+
+}
diff --git a/plugin-maven/src/test/resources/testproject/backwardComppom.xml b/plugin-maven/src/test/resources/testproject/backwardComppom.xml
new file mode 100644
index 000000000..0ef38c67f
--- /dev/null
+++ b/plugin-maven/src/test/resources/testproject/backwardComppom.xml
@@ -0,0 +1,153 @@
+
+
+ 4.0.0
+
+ foo.bar
+ sampletest
+ 1.0.0
+
+
+
+ 3.0.10-SNAPSHOT
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.1.3
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.10
+
+
+ copy-vulas
+ generate-test-resources
+
+ copy
+
+
+
+
+ com.sap.research.security.vulas
+ lang-java
+ ${vulas.version}
+ jar
+ jar-with-dependencies
+ ${project.build.directory}/vulas/lib
+ vulas-core-latest-jar-with-dependencies.jar
+
+
+ com.sap.research.security.vulas
+ lang-java
+ ${vulas.version}
+ jar
+ jar-with-dependencies
+ ${project.build.directory}/vulas/include
+ vulas-core-latest-jar-with-dependencies.jar
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.21.0
+
+
+ 1
+ 0
+
+ -javaagent:"${project.build.directory}/vulas/lib/vulas-core-latest-jar-with-dependencies.jar"
+ -Dvulas.shared.tmpDir=${project.build.directory}/vulas/tmp
+ -Dvulas.core.dummy=dummy
+ -Dvulas.core.backendConnection=READ_ONLY
+ -Dvulas.core.uploadDir=${project.build.directory}/vulas/upload
+ -Dvulas.core.monitor.periodicUpload.enabled=false
+ -Dvulas.core.appContext.group=${vulas.core.appContext.group}
+ -Dvulas.core.appContext.artifact=${vulas.core.appContext.artifact}
+ -Dvulas.core.appContext.version=${vulas.core.appContext.version}
+ -Dvulas.shared.backend.serviceUrl=REPLACE_WITH_BACKENDURL
+ -Dvulas.core.instr.writeCode=false
+ -Dvulas.core.instr.maxStacktraces=10
+ -Dvulas.core.instr.instrumentorsChoosen=com.sap.psr.vulas.monitor.trace.StackTraceInstrumentor,com.sap.psr.vulas.monitor.touch.TouchPointInstrumentor
+ -noverify
+
+
+
+
+
+
+
+ com.sap.research.security.vulas
+ plugin-maven
+ 3.0.10-SNAPSHOT
+
+
+
+ wala
+ ${project.build.directory}/vulas/tmp
+ ${vulas.core.appContext.group}
+ ${vulas.core.appContext.artifact}
+
+ ${vulas.core.appContext.version}
+ 1
+
+ ${project.build.directory}/vulas/upload
+
+
+ ${project.build.directory}/classes,${project.basedir}/src/main/java,${project.basedir}/src/main/python
+
+
+ ${project.build.directory}
+ ${project.build.directory}/vulas/target
+ ${project.build.directory}/vulas/include
+
+ ${project.build.directory}/vulas/lib
+ false
+
+ com.sap.psr.vulas.monitor.trace.StackTraceInstrumentor,com.sap.psr.vulas.monitor.touch.TouchPointInstrumentor
+
+ false
+
+ NO_FLOW_TO_CASTS_NO_METHOD_INVOKE
+
+ 15
+
+
+ ${project.build.directory}/vulas/report
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugin-maven/src/test/resources/testproject/mixedpom.xml b/plugin-maven/src/test/resources/testproject/mixedpom.xml
new file mode 100644
index 000000000..c3f274474
--- /dev/null
+++ b/plugin-maven/src/test/resources/testproject/mixedpom.xml
@@ -0,0 +1,161 @@
+
+
+ 4.0.0
+
+ foo.bar
+ sampletest
+ 1.0.0
+
+
+
+ 3.0.10-SNAPSHOT
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.1.3
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.10
+
+
+ copy-vulas
+ generate-test-resources
+
+ copy
+
+
+
+
+ com.sap.research.security.vulas
+ lang-java
+ ${vulas.version}
+ jar
+ jar-with-dependencies
+ ${project.build.directory}/vulas/lib
+ vulas-core-latest-jar-with-dependencies.jar
+
+
+ com.sap.research.security.vulas
+ lang-java
+ ${vulas.version}
+ jar
+ jar-with-dependencies
+ ${project.build.directory}/vulas/include
+ vulas-core-latest-jar-with-dependencies.jar
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.0
+
+
+ 1
+ 0
+
+ -javaagent:"${project.build.directory}/vulas/lib/vulas-core-latest-jar-with-dependencies.jar"
+ -Dvulas.shared.backend.serviceUrl=REPLACE_WITH_BACKENDURL
+ -Dvulas.shared.tmpDir=${project.build.directory}/vulas/tmp
+ -Dvulas.core.dummy=dummy
+ -Dvulas.core.backendConnection=READ_ONLY
+ -Dvulas.core.uploadDir=${project.build.directory}/vulas/upload
+ -Dvulas.core.monitor.periodicUpload.enabled=false
+ -Dvulas.core.appContext.group=${project.groupId}
+ -Dvulas.core.appContext.artifact=${project.artifactId}
+ -Dvulas.core.appContext.version=${project.version}
+ -Dvulas.core.instr.writeCode=false
+ -Dvulas.core.instr.maxStacktraces=10
+ -Dvulas.core.instr.instrumentorsChoosen=com.sap.psr.vulas.monitor.trace.StackTraceInstrumentor,com.sap.psr.vulas.monitor.touch.TouchPointInstrumentor
+ -noverify
+
+
+
+
+
+
+
+ com.sap.research.security.vulas
+ plugin-maven
+ 3.0.10-SNAPSHOT
+
+
+ pre-unit-test
+
+ prepare-vulas-agent
+
+
+
+
+
+
+ wala
+ ${project.build.directory}/vulas/tmp
+ ${vulas.core.appContext.group}
+ ${vulas.core.appContext.artifact}
+
+ ${vulas.core.appContext.version}
+ 1
+
+ ${project.build.directory}/vulas/upload
+
+
+ ${project.build.directory}/classes,${project.basedir}/src/main/java,${project.basedir}/src/main/python
+
+
+ ${project.build.directory}
+ ${project.build.directory}/vulas/target
+ ${project.build.directory}/vulas/include
+
+ ${project.build.directory}/vulas/lib
+ false
+
+ com.sap.psr.vulas.monitor.trace.StackTraceInstrumentor,com.sap.psr.vulas.monitor.touch.TouchPointInstrumentor
+
+ false
+
+ NO_FLOW_TO_CASTS_NO_METHOD_INVOKE
+
+ 15
+
+
+ ${project.build.directory}/vulas/report
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugin-maven/src/test/resources/testproject/pom.xml b/plugin-maven/src/test/resources/testproject/pom.xml
new file mode 100644
index 000000000..208fac7ae
--- /dev/null
+++ b/plugin-maven/src/test/resources/testproject/pom.xml
@@ -0,0 +1,106 @@
+
+
+ 4.0.0
+
+ foo.bar
+ sampletest
+ 1.0.0
+
+
+
+ 3.0.10-SNAPSHOT
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.1.3
+
+
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.3-SNAPSHOT
+
+
+
+ prepare-agent
+
+
+
+
+
+
+ com.sap.research.security.vulas
+ plugin-maven
+ 3.0.10-SNAPSHOT
+
+
+ pre-unit-test
+
+ prepare-vulas-agent
+
+
+
+
+
+
+ wala
+ ${project.build.directory}/vulas/tmp
+ ${vulas.core.appContext.group}
+ ${vulas.core.appContext.artifact}
+
+ ${vulas.core.appContext.version}
+ 1
+
+ ${project.build.directory}/vulas/upload
+
+
+ ${project.build.directory}/classes,${project.basedir}/src/main/java,${project.basedir}/src/main/python
+
+
+ ${project.build.directory}
+ ${project.build.directory}/vulas/target
+ ${project.build.directory}/vulas/include
+
+ ${project.build.directory}/vulas/lib
+ false
+
+ com.sap.psr.vulas.monitor.trace.StackTraceInstrumentor,com.sap.psr.vulas.monitor.touch.TouchPointInstrumentor
+
+ false
+
+ NO_FLOW_TO_CASTS_NO_METHOD_INVOKE
+
+ 15
+
+
+ ${project.build.directory}/vulas/report
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugin-maven/src/test/resources/testproject/src/main/java/com/acme/Simple.java b/plugin-maven/src/test/resources/testproject/src/main/java/com/acme/Simple.java
new file mode 100644
index 000000000..0395bb38b
--- /dev/null
+++ b/plugin-maven/src/test/resources/testproject/src/main/java/com/acme/Simple.java
@@ -0,0 +1,75 @@
+package com.acme;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.security.cert.CertificateException;
+import javax.security.cert.X509Certificate;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+public class Simple {
+
+ public void callHttpClient(String _url) throws Exception {
+
+ //build a trust manager, which checks if given certificates are valid. Here accept all certificates, never throw an exception
+ X509TrustManager tm = new X509TrustManager() {
+
+ /** Same method name and signature as below, only difference is that argument type belongs to package javax.security.cert and the other one to java.security.cert. */
+ public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
+ }
+
+ /** Same method name and signature as below, only difference is that argument type belongs to package javax.security.cert and the other one to java.security.cert. */
+ public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
+ }
+
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] chain, String authType)
+ throws java.security.cert.CertificateException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] chain, String authType)
+ throws java.security.cert.CertificateException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ };
+
+
+ SSLContext sslcontext = SSLContext.getInstance("SSL");
+ sslcontext.init(null, new TrustManager[]{tm}, null);
+
+ SSLSocketFactory sslsf = new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ SchemeRegistry schemeRegistry = new SchemeRegistry();
+ schemeRegistry.register(new Scheme("http", new PlainSocketFactory(), 80));
+ schemeRegistry.register(new Scheme("https", sslsf, 443));
+
+ ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(schemeRegistry);
+ HttpClient client = new DefaultHttpClient(manager);
+ HttpGet httpGet = new HttpGet(_url);
+ try {
+ client.execute(httpGet);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/plugin-maven/src/test/resources/testproject/src/test/java/SimpleTest.java b/plugin-maven/src/test/resources/testproject/src/test/java/SimpleTest.java
new file mode 100644
index 000000000..ee2323605
--- /dev/null
+++ b/plugin-maven/src/test/resources/testproject/src/test/java/SimpleTest.java
@@ -0,0 +1,24 @@
+import static org.junit.Assert.assertEquals;
+
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
+import java.nio.file.Paths;
+
+import org.junit.Test;
+
+import com.acme.Simple;
+
+public class SimpleTest {
+
+ @Test
+ public void callHttpClientTest() {
+ Simple p = null;
+ try {
+ p = new Simple();
+ p.callHttpClient("https://example.com");
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugin-maven/src/test/resources/unitTestPom/pom.xml b/plugin-maven/src/test/resources/unitTestPom/pom.xml
new file mode 100644
index 000000000..305e4f2c7
--- /dev/null
+++ b/plugin-maven/src/test/resources/unitTestPom/pom.xml
@@ -0,0 +1,27 @@
+
+
+ 4.0.0
+
+ foo.bar
+ vulas-testpom
+ 1.0.0
+ pom
+
+
+
+ 3.0.10-SNAPSHOT
+
+
+
+
+
+ com.sap.research.security.vulas
+ plugin-maven
+ ${vulas.version}
+
+
+
+
+
+
diff --git a/plugin-maven/src/test/resources/unitTestPom/pom2.xml b/plugin-maven/src/test/resources/unitTestPom/pom2.xml
new file mode 100644
index 000000000..cef43cf94
--- /dev/null
+++ b/plugin-maven/src/test/resources/unitTestPom/pom2.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ foo.bar
+ vulas-testpom
+ 1.0.0
+ pom
+
+
+
+ 3.0.10-SNAPSHOT
+ -Djava.security.manager -Djava.security.policy=${basedir}/src/test/resources/java.policy
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.0
+
+
+
+
+ com.sap.research.security.vulas
+ plugin-maven
+ ${vulas.version}
+
+
+
+
+
+