From d4367de2e27bfea8989ed7039ca239f2d86efafd Mon Sep 17 00:00:00 2001
From: Tim Kelsey <tim.kelsey@hpe.com>
Date: Fri, 29 Jul 2016 11:19:50 +0100
Subject: [PATCH] Adding a config block to the analyzer, parsed from JSON

A CLI option can now be given to tell GAS it should parse data
from a JSON file. Fatal errors are given if the file is not
readable or is not valid JSON.
---
 core/analyzer.go                    | 20 ++++++++++++++++++--
 main.go                             |  4 +++-
 rules/bind_test.go                  |  7 ++++---
 rules/errors_test.go                |  6 +++---
 rules/fileperms_test.go             |  7 ++++---
 rules/hardcoded_credentials_test.go |  5 +++--
 rules/httpoxy_test.go               |  2 +-
 rules/nosec_test.go                 |  4 ++--
 rules/rand_test.go                  |  4 ++--
 rules/rsa_test.go                   |  5 +++--
 rules/sql_test.go                   | 12 ++++++------
 rules/subproc_test.go               |  9 +++++----
 rules/tempfiles_test.go             |  5 +++--
 rules/templates_test.go             | 11 ++++++-----
 rules/tls_test.go                   |  8 ++++----
 rules/unsafe_test.go                |  5 +++--
 rules/weakcrypto_test.go            |  9 +++++----
 17 files changed, 75 insertions(+), 48 deletions(-)

diff --git a/core/analyzer.go b/core/analyzer.go
index e20bf1c..304e045 100644
--- a/core/analyzer.go
+++ b/core/analyzer.go
@@ -15,11 +15,13 @@
 package core
 
 import (
+	"encoding/json"
 	"go/ast"
 	"go/importer"
 	"go/parser"
 	"go/token"
 	"go/types"
+	"io/ioutil"
 	"log"
 	"os"
 	"reflect"
@@ -53,19 +55,33 @@ type Analyzer struct {
 	logger      *log.Logger
 	Issues      []Issue `json:"issues"`
 	Stats       Metrics `json:"metrics"`
+	Config      map[string]interface{}
 }
 
-func NewAnalyzer(ignoreNosec bool, logger *log.Logger) Analyzer {
+func NewAnalyzer(ignoreNosec bool, conf *string, logger *log.Logger) Analyzer {
 	if logger == nil {
 		logger = log.New(os.Stdout, "[gas]", 0)
 	}
-	return Analyzer{
+	a := Analyzer{
 		ignoreNosec: ignoreNosec,
 		ruleset:     make(RuleSet),
 		Issues:      make([]Issue, 0),
 		context:     Context{token.NewFileSet(), nil, nil, nil},
 		logger:      logger,
+		Config:      nil,
 	}
+
+	if conf != nil && *conf != "" { // if we have a config
+		if data, err := ioutil.ReadFile(*conf); err == nil {
+			if err := json.Unmarshal(data, &(a.Config)); err != nil {
+				logger.Fatal("Could not parse JSON config: ", *conf, ": ", err)
+			}
+		} else {
+			logger.Fatal("Could not read config file: ", *conf)
+		}
+	}
+
+	return a
 }
 
 func (gas *Analyzer) process(filename string, source interface{}) error {
diff --git a/main.go b/main.go
index e64bf90..97fd4c2 100644
--- a/main.go
+++ b/main.go
@@ -35,6 +35,8 @@ var flagFormat = flag.String("fmt", "text", "Set output format. Valid options ar
 // output file
 var flagOutput = flag.String("out", "", "Set output file for results")
 
+var flagConfig = flag.String("conf", "", "Path to optional config file")
+
 var usageText = `
 GAS - Go AST Scanner
 
@@ -99,7 +101,7 @@ func main() {
 	}
 
 	// Setup analyzer
-	analyzer := gas.NewAnalyzer(*flagIgnoreNoSec, logger)
+	analyzer := gas.NewAnalyzer(*flagIgnoreNoSec, flagConfig, logger)
 	if !rules.overwritten {
 		rules.useDefaults()
 	}
diff --git a/rules/bind_test.go b/rules/bind_test.go
index 13ca4ee..512e08f 100644
--- a/rules/bind_test.go
+++ b/rules/bind_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestBind0000(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewBindsToAllNetworkInterfaces())
 
 	issues := gasTestRunner(`
@@ -41,7 +42,7 @@ func TestBind0000(t *testing.T) {
 }
 
 func TestBindEmptyHost(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewBindsToAllNetworkInterfaces())
 
 	issues := gasTestRunner(`
diff --git a/rules/errors_test.go b/rules/errors_test.go
index f45161f..4689ed4 100644
--- a/rules/errors_test.go
+++ b/rules/errors_test.go
@@ -21,7 +21,7 @@ import (
 )
 
 func TestErrorsMulti(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewNoErrorCheck())
 
 	issues := gasTestRunner(
@@ -43,7 +43,7 @@ func TestErrorsMulti(t *testing.T) {
 }
 
 func TestErrorsSingle(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewNoErrorCheck())
 
 	issues := gasTestRunner(
@@ -65,7 +65,7 @@ func TestErrorsSingle(t *testing.T) {
 }
 
 func TestErrorsGood(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewNoErrorCheck())
 
 	issues := gasTestRunner(
diff --git a/rules/fileperms_test.go b/rules/fileperms_test.go
index e5e5016..9a5eaa5 100644
--- a/rules/fileperms_test.go
+++ b/rules/fileperms_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestChmod(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewChmodPerms())
 
 	issues := gasTestRunner(`
@@ -35,7 +36,7 @@ func TestChmod(t *testing.T) {
 }
 
 func TestMkdir(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewMkdirPerms())
 
 	issues := gasTestRunner(`
diff --git a/rules/hardcoded_credentials_test.go b/rules/hardcoded_credentials_test.go
index e59fe37..bbcf2be 100644
--- a/rules/hardcoded_credentials_test.go
+++ b/rules/hardcoded_credentials_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestHardcoded(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewHardcodedCredentials())
 
 	issues := gasTestRunner(
diff --git a/rules/httpoxy_test.go b/rules/httpoxy_test.go
index d85a5c1..0d42260 100644
--- a/rules/httpoxy_test.go
+++ b/rules/httpoxy_test.go
@@ -21,7 +21,7 @@ import (
 )
 
 func TestHttpoxy(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewHttpoxyTest())
 
 	issues := gasTestRunner(`
diff --git a/rules/nosec_test.go b/rules/nosec_test.go
index e6616a5..b7bbc10 100644
--- a/rules/nosec_test.go
+++ b/rules/nosec_test.go
@@ -21,7 +21,7 @@ import (
 )
 
 func TestNosec(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSubproc())
 
 	issues := gasTestRunner(
@@ -39,7 +39,7 @@ func TestNosec(t *testing.T) {
 }
 
 func TestNosecBlock(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSubproc())
 
 	issues := gasTestRunner(
diff --git a/rules/rand_test.go b/rules/rand_test.go
index a65a723..faab035 100644
--- a/rules/rand_test.go
+++ b/rules/rand_test.go
@@ -21,7 +21,7 @@ import (
 )
 
 func TestRandOk(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewWeakRandCheck())
 
 	issues := gasTestRunner(
@@ -38,7 +38,7 @@ func TestRandOk(t *testing.T) {
 }
 
 func TestRandBad(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewWeakRandCheck())
 
 	issues := gasTestRunner(
diff --git a/rules/rsa_test.go b/rules/rsa_test.go
index 64e804c..9ec2a51 100644
--- a/rules/rsa_test.go
+++ b/rules/rsa_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestRSAKeys(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewWeakKeyStrength())
 
 	issues := gasTestRunner(
diff --git a/rules/sql_test.go b/rules/sql_test.go
index 3dc6171..df8031c 100644
--- a/rules/sql_test.go
+++ b/rules/sql_test.go
@@ -21,7 +21,7 @@ import (
 )
 
 func TestSQLInjectionViaConcatenation(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSqlStrConcat())
 
 	source := `
@@ -48,7 +48,7 @@ func TestSQLInjectionViaConcatenation(t *testing.T) {
 }
 
 func TestSQLInjectionViaIntepolation(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSqlStrFormat())
 
 	source := `
@@ -77,7 +77,7 @@ func TestSQLInjectionViaIntepolation(t *testing.T) {
 }
 
 func TestSQLInjectionFalsePositiveA(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSqlStrConcat())
 	analyzer.AddRule(NewSqlStrFormat())
 
@@ -112,7 +112,7 @@ func TestSQLInjectionFalsePositiveA(t *testing.T) {
 }
 
 func TestSQLInjectionFalsePositiveB(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSqlStrConcat())
 	analyzer.AddRule(NewSqlStrFormat())
 
@@ -147,7 +147,7 @@ func TestSQLInjectionFalsePositiveB(t *testing.T) {
 }
 
 func TestSQLInjectionFalsePositiveC(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSqlStrConcat())
 	analyzer.AddRule(NewSqlStrFormat())
 
@@ -182,7 +182,7 @@ func TestSQLInjectionFalsePositiveC(t *testing.T) {
 }
 
 func TestSQLInjectionFalsePositiveD(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSqlStrConcat())
 	analyzer.AddRule(NewSqlStrFormat())
 
diff --git a/rules/subproc_test.go b/rules/subproc_test.go
index 6ea95d0..4f9528c 100644
--- a/rules/subproc_test.go
+++ b/rules/subproc_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestSubprocess(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSubproc())
 
 	issues := gasTestRunner(`
@@ -46,7 +47,7 @@ func TestSubprocess(t *testing.T) {
 }
 
 func TestSubprocessVar(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSubproc())
 
 	issues := gasTestRunner(`
@@ -73,7 +74,7 @@ func TestSubprocessVar(t *testing.T) {
 }
 
 func TestSubprocessPath(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewSubproc())
 
 	issues := gasTestRunner(`
diff --git a/rules/tempfiles_test.go b/rules/tempfiles_test.go
index 911e644..1a5fc68 100644
--- a/rules/tempfiles_test.go
+++ b/rules/tempfiles_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestTempfiles(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewBadTempFile())
 
 	source := `
diff --git a/rules/templates_test.go b/rules/templates_test.go
index c969182..e1f84ed 100644
--- a/rules/templates_test.go
+++ b/rules/templates_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestTemplateCheckSafe(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewTemplateCheck())
 
 	source := `
@@ -47,7 +48,7 @@ func TestTemplateCheckSafe(t *testing.T) {
 }
 
 func TestTemplateCheckBadHTML(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewTemplateCheck())
 
 	source := `
@@ -75,7 +76,7 @@ func TestTemplateCheckBadHTML(t *testing.T) {
 }
 
 func TestTemplateCheckBadJS(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewTemplateCheck())
 
 	source := `
@@ -103,7 +104,7 @@ func TestTemplateCheckBadJS(t *testing.T) {
 }
 
 func TestTemplateCheckBadURL(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewTemplateCheck())
 
 	source := `
diff --git a/rules/tls_test.go b/rules/tls_test.go
index 0c103b0..6ead5d2 100644
--- a/rules/tls_test.go
+++ b/rules/tls_test.go
@@ -21,7 +21,7 @@ import (
 )
 
 func TestInsecureSkipVerify(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewModernTlsCheck())
 
 	issues := gasTestRunner(`
@@ -49,7 +49,7 @@ func TestInsecureSkipVerify(t *testing.T) {
 }
 
 func TestInsecureMinVersion(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewModernTlsCheck())
 
 	issues := gasTestRunner(`
@@ -77,7 +77,7 @@ func TestInsecureMinVersion(t *testing.T) {
 }
 
 func TestInsecureMaxVersion(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewModernTlsCheck())
 
 	issues := gasTestRunner(`
@@ -105,7 +105,7 @@ func TestInsecureMaxVersion(t *testing.T) {
 }
 
 func TestInsecureCipherSuite(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewModernTlsCheck())
 
 	issues := gasTestRunner(`
diff --git a/rules/unsafe_test.go b/rules/unsafe_test.go
index 326a430..2a35649 100644
--- a/rules/unsafe_test.go
+++ b/rules/unsafe_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestUnsafe(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewUsingUnsafe())
 
 	issues := gasTestRunner(`
diff --git a/rules/weakcrypto_test.go b/rules/weakcrypto_test.go
index 774d51b..388aebd 100644
--- a/rules/weakcrypto_test.go
+++ b/rules/weakcrypto_test.go
@@ -15,12 +15,13 @@
 package rules
 
 import (
-	gas "github.com/HewlettPackard/gas/core"
 	"testing"
+
+	gas "github.com/HewlettPackard/gas/core"
 )
 
 func TestMD5(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewImportsWeakCryptography())
 	analyzer.AddRule(NewUsesWeakCryptography())
 
@@ -41,7 +42,7 @@ func TestMD5(t *testing.T) {
 }
 
 func TestDES(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewImportsWeakCryptography())
 	analyzer.AddRule(NewUsesWeakCryptography())
 
@@ -80,7 +81,7 @@ func TestDES(t *testing.T) {
 }
 
 func TestRC4(t *testing.T) {
-	analyzer := gas.NewAnalyzer(false, nil)
+	analyzer := gas.NewAnalyzer(false, nil, nil)
 	analyzer.AddRule(NewImportsWeakCryptography())
 	analyzer.AddRule(NewUsesWeakCryptography())