commit: eed0fdb7e16ff4d2b475f7803a6888c8a3c0d7da Author: John Helmert III <ajak <AT> gentoo <DOT> org> AuthorDate: Sun Jul 4 04:41:53 2021 +0000 Commit: John Helmert III <ajak <AT> gentoo <DOT> org> CommitDate: Sun Jul 4 04:41:53 2021 +0000 URL: https://gitweb.gentoo.org/proj/security.git/commit/?id=eed0fdb7
cvetool: implement dobug command This command grabs bug data from Bugzilla and adds the CVEs in its alias field to the GLSAMaker CVE database and assigns the CVEs to that bug in GLSAMaker. Signed-off-by: John Helmert III <ajak <AT> gentoo.org> bin/cvetool | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/bin/cvetool b/bin/cvetool index dc9c35d..233375a 100755 --- a/bin/cvetool +++ b/bin/cvetool @@ -9,7 +9,8 @@ from urllib.parse import urlencode from base64 import b64encode import requests -URI_BASE = 'https://glsamaker.gentoo.org' +GLSAMAKER_URI = 'https://glsamaker.gentoo.org' +BGO_URI = 'https://bugs.gentoo.org' class CVETool: @@ -78,6 +79,13 @@ class CVETool: sys.exit(1) self.pw(sys.argv[2], sys.argv[3]) + elif command == 'dobug': + if len(sys.argv) != 3: + print('Usage: dobug <bug>') + print('Adds and assigns a bug\'s CVEs') + sys.exit(1) + + self.dobug(sys.argv[2]) else: self.usage(sys.argv[0]) sys.exit(1) @@ -162,6 +170,36 @@ class CVETool: def pw(self, user, password): print(b64encode(bytes(user + ':' + password, 'utf-8')).decode('ascii')) + def dobug(self, bug): + cves = [] + data = self.request('/rest/bug/' + bug, jsondata=True, bgo=True) + for alias in data['bugs'][0]['alias']: + # If we were able to catch a sane error in new() to + # reflect a duplicate CVE we wouldn't have to check if the + # CVE exists beforehand with cve_exists, but it seems the + # only other way is to try to do two requests and check if + # one fails and the other succeeds (as new() currently + # works). By doing it this way though, we actually reduce + # the number of requests by not making useless requests in + # new(). + if self.is_cve(alias) and not self.cve_exists(alias): + self.new(alias) + cves.append(alias) + # We can do assignment in one request, so do it + if cves: + self.assign(bug, cves) + + def cve_exists(self, cve): + try: + return self.request('/cve/info/' + cve, method='HEAD') == '' + except RuntimeError: + return False + + @staticmethod + def is_cve(string): + regex = re.compile('^(CVE-)?\d{4}-\d{4,}$') + return regex.match(string) + def get_internal_cve_id(self, cve): """ Resolves a CVE id to the internal databse ID """ return self.json_request('/cve/info/' + cve + '.json')['id'] @@ -170,8 +208,7 @@ class CVETool: return self.request(uri, method, jsondata=True) def cleanup_cve(self, string): - regex = re.compile('^(CVE-)?\d{4}-\d{4,}$') - if not regex.match(string): + if not self.is_cve(string): raise ValueError('Cannot parse CVE: ' + string) if not string.startswith('CVE-'): @@ -179,8 +216,12 @@ class CVETool: else: return string - def request(self, uri, method='GET', jsondata=False): - full_uri = URI_BASE + uri + def request(self, uri, method='GET', jsondata=False, bgo=False): + if bgo: + full_uri = BGO_URI + uri + else: + full_uri = GLSAMAKER_URI + uri + if method == 'GET': response = \ requests.get(full_uri, @@ -189,6 +230,10 @@ class CVETool: response = \ requests.post(full_uri, headers={'Authorization': 'Basic ' + self.auth}) + elif method == 'HEAD': + response = \ + requests.head(full_uri, + headers={'Authorization': 'Basic ' + self.auth}) status = response.status_code if status == 404:
