Gentoo Archives: gentoo-commits

From: John Helmert III <ajak@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/security:ajak-cvetool commit in: bin/
Date: Sun, 04 Jul 2021 04:43:24
Message-Id: 1625373713.eed0fdb7e16ff4d2b475f7803a6888c8a3c0d7da.ajak@gentoo
1 commit: eed0fdb7e16ff4d2b475f7803a6888c8a3c0d7da
2 Author: John Helmert III <ajak <AT> gentoo <DOT> org>
3 AuthorDate: Sun Jul 4 04:41:53 2021 +0000
4 Commit: John Helmert III <ajak <AT> gentoo <DOT> org>
5 CommitDate: Sun Jul 4 04:41:53 2021 +0000
6 URL: https://gitweb.gentoo.org/proj/security.git/commit/?id=eed0fdb7
7
8 cvetool: implement dobug command
9
10 This command grabs bug data from Bugzilla and adds the CVEs in its alias
11 field to the GLSAMaker CVE database and assigns the CVEs to that bug in
12 GLSAMaker.
13
14 Signed-off-by: John Helmert III <ajak <AT> gentoo.org>
15
16 bin/cvetool | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
17 1 file changed, 50 insertions(+), 5 deletions(-)
18
19 diff --git a/bin/cvetool b/bin/cvetool
20 index dc9c35d..233375a 100755
21 --- a/bin/cvetool
22 +++ b/bin/cvetool
23 @@ -9,7 +9,8 @@ from urllib.parse import urlencode
24 from base64 import b64encode
25 import requests
26
27 -URI_BASE = 'https://glsamaker.gentoo.org'
28 +GLSAMAKER_URI = 'https://glsamaker.gentoo.org'
29 +BGO_URI = 'https://bugs.gentoo.org'
30
31
32 class CVETool:
33 @@ -78,6 +79,13 @@ class CVETool:
34 sys.exit(1)
35
36 self.pw(sys.argv[2], sys.argv[3])
37 + elif command == 'dobug':
38 + if len(sys.argv) != 3:
39 + print('Usage: dobug <bug>')
40 + print('Adds and assigns a bug\'s CVEs')
41 + sys.exit(1)
42 +
43 + self.dobug(sys.argv[2])
44 else:
45 self.usage(sys.argv[0])
46 sys.exit(1)
47 @@ -162,6 +170,36 @@ class CVETool:
48 def pw(self, user, password):
49 print(b64encode(bytes(user + ':' + password, 'utf-8')).decode('ascii'))
50
51 + def dobug(self, bug):
52 + cves = []
53 + data = self.request('/rest/bug/' + bug, jsondata=True, bgo=True)
54 + for alias in data['bugs'][0]['alias']:
55 + # If we were able to catch a sane error in new() to
56 + # reflect a duplicate CVE we wouldn't have to check if the
57 + # CVE exists beforehand with cve_exists, but it seems the
58 + # only other way is to try to do two requests and check if
59 + # one fails and the other succeeds (as new() currently
60 + # works). By doing it this way though, we actually reduce
61 + # the number of requests by not making useless requests in
62 + # new().
63 + if self.is_cve(alias) and not self.cve_exists(alias):
64 + self.new(alias)
65 + cves.append(alias)
66 + # We can do assignment in one request, so do it
67 + if cves:
68 + self.assign(bug, cves)
69 +
70 + def cve_exists(self, cve):
71 + try:
72 + return self.request('/cve/info/' + cve, method='HEAD') == ''
73 + except RuntimeError:
74 + return False
75 +
76 + @staticmethod
77 + def is_cve(string):
78 + regex = re.compile('^(CVE-)?\d{4}-\d{4,}$')
79 + return regex.match(string)
80 +
81 def get_internal_cve_id(self, cve):
82 """ Resolves a CVE id to the internal databse ID """
83 return self.json_request('/cve/info/' + cve + '.json')['id']
84 @@ -170,8 +208,7 @@ class CVETool:
85 return self.request(uri, method, jsondata=True)
86
87 def cleanup_cve(self, string):
88 - regex = re.compile('^(CVE-)?\d{4}-\d{4,}$')
89 - if not regex.match(string):
90 + if not self.is_cve(string):
91 raise ValueError('Cannot parse CVE: ' + string)
92
93 if not string.startswith('CVE-'):
94 @@ -179,8 +216,12 @@ class CVETool:
95 else:
96 return string
97
98 - def request(self, uri, method='GET', jsondata=False):
99 - full_uri = URI_BASE + uri
100 + def request(self, uri, method='GET', jsondata=False, bgo=False):
101 + if bgo:
102 + full_uri = BGO_URI + uri
103 + else:
104 + full_uri = GLSAMAKER_URI + uri
105 +
106 if method == 'GET':
107 response = \
108 requests.get(full_uri,
109 @@ -189,6 +230,10 @@ class CVETool:
110 response = \
111 requests.post(full_uri,
112 headers={'Authorization': 'Basic ' + self.auth})
113 + elif method == 'HEAD':
114 + response = \
115 + requests.head(full_uri,
116 + headers={'Authorization': 'Basic ' + self.auth})
117
118 status = response.status_code
119 if status == 404: