Skip to content

Commit

Permalink
pull dev
Browse files Browse the repository at this point in the history
  • Loading branch information
EyalDelarea committed Sep 10, 2023
2 parents 32f61cd + 1ae3674 commit f33c559
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 74 deletions.
2 changes: 1 addition & 1 deletion artifactory/commands/python/python.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (pc *PythonCommand) SetPypiRepoUrlWithCredentials() error {
if err != nil {
return err
}
pc.args = append(pc.args, python.GetPypiRemoteRegistryFlag(pc.pythonTool), rtUrl.String())
pc.args = append(pc.args, python.GetPypiRemoteRegistryFlag(pc.pythonTool), rtUrl)
return nil
}

Expand Down
15 changes: 15 additions & 0 deletions utils/coreutils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,3 +584,18 @@ func GetServerIdAndRepo(remoteEnv string) (serverID string, repoName string, err
}
return
}

func GetMaskedCommandString(cmd *exec.Cmd) string {
cmdString := strings.Join(cmd.Args, " ")
// Mask url if required
matchedResult := regexp.MustCompile(utils.CredentialsInUrlRegexp).FindString(cmdString)
if matchedResult != "" {
cmdString = strings.ReplaceAll(cmdString, matchedResult, "***@")
}

matchedResults := regexp.MustCompile(`--(?:password|access-token)=(\S+)`).FindStringSubmatch(cmdString)
if len(matchedResults) > 1 && matchedResults[1] != "" {
cmdString = strings.ReplaceAll(cmdString, matchedResults[1], "***")
}
return cmdString
}
15 changes: 15 additions & 0 deletions utils/coreutils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"reflect"
"testing"
Expand Down Expand Up @@ -264,3 +265,17 @@ func TestGetFullPathsWorkingDirs(t *testing.T) {
})
}
}

func TestGetMaskedCommandString(t *testing.T) {
assert.Equal(t,
"pip -i ***@someurl.com/repo",
GetMaskedCommandString(exec.Command("pip", "-i", "https://user:[email protected]/repo")))

assert.Equal(t,
"pip -i ***@someurl.com/repo --password=***",
GetMaskedCommandString(exec.Command("pip", "-i", "https://user:[email protected]/repo", "--password=123")))

assert.Equal(t,
"pip -i ***@someurl.com/repo --access-token=***",
GetMaskedCommandString(exec.Command("pip", "-i", "https://user:[email protected]/repo", "--access-token=123")))
}
6 changes: 3 additions & 3 deletions utils/python/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ func GetPypiRemoteRegistryFlag(tool pythonutils.PythonTool) string {
return pipenvRemoteRegistryFlag
}

func GetPypiRepoUrl(serverDetails *config.ServerDetails, repository string) (*url.URL, error) {
func GetPypiRepoUrl(serverDetails *config.ServerDetails, repository string) (string, error) {
rtUrl, username, password, err := GetPypiRepoUrlWithCredentials(serverDetails, repository)
if err != nil {
return nil, err
return "", err
}
if password != "" {
rtUrl.User = url.UserPassword(username, password)
}
return rtUrl, err
return rtUrl.String(), err
}

func ConfigPoetryRepo(url, username, password, configRepoName string) error {
Expand Down
3 changes: 1 addition & 2 deletions xray/commands/audit/jasrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package audit

import (
"errors"
"github.com/jfrog/gofrog/version"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/jas"
"github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/jas/applicability"
Expand Down Expand Up @@ -49,7 +48,7 @@ func runJasScannersAndSetResults(scanResults *utils.ExtendedScanResults, directD
if err != nil {
return
}
if !version.NewVersion(utils.AnalyzerManagerVersion).AtLeast(utils.MinAnalyzerManagerVersionForSast) {
if !utils.IsSastSupported() {
return
}
if progress != nil {
Expand Down
14 changes: 9 additions & 5 deletions xray/commands/audit/sca/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,18 @@ func GetModule(modules []*xrayUtils.GraphNode, moduleId string) *xrayUtils.Graph

// GetExecutableVersion gets an executable version and prints to the debug log if possible.
// Only supported for package managers that use "--version".
func GetExecutableVersion(executable string) (version string, err error) {
func LogExecutableVersion(executable string) {
verBytes, err := exec.Command(executable, "--version").CombinedOutput()
if err != nil || len(verBytes) == 0 {
return "", err
if err != nil {
log.Debug(fmt.Sprintf("'%q --version' command received an error: %s", executable, err.Error()))
return
}
version = strings.TrimSpace(string(verBytes))
if len(verBytes) == 0 {
log.Debug(fmt.Sprintf("'%q --version' command received an empty response", executable))
return
}
version := strings.TrimSpace(string(verBytes))
log.Debug(fmt.Sprintf("Used %q version: %s", executable, version))
return
}

// BuildImpactPathsForScanResponse builds the full impact paths for each vulnerability found in the scanResult argument, using the dependencyTrees argument.
Expand Down
66 changes: 27 additions & 39 deletions xray/commands/audit/sca/python/python.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package python

import (
"errors"
"fmt"
biutils "github.com/jfrog/build-info-go/utils"
"github.com/jfrog/build-info-go/utils/pythonutils"
"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
utils "github.com/jfrog/jfrog-cli-core/v2/utils/python"
"github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/sca"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
Expand Down Expand Up @@ -72,15 +74,11 @@ func getDependencies(auditPython *AuditPython) (dependenciesGraph map[string][]s
}

defer func() {
e := os.Chdir(wd)
if err == nil {
err = errorutils.CheckError(e)
}

e = fileutils.RemoveTempDir(tempDirPath)
if err == nil {
err = e
}
err = errors.Join(
err,
errorutils.CheckError(os.Chdir(wd)),
fileutils.RemoveTempDir(tempDirPath),
)
}()

err = biutils.CopyDir(wd, tempDirPath, true, nil)
Expand All @@ -90,10 +88,7 @@ func getDependencies(auditPython *AuditPython) (dependenciesGraph map[string][]s

restoreEnv, err := runPythonInstall(auditPython)
defer func() {
e := restoreEnv()
if err == nil {
err = e
}
err = errors.Join(err, restoreEnv())
}()
if err != nil {
return
Expand All @@ -105,12 +100,8 @@ func getDependencies(auditPython *AuditPython) (dependenciesGraph map[string][]s
}
dependenciesGraph, directDependencies, err = pythonutils.GetPythonDependencies(auditPython.Tool, tempDirPath, localDependenciesPath)
if err != nil {
if _, innerErr := sca.GetExecutableVersion("python"); innerErr != nil {
log.Error(innerErr)
}
if _, innerErr := sca.GetExecutableVersion(string(auditPython.Tool)); innerErr != nil {
log.Error(innerErr)
}
sca.LogExecutableVersion("python")
sca.LogExecutableVersion(string(auditPython.Tool))
}
return
}
Expand Down Expand Up @@ -168,14 +159,19 @@ func installPipDeps(auditPython *AuditPython) (restoreEnv func() error, err erro
if err != nil {
return
}

remoteUrl := ""
if auditPython.RemotePypiRepo != "" {
return restoreEnv, runPipInstallFromRemoteRegistry(auditPython.Server, auditPython.RemotePypiRepo, auditPython.PipRequirementsFile)
remoteUrl, err = utils.GetPypiRepoUrl(auditPython.Server, auditPython.RemotePypiRepo)
if err != nil {
return
}
}
pipInstallArgs := getPipInstallArgs(auditPython.PipRequirementsFile)
pipInstallArgs := getPipInstallArgs(auditPython.PipRequirementsFile, remoteUrl)
err = executeCommand("python", pipInstallArgs...)
if err != nil && auditPython.PipRequirementsFile == "" {
log.Debug(err.Error() + "\nTrying to install using a requirements file...")
pipInstallArgs = getPipInstallArgs("requirements.txt")
pipInstallArgs = getPipInstallArgs("requirements.txt", remoteUrl)
reqErr := executeCommand("python", pipInstallArgs...)
if reqErr != nil {
// Return Pip install error and log the requirements fallback error.
Expand All @@ -189,18 +185,17 @@ func installPipDeps(auditPython *AuditPython) (restoreEnv func() error, err erro

func executeCommand(executable string, args ...string) error {
installCmd := exec.Command(executable, args...)
log.Debug(fmt.Sprintf("Running %q", strings.Join(installCmd.Args, " ")))
maskedCmdString := coreutils.GetMaskedCommandString(installCmd)
log.Debug("Running", maskedCmdString)
output, err := installCmd.CombinedOutput()
if err != nil {
if _, innerErr := sca.GetExecutableVersion(executable); innerErr != nil {
log.Error(innerErr)
}
return errorutils.CheckErrorf("%q command failed: %s - %s", strings.Join(installCmd.Args, " "), err.Error(), output)
sca.LogExecutableVersion(executable)
return errorutils.CheckErrorf("%q command failed: %s - %s", maskedCmdString, err.Error(), output)
}
return nil
}

func getPipInstallArgs(requirementsFile string) []string {
func getPipInstallArgs(requirementsFile, remoteUrl string) []string {
args := []string{"-m", "pip", "install"}
if requirementsFile == "" {
// Run 'pip install .'
Expand All @@ -209,25 +204,18 @@ func getPipInstallArgs(requirementsFile string) []string {
// Run pip 'install -r requirements <requirementsFile>'
args = append(args, "-r", requirementsFile)
}
return args
}

func runPipInstallFromRemoteRegistry(server *config.ServerDetails, depsRepoName, pipRequirementsFile string) (err error) {
rtUrl, err := utils.GetPypiRepoUrl(server, depsRepoName)
if err != nil {
return err
if remoteUrl != "" {
args = append(args, utils.GetPypiRemoteRegistryFlag(pythonutils.Pip), remoteUrl)
}
args := getPipInstallArgs(pipRequirementsFile)
args = append(args, utils.GetPypiRemoteRegistryFlag(pythonutils.Pip), rtUrl.String())
return executeCommand("python", args...)
return args
}

func runPipenvInstallFromRemoteRegistry(server *config.ServerDetails, depsRepoName string) (err error) {
rtUrl, err := utils.GetPypiRepoUrl(server, depsRepoName)
if err != nil {
return err
}
args := []string{"install", "-d", utils.GetPypiRemoteRegistryFlag(pythonutils.Pipenv), rtUrl.String()}
args := []string{"install", "-d", utils.GetPypiRemoteRegistryFlag(pythonutils.Pipenv), rtUrl}
return executeCommand("pipenv", args...)
}

Expand Down
7 changes: 5 additions & 2 deletions xray/commands/audit/sca/python/python_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ func TestBuildPoetryDependencyList(t *testing.T) {
}

func TestGetPipInstallArgs(t *testing.T) {
assert.Equal(t, []string{"-m", "pip", "install", "."}, getPipInstallArgs(""))
assert.Equal(t, []string{"-m", "pip", "install", "-r", "requirements.txt"}, getPipInstallArgs("requirements.txt"))
assert.Equal(t, []string{"-m", "pip", "install", "."}, getPipInstallArgs("", ""))
assert.Equal(t, []string{"-m", "pip", "install", "-r", "requirements.txt"}, getPipInstallArgs("requirements.txt", ""))

assert.Equal(t, []string{"-m", "pip", "install", ".", "-i", "https://user@pass:remote.url/repo"}, getPipInstallArgs("", "https://user@pass:remote.url/repo"))
assert.Equal(t, []string{"-m", "pip", "install", "-r", "requirements.txt", "-i", "https://user@pass:remote.url/repo"}, getPipInstallArgs("requirements.txt", "https://user@pass:remote.url/repo"))
}
4 changes: 3 additions & 1 deletion xray/commands/audit/scarunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ func getDirectDependenciesFromTree(dependencyTrees []*xrayCmdUtils.GraphNode) []
}

func GetTechDependencyTree(params *xrayutils.AuditBasicParams, tech coreutils.Technology) (flatTree *xrayCmdUtils.GraphNode, fullDependencyTrees []*xrayCmdUtils.GraphNode, err error) {
logMessage := fmt.Sprintf("Calculating %s dependencies", tech.ToFormal())
log.Info(logMessage)
if params.Progress() != nil {
params.Progress().SetHeadlineMsg(fmt.Sprintf("Calculating %v dependencies", tech.ToFormal()))
params.Progress().SetHeadlineMsg(logMessage)
}
serverDetails, err := params.ServerDetails()
if err != nil {
Expand Down
51 changes: 32 additions & 19 deletions xray/utils/analyzermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package utils
import (
"errors"
"fmt"
"github.com/jfrog/gofrog/version"
"os"
"os/exec"
"path"
Expand Down Expand Up @@ -38,24 +39,25 @@ var (
)

const (
EntitlementsMinVersion = "3.66.5"
ApplicabilityFeatureId = "contextual_analysis"
AnalyzerManagerZipName = "analyzerManager.zip"
AnalyzerManagerVersion = "1.2.4.1953469"
MinAnalyzerManagerVersionForSast = "1.3"
analyzerManagerDownloadPath = "xsc-gen-exe-analyzer-manager-local/v1"
analyzerManagerDirName = "analyzerManager"
analyzerManagerExecutableName = "analyzerManager"
analyzerManagerLogDirName = "analyzerManagerLogs"
jfUserEnvVariable = "JF_USER"
jfPasswordEnvVariable = "JF_PASS"
jfTokenEnvVariable = "JF_TOKEN"
jfPlatformUrlEnvVariable = "JF_PLATFORM_URL"
logDirEnvVariable = "AM_LOG_DIRECTORY"
notEntitledExitCode = 31
unsupportedCommandExitCode = 13
unsupportedOsExitCode = 55
ErrFailedScannerRun = "failed to run %s scan. Exit code received: %s"
EntitlementsMinVersion = "3.66.5"
ApplicabilityFeatureId = "contextual_analysis"
AnalyzerManagerZipName = "analyzerManager.zip"
defaultAnalyzerManagerVersion = "1.2.4.1953469"
minAnalyzerManagerVersionForSast = "1.3"
analyzerManagerDownloadPath = "xsc-gen-exe-analyzer-manager-local/v1"
analyzerManagerDirName = "analyzerManager"
analyzerManagerExecutableName = "analyzerManager"
analyzerManagerLogDirName = "analyzerManagerLogs"
jfUserEnvVariable = "JF_USER"
jfPasswordEnvVariable = "JF_PASS"
jfTokenEnvVariable = "JF_TOKEN"
jfPlatformUrlEnvVariable = "JF_PLATFORM_URL"
logDirEnvVariable = "AM_LOG_DIRECTORY"
notEntitledExitCode = 31
unsupportedCommandExitCode = 13
unsupportedOsExitCode = 55
ErrFailedScannerRun = "failed to run %s scan. Exit code received: %s"
jfrogCliAnalyzerManagerVersionEnvVariable = "JFROG_CLI_ANALYZER_MANAGER_VERSION"
)

type ApplicabilityStatus string
Expand Down Expand Up @@ -142,7 +144,18 @@ func GetAnalyzerManagerDownloadPath() (string, error) {
if err != nil {
return "", err
}
return path.Join(analyzerManagerDownloadPath, AnalyzerManagerVersion, osAndArc, AnalyzerManagerZipName), nil
return path.Join(analyzerManagerDownloadPath, GetAnalyzerManagerVersion(), osAndArc, AnalyzerManagerZipName), nil
}

func GetAnalyzerManagerVersion() string {
if analyzerManagerVersion, exists := os.LookupEnv(jfrogCliAnalyzerManagerVersionEnvVariable); exists {
return analyzerManagerVersion
}
return defaultAnalyzerManagerVersion
}

func IsSastSupported() bool {
return version.NewVersion(GetAnalyzerManagerVersion()).AtLeast(minAnalyzerManagerVersionForSast)
}

func GetAnalyzerManagerDirAbsolutePath() (string, error) {
Expand Down
3 changes: 1 addition & 2 deletions xray/utils/resultwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strconv"
"strings"

"github.com/jfrog/gofrog/version"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-cli-core/v2/xray/formats"
clientUtils "github.com/jfrog/jfrog-client-go/utils"
Expand Down Expand Up @@ -188,7 +187,7 @@ func (rw *ResultsWriter) printScanResultsTables() (err error) {
if err = PrintIacTable(rw.results.IacScanResults, rw.results.EntitledForJas); err != nil {
return
}
if !version.NewVersion(AnalyzerManagerVersion).AtLeast(MinAnalyzerManagerVersionForSast) {
if !IsSastSupported() {
return
}
return PrintSastTable(rw.results.SastResults, rw.results.EntitledForJas)
Expand Down

0 comments on commit f33c559

Please sign in to comment.