From 68ea4cfb908fbe891d819317913be64e98ccaeb7 Mon Sep 17 00:00:00 2001 From: SubhadraSahoo <75673851+SubhadraSahoo@users.noreply.github.com> Date: Mon, 17 May 2021 15:17:47 +0530 Subject: [PATCH] Sca features vulfixes (#64) * To close the issue #AB1976 * For the fix of defect #AB 1832 : SCA job configuration not indicating on UI on test connection without providing credentials and account * Changes for exploitable path and private registry and Environment variables Changes for exploitable path and private registry and Environment variables * Changes for Exploitable path added projectFullPath and Project ID field Changes for Exploitable path added projectFullPath and Project ID field * Various changes to get UI and backend logic working * SCA feature changes related to help, ui and exploitable parameters This commit has been tested for all SCA features with and without SAST but limited to checking values (not via SCA Agent). * Increment version - sca features release * Updated help files for allow global SAST comment to be part of build comment. Added help file for SAST global comment * Changes for null check scaSastcredential Id fixed AB#2065 * package upgrades to fix vulnerabilities * Fixed AB#2071 Typo in the variable name between config.jelly and validation code. Missed during conflict resolution. * Updated the help file Updated the help file to remove the space in the example and corrected typo Co-authored-by: sangam chitmugre Co-authored-by: umeshwaghode --- build.gradle | 19 +- gradle.properties | 2 +- .../checkmarx/jenkins/CxLoggerAdapter.java | 22 +- .../com/checkmarx/jenkins/CxScanBuilder.java | 247 ++++++++++++++++-- .../com/checkmarx/jenkins/CxScanCallable.java | 11 +- .../jenkins/DependencyScanConfig.java | 32 ++- .../jenkins/CxScanBuilder/config.jelly | 43 ++- .../jenkins/CxScanBuilder/global.jelly | 26 +- .../help-addGlobalCommenToBuildCommet.html | 4 +- .../jenkins/CxScanBuilder/help-comment.html | 4 +- .../CxScanBuilder/help-hideDebugLogs.html | 3 + .../CxScanBuilder/help-isExploitablePath.html | 8 + .../CxScanBuilder/help-isIncludeSources.html | 3 + .../CxScanBuilder/help-sastcomment.html | 5 + .../CxScanBuilder/help-scaConfigFile.html | 9 + .../CxScanBuilder/help-scaEnvVariables.html | 7 + .../help-useGlobalSastDetails.html | 4 + 17 files changed, 414 insertions(+), 35 deletions(-) create mode 100644 src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-hideDebugLogs.html create mode 100644 src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-isExploitablePath.html create mode 100644 src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-isIncludeSources.html create mode 100644 src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-sastcomment.html create mode 100644 src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-scaConfigFile.html create mode 100644 src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-scaEnvVariables.html create mode 100644 src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-useGlobalSastDetails.html diff --git a/build.gradle b/build.gradle index 845e1e18..ab5e77e8 100644 --- a/build.gradle +++ b/build.gradle @@ -44,10 +44,27 @@ dependencies { compileOnly 'com.intellij:annotations:12.0', 'org.slf4j:slf4j-api:1.6.1' - compile 'com.checkmarx:cx-client-common:2021.1.145', + compile 'com.checkmarx:cx-client-common:2021.2.159', 'com.checkmarx:cx-config-provider:1.0.14', 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.5', 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.5' + constraints { + implementation('io.vertx:vertx-web:3.9.7') { + because 'previous versions have a bug impacting this application' + } + implementation('commons-beanutils:commons-beanutils:1.9.4') { + because 'previous versions have a bug impacting this application' + } + implementation('io.netty:netty-codec-http:4.1.60.Final') { + because 'previous versions have a bug impacting this application' + } + implementation('org.apache.httpcomponents:httpclient:4.5.13') { + because 'previous versions have a bug impacting this application' + } + implementation('commons-io:commons-io:2.7') { + because 'previous versions have a bug impacting this application' + } + } optionalJenkinsPlugins 'org.jenkins-ci.main:maven-plugin:1.509.4@jar', 'org.jenkins-ci.plugins:credentials:2.1.19@jar' diff --git a/gradle.properties b/gradle.properties index 409b10ed..21529d91 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ description = Provides automatic scan of code by Checkmarx server and shows results summary and trend in Jenkins interface. group = com.checkmarx.jenkins -version = 2021.1.2 +version = 2021.2.94 repositoryVersion= diff --git a/src/main/java/com/checkmarx/jenkins/CxLoggerAdapter.java b/src/main/java/com/checkmarx/jenkins/CxLoggerAdapter.java index a05ca941..9e8a6eee 100644 --- a/src/main/java/com/checkmarx/jenkins/CxLoggerAdapter.java +++ b/src/main/java/com/checkmarx/jenkins/CxLoggerAdapter.java @@ -16,6 +16,8 @@ public class CxLoggerAdapter implements Logger { private static final String TRACE_PREFIX = "[Cx-Trace]: "; private final PrintStream log; + private boolean debugEnabled; + private boolean traceEnabled; public CxLoggerAdapter(PrintStream log) { this.log = log; @@ -28,7 +30,7 @@ public String getName() { public boolean isDebugEnabled() { - return true; + return debugEnabled; } @Override @@ -45,9 +47,18 @@ public boolean isWarnEnabled() { public boolean isErrorEnabled() { return true; } + + public final void setDebugEnabled(boolean debugEnabled) { + this.debugEnabled = debugEnabled; + } + + public final void setTraceEnabled(boolean traceEnabled) { + this.traceEnabled = traceEnabled; + } - public void debug(String s) { - log.println(DEBUG_PREFIX + s); + public void debug(String s) { + if(isDebugEnabled()) + log.println(DEBUG_PREFIX + s); } public void debug(String s, Throwable throwable) { @@ -218,11 +229,12 @@ public void error(Marker marker, String msg, Throwable t) { } public boolean isTraceEnabled() { - return false; + return traceEnabled; } public void trace(String s) { - log.println(TRACE_PREFIX + s); + if (this.isTraceEnabled()) + log.println(TRACE_PREFIX + s); } public void trace(String s, Object o) { diff --git a/src/main/java/com/checkmarx/jenkins/CxScanBuilder.java b/src/main/java/com/checkmarx/jenkins/CxScanBuilder.java index bc98ab4a..f410d474 100644 --- a/src/main/java/com/checkmarx/jenkins/CxScanBuilder.java +++ b/src/main/java/com/checkmarx/jenkins/CxScanBuilder.java @@ -6,6 +6,7 @@ import com.checkmarx.jenkins.configascode.ConfigAsCode; import com.checkmarx.jenkins.configascode.SastConfig; import com.checkmarx.jenkins.configascode.ScaConfig; +import com.checkmarx.jenkins.exception.CxCredException; import com.cloudbees.plugins.credentials.CredentialsMatchers; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardListBoxModel; @@ -36,6 +37,7 @@ import hudson.util.FormValidation; import hudson.util.ListBoxModel; import hudson.util.Secret; +import io.netty.util.internal.StringUtil; import jenkins.model.Jenkins; import jenkins.tasks.SimpleBuildStep; import net.sf.json.JSONObject; @@ -46,6 +48,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.kohsuke.stapler.*; +import org.kohsuke.stapler.verb.POST; import javax.annotation.Nonnull; import javax.naming.ConfigurationException; @@ -61,6 +64,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.cx.restclient.sca.utils.CxSCAFileSystemUtils; /** * The main entry point for Checkmarx plugin. This class implements the Builder @@ -89,7 +93,7 @@ public class CxScanBuilder extends Builder implements SimpleBuildStep { ////////////////////////////////////////////////////////////////////////////////////// // Persistent plugin configuration parameters ////////////////////////////////////////////////////////////////////////////////////// - private boolean useOwnServerCredentials; + private boolean useOwnServerCredentials; private boolean configAsCode; @Nullable @@ -99,6 +103,8 @@ public class CxScanBuilder extends Builder implements SimpleBuildStep { @Nullable private String password; private String credentialsId; + //used for SCA Exploitable path feature + private String sastCredentialsId; private Boolean isProxy = true; @Nullable private String projectName; @@ -162,6 +168,8 @@ public class CxScanBuilder extends Builder implements SimpleBuildStep { */ @Nullable private DependencyScanConfig dependencyScanConfig; + + private boolean hideDebugLogs; ////////////////////////////////////////////////////////////////////////////////////// // Private variables @@ -194,6 +202,7 @@ public CxScanBuilder( @Nullable String password, Boolean isProxy, String credentialsId, + String sastCredentialsId, boolean configAsCode, String projectName, long projectId, @@ -229,13 +238,15 @@ public CxScanBuilder( String vulnerabilityThresholdResult, boolean avoidDuplicateProjectScans, boolean addGlobalCommenToBuildCommet, - Boolean generateXmlReport + Boolean generateXmlReport, + boolean hideDebugLogs ) { this.useOwnServerCredentials = useOwnServerCredentials; this.serverUrl = serverUrl; this.username = username; this.password = Secret.fromString(password).getEncryptedValue(); this.credentialsId = credentialsId; + this.sastCredentialsId=sastCredentialsId; this.configAsCode = configAsCode; // Workaround for compatibility with Conditional BuildStep Plugin this.isProxy = (isProxy == null) ? true : isProxy; @@ -276,6 +287,7 @@ public CxScanBuilder( this.avoidDuplicateProjectScans = avoidDuplicateProjectScans; this.addGlobalCommenToBuildCommet=addGlobalCommenToBuildCommet; this.generateXmlReport = (generateXmlReport == null) ? true : generateXmlReport; + this.hideDebugLogs = hideDebugLogs; } // Configuration fields getters @@ -283,7 +295,7 @@ public boolean isUseOwnServerCredentials() { return useOwnServerCredentials; } - public boolean isConfigAsCode() { + public boolean isConfigAsCode() { return configAsCode; } @@ -320,7 +332,16 @@ public void setCredentialsId(String credentialsId) { this.credentialsId = credentialsId; } - @Nullable + + public String getSastCredentialsId() { + return sastCredentialsId; + } + + public void setSastCredentialsId(String sastCredentialsId) { + this.sastCredentialsId = sastCredentialsId; + } + + @Nullable public String getProjectName() { return projectName; } @@ -552,6 +573,10 @@ public Boolean getIsProxy() { public Boolean getGenerateXmlReport() { return generateXmlReport; } + + public boolean isHideDebugLogs() { + return hideDebugLogs; + } @DataBoundSetter public void setThresholdSettings(String thresholdSettings) { @@ -740,6 +765,11 @@ public DependencyScanConfig getDependencyScanConfig() { public void setDependencyScanConfig(DependencyScanConfig dependencyScanConfig) { this.dependencyScanConfig = dependencyScanConfig; } + + @DataBoundSetter + public void setHideDebugLogs(Boolean hideDebugLogs) { + this.hideDebugLogs = hideDebugLogs; + } private void setFsaConfiguration(EnvVars env) { // As job environment variable @@ -774,6 +804,15 @@ public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnul log = new CxLoggerAdapter(listener.getLogger()); + log.info("Hide debug logs: " + isHideDebugLogs()); + if(isHideDebugLogs()) { + log.setDebugEnabled(false); + log.setTraceEnabled(false); + }else { + log.setDebugEnabled(true); + log.setTraceEnabled(true); + } + if ((sastEnabled == null || sastEnabled) && isSkipScan(run)) { log.info("Checkmarx scan skipped since the build was triggered by SCM. " + "Visit plugin configuration page to disable this skip."); @@ -810,9 +849,9 @@ public void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnul if (instance != null && instance.proxy != null && (useOwnServerCredentials ? this.isProxy : getDescriptor().getIsProxy()) && !(isCxURLinNoProxyHost(useOwnServerCredentials ? this.serverUrl : getDescriptor().getServerUrl(), instance.proxy.getNoProxyHostPatterns()))) { - action = new CxScanCallable(config, listener, instance.proxy); + action = new CxScanCallable(config, listener, instance.proxy, log); } else { - action = new CxScanCallable(config, listener); + action = new CxScanCallable(config, listener, log); } //create scans and retrieve results (in jenkins agent) @@ -1190,8 +1229,8 @@ private CxScanConfig resolveConfiguration(Run run, DescriptorImpl descript //general ret.setCxOrigin(jenkinURL); - log.debug(" ORIGIN FROM JENKIN :: "+ jenkinURL); - log.debug(" ORIGIN URL FROM JENKIN :: "+ originUrl); + log.info(" ORIGIN FROM JENKIN :: "+ jenkinURL); + log.info(" ORIGIN URL FROM JENKIN :: "+ originUrl); ret.setDisableCertificateValidation(!descriptor.isEnableCertificateValidation()); ret.setMvnPath(descriptor.getMvnPath()); @@ -1210,6 +1249,9 @@ private CxScanConfig resolveConfiguration(Run run, DescriptorImpl descript instance.proxy.getUserName(), instance.proxy.getPassword(), false)); } } + + //Jenkins UI does not send teamName but team Id + teamPath = getTeamNameFromId(cxCredentials,descriptor, groupId); //project ret.setProjectName(env.expand(projectName.trim())); @@ -1251,7 +1293,11 @@ private CxScanConfig resolveConfiguration(Run run, DescriptorImpl descript ret.setSastThresholdsEnabled(useGlobalThreshold || useJobThreshold); if(addGlobalCommenToBuildCommet) { - ret.setScanComment(comment+" "+env.expand(descriptor.sastcomment)); + if ((env.expand(descriptor.sastcomment))!= null){ + ret.setScanComment(env.expand(comment)+" "+env.expand(descriptor.sastcomment));} + else { + ret.setScanComment(env.expand(comment)); + } } if (useGlobalThreshold) { @@ -1290,7 +1336,44 @@ private CxScanConfig resolveConfiguration(Run run, DescriptorImpl descript return ret; } - private void configureDependencyScan(Run run, DescriptorImpl descriptor, EnvVars env, CxScanConfig config) { + private String getTeamNameFromId(CxCredentials credentials, DescriptorImpl descriptor, String teamId) { + LegacyClient commonClient = null; + String teamName = null; + try { + + commonClient = prepareLoggedInClient(credentials, descriptor); + teamName = commonClient.getTeamNameById(teamId); + + } catch (Exception e) { + serverLog.error("Failed to get team name by team id: " + e.toString()); + } finally { + if (commonClient != null) { + commonClient.close(); + } + } + return teamName; + } + + // Prepares a cx client object to be connected and logged in + /* + * Note: This method is called concurrently by multiple threads, refrain from using mutable + * shared state to avoid synchronization issues. + */ + private LegacyClient prepareLoggedInClient(CxCredentials credentials, DescriptorImpl descriptor) + throws IOException, CxClientException { + LegacyClient ret; + Jenkins instance = Jenkins.getInstance(); + if (instance != null && instance.proxy != null && isProxy && !(isCxURLinNoProxyHost(serverUrl, instance.proxy.getNoProxyHostPatterns()))) { + ret = CommonClientFactory.getInstance(credentials, descriptor.isEnableCertificateValidation(), serverLog, true); + } else { + ret = CommonClientFactory.getInstance(credentials, descriptor.isEnableCertificateValidation(), serverLog, false); + } + ret.login(); + return ret; + } + + + private void configureDependencyScan(Run run, DescriptorImpl descriptor, EnvVars env, CxScanConfig config) { boolean dependencyScanEnabled = dependencyScanConfig != null; if (!dependencyScanEnabled) { return; @@ -1341,17 +1424,28 @@ private void configureDependencyScan(Run run, DescriptorImpl descriptor, E config.setOsaArchiveIncludePatterns(effectiveConfig.osaArchiveIncludePatterns.trim()); config.setOsaRunInstall(effectiveConfig.osaInstallBeforeScan); } else if (config.isAstScaEnabled()) { - config.setAstScaConfig(getScaConfig(run, effectiveConfig)); + config.setAstScaConfig(getScaConfig(run,env, dependencyScanConfig, descriptor)); } } - private AstScaConfig getScaConfig(Run run, DependencyScanConfig dsConfig) { + private AstScaConfig getScaConfig(Run run, EnvVars env,DependencyScanConfig dsConfigJobLevel, DescriptorImpl descriptor) { + + + DependencyScanConfig dsConfig; + boolean globalSettingsInUse = false; + if (dsConfigJobLevel.overrideGlobalConfig) { + dsConfig = dsConfigJobLevel; + } else { + globalSettingsInUse = true; + dsConfig = descriptor.getDependencyScanConfig(); + } + AstScaConfig result = new AstScaConfig(); result.setApiUrl(dsConfig.scaServerUrl); result.setAccessControlUrl(dsConfig.scaAccessControlUrl); result.setWebAppUrl(dsConfig.scaWebAppUrl); result.setTenant(dsConfig.scaTenant); - + result.setIncludeSources(dsConfig.isIncludeSources); UsernamePasswordCredentials credentials = CxCredentials.getCredentialsById(dsConfig.scaCredentialsId, run); if (credentials != null) { result.setUsername(credentials.getUsername()); @@ -1359,6 +1453,41 @@ private AstScaConfig getScaConfig(Run run, DependencyScanConfig dsConfig) } else { log.warn("CxSCA credentials are not specified."); } + if(StringUtils.isNotEmpty(dsConfig.scaEnvVariables)) + { + result.setEnvVariables(CxSCAFileSystemUtils.convertStringToKeyValueMap(env.expand(dsConfig.scaEnvVariables))); + } + String filePath = dsConfig.scaConfigFile; + String[] strArrayFile=filePath.split(","); + result.setConfigFilePaths(Arrays.asList(strArrayFile)); + + + String derivedProjectName = projectName; + String derivedProjectId = null; + UsernamePasswordCredentials scaSASTCred = null; + String scaSASTServerUrl = null; + if(dsConfig.isExploitablePath) { + + scaSASTCred = CxCredentials.getCredentialsById(dsConfig.sastCredentialsId, run); + scaSASTServerUrl = dsConfig.scaSastServerUrl; + + if(!globalSettingsInUse){ + if(!dsConfig.useJobLevelSastDetails){ + scaSASTCred = CxCredentials.getCredentialsById(descriptor.getDependencyScanConfig().sastCredentialsId, run); + scaSASTServerUrl = descriptor.getDependencyScanConfig().scaSastServerUrl; + } + derivedProjectName = dsConfig.scaSASTProjectFullPath; + derivedProjectId = dsConfig.scaSASTProjectID; + } + if(scaSASTCred!=null){ + result.setSastServerUrl(scaSASTServerUrl); + result.setSastUsername(scaSASTCred.getUsername()); + result.setSastPassword(scaSASTCred.getPassword().getPlainText()); + } + result.setSastProjectName(derivedProjectName); + result.setSastProjectId(derivedProjectId); + + } return result; } @@ -1559,7 +1688,8 @@ private void printBuildFailure(String thDescription, ScanResults ret, CxLoggerAd log.error(""); } - private void logError(Exception ex) { + + private void logError(Exception ex) { if (ex != null) { log.error(ex.getMessage()); } @@ -1766,7 +1896,8 @@ public void setSastcomment(String sastcomment) { private final String DEPENDENCY_SCAN_CONFIG_PROP = "dependencyScanConfig"; private DependencyScanConfig dependencyScanConfig; - + private boolean hideDebugLogs = false; + public DescriptorImpl() { load(); } @@ -1967,6 +2098,14 @@ public Integer getScanTimeoutDuration() { public void setScanTimeoutDuration(@Nullable Integer scanTimeoutDurationInMinutes) { this.scanTimeoutDuration = scanTimeoutDurationInMinutes; } + + public final boolean isHideDebugLogs() { + return hideDebugLogs; + } + + public final void setHideDebugLogs(boolean hideDebugLogs) { + this.hideDebugLogs = hideDebugLogs; + } public FormValidation doCheckScanTimeoutDuration(@QueryParameter final Integer value) { return timeoutValid(value); @@ -2080,7 +2219,71 @@ public FormValidation doTestConnection(@QueryParameter final String serverUrl, @ commonClient.close(); } } - } + } + + /** + * Performs on-the-fly validation of the form field 'value'. + * + * @param value + * This parameter receives the value that the user has typed. + * @return Indicates the outcome of the validation. This is sent to the + * browser. + */ + @POST + public FormValidation doCheckScaSASTProjectID(@QueryParameter String value,@QueryParameter String scaSASTProjectFullPath) { + if (StringUtil.isNullOrEmpty(value) && StringUtil.isNullOrEmpty(scaSASTProjectFullPath)) { + return FormValidation.error("Must provide value for either 'Project Full Path' or 'Project Id'."); + } + return FormValidation.ok(); + } + + public FormValidation doTestScaSASTConnection(@QueryParameter final String scaSastServerUrl, @QueryParameter final String password, + @QueryParameter final String username, @QueryParameter final String timestamp, + @QueryParameter final String sastCredentialsId, @QueryParameter final boolean isProxy, + @AncestorInPath Item item) { + // timestamp is not used in code, it is one of the arguments to + // invalidate Internet Explorer cache + CxCredentials cred; + LegacyClient commonClient = null; + try { + try { + cred = CxCredentials.resolveCred(true, scaSastServerUrl, username, getPasswordPlainText(password), + sastCredentialsId, this, item); + CxCredentials.validateCxCredentials(cred); + Jenkins instance = Jenkins.getInstance(); + if (instance != null && instance.proxy != null && isProxy + && !(isCxURLinNoProxyHost(serverUrl, instance.proxy.getNoProxyHostPatterns()))) { + commonClient = CommonClientFactory.getInstance(cred, this.isEnableCertificateValidation(), + serverLog, true); + } else { + commonClient = CommonClientFactory.getInstance(cred, this.isEnableCertificateValidation(), + serverLog, false); + } + } catch (Exception e) { + return buildError(e, "Failed to init cx client"); + } + + try { + commonClient.login(); + try { + commonClient.getTeamList(); + } catch (Exception e) { + return FormValidation.error("Connection Failed.\n" + + "Validate the provided login credentials and server URL are correct.\n" + + "In addition, make sure the installed plugin version is compatible with the CxSAST version according to CxSAST release notes.\n" + + "Error: " + e.getMessage()); + } + return FormValidation.ok("Success"); + } catch (Exception e) { + return buildError(e, "Failed to login to Checkmarx server"); + } + } finally { + if (commonClient != null) { + commonClient.close(); + } + } + } + public FormValidation doValidateMvnPath(@QueryParameter final String mvnPath) throws InterruptedException { boolean mvnPathExists = false; @@ -2117,6 +2320,9 @@ public FormValidation doTestScaConnection(@QueryParameter String scaServerUrl, scaConfig.setTenant(scaTenant); UsernamePasswordCredentials credentials = CxCredentials.getCredentialsById(scaCredentialsId, item); + if(credentials == null) { + throw new CxCredException("Sca connection failed. Please recheck the account name and CxSCA credentials you provided and try again."); + } scaConfig.setUsername(credentials.getUsername()); scaConfig.setPassword(credentials.getPassword().getPlainText()); scaConfig.setSourceLocationType(SourceLocationType.LOCAL_DIRECTORY); @@ -2135,7 +2341,11 @@ public FormValidation doTestScaConnection(@QueryParameter String scaServerUrl, } CxClientDelegator commonClient = CommonClientFactory.getClientDelegatorInstance(config, serverLog); - commonClient.getScaClient().testScaConnection(); + try { + commonClient.getScaClient().testScaConnection(); + } catch (CxClientException e) { + throw new CxCredException("Sca connection failed. Please recheck the account name and CxSCA credentials you provided and try again."); + } return FormValidation.ok("Success"); } catch (Exception e) { return buildError(e, "Failed to verify CxSCA connection."); @@ -2544,6 +2754,9 @@ public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item item, @QueryPa public ListBoxModel doFillScaCredentialsIdItems(@AncestorInPath Item item, @QueryParameter String scaCredentialsId) { return getCredentialList(item, scaCredentialsId); } + public ListBoxModel doFillSastCredentialsIdItems(@AncestorInPath Item item, @QueryParameter String sastCredentialsId) { + return getCredentialList(item, sastCredentialsId); + } private ListBoxModel getCredentialList(Item item, String credentialsId) { StandardListBoxModel result = new StandardListBoxModel(); diff --git a/src/main/java/com/checkmarx/jenkins/CxScanCallable.java b/src/main/java/com/checkmarx/jenkins/CxScanCallable.java index cb881cd5..fef2e6f3 100644 --- a/src/main/java/com/checkmarx/jenkins/CxScanCallable.java +++ b/src/main/java/com/checkmarx/jenkins/CxScanCallable.java @@ -30,21 +30,24 @@ public class CxScanCallable implements FilePath.FileCallable, Se private final CxScanConfig config; private final TaskListener listener; private ProxyConfiguration jenkinsProxy = null; - - public CxScanCallable(CxScanConfig config, TaskListener listener) { + CxLoggerAdapter log = null; + + public CxScanCallable(CxScanConfig config, TaskListener listener, CxLoggerAdapter log) { this.config = config; this.listener = listener; + this.log = log; } - public CxScanCallable(CxScanConfig config, TaskListener listener, ProxyConfiguration jenkinsProxy) { + public CxScanCallable(CxScanConfig config, TaskListener listener, ProxyConfiguration jenkinsProxy, CxLoggerAdapter log) { this.config = config; this.listener = listener; this.jenkinsProxy = jenkinsProxy; + this.log = log; } @Override public RemoteScanInfo invoke(File file, VirtualChannel channel) throws IOException, InterruptedException { - CxLoggerAdapter log = new CxLoggerAdapter(listener.getLogger()); + config.setSourceDir(file.getAbsolutePath()); config.setReportsDir(file); if (jenkinsProxy != null) { diff --git a/src/main/java/com/checkmarx/jenkins/DependencyScanConfig.java b/src/main/java/com/checkmarx/jenkins/DependencyScanConfig.java index e00bc2a8..5ce2c362 100644 --- a/src/main/java/com/checkmarx/jenkins/DependencyScanConfig.java +++ b/src/main/java/com/checkmarx/jenkins/DependencyScanConfig.java @@ -34,6 +34,30 @@ public class DependencyScanConfig { @DataBoundSetter public String scaAccessControlUrl; + + @DataBoundSetter + public String scaEnvVariables; + + @DataBoundSetter + public boolean isExploitablePath; + + @DataBoundSetter + public boolean useJobLevelSastDetails; + + @DataBoundSetter + public String scaConfigFile; + + @DataBoundSetter + public String scaSASTProjectFullPath; + + @DataBoundSetter + public String scaSASTProjectID; + + @DataBoundSetter + public String SASTUserName; + + @DataBoundSetter + public String scaSastServerUrl; @DataBoundSetter public String scaWebAppUrl; @@ -43,9 +67,15 @@ public class DependencyScanConfig { @DataBoundSetter public String scaTenant; - + + @DataBoundSetter + public boolean isIncludeSources; + @DataBoundSetter public String fsaVariables; + + @DataBoundSetter + public String sastCredentialsId; @DataBoundConstructor public DependencyScanConfig() { diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/config.jelly b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/config.jelly index c95ce702..cca010cb 100644 --- a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/config.jelly +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/config.jelly @@ -38,7 +38,7 @@ + with="serverUrl,password, username,timestamp,credentialsId,isProxy" /> @@ -163,14 +163,50 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -334,5 +370,6 @@ + diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/global.jelly b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/global.jelly index 45bee215..fb3174ae 100644 --- a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/global.jelly +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/global.jelly @@ -47,9 +47,10 @@ - + + @@ -159,8 +160,31 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-addGlobalCommenToBuildCommet.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-addGlobalCommenToBuildCommet.html index fe781da5..dc434f04 100644 --- a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-addGlobalCommenToBuildCommet.html +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-addGlobalCommenToBuildCommet.html @@ -1,3 +1,5 @@
- Allow sast comment to be added to the build comment.By default the global comment is empty + Allow global sast comment to be added to the build comment.By default the global comment is empty. + When both job level comments and global comments are provided and 'Allow Global comment' is selected, + then both comments shall be concatenated.
\ No newline at end of file diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-comment.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-comment.html index 2a155e41..e9de15d3 100644 --- a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-comment.html +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-comment.html @@ -1,3 +1,5 @@
- Free text comment. May reference build parameters like ${PARAM}. + Free text comment. If the comment contains variables like ${GIT_COMMIT}, ${GIT_BRANCH}, ${GIT_URL}, + ${GIT_AUTHOR_NAME} or any Jenkins variable. It shall be expanded as long as it is a valid variable available to + Jenkins else considers it as plain text.
\ No newline at end of file diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-hideDebugLogs.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-hideDebugLogs.html new file mode 100644 index 00000000..4c2a9e03 --- /dev/null +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-hideDebugLogs.html @@ -0,0 +1,3 @@ +
+ Enabling this will not generate any debug level logs in the job output. +
\ No newline at end of file diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-isExploitablePath.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-isExploitablePath.html new file mode 100644 index 00000000..cb598530 --- /dev/null +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-isExploitablePath.html @@ -0,0 +1,8 @@ +
+Exploitable Path feature will attempt to co-relate CxSCA scan with the available CxSAST scan results. +In this section, provide details like CxSAST server url, credentials. +At the job level, two more parameters need to be configured. These project full path name and/or project id from CxSAST. +

+Example of Project Full Path: CxServer/team1/projectname +

+
diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-isIncludeSources.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-isIncludeSources.html new file mode 100644 index 00000000..6ea24ab3 --- /dev/null +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-isIncludeSources.html @@ -0,0 +1,3 @@ +
+ When this flag is enabled, it will include entire source code in the zip file to be scanned. +
\ No newline at end of file diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-sastcomment.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-sastcomment.html new file mode 100644 index 00000000..b2d3af49 --- /dev/null +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-sastcomment.html @@ -0,0 +1,5 @@ +
+ Free text sast scan comment. If the comment contains variables like ${GIT_COMMIT}, ${GIT_BRANCH}, ${GIT_URL}, + ${GIT_AUTHOR_NAME} or any Jenkins variable. It shall be expanded as long as it is a valid variable available to + Jenkins else considers it as plain text. +
\ No newline at end of file diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-scaConfigFile.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-scaConfigFile.html new file mode 100644 index 00000000..7c247ae2 --- /dev/null +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-scaConfigFile.html @@ -0,0 +1,9 @@ +
+This parameter is to provide configuration files of the package managers used in the project. For ex. Settings.xml for maven, Nuget.config for Nuget, .npmrc for npm etc. +This option is relevant for projects that use private artifactory. +Use CxSCA agent to perform the scan. CxSCA agent will try to perform dependency resolution using the package manager's configuration files provided. +Multiple comma character separated file path can be provided. +

+Example: c:\user\.m2\settings.xml,c:\user\npm\.npmrc +

+
\ No newline at end of file diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-scaEnvVariables.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-scaEnvVariables.html new file mode 100644 index 00000000..16f89308 --- /dev/null +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-scaEnvVariables.html @@ -0,0 +1,7 @@ +
+This option is relevant only if Package Manager's config files are provided. +In many cases, package manager's configuration files reference environment variables, often to provide credentials without storing them in a file. Pass all such variables using this option. +

+Example: param1:value1,param2:value2 +

+
\ No newline at end of file diff --git a/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-useGlobalSastDetails.html b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-useGlobalSastDetails.html new file mode 100644 index 00000000..040ac426 --- /dev/null +++ b/src/main/resources/com/checkmarx/jenkins/CxScanBuilder/help-useGlobalSastDetails.html @@ -0,0 +1,4 @@ +
+Select this to use globally defined CxSAST Server URL and credentials. +
+ \ No newline at end of file