Skip to content

Commit

Permalink
Feature/sca resolver (#268)
Browse files Browse the repository at this point in the history
* - Added support for SCA resolver.

* - Updated scan process.

* - Changed name of included sca results file to .cxsca-results.json.

* - ClI parameter or environment variable can now be used to activate
resolver. If both values are found the CLI parameter wins.
  • Loading branch information
tsunez authored Sep 9, 2021
1 parent bc770e2 commit b2b13b4
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 1 deletion.
1 change: 1 addition & 0 deletions internal/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
GroupList = "groups"
IncrementalSast = "sast-incremental"
PresetName = "sast-preset-name"
ScaResolverFlag = "sca-resolver"
AccessKeyIDFlag = "client-id"
AccessKeySecretFlag = "client-secret"
AccessKeyIDFlagUsage = "The OAuth2 client ID"
Expand Down
61 changes: 60 additions & 1 deletion internal/commands/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
Expand Down Expand Up @@ -38,6 +39,7 @@ const (
)

var (
scaResolverResultsFile = ""
actualScanTypes = "sast,kics,sca"
filterScanListFlagUsage = fmt.Sprintf("Filter the list of scans. Use ';' as the delimeter for arrays. Available filters are: %s",
strings.Join([]string{
Expand Down Expand Up @@ -279,18 +281,23 @@ func scanCreateSubCommand(
}
createScanCmd.PersistentFlags().String(IncrementalSast, "false", "Incremental SAST scan should be performed.")
createScanCmd.PersistentFlags().String(PresetName, "", "The name of the Checkmarx preset to use.")
createScanCmd.PersistentFlags().String(ScaResolverFlag, "", "Resolve SCA project dependencies (default true)")
createScanCmd.PersistentFlags().String(ScanTypes, "", "Scan types, ex: (sast,kics,sca)")
createScanCmd.PersistentFlags().String(TagList, "", "List of tags, ex: (tagA,tagB:val,etc)")
createScanCmd.PersistentFlags().StringP(BranchFlag, BranchFlagSh, commonParams.Branch, BranchFlagUsage)
addResultFormatFlag(createScanCmd, util.FormatSummaryConsole, util.FormatJSON, util.FormatSummary, util.FormatSarif)
createScanCmd.PersistentFlags().String(TargetFlag, "cx_result", "Output file")
createScanCmd.PersistentFlags().String(TargetPathFlag, ".", "Output Path")
createScanCmd.PersistentFlags().StringSlice(FilterFlag, []string{}, filterResultsListFlagUsage)
// Link the environment variable to the CLI argument(s).
// Link the environment variables to the CLI argument(s).
err = viper.BindPFlag(commonParams.BranchKey, createScanCmd.PersistentFlags().Lookup(BranchFlag))
if err != nil {
log.Fatal(err)
}
err = viper.BindPFlag(commonParams.ScaToolKey, createScanCmd.PersistentFlags().Lookup(ScaResolverFlag))
if err != nil {
log.Fatal(err)
}
return createScanCmd
}

Expand Down Expand Up @@ -479,6 +486,7 @@ func addScaScan() map[string]interface{} {

func compressFolder(sourceDir, filter, userIncludeFilter string) (string, error) {
var err error
scaToolPath := viper.GetString(commonParams.ScaToolKey)
outputFile, err := ioutil.TempFile(os.TempDir(), "cx-*.zip")
if err != nil {
log.Fatal("Cannot source code temp file.", err)
Expand All @@ -488,6 +496,12 @@ func compressFolder(sourceDir, filter, userIncludeFilter string) (string, error)
if err != nil {
log.Fatal(err)
}
if len(scaToolPath) > 0 && len(scaResolverResultsFile) > 0 {
err = addScaResults(zipWriter)
if err != nil {
log.Fatal(err)
}
}
// Close the file
if err = zipWriter.Close(); err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -618,6 +632,50 @@ func filterMatched(filters []string, fileName string) bool {
return matched
}

func runScaResolver(sourceDir string) {
scaToolPath := viper.GetString(commonParams.ScaToolKey)
if len(scaToolPath) > 0 {
fmt.Println("Using SCA resolver: " + scaToolPath)
scaFile, err := ioutil.TempFile("", "sca")
scaResolverResultsFile = scaFile.Name() + ".json"
if err != nil {
log.Fatal(err)
}
if scaToolPath != "nop" {
out, err := exec.Command(scaToolPath, "offline", "-s", sourceDir, "-n", ProjectName, "-r", scaResolverResultsFile).Output()
fmt.Println(string(out))
if err != nil {
log.Fatal(err)
}
} else {
fmt.Println("Creating 'No Op' resolver file.")
d1 := []byte("{}")
err := os.WriteFile(scaResolverResultsFile, d1, 0644)
if err != nil {
log.Fatal(err)
}
}
}
}

func addScaResults(zipWriter *zip.Writer) error {
fmt.Println("Included SCA Results: ", ".cxsca-results.json")
dat, err := ioutil.ReadFile(scaResolverResultsFile)
os.Remove(scaResolverResultsFile)
if err != nil {
return err
}
f, err := zipWriter.Create(".cxsca-results.json")
if err != nil {
return err
}
_, err = f.Write(dat)
if err != nil {
return err
}
return nil
}

func determineSourceFile(uploadsWrapper wrappers.UploadsWrapper,
sourcesFile,
sourceDir,
Expand All @@ -626,6 +684,7 @@ func determineSourceFile(uploadsWrapper wrappers.UploadsWrapper,
var err error
var preSignedURL string
if sourceDir != "" {
runScaResolver(sourceDir)
sourcesFile, _ = compressFolder(sourceDir, sourceDirFilter, userIncludeFilter)
}
if sourcesFile != "" {
Expand Down
1 change: 1 addition & 0 deletions internal/params/binds.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var EnvVarsBinds = []struct {
{ProxyDomainKey, ProxyDomainEnv, ""},
{BaseAuthURIKey, BaseAuthURIEnv, ""},
{AstAPIKey, AstAPIKeyEnv, ""},
{ScaToolKey, ScaToolEnv, ""},
{AgentNameKey, AgentNameEnv, "ASTCLI"},
{ScansPathKey, ScansPathEnv, "api/scans"},
{ProjectsPathKey, ProjectsPathEnv, "api/projects"},
Expand Down
1 change: 1 addition & 0 deletions internal/params/envs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const (
ProxyTypeEnv = "CX_PROXY_AUTH_TYPE"
ProxyDomainEnv = "CX_PROXY_NTLM_DOMAIN"
BaseAuthURIEnv = "CX_BASE_AUTH_URI"
ScaToolEnv = "SCA_RESOLVER"
AstAPIKeyEnv = "CX_APIKEY"
AccessKeyIDEnv = "CX_CLIENT_ID"
AccessKeySecretEnv = "CX_CLIENT_SECRET"
Expand Down
1 change: 1 addition & 0 deletions internal/params/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var (
ProxyDomainKey = strings.ToLower(ProxyDomainEnv)
BaseAuthURIKey = strings.ToLower(BaseAuthURIEnv)
AstAPIKey = strings.ToLower(AstAPIKeyEnv)
ScaToolKey = strings.ToLower(ScaToolEnv)
ScansPathKey = strings.ToLower(ScansPathEnv)
AgentNameKey = strings.ToLower(AgentNameEnv)
ProjectsPathKey = strings.ToLower(ProjectsPathEnv)
Expand Down
16 changes: 16 additions & 0 deletions test/integration/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ func TestNoWaitScan(t *testing.T) {
executeScanTest(t, projectID, scanID, map[string]string{})
}

// Test ScaResolver environment variable, this is a nop test
func TestScaResolverEnv(t *testing.T) {
scanID, projectID := createScanNoWaitWithResolver(t, Dir, map[string]string{})
defer deleteProject(t, projectID)
assert.Assert(
t,
pollScanUntilStatus(t, scanID, scansApi.ScanCompleted, FullScanWait, ScanPollSleep),
"Polling should complete when resolver used.",
)
executeScanTest(t, projectID, scanID, map[string]string{})
}

// Perform an initial scan with complete sources and an incremental scan with a smaller wait time
func TestIncrementalScan(t *testing.T) {
projectName := fmt.Sprintf("integration_test_incremental_%s", uuid.New().String())
Expand Down Expand Up @@ -174,6 +186,10 @@ func createScanNoWait(t *testing.T, source string, tags map[string]string) (stri
return executeCreateScan(t, append(getCreateArgs(source, tags), "--nowait"))
}

func createScanNoWaitWithResolver(t *testing.T, source string, tags map[string]string) (string, string) {
return executeCreateScan(t, append(getCreateArgs(source, tags), "--nowait", "--sca-resolver", "nop"))
}

func createScanIncremental(t *testing.T, source string, name string, tags map[string]string) (string, string) {
return executeCreateScan(t, append(getCreateArgsWithName(source, tags, name), "--sast-incremental"))
}
Expand Down

0 comments on commit b2b13b4

Please sign in to comment.