aboutsummaryrefslogtreecommitdiff
path: root/dbstore
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2022-02-19 22:54:09 -0500
committerPaul Duncan <pabs@pablotron.org>2022-02-19 22:54:09 -0500
commitc1a3a44dc43d9cbfe074cb5d8fd09e36112f67a0 (patch)
treef1cef914d51b85f0f7f99bb332eacca505088cd8 /dbstore
parenta84fa75165f0ec80a3bf604939ca55f9076c1282 (diff)
downloadcvez-c1a3a44dc43d9cbfe074cb5d8fd09e36112f67a0.tar.bz2
cvez-c1a3a44dc43d9cbfe074cb5d8fd09e36112f67a0.zip
dbstore: add CveSearch() and test (but not test data)
Diffstat (limited to 'dbstore')
-rw-r--r--dbstore/dbstore.go49
-rw-r--r--dbstore/dbstore_test.go28
2 files changed, 76 insertions, 1 deletions
diff --git a/dbstore/dbstore.go b/dbstore/dbstore.go
index 98f3b61..d1e44ba 100644
--- a/dbstore/dbstore.go
+++ b/dbstore/dbstore.go
@@ -4,6 +4,7 @@ package dbstore
import (
"context"
db_sql "database/sql"
+ "encoding/json"
"fmt"
_ "github.com/mattn/go-sqlite3"
"github.com/pablotron/cvez/cpedict"
@@ -157,6 +158,23 @@ func (me DbStore) Query(
return nil
}
+// Execute query and invoke callback with each row of result.
+func (me DbStore) QueryRow(
+ ctx context.Context,
+ queryId string,
+ args []interface{},
+ fn func (*db_sql.Row) error,
+) error {
+ // get query
+ sql, err := getQuery(queryId)
+ if err != nil {
+ return err
+ }
+
+ // exec query, invoke callback, return result
+ return fn(me.db.QueryRowContext(ctx, sql, args...))
+}
+
// import CPE dictionary
func (me DbStore) AddCpeDictionary(ctx context.Context, dict cpedict.Dictionary) error {
// lazy-init db
@@ -685,7 +703,7 @@ var addCveFeedQueryIds = []string {
"feed/insert-item-cvss-v3",
}
-// Add CVE feed.
+// Import CVE feed.
func (me DbStore) AddCveFeed(ctx context.Context, feed nvd_feed.Feed) (int64, error) {
// feed ID
var feedId int64
@@ -709,3 +727,32 @@ func (me DbStore) AddCveFeed(ctx context.Context, feed nvd_feed.Feed) (int64, er
// return result
return feedId, err
}
+
+// search CVEs
+func (me DbStore) CveSearch(
+ ctx context.Context,
+ s string,
+) ([]CveSearchRow, error) {
+ var r []CveSearchRow
+
+ // lazy-init db
+ if err := me.Init(ctx); err != nil {
+ return r, err
+ }
+
+ // get/exec search query
+ err := me.QueryRow(ctx, "feed/search", []interface{} {
+ db_sql.Named("q", s),
+ }, func(row *db_sql.Row) error {
+ var s string
+ if err := row.Scan(&s); err != nil {
+ return err
+ }
+
+ return json.Unmarshal([]byte(s), &r)
+ })
+
+ // return results
+ return r, err
+}
+
diff --git a/dbstore/dbstore_test.go b/dbstore/dbstore_test.go
index ea5d284..2dcadfa 100644
--- a/dbstore/dbstore_test.go
+++ b/dbstore/dbstore_test.go
@@ -1005,3 +1005,31 @@ func TestAddCveFeed(t *testing.T) {
})
}
}
+
+func TestCveSearch(t *testing.T) {
+ ctx := context.Background()
+
+ tests := []string {
+ "cisco anyconnect ipc dll mobility secure",
+ }
+// [{"nvd_cve_id":"CVE-2021-1366","rank":-36.4874758136269,"description":"A vulnerability in the interprocess communication (IPC) channel of Cisco AnyConnect Secure Mobility Client for Windows could allow an authenticated, local attacker to perform a DLL hijacking attack on an affected device if the VPN Posture (HostScan) Module is installed on the AnyConnect client. This vulnerability is due to insufficient validation of resources that are loaded by the application at run time. An attacker could exploit this vulnerability by sending a crafted IPC message to the AnyConnect process. A successful exploit could allow the attacker to execute arbitrary code on the affected machine with SYSTEM privileges. To exploit this vulnerability, the attacker needs valid credentials on the Windows system."},{"nvd_cve_id":"CVE-2021-1567","rank":-34.6220092956805,"description":"A vulnerability in the DLL loading mechanism of Cisco AnyConnect Secure Mobility Client for Windows could allow an authenticated, local attacker to perform a DLL hijacking attack on an affected device if the VPN Posture (HostScan) Module is installed on the AnyConnect client. This vulnerability is due to a race condition in the signature verification process for DLL files that are loaded on an affected device. An attacker could exploit this vulnerability by sending a series of crafted interprocess communication (IPC) messages to the AnyConnect process. A successful exploit could allow the attacker to execute arbitrary code on the affected device with SYSTEM privileges. To exploit this vulnerability, the attacker must have valid credentials on the Windows system."}]
+
+ // open test db
+ db, err := Open("testdata/cvesearch-test.db")
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ // run tests
+ for _, test := range(tests) {
+ t.Run(test, func(t *testing.T) {
+ rows, err := db.CveSearch(ctx, test)
+ if err != nil {
+ t.Error(err)
+ } else {
+ t.Errorf("success: got %v", rows)
+ }
+ })
+ }
+}