diff options
author | Pierre Le Magourou <pierre.lemagourou@softbankrobotics.com> | 2019-07-05 11:40:36 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2019-07-09 23:30:44 +0100 |
commit | 8f81d2e863283557e360a0cb4cdcb70a94ce0a8c (patch) | |
tree | f1a6b8605e30ac0d5169156f35eb77d8ed0b2a3e /meta/recipes-core/meta/cve-update-db-native.bb | |
parent | 4a68a44f56c725914cfa721993a2ea8a3dc6ebd5 (diff) | |
download | poky-8f81d2e863283557e360a0cb4cdcb70a94ce0a8c.tar.gz |
cve-check: Depends on cve-update-db-native
do_populate_cve_db is a native task.
(From OE-Core rev: 4078da92b49946848cddebe1735f301af161e162)
Signed-off-by: Pierre Le Magourou <pierre.lemagourou@softbankrobotics.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-core/meta/cve-update-db-native.bb')
-rw-r--r-- | meta/recipes-core/meta/cve-update-db-native.bb | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/meta/recipes-core/meta/cve-update-db-native.bb b/meta/recipes-core/meta/cve-update-db-native.bb new file mode 100644 index 0000000000..ae8f1a958b --- /dev/null +++ b/meta/recipes-core/meta/cve-update-db-native.bb | |||
@@ -0,0 +1,143 @@ | |||
1 | SUMMARY = "Updates the NVD CVE database" | ||
2 | LICENSE = "MIT" | ||
3 | |||
4 | INHIBIT_DEFAULT_DEPS = "1" | ||
5 | PACKAGES = "" | ||
6 | |||
7 | inherit nopackages | ||
8 | |||
9 | deltask do_unpack | ||
10 | deltask do_patch | ||
11 | deltask do_configure | ||
12 | deltask do_compile | ||
13 | deltask do_install | ||
14 | deltask do_populate_sysroot | ||
15 | |||
16 | python do_populate_cve_db() { | ||
17 | """ | ||
18 | Update NVD database with json data feed | ||
19 | """ | ||
20 | |||
21 | import sqlite3, urllib, shutil, gzip, re | ||
22 | from datetime import date | ||
23 | |||
24 | BASE_URL = "https://nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-" | ||
25 | YEAR_START = 2002 | ||
26 | |||
27 | db_dir = d.getVar("DL_DIR") + '/CVE_CHECK' | ||
28 | db_file = db_dir + '/nvd-json.db' | ||
29 | json_tmpfile = db_dir + '/nvd.json.gz' | ||
30 | proxy = d.getVar("https_proxy") | ||
31 | cve_f = open(d.getVar("TMPDIR") + '/cve_check', 'a') | ||
32 | |||
33 | if not os.path.isdir(db_dir): | ||
34 | os.mkdir(db_dir) | ||
35 | |||
36 | # Connect to database | ||
37 | conn = sqlite3.connect(db_file) | ||
38 | c = conn.cursor() | ||
39 | |||
40 | initialize_db(c) | ||
41 | |||
42 | for year in range(YEAR_START, date.today().year + 1): | ||
43 | year_url = BASE_URL + str(year) | ||
44 | meta_url = year_url + ".meta" | ||
45 | json_url = year_url + ".json.gz" | ||
46 | |||
47 | # Retrieve meta last modified date | ||
48 | req = urllib.request.Request(meta_url) | ||
49 | if proxy: | ||
50 | req.set_proxy(proxy, 'https') | ||
51 | try: | ||
52 | with urllib.request.urlopen(req, timeout=1) as r: | ||
53 | date_line = str(r.read().splitlines()[0]) | ||
54 | last_modified = re.search('lastModifiedDate:(.*)', date_line).group(1) | ||
55 | except: | ||
56 | cve_f.write('Warning: CVE db update error, CVE data is outdated.\n\n') | ||
57 | break | ||
58 | |||
59 | # Compare with current db last modified date | ||
60 | c.execute("select DATE from META where YEAR = '%d'" % year) | ||
61 | meta = c.fetchone() | ||
62 | if not meta or meta[0] != last_modified: | ||
63 | # Update db with current year json file | ||
64 | req = urllib.request.Request(json_url) | ||
65 | if proxy: | ||
66 | req.set_proxy(proxy, 'https') | ||
67 | try: | ||
68 | with urllib.request.urlopen(req, timeout=1) as r, \ | ||
69 | open(json_tmpfile, 'wb') as tmpfile: | ||
70 | shutil.copyfileobj(r, tmpfile) | ||
71 | except: | ||
72 | cve_f.write('Warning: CVE db update error, CVE data is outdated.\n\n') | ||
73 | break | ||
74 | |||
75 | with gzip.open(json_tmpfile, 'rt') as jsonfile: | ||
76 | update_db(c, jsonfile) | ||
77 | c.execute("insert or replace into META values (?, ?)", | ||
78 | [year, last_modified]) | ||
79 | |||
80 | # Update success, set the date to cve_check file. | ||
81 | if year == date.today().year: | ||
82 | cve_f.write('CVE database update : %s\n\n' % date.today()) | ||
83 | |||
84 | cve_f.close() | ||
85 | conn.commit() | ||
86 | conn.close() | ||
87 | } | ||
88 | |||
89 | # DJB2 hash algorithm | ||
90 | def hash_djb2(s): | ||
91 | hash = 5381 | ||
92 | for x in s: | ||
93 | hash = (( hash << 5) + hash) + ord(x) | ||
94 | |||
95 | return hash & 0xFFFFFFFF | ||
96 | |||
97 | def initialize_db(c): | ||
98 | c.execute("CREATE TABLE IF NOT EXISTS META (YEAR INTEGER UNIQUE, DATE TEXT)") | ||
99 | c.execute("CREATE TABLE IF NOT EXISTS NVD (ID TEXT UNIQUE, SUMMARY TEXT, \ | ||
100 | SCOREV2 TEXT, SCOREV3 TEXT, MODIFIED INTEGER, VECTOR TEXT)") | ||
101 | c.execute("CREATE TABLE IF NOT EXISTS PRODUCTS (HASH INTEGER UNIQUE, ID TEXT, \ | ||
102 | VENDOR TEXT, PRODUCT TEXT, VERSION TEXT, OPERATOR TEXT)") | ||
103 | c.execute("CREATE INDEX IF NOT EXISTS PRODUCT_IDX ON PRODUCTS \ | ||
104 | (PRODUCT, VERSION)") | ||
105 | |||
106 | def update_db(c, json_filename): | ||
107 | import json | ||
108 | root = json.load(json_filename) | ||
109 | |||
110 | for elt in root['CVE_Items']: | ||
111 | if not elt['impact']: | ||
112 | continue | ||
113 | |||
114 | cveId = elt['cve']['CVE_data_meta']['ID'] | ||
115 | cveDesc = elt['cve']['description']['description_data'][0]['value'] | ||
116 | date = elt['lastModifiedDate'] | ||
117 | accessVector = elt['impact']['baseMetricV2']['cvssV2']['accessVector'] | ||
118 | cvssv2 = elt['impact']['baseMetricV2']['cvssV2']['baseScore'] | ||
119 | |||
120 | try: | ||
121 | cvssv3 = elt['impact']['baseMetricV3']['cvssV3']['baseScore'] | ||
122 | except: | ||
123 | cvssv3 = 0.0 | ||
124 | |||
125 | c.execute("insert or replace into NVD values (?, ?, ?, ?, ?, ?)", | ||
126 | [cveId, cveDesc, cvssv2, cvssv3, date, accessVector]) | ||
127 | |||
128 | for vendor in elt['cve']['affects']['vendor']['vendor_data']: | ||
129 | for product in vendor['product']['product_data']: | ||
130 | for version in product['version']['version_data']: | ||
131 | product_str = cveId+vendor['vendor_name']+product['product_name']+version['version_value'] | ||
132 | hashstr = hash_djb2(product_str) | ||
133 | c.execute("insert or replace into PRODUCTS values (?, ?, ?, ?, ?, ?)", | ||
134 | [ hashstr, cveId, vendor['vendor_name'], | ||
135 | product['product_name'], version['version_value'], | ||
136 | version['version_affected']]) | ||
137 | |||
138 | |||
139 | |||
140 | addtask do_populate_cve_db before do_fetch | ||
141 | do_populate_cve_db[nostamp] = "1" | ||
142 | |||
143 | EXCLUDE_FROM_WORLD = "1" | ||