2022-06-24 09:04:24 +02:00
package cmd
import (
2023-06-20 14:50:28 +02:00
"bytes"
2022-06-24 09:04:24 +02:00
"fmt"
2023-12-13 10:55:07 +02:00
"net/http"
2022-06-24 09:04:24 +02:00
"os"
2023-04-28 15:47:05 +02:00
"path/filepath"
2022-06-24 09:04:24 +02:00
"regexp"
2023-02-22 19:00:53 +02:00
"strings"
2023-06-20 14:50:28 +02:00
"time"
2022-06-24 09:04:24 +02:00
2023-04-28 15:47:05 +02:00
"github.com/SAP/jenkins-library/pkg/codeql"
2022-06-24 09:04:24 +02:00
"github.com/SAP/jenkins-library/pkg/command"
2023-12-13 10:55:07 +02:00
piperhttp "github.com/SAP/jenkins-library/pkg/http"
2022-06-24 09:04:24 +02:00
"github.com/SAP/jenkins-library/pkg/log"
2023-12-13 10:55:07 +02:00
"github.com/SAP/jenkins-library/pkg/maven"
2022-06-24 09:04:24 +02:00
"github.com/SAP/jenkins-library/pkg/orchestrator"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/pkg/errors"
)
type codeqlExecuteScanUtils interface {
command . ExecRunner
2022-08-09 10:57:02 +02:00
piperutils . FileUtils
2023-12-13 10:55:07 +02:00
DownloadFile ( url , filename string , header http . Header , cookies [ ] * http . Cookie ) error
2022-06-24 09:04:24 +02:00
}
type codeqlExecuteScanUtilsBundle struct {
* command . Command
* piperutils . Files
2023-12-13 10:55:07 +02:00
* piperhttp . Client
2022-06-24 09:04:24 +02:00
}
2023-12-04 12:02:12 +02:00
const (
sarifUploadComplete = "complete"
sarifUploadFailed = "failed"
)
2023-06-20 14:50:28 +02:00
2022-06-24 09:04:24 +02:00
func newCodeqlExecuteScanUtils ( ) codeqlExecuteScanUtils {
utils := codeqlExecuteScanUtilsBundle {
Command : & command . Command { } ,
Files : & piperutils . Files { } ,
2023-12-13 10:55:07 +02:00
Client : & piperhttp . Client { } ,
2022-06-24 09:04:24 +02:00
}
utils . Stdout ( log . Writer ( ) )
utils . Stderr ( log . Writer ( ) )
return & utils
}
2024-01-17 10:38:16 +02:00
func codeqlExecuteScan ( config codeqlExecuteScanOptions , telemetryData * telemetry . CustomData , influx * codeqlExecuteScanInflux ) {
2022-06-24 09:04:24 +02:00
utils := newCodeqlExecuteScanUtils ( )
2024-01-17 10:38:16 +02:00
influx . step_data . fields . codeql = false
reports , err := runCodeqlExecuteScan ( & config , telemetryData , utils , influx )
2023-04-28 15:47:05 +02:00
piperutils . PersistReportsAndLinks ( "codeqlExecuteScan" , "./" , utils , reports , nil )
2022-06-24 09:04:24 +02:00
if err != nil {
log . Entry ( ) . WithError ( err ) . Fatal ( "Codeql scan failed" )
}
2024-01-17 10:38:16 +02:00
influx . step_data . fields . codeql = true
2022-06-24 09:04:24 +02:00
}
2024-04-02 06:48:17 +02:00
func appendCodeqlQuery ( cmd [ ] string , codeqlQuery string ) [ ] string {
2022-06-24 09:04:24 +02:00
if len ( codeqlQuery ) > 0 {
cmd = append ( cmd , codeqlQuery )
}
return cmd
}
func execute ( utils codeqlExecuteScanUtils , cmd [ ] string , isVerbose bool ) error {
if isVerbose {
cmd = append ( cmd , "-v" )
}
2023-06-14 13:29:01 +02:00
2022-06-24 09:04:24 +02:00
return utils . RunExecutable ( "codeql" , cmd ... )
}
func getLangFromBuildTool ( buildTool string ) string {
switch buildTool {
case "maven" :
return "java"
case "pip" :
return "python"
case "npm" :
return "javascript"
case "yarn" :
return "javascript"
case "golang" :
return "go"
default :
return ""
}
}
2023-11-20 15:21:04 +02:00
func getGitRepoInfo ( repoUri string , repoInfo * codeql . RepoInfo ) error {
2022-06-24 09:04:24 +02:00
if repoUri == "" {
return errors . New ( "repository param is not set or it cannot be auto populated" )
}
2023-05-05 18:57:47 +02:00
pat := regexp . MustCompile ( ` ^(https:\/\/|git@)([\S]+:[\S]+@)?([^\/:]+)[\/:]([^\/:]+\/[\S]+)$ ` )
2022-06-24 09:04:24 +02:00
matches := pat . FindAllStringSubmatch ( repoUri , - 1 )
if len ( matches ) > 0 {
match := matches [ 0 ]
2023-11-20 15:21:04 +02:00
repoInfo . ServerUrl = "https://" + match [ 3 ]
2023-04-28 15:47:05 +02:00
repoData := strings . Split ( strings . TrimSuffix ( match [ 4 ] , ".git" ) , "/" )
if len ( repoData ) != 2 {
return fmt . Errorf ( "Invalid repository %s" , repoUri )
}
2023-11-20 15:21:04 +02:00
repoInfo . Owner = repoData [ 0 ]
repoInfo . Repo = repoData [ 1 ]
2022-06-24 09:04:24 +02:00
return nil
}
return fmt . Errorf ( "Invalid repository %s" , repoUri )
}
2023-11-20 15:21:04 +02:00
func initGitInfo ( config * codeqlExecuteScanOptions ) ( codeql . RepoInfo , error ) {
var repoInfo codeql . RepoInfo
2023-04-28 15:47:05 +02:00
err := getGitRepoInfo ( config . Repository , & repoInfo )
if err != nil {
log . Entry ( ) . Error ( err )
}
2023-10-18 13:20:15 +02:00
2023-11-20 15:21:04 +02:00
repoInfo . Ref = config . AnalyzedRef
repoInfo . CommitId = config . CommitID
2022-06-24 09:04:24 +02:00
2024-01-09 13:01:15 +02:00
provider , err := orchestrator . GetOrchestratorConfigProvider ( nil )
2023-04-28 15:47:05 +02:00
if err != nil {
log . Entry ( ) . Warn ( "No orchestrator found. We assume piper is running locally." )
} else {
2023-11-20 15:21:04 +02:00
if repoInfo . Ref == "" {
2024-01-09 13:01:15 +02:00
repoInfo . Ref = provider . GitReference ( )
2022-07-12 10:25:17 +02:00
}
2023-11-20 15:21:04 +02:00
if repoInfo . CommitId == "" || repoInfo . CommitId == "NA" {
2024-01-09 13:01:15 +02:00
repoInfo . CommitId = provider . CommitSHA ( )
2022-06-24 09:04:24 +02:00
}
2023-11-20 15:21:04 +02:00
if repoInfo . ServerUrl == "" {
2024-01-09 13:01:15 +02:00
err = getGitRepoInfo ( provider . RepoURL ( ) , & repoInfo )
2023-04-28 15:47:05 +02:00
if err != nil {
log . Entry ( ) . Error ( err )
2022-06-24 09:04:24 +02:00
}
2023-04-28 15:47:05 +02:00
}
}
2023-10-18 13:20:15 +02:00
if len ( config . TargetGithubRepoURL ) > 0 {
2024-02-05 12:24:49 +02:00
log . Entry ( ) . Infof ( "Checking target GitHub repo URL: %s" , config . TargetGithubRepoURL )
2023-11-20 15:21:04 +02:00
if strings . Contains ( repoInfo . ServerUrl , "github" ) {
2023-10-18 13:20:15 +02:00
log . Entry ( ) . Errorf ( "TargetGithubRepoURL should not be set as the source repo is on github." )
return repoInfo , errors . New ( "TargetGithubRepoURL should not be set as the source repo is on github." )
}
err := getGitRepoInfo ( config . TargetGithubRepoURL , & repoInfo )
if err != nil {
log . Entry ( ) . Error ( err )
return repoInfo , err
}
if len ( config . TargetGithubBranchName ) > 0 {
2024-02-05 12:24:49 +02:00
log . Entry ( ) . Infof ( "Target GitHub branch name: %s" , config . TargetGithubBranchName )
2023-11-20 15:21:04 +02:00
repoInfo . Ref = config . TargetGithubBranchName
2023-10-18 13:20:15 +02:00
if len ( strings . Split ( config . TargetGithubBranchName , "/" ) ) < 3 {
2023-11-20 15:21:04 +02:00
repoInfo . Ref = "refs/heads/" + config . TargetGithubBranchName
2023-10-18 13:20:15 +02:00
}
}
}
2022-06-24 09:04:24 +02:00
2023-10-18 13:20:15 +02:00
return repoInfo , nil
2023-04-28 15:47:05 +02:00
}
2022-06-24 09:04:24 +02:00
2023-04-28 15:47:05 +02:00
func getToken ( config * codeqlExecuteScanOptions ) ( bool , string ) {
if len ( config . GithubToken ) > 0 {
return true , config . GithubToken
}
2022-06-24 09:04:24 +02:00
2023-04-28 15:47:05 +02:00
envVal , isEnvGithubToken := os . LookupEnv ( "GITHUB_TOKEN" )
if isEnvGithubToken {
return true , envVal
}
2022-06-24 09:04:24 +02:00
2023-04-28 15:47:05 +02:00
return false , ""
}
2022-06-24 09:04:24 +02:00
2023-11-20 15:21:04 +02:00
func uploadResults ( config * codeqlExecuteScanOptions , repoInfo codeql . RepoInfo , token string , utils codeqlExecuteScanUtils ) ( string , error ) {
2024-04-02 06:48:17 +02:00
cmd := prepareCmdForUploadResults ( config , & repoInfo , token )
2023-04-28 15:47:05 +02:00
2023-09-27 13:59:35 +02:00
//if no git params are passed(commitId, reference, serverUrl, repository), then codeql tries to auto populate it based on git information of the checkout repository.
2023-04-28 15:47:05 +02:00
//It also depends on the orchestrator. Some orchestrator keep git information and some not.
2023-06-20 14:50:28 +02:00
2023-09-27 13:59:35 +02:00
var bufferOut , bufferErr bytes . Buffer
utils . Stdout ( & bufferOut )
defer utils . Stdout ( log . Writer ( ) )
utils . Stderr ( & bufferErr )
defer utils . Stderr ( log . Writer ( ) )
2023-04-28 15:47:05 +02:00
err := execute ( utils , cmd , GeneralConfig . Verbose )
if err != nil {
2023-09-27 13:59:35 +02:00
e := bufferErr . String ( )
log . Entry ( ) . Error ( e )
if strings . Contains ( e , "Unauthorized" ) {
log . Entry ( ) . Error ( "Either your Github Token is invalid or you use both Vault and Jenkins credentials where your Vault credentials are invalid, to use your Jenkins credentials try setting 'skipVault:true'" )
}
2023-04-28 15:47:05 +02:00
log . Entry ( ) . Error ( "failed to upload sarif results" )
2023-06-20 14:50:28 +02:00
return "" , err
2022-06-24 09:04:24 +02:00
}
2023-06-20 14:50:28 +02:00
2023-09-27 13:59:35 +02:00
url := bufferOut . String ( )
2023-06-20 14:50:28 +02:00
return strings . TrimSpace ( url ) , nil
}
func waitSarifUploaded ( config * codeqlExecuteScanOptions , codeqlSarifUploader codeql . CodeqlSarifUploader ) error {
maxRetries := config . SarifCheckMaxRetries
retryInterval := time . Duration ( config . SarifCheckRetryInterval ) * time . Second
2022-06-24 09:04:24 +02:00
2023-06-20 14:50:28 +02:00
log . Entry ( ) . Info ( "waiting for the SARIF to upload" )
i := 1
for {
sarifStatus , err := codeqlSarifUploader . GetSarifStatus ( )
if err != nil {
return err
}
log . Entry ( ) . Infof ( "the SARIF processing status: %s" , sarifStatus . ProcessingStatus )
if sarifStatus . ProcessingStatus == sarifUploadComplete {
return nil
}
if sarifStatus . ProcessingStatus == sarifUploadFailed {
for e := range sarifStatus . Errors {
log . Entry ( ) . Error ( e )
}
return errors . New ( "failed to upload sarif file" )
}
if i <= maxRetries {
log . Entry ( ) . Infof ( "still waiting for the SARIF to upload: retrying in %d seconds... (retry %d/%d)" , config . SarifCheckRetryInterval , i , maxRetries )
time . Sleep ( retryInterval )
i ++
continue
}
return errors . New ( "failed to check sarif uploading status: max retries reached" )
}
2022-06-24 09:04:24 +02:00
}
2024-01-17 10:38:16 +02:00
func runCodeqlExecuteScan ( config * codeqlExecuteScanOptions , telemetryData * telemetry . CustomData , utils codeqlExecuteScanUtils , influx * codeqlExecuteScanInflux ) ( [ ] piperutils . Path , error ) {
2023-03-14 14:48:42 +02:00
codeqlVersion , err := os . ReadFile ( "/etc/image-version" )
if err != nil {
log . Entry ( ) . Infof ( "CodeQL image version: unknown" )
} else {
log . Entry ( ) . Infof ( "CodeQL image version: %s" , string ( codeqlVersion ) )
}
2022-06-24 09:04:24 +02:00
var reports [ ] piperutils . Path
2024-04-02 06:48:17 +02:00
dbCreateCustomFlags := codeql . ParseCustomFlags ( config . DatabaseCreateFlags )
cmd , err := prepareCmdForDatabaseCreate ( dbCreateCustomFlags , config , utils )
if err != nil {
log . Entry ( ) . WithError ( err ) . Error ( "failed to prepare command for codeql database create" )
return reports , err
2022-06-24 09:04:24 +02:00
}
2023-03-14 14:48:42 +02:00
err = execute ( utils , cmd , GeneralConfig . Verbose )
2022-06-24 09:04:24 +02:00
if err != nil {
log . Entry ( ) . Error ( "failed running command codeql database create" )
2023-04-28 15:47:05 +02:00
return reports , err
2022-06-24 09:04:24 +02:00
}
2023-04-28 15:47:05 +02:00
err = os . MkdirAll ( filepath . Join ( config . ModulePath , "target" ) , os . ModePerm )
2022-07-21 09:04:21 +02:00
if err != nil {
2023-04-28 15:47:05 +02:00
return reports , fmt . Errorf ( "failed to create directory: %w" , err )
2022-07-21 09:04:21 +02:00
}
2022-06-24 09:04:24 +02:00
2024-04-02 06:48:17 +02:00
dbAnalyzeCustomFlags := codeql . ParseCustomFlags ( config . DatabaseAnalyzeFlags )
cmd , err = prepareCmdForDatabaseAnalyze ( dbAnalyzeCustomFlags , config , "sarif-latest" , "codeqlReport.sarif" )
if err != nil {
log . Entry ( ) . WithError ( err ) . Error ( "failed to prepare command for codeql database analyze format=sarif-latest" )
return reports , err
}
2022-06-24 09:04:24 +02:00
err = execute ( utils , cmd , GeneralConfig . Verbose )
if err != nil {
log . Entry ( ) . Error ( "failed running command codeql database analyze for sarif generation" )
2023-04-28 15:47:05 +02:00
return reports , err
2022-06-24 09:04:24 +02:00
}
2023-04-28 15:47:05 +02:00
reports = append ( reports , piperutils . Path { Target : filepath . Join ( config . ModulePath , "target" , "codeqlReport.sarif" ) } )
2022-06-24 09:04:24 +02:00
2024-04-02 06:48:17 +02:00
cmd , err = prepareCmdForDatabaseAnalyze ( dbAnalyzeCustomFlags , config , "csv" , "codeqlReport.csv" )
if err != nil {
log . Entry ( ) . WithError ( err ) . Error ( "failed to prepare command for codeql database analyze format=csv" )
return reports , err
}
2022-06-24 09:04:24 +02:00
err = execute ( utils , cmd , GeneralConfig . Verbose )
if err != nil {
log . Entry ( ) . Error ( "failed running command codeql database analyze for csv generation" )
2023-04-28 15:47:05 +02:00
return reports , err
2022-06-24 09:04:24 +02:00
}
2023-04-28 15:47:05 +02:00
reports = append ( reports , piperutils . Path { Target : filepath . Join ( config . ModulePath , "target" , "codeqlReport.csv" ) } )
2023-10-18 13:20:15 +02:00
repoInfo , err := initGitInfo ( config )
if err != nil {
return reports , err
}
2023-11-20 15:21:04 +02:00
repoUrl := fmt . Sprintf ( "%s/%s/%s" , repoInfo . ServerUrl , repoInfo . Owner , repoInfo . Repo )
repoReference , err := codeql . BuildRepoReference ( repoUrl , repoInfo . Ref )
repoCodeqlScanUrl := fmt . Sprintf ( "%s/security/code-scanning?query=is:open+ref:%s" , repoUrl , repoInfo . Ref )
2023-04-28 15:47:05 +02:00
2023-10-18 13:20:15 +02:00
if len ( config . TargetGithubRepoURL ) > 0 {
2024-02-05 12:24:49 +02:00
log . Entry ( ) . Infof ( "DB sources for %s will be uploaded to target GitHub repo: %s" , config . Repository , repoUrl )
2023-10-18 13:20:15 +02:00
hasToken , token := getToken ( config )
if ! hasToken {
return reports , errors . New ( "failed running upload db sources to GitHub as githubToken was not specified" )
}
repoUploader , err := codeql . NewGitUploaderInstance (
token ,
2023-11-20 15:21:04 +02:00
repoInfo . Ref ,
2023-10-18 13:20:15 +02:00
config . Database ,
2023-11-20 15:21:04 +02:00
repoInfo . CommitId ,
2023-10-18 13:20:15 +02:00
config . Repository ,
config . TargetGithubRepoURL ,
)
if err != nil {
return reports , err
}
targetCommitId , err := repoUploader . UploadProjectToGithub ( )
if err != nil {
return reports , errors . Wrap ( err , "failed uploading db sources from non-GitHub SCM to GitHub" )
}
2023-11-20 15:21:04 +02:00
repoInfo . CommitId = targetCommitId
2024-02-05 12:24:49 +02:00
log . Entry ( ) . Info ( "DB sources were successfully uploaded to target GitHub repo" )
2023-10-18 13:20:15 +02:00
}
2024-01-17 10:38:16 +02:00
var scanResults [ ] codeql . CodeqlFindings
2023-04-28 15:47:05 +02:00
if ! config . UploadResults {
log . Entry ( ) . Warn ( "The sarif results will not be uploaded to the repository and compliance report will not be generated as uploadResults is set to false." )
} else {
2024-02-05 12:24:49 +02:00
log . Entry ( ) . Infof ( "The sarif results will be uploaded to the repository %s" , repoUrl )
2023-04-28 15:47:05 +02:00
hasToken , token := getToken ( config )
if ! hasToken {
return reports , errors . New ( "failed running upload-results as githubToken was not specified" )
}
2023-06-20 14:50:28 +02:00
sarifUrl , err := uploadResults ( config , repoInfo , token , utils )
2023-04-28 15:47:05 +02:00
if err != nil {
return reports , err
}
2023-06-20 14:50:28 +02:00
codeqlSarifUploader := codeql . NewCodeqlSarifUploaderInstance ( sarifUrl , token )
err = waitSarifUploaded ( config , & codeqlSarifUploader )
if err != nil {
return reports , errors . Wrap ( err , "failed to upload sarif" )
}
2023-04-28 15:47:05 +02:00
2023-11-20 15:21:04 +02:00
codeqlScanAuditInstance := codeql . NewCodeqlScanAuditInstance ( repoInfo . ServerUrl , repoInfo . Owner , repoInfo . Repo , token , [ ] string { } )
2024-01-17 10:38:16 +02:00
scanResults , err = codeqlScanAuditInstance . GetVulnerabilities ( repoInfo . Ref )
2023-07-11 18:32:54 +02:00
if err != nil {
return reports , errors . Wrap ( err , "failed to get scan results" )
}
2023-05-31 10:37:09 +02:00
2023-07-25 14:50:26 +02:00
codeqlAudit := codeql . CodeqlAudit { ToolName : "codeql" , RepositoryUrl : repoUrl , CodeScanningLink : repoCodeqlScanUrl , RepositoryReferenceUrl : repoReference , QuerySuite : config . QuerySuite , ScanResults : scanResults }
2023-07-11 18:32:54 +02:00
paths , err := codeql . WriteJSONReport ( codeqlAudit , config . ModulePath )
if err != nil {
return reports , errors . Wrap ( err , "failed to write json compliance report" )
}
reports = append ( reports , paths ... )
2023-04-28 15:47:05 +02:00
2023-07-11 18:32:54 +02:00
if config . CheckForCompliance {
2023-07-19 15:46:05 +02:00
for _ , scanResult := range scanResults {
2024-01-25 07:35:29 +02:00
if scanResult . ClassificationName == codeql . AuditAll {
unaudited := scanResult . Total - scanResult . Audited
if unaudited > config . VulnerabilityThresholdTotal {
msg := fmt . Sprintf ( "Your repository %v with ref %v is not compliant. Total unaudited issues are %v which is greater than the VulnerabilityThresholdTotal count %v" , repoUrl , repoInfo . Ref , unaudited , config . VulnerabilityThresholdTotal )
return reports , errors . Errorf ( msg )
}
2023-07-19 15:46:05 +02:00
}
2023-04-28 15:47:05 +02:00
}
}
2022-06-24 09:04:24 +02:00
}
2024-01-17 10:38:16 +02:00
addDataToInfluxDB ( repoUrl , repoReference , repoCodeqlScanUrl , config . QuerySuite , scanResults , influx )
2023-11-20 15:21:04 +02:00
toolRecordFileName , err := codeql . CreateAndPersistToolRecord ( utils , repoInfo , repoReference , repoUrl , config . ModulePath )
2023-02-22 19:00:53 +02:00
if err != nil {
log . Entry ( ) . Warning ( "TR_CODEQL: Failed to create toolrecord file ..." , err )
} else {
reports = append ( reports , piperutils . Path { Target : toolRecordFileName } )
}
2023-04-28 15:47:05 +02:00
return reports , nil
2022-06-24 09:04:24 +02:00
}
2023-02-22 19:00:53 +02:00
2024-04-02 06:48:17 +02:00
func prepareCmdForDatabaseCreate ( customFlags map [ string ] string , config * codeqlExecuteScanOptions , utils codeqlExecuteScanUtils ) ( [ ] string , error ) {
cmd := [ ] string { "database" , "create" , config . Database }
cmd = codeql . AppendFlagIfNotSetByUser ( cmd , [ ] string { "--overwrite" , "--no-overwrite" } , [ ] string { "--overwrite" } , customFlags )
cmd = codeql . AppendFlagIfNotSetByUser ( cmd , [ ] string { "--source-root" , "-s" } , [ ] string { "--source-root" , "." } , customFlags )
cmd = codeql . AppendFlagIfNotSetByUser ( cmd , [ ] string { "--working-dir" } , [ ] string { "--working-dir" , config . ModulePath } , customFlags )
if ! codeql . IsFlagSetByUser ( customFlags , [ ] string { "--language" , "-l" } ) {
language := getLangFromBuildTool ( config . BuildTool )
if len ( language ) == 0 && len ( config . Language ) == 0 {
if config . BuildTool == "custom" {
return nil , fmt . Errorf ( "as the buildTool is custom. please specify the language parameter" )
} else {
return nil , fmt . Errorf ( "the step could not recognize the specified buildTool %s. please specify valid buildtool" , config . BuildTool )
}
}
if len ( language ) > 0 {
cmd = append ( cmd , "--language=" + language )
} else {
cmd = append ( cmd , "--language=" + config . Language )
}
}
cmd = codeql . AppendThreadsAndRam ( cmd , config . Threads , config . Ram , customFlags )
if len ( config . BuildCommand ) > 0 && ! codeql . IsFlagSetByUser ( customFlags , [ ] string { "--command" , "-c" } ) {
buildCmd := config . BuildCommand
buildCmd = buildCmd + getMavenSettings ( buildCmd , config , utils )
cmd = append ( cmd , "--command=" + buildCmd )
}
if codeql . IsFlagSetByUser ( customFlags , [ ] string { "--command" , "-c" } ) {
updateCmdFlag ( config , customFlags , utils )
}
cmd = codeql . AppendCustomFlags ( cmd , customFlags )
return cmd , nil
}
func prepareCmdForDatabaseAnalyze ( customFlags map [ string ] string , config * codeqlExecuteScanOptions , format , reportName string ) ( [ ] string , error ) {
cmd := [ ] string { "database" , "analyze" , "--format=" + format , fmt . Sprintf ( "--output=%v" , filepath . Join ( config . ModulePath , "target" , reportName ) ) , config . Database }
cmd = codeql . AppendThreadsAndRam ( cmd , config . Threads , config . Ram , customFlags )
cmd = codeql . AppendCustomFlags ( cmd , customFlags )
cmd = appendCodeqlQuery ( cmd , config . QuerySuite )
return cmd , nil
}
func prepareCmdForUploadResults ( config * codeqlExecuteScanOptions , repoInfo * codeql . RepoInfo , token string ) [ ] string {
cmd := [ ] string { "github" , "upload-results" , "--sarif=" + filepath . Join ( config . ModulePath , "target" , "codeqlReport.sarif" ) }
//if no git params are passed(commitId, reference, serverUrl, repository), then codeql tries to auto populate it based on git information of the checkout repository.
//It also depends on the orchestrator. Some orchestrator keep git information and some not.
if token != "" {
cmd = append ( cmd , "-a=" + token )
}
if repoInfo . CommitId != "" {
cmd = append ( cmd , "--commit=" + repoInfo . CommitId )
}
if repoInfo . ServerUrl != "" {
cmd = append ( cmd , "--github-url=" + repoInfo . ServerUrl )
}
if repoInfo . Repo != "" && repoInfo . Owner != "" {
cmd = append ( cmd , "--repository=" + ( repoInfo . Owner + "/" + repoInfo . Repo ) )
}
if repoInfo . Ref != "" {
cmd = append ( cmd , "--ref=" + repoInfo . Ref )
}
return cmd
}
2024-01-17 10:38:16 +02:00
func addDataToInfluxDB ( repoUrl , repoRef , repoScanUrl , querySuite string , scanResults [ ] codeql . CodeqlFindings , influx * codeqlExecuteScanInflux ) {
influx . codeql_data . fields . repositoryURL = repoUrl
influx . codeql_data . fields . repositoryReferenceURL = repoRef
influx . codeql_data . fields . codeScanningLink = repoScanUrl
influx . codeql_data . fields . querySuite = querySuite
for _ , sr := range scanResults {
if sr . ClassificationName == codeql . AuditAll {
influx . codeql_data . fields . auditAllAudited = sr . Audited
influx . codeql_data . fields . auditAllTotal = sr . Total
}
if sr . ClassificationName == codeql . Optional {
influx . codeql_data . fields . optionalAudited = sr . Audited
influx . codeql_data . fields . optionalTotal = sr . Total
}
}
}
2024-04-02 06:48:17 +02:00
func getMavenSettings ( buildCmd string , config * codeqlExecuteScanOptions , utils codeqlExecuteScanUtils ) string {
2023-12-04 12:02:12 +02:00
params := ""
2024-04-02 06:48:17 +02:00
if len ( buildCmd ) > 0 && config . BuildTool == "maven" && ! strings . Contains ( buildCmd , "--global-settings" ) && ! strings . Contains ( buildCmd , "--settings" ) {
2023-12-13 10:55:07 +02:00
mvnParams , err := maven . DownloadAndGetMavenParameters ( config . GlobalSettingsFile , config . ProjectSettingsFile , utils )
if err != nil {
log . Entry ( ) . Error ( "failed to download and get maven parameters: " , err )
return params
2023-12-04 12:02:12 +02:00
}
2023-12-13 10:55:07 +02:00
for i := 1 ; i < len ( mvnParams ) ; i += 2 {
params = fmt . Sprintf ( "%s %s=%s" , params , mvnParams [ i - 1 ] , mvnParams [ i ] )
2023-12-04 12:02:12 +02:00
}
}
return params
}
2024-04-02 06:48:17 +02:00
func updateCmdFlag ( config * codeqlExecuteScanOptions , customFlags map [ string ] string , utils codeqlExecuteScanUtils ) {
var buildCmd string
if customFlags [ "--command" ] != "" {
buildCmd = customFlags [ "--command" ]
} else {
buildCmd = customFlags [ "-c" ]
}
buildCmd += getMavenSettings ( buildCmd , config , utils )
customFlags [ "--command" ] = buildCmd
delete ( customFlags , "-c" )
}