diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index fcf4e51..2792093 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.43 +2.3.42-iac-engine-fallbackPath \ No newline at end of file diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java b/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java index f23a5ea..ab0a732 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java @@ -16,7 +16,7 @@ public class CxConfig { private static final Pattern pattern = Pattern.compile("([^\"]\\S*|\".+?\")\\s*"); - + private String agentName; //JETBRAINS private String baseUri; private String baseAuthUri; private String tenant; @@ -66,6 +66,10 @@ List toArguments() { commands.add(CxConstants.BASE_AUTH_URI); commands.add(getBaseAuthUri()); } + if (getAgentName() != null && !getAgentName().isEmpty()) { + commands.add("--agent"); + commands.add(getAgentName()); + } if (getAdditionalParameters() != null) commands.addAll(getAdditionalParameters()); diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java index 79f171c..450475d 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java @@ -75,6 +75,8 @@ public final class CxConstants { static final String SUB_CMD_TENANT = "tenant"; static final String IDE_SCANS_KEY = "scan.config.plugins.ideScans"; static final String AI_MCP_SERVER_KEY = "scan.config.plugins.aiMcpServer"; + static final String DEV_ASSIST_LICENSE_KEY = "scan.config.plugins.cxdevassist"; + static final String ONE_ASSIST_LICENSE_KEY = "scan.config.plugins.cxoneassist"; static final String IGNORED_FILE_PATH = "--ignored-file-path"; static final String SUB_CMD_OSS_REALTIME = "oss-realtime"; static final String SUB_CMD_IAC_REALTIME = "iac-realtime"; diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java index 386133a..4060c4c 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java @@ -31,15 +31,17 @@ import java.io.IOException; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; + +import static com.checkmarx.ast.wrapper.Execution.*; public class CxWrapper { private static final CollectionType BRANCHES_TYPE = TypeFactory.defaultInstance() .constructCollectionType(List.class, String.class); + private static final String OS_LINUX = "linux"; + private static final String OS_WINDOWS = "windows"; + private static final String OS_MAC = "mac"; @NonNull private final CxConfig cxConfig; @@ -248,7 +250,7 @@ public List projectList(String filter) throws IOException, InterruptedE return Execution.executeCommand(withConfigArguments(arguments), logger, Project::listFromLine); } - public ScanResult ScanAsca(String fileSource, boolean ascaLatestVersion, String agent) throws IOException, InterruptedException, CxException { + public ScanResult ScanAsca(String fileSource, boolean ascaLatestVersion, String agent, String ignoredFilePath) throws IOException, InterruptedException, CxException { this.logger.info("Fetching ASCA scanResult"); List arguments = new ArrayList<>(); @@ -259,23 +261,27 @@ public ScanResult ScanAsca(String fileSource, boolean ascaLatestVersion, String if (ascaLatestVersion) { arguments.add(CxConstants.ASCA_LATEST_VERSION); } + if (StringUtils.isNotBlank(ignoredFilePath)) { + arguments.add(CxConstants.IGNORED_FILE_PATH); + arguments.add(ignoredFilePath); + } + - appendAgentToArguments(agent, arguments); return Execution.executeCommand(withConfigArguments(arguments), logger, ScanResult::fromLine, (args, ignored) -> (args.size() >= 3 && args.get(1).equals(CxConstants.CMD_SCAN) && args.get(2).equals(CxConstants.SUB_CMD_ASCA))); } - private static void appendAgentToArguments(String agent, List arguments) { - arguments.add(CxConstants.AGENT); - if (agent != null && !agent.isEmpty()){ - arguments.add(agent); - } - else{ - arguments.add("CLI-Java-Wrapper"); - } - } + // private static void appendAgentToArguments(String agent, List arguments) { + // arguments.add(CxConstants.AGENT); + // if (agent != null && !agent.isEmpty()){ + // arguments.add(agent); + // } + // else{ + // arguments.add("CLI-Java-Wrapper"); + // } + // } public List projectBranches(@NonNull UUID projectId, String filter) throws CxException, IOException, InterruptedException { @@ -345,10 +351,6 @@ public String results(@NonNull UUID scanId, ReportFormat reportFormat, String ag arguments.add(fileName); arguments.add(CxConstants.OUTPUT_PATH); arguments.add(tempDir); - if (agent != null) { - arguments.add(CxConstants.AGENT); - arguments.add(agent); - } return Execution.executeCommand(arguments, logger, tempDir, fileName + reportFormat.getExtension()); @@ -409,6 +411,48 @@ public KicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String return Execution.executeCommand(withConfigArguments(arguments), logger, KicsRealtimeResults::fromLine); } + // public T realtimeScan(@NonNull String subCommand, @NonNull String sourcePath, String containerTool, String ignoredFilePath, java.util.function.Function resultParser) + public String checkEngineExist(@NonNull String engineName) throws CxException, IOException, InterruptedException { + String osName = System.getProperty("os.name").toLowerCase(Locale.ENGLISH); + String osType=Execution.getOperatingSystemType(osName); + return this.checkEngine(engineName,osType); + } + + private String checkEngine(String engineName, String osType ) throws CxException, IOException, InterruptedException { + List arguments = new ArrayList<>(); + switch (osType){ + case OS_MAC: + String enginePath; + arguments.add("/bin/sh"); + arguments.add("-c"); + arguments.add("command -v " + engineName); + try{ + enginePath= Execution.executeCommand((arguments), logger, line->line); + } catch (CxException | IOException e) { + throw new CxException( + 1, + "Engine '" + engineName + "' is not installed or not found at /usr/local/bin)." + ); + } + return enginePath; + case OS_WINDOWS: + case OS_LINUX: + arguments.add(engineName); + arguments.add("--version"); + try { + Execution.executeCommand(arguments, logger, line -> line); + return engineName; + } catch (CxException | IOException e) { + throw new CxException( + 1,engineName+" is not installed or is not accessible from the system PATH." + ); + } + default: + throw new IllegalArgumentException("Unsupported OS: " + osType); + } + + } + public T realtimeScan(@NonNull String subCommand, @NonNull String sourcePath, String containerTool, String ignoredFilePath, java.util.function.Function resultParser) throws IOException, InterruptedException, CxException { this.logger.info("Executing 'scan {}' command using the CLI.", subCommand); @@ -526,6 +570,28 @@ public List tenantSettings() throws CxException, IOException, Int return Execution.executeCommand(withConfigArguments(arguments), logger, TenantSetting::listFromLine); } + + + public boolean getTenantSetting(String key) throws CxException, IOException, InterruptedException { + List tenantSettings = tenantSettings(); + if (tenantSettings == null) { + throw new CxException(1, "Unable to parse tenant settings"); + } + return tenantSettings.stream() + .filter(t -> t.getKey().equals(key)) + .findFirst() + .map(t -> Boolean.parseBoolean(t.getValue())) + .orElse(false); + } + public boolean devAssistEnabled() throws CxException, IOException, InterruptedException { + return getTenantSetting(CxConstants.DEV_ASSIST_LICENSE_KEY); + + } + + public boolean oneAssistEnabled() throws CxException, IOException, InterruptedException { + return getTenantSetting(CxConstants.ONE_ASSIST_LICENSE_KEY); + } + public MaskResult maskSecrets(@NonNull String filePath) throws CxException, IOException, InterruptedException { List arguments = new ArrayList<>(); @@ -565,8 +631,6 @@ public String telemetryAIEvent(String aiProvider, String agent, String eventType arguments.add(CxConstants.SUB_CMD_TELEMETRY_AI); arguments.add(CxConstants.AI_PROVIDER); arguments.add(aiProvider); - arguments.add(CxConstants.AGENT); - arguments.add(agent); arguments.add(CxConstants.TYPE); arguments.add(eventType); arguments.add(CxConstants.SUB_TYPE); diff --git a/src/main/java/com/checkmarx/ast/wrapper/Execution.java b/src/main/java/com/checkmarx/ast/wrapper/Execution.java index c233ff2..0a888ec 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/Execution.java +++ b/src/main/java/com/checkmarx/ast/wrapper/Execution.java @@ -1,5 +1,6 @@ package com.checkmarx.ast.wrapper; +import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults; import lombok.NonNull; import org.slf4j.Logger; @@ -12,10 +13,7 @@ import java.nio.file.Paths; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Objects; +import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; @@ -171,7 +169,7 @@ private static String detectBinaryName(@NonNull Logger logger) { return fileName; } - private static String getOperatingSystemType(String osName) { + public static String getOperatingSystemType(String osName) { if (osName.contains(OS_LINUX)) { return OS_LINUX; } else if (osName.contains(OS_WINDOWS)) { @@ -217,4 +215,6 @@ private static String md5(InputStream a) { } return md5; } + + } diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 5bd22e2..f9909fd 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2ec1fcc76f04596c976b5039ff8d755f3e6534f06ecf442cb8d22c4f3e8f9c8 -size 81055928 +oid sha256:2972512d55630f04f494fdf3543a3edf37906b970f5e29f58127ad27c40b652c +size 81023160 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index fe820c8..f17f02d 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23dbe8b789c4c358023a98c15fdc57a468fff934804bbbfbb3ec5fa90d803c11 +oid sha256:ba3e45134be18e2093521df1f5e337c749e231fc926d5928815be4bbc68c4dd0 size 77332664 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 5423173..52f3f40 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0a89e14ad8516e093625d3eff5713c83696d12494664c338839731f8dd8a79e -size 163042800 +oid sha256:7da05ed86e02142c414ebfa2ed335b71357f7d407291b9952bf5860c7bf78dab +size 162975392 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index a71d047..0341df0 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f73d920a720bd8c3a6f4f234a77589e51611f07645c53baf1650396f77ed4f3 -size 83032512 +oid sha256:5fb41bc7c8d5b3db18f4626d9523fc626fd19c6f88e1bb078184e7b6e2532fed +size 82995136 diff --git a/src/test/java/com/checkmarx/ast/ScanTest.java b/src/test/java/com/checkmarx/ast/ScanTest.java index 5e31b33..a414281 100644 --- a/src/test/java/com/checkmarx/ast/ScanTest.java +++ b/src/test/java/com/checkmarx/ast/ScanTest.java @@ -25,7 +25,7 @@ void testScanShow() throws Exception { @Test void testScanAsca_WhenFileWithVulnerabilitiesIsSentWithAgent_ReturnSuccessfulResponseWithCorrectValues() throws Exception { - ScanResult scanResult = wrapper.ScanAsca("src/test/resources/python-vul-file.py", true, "vscode"); + ScanResult scanResult = wrapper.ScanAsca("src/test/resources/python-vul-file.py", true, "vscode", null); // Assertions for the scan result Assertions.assertNotNull(scanResult.getRequestId(), "Request ID should not be null"); @@ -46,7 +46,7 @@ void testScanAsca_WhenFileWithVulnerabilitiesIsSentWithAgent_ReturnSuccessfulRes @Test void testScanAsca_WhenFileWithoutVulnerabilitiesIsSent_ReturnSuccessfulResponseWithCorrectValues() throws Exception { - ScanResult scanResult = wrapper.ScanAsca("src/test/resources/csharp-no-vul.cs", true, null); + ScanResult scanResult = wrapper.ScanAsca("src/test/resources/csharp-no-vul.cs", true, null, null); Assertions.assertNotNull(scanResult.getRequestId()); Assertions.assertTrue(scanResult.isStatus()); Assertions.assertNull(scanResult.getError()); @@ -55,12 +55,25 @@ void testScanAsca_WhenFileWithoutVulnerabilitiesIsSent_ReturnSuccessfulResponseW @Test void testScanAsca_WhenMissingFileExtension_ReturnFileExtensionIsRequiredFailure() throws Exception { - ScanResult scanResult = wrapper.ScanAsca("CODEOWNERS", true, null); + ScanResult scanResult = wrapper.ScanAsca("CODEOWNERS", true, null, null); Assertions.assertNotNull(scanResult.getRequestId()); Assertions.assertNotNull(scanResult.getError()); Assertions.assertEquals("The file name must have an extension.", scanResult.getError().getDescription()); } + @Test + void testScanAsca_WithIgnoreFilePath_ShouldWorkCorrectly() throws Exception { + String ignoreFile = "src/test/resources/ignored-packages.json"; + + // Test with ignore file - should not break the scanning process + ScanResult scanResult = wrapper.ScanAsca("src/test/resources/python-vul-file.py", true, "test-agent", ignoreFile); + + // Verify the scan completes successfully + Assertions.assertNotNull(scanResult.getRequestId(), "Request ID should not be null"); + Assertions.assertTrue(scanResult.isStatus(), "Status should be true"); + Assertions.assertNull(scanResult.getError(), "Error should be null when scan is successful"); + } + @Test void testScanList() throws Exception { List cxOutput = wrapper.scanList("limit=10"); diff --git a/src/test/java/com/checkmarx/ast/TenantTest.java b/src/test/java/com/checkmarx/ast/TenantTest.java index 7f49da1..91824f4 100644 --- a/src/test/java/com/checkmarx/ast/TenantTest.java +++ b/src/test/java/com/checkmarx/ast/TenantTest.java @@ -24,4 +24,14 @@ void testAiMcpServerEnabled() throws Exception { boolean enabled = Assertions.assertDoesNotThrow(() -> wrapper.aiMcpServerEnabled()); Assertions.assertTrue(enabled, "AI MCP Server flag expected to be true"); } + + @Test + void testDevAssistEnabled() { + Assertions.assertDoesNotThrow(() -> wrapper.devAssistEnabled()); + } + + @Test + void testOneAssistEnabled() { + Assertions.assertDoesNotThrow(() -> wrapper.oneAssistEnabled()); + } }