[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-23 Thread John Helmert III
commit: b3cdddf783f0f31bc2b44e85edec6abade128fe3
Author: John Helmert III  gentoo  org>
AuthorDate: Sat Jul 24 03:18:26 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Sat Jul 24 03:18:26 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=b3cdddf7

glsatool: avoid trying to publish GLSAs with TODOs

Signed-off-by: John Helmert III  gentoo.org>

 bin/GLSATool.py | 4 
 1 file changed, 4 insertions(+)

diff --git a/bin/GLSATool.py b/bin/GLSATool.py
index a2a1b1b..9aa21b9 100644
--- a/bin/GLSATool.py
+++ b/bin/GLSATool.py
@@ -85,6 +85,10 @@ class GLSATool:
features='lxml')
 glsa_id = 'glsa-' + released_soup.find('strong').text.split()[1]
 
+# If there are red flags glsa_id will end up being 'for', so
+# bail out on the releasing process just like GLSAMaker would
+assert 'for' not in glsa_id
+
 # Grab the xml
 xml = self.request(xml_path)
 xml_filename = '{}.xml'.format(glsa_id)



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-23 Thread John Helmert III
commit: cd40de0310372a545d7190f716de184e5882be41
Author: John Helmert III  gentoo  org>
AuthorDate: Sat Jul 24 03:19:04 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Sat Jul 24 03:19:04 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=cd40de03

glsatool: implement closing bugs when releasing

Signed-off-by: John Helmert III  gentoo.org>

 bin/GLSATool.py | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/bin/GLSATool.py b/bin/GLSATool.py
index 9aa21b9..7f3a9b2 100644
--- a/bin/GLSATool.py
+++ b/bin/GLSATool.py
@@ -74,6 +74,7 @@ class GLSATool:
 release_path = '/glsas/{}/release'.format(num)
 xml_path = '/glsas/{}/download.xml'.format(num)
 txt_path = '/glsas/{}/download.txt'.format(num)
+finalize_path = '/glsas/{}/finalize_release'.format(num)
 
 data = {
 'value': 'Release ',
@@ -110,9 +111,11 @@ class GLSATool:
 f.write(txt)
 print("Wrote {}".format(txt_filename))
 
-# TODO:
-# Mail it
 # Close bugs
+self.request(finalize_path, 'POST', data={'close_bugs': 1})
+
+# TODO: Mail it
+
 
 def new_whiteboard(self, old_whiteboard):
 regex = re.compile('[A-C~][0-4] \[.*\]')



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-18 Thread John Helmert III
commit: f1634540fe60edd3cbcff258b04d3b4e3aa31577
Author: John Helmert III  gentoo  org>
AuthorDate: Mon Jul 19 02:49:49 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Mon Jul 19 02:54:53 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=f1634540

glsatool: add partial releasing functionality

This separates the previous functionality into a `glsatool new` and adds
some new functionality as `glsatool release`. Currently only fetches the
GLSA XML and text, places the XML in your glsa.git repository, and adds
the necessary headers to the mail text.

Signed-off-by: John Helmert III  gentoo.org>

 bin/GLSATool.py | 99 +++--
 1 file changed, 90 insertions(+), 9 deletions(-)

diff --git a/bin/GLSATool.py b/bin/GLSATool.py
index c7fc804..a2a1b1b 100644
--- a/bin/GLSATool.py
+++ b/bin/GLSATool.py
@@ -2,6 +2,7 @@ from configparser import ConfigParser
 import argparse
 import os
 import re
+import sys
 
 import bugzilla
 import requests
@@ -19,9 +20,15 @@ class GLSATool:
 self.auth = glsamaker_key
 self.bgo = bugzilla.Bugzilla('https://bugs.gentoo.org',
  api_key=bgo_key, force_rest=True)
-
-def get_csrf_token(self):
-soup = bs(self.request('/glsas/new'), features='lxml')
+config_path = os.path.join(os.path.expanduser('~'),
+   '.config', 'glsatool')
+c = ConfigParser()
+c.read(config_path)
+self.glsa_path = c['default']['glsa']
+self.from_str = c['default']['from']
+
+def get_csrf_token(self, path):
+soup = bs(self.request(path), features='lxml')
 csrf_token = \
 soup.find('input', {'name': 'authenticity_token'})['value']
 return csrf_token
@@ -45,6 +52,64 @@ class GLSATool:
 raise RuntimeError(path + ': ' + str(response.status_code))
 return response.text
 
+def get_int_input(self, msg):
+while True:
+i = input(msg)
+try:
+return int(i)
+except (ValueError, EOFError):
+continue
+
+def release_glsa(self, num=None):
+if not num:
+soup = bs(self.request('/glsas/drafts'), features='lxml')
+glsas = soup.find_all('tr', {'class': True})
+for idx, item in enumerate(glsas):
+print('[{0}] {1}'.format(idx, item.find('a').text))
+i = self.get_int_input("Which GLSA to release? ")
+print("Selected '{0}'".format(glsas[i].a.text))
+num = glsas[i].a['href'][-4:]
+
+prepare_path = '/glsas/{}/prepare_release'.format(num)
+release_path = '/glsas/{}/release'.format(num)
+xml_path = '/glsas/{}/download.xml'.format(num)
+txt_path = '/glsas/{}/download.txt'.format(num)
+
+data = {
+'value': 'Release ',
+'authenticity_token': self.get_csrf_token(prepare_path)
+}
+
+# Click the "release" button
+released_soup = bs(self.request(release_path, method='POST', 
data=data),
+   features='lxml')
+glsa_id = 'glsa-' + released_soup.find('strong').text.split()[1]
+
+# Grab the xml
+xml = self.request(xml_path)
+xml_filename = '{}.xml'.format(glsa_id)
+xml_path = os.path.join(self.glsa_path, xml_filename)
+
+# Write and (TODO) commit it
+with open(xml_path, 'w') as f:
+f.write(xml)
+print("Wrote {}".format(xml_filename))
+
+# Grab the mail text
+txt = self.request(txt_path)
+txt_filename = '{}.txt'.format(glsa_id)
+
+# Write it
+with open(txt_filename, 'w') as f:
+f.write('From: {}\n'.format(self.from_str))
+f.write('Reply-To: secur...@gentoo.org\n')
+f.write(txt)
+print("Wrote {}".format(txt_filename))
+
+# TODO:
+# Mail it
+# Close bugs
+
 def new_whiteboard(self, old_whiteboard):
 regex = re.compile('[A-C~][0-4] \[.*\]')
 severity = old_whiteboard[:2]
@@ -78,7 +143,7 @@ class GLSATool:
 'access': 'public',
 'import_references': '1',
 'what': 'request',  # ???
-'authenticity_token': self.get_csrf_token()
+'authenticity_token': self.get_csrf_token('/glsas/new')
 }
 self.request('/glsas', method='POST', data=data)
 print("GLSA request filed")
@@ -104,10 +169,26 @@ def bgo_key():
 
 def glsatool():
 parser = argparse.ArgumentParser()
-parser.add_argument('-b', '--bugs', required=True, nargs='+')
-parser.add_argument('-t', '--title', required=True)
+subparsers = parser.add_subparsers(dest='command')
+
+new_parser = subparsers.add_parser('new')
+new_parser.add_argument('-b', '--bugs', required=True, nargs='+')
+new_parser.add_argument('-t', '--title', 

[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-18 Thread John Helmert III
commit: 4a160a6b646b01fa14f59ac14337640141451864
Author: John Helmert III  gentoo  org>
AuthorDate: Sat Jul 17 16:46:39 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Mon Jul 19 02:54:43 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=4a160a6b

cvetool: fix missing import

Signed-off-by: John Helmert III  gentoo.org>

 bin/CVETool.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bin/CVETool.py b/bin/CVETool.py
index 7a5c576..29eab39 100644
--- a/bin/CVETool.py
+++ b/bin/CVETool.py
@@ -1,4 +1,5 @@
 import re
+import os
 import sys
 
 from base64 import b64encode



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-06 Thread John Helmert III
commit: b95debb109f03769167713f63d572e5857709b39
Author: John Helmert III  gentoo  org>
AuthorDate: Tue Jul  6 23:32:42 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Tue Jul  6 23:32:42 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=b95debb1

glsatool: reorganize into module and script (like cvetool)

Signed-off-by: John Helmert III  gentoo.org>

 bin/{glsatool => GLSATool.py} |   4 +-
 bin/glsatool  | 116 ++
 2 files changed, 6 insertions(+), 114 deletions(-)

diff --git a/bin/glsatool b/bin/GLSATool.py
old mode 100755
new mode 100644
similarity index 98%
copy from bin/glsatool
copy to bin/GLSATool.py
index 6755f32..c7fc804
--- a/bin/glsatool
+++ b/bin/GLSATool.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
 from configparser import ConfigParser
 import argparse
 import os
@@ -104,7 +102,7 @@ def bgo_key():
 return apikey
 
 
-if __name__ == '__main__':
+def glsatool():
 parser = argparse.ArgumentParser()
 parser.add_argument('-b', '--bugs', required=True, nargs='+')
 parser.add_argument('-t', '--title', required=True)

diff --git a/bin/glsatool b/bin/glsatool
index 6755f32..2f8e88a 100755
--- a/bin/glsatool
+++ b/bin/glsatool
@@ -1,115 +1,9 @@
 #!/usr/bin/env python
 
-from configparser import ConfigParser
-import argparse
-import os
-import re
-
-import bugzilla
-import requests
-from bs4 import BeautifulSoup as bs
-
-from CVETool import CVETool
-
-GLSAMAKER_URI = 'https://glsamaker.gentoo.org'
-
-
-class GLSATool:
-""" Utility to ease GLSA handling in GLSAMaker """
-
-def __init__(self, glsamaker_key, bgo_key):
-self.auth = glsamaker_key
-self.bgo = bugzilla.Bugzilla('https://bugs.gentoo.org',
- api_key=bgo_key, force_rest=True)
-
-def get_csrf_token(self):
-soup = bs(self.request('/glsas/new'), features='lxml')
-csrf_token = \
-soup.find('input', {'name': 'authenticity_token'})['value']
-return csrf_token
-
-def request(self, path, method='GET', data=None):
-if method == 'GET':
-response = requests.get(GLSAMAKER_URI + path,
-headers={'Authorization':
- 'Basic ' + self.auth})
-elif method == 'POST':
-if data:
-response = requests.post(GLSAMAKER_URI + path,
- data=data,
- headers={'Authorization':
-  'Basic ' + self.auth})
-else:
-response = requests.post(GLSAMAKER_URI + path,
- headers={'Authorization':
-  'Basic ' + self.auth})
-if not response.ok:
-raise RuntimeError(path + ': ' + str(response.status_code))
-return response.text
-
-def new_whiteboard(self, old_whiteboard):
-regex = re.compile('[A-C~][0-4] \[.*\]')
-severity = old_whiteboard[:2]
-new = ['glsa']
-
-if not regex.match(old_whiteboard):
-# Don't even try to operate on a whiteboard with a strange
-# format
-raise RuntimeError("Bad whiteboard! '" + old_whiteboard + "'")
-
-# Iterate over words within the [] part of whiteboard
-for word in re.sub('[\[\]]', '', old_whiteboard[2:]).split():
-if 'glsa' not in word:
-new += [word]
-if 'cve' not in new:
-new.append('cve')
-return severity + ' [' + ' '.join(new) + ']'
-
-def update_bugs(self, bugs):
-for bug in self.bgo.getbugs(bugs):
-update = {'whiteboard': self.new_whiteboard(bug.whiteboard),
-  'comment': {'comment': 'GLSA request filed.'}}
-print('https://bugs.gentoo.org/{}: {} -> {}'
-  .format(str(bug.id), bug.whiteboard, update['whiteboard']))
-self.bgo.update_bugs([bug.id], update)
-
-def new_glsa(self, title, bugs):
-data = {
-'title': title + ' [DRAFT]',
-'bugs': ','.join(bugs),
-'access': 'public',
-'import_references': '1',
-'what': 'request',  # ???
-'authenticity_token': self.get_csrf_token()
-}
-self.request('/glsas', method='POST', data=data)
-print("GLSA request filed")
-self.update_bugs(bugs)
-
-
-def glsamaker_key():
-authpath = os.path.join(os.path.expanduser('~'), '.config', 'cvetool_auth')
-if 'CVETOOL_AUTH' in os.environ:
-return os.environ['CVETOOL_AUTH']
-if os.path.isfile(authpath):
-with open(authpath, 'r') as authfile:
-return authfile.readlines()[0]
-
-
-def bgo_key():
-bugzrc = os.path.expanduser("~/.bugzrc")
-config = ConfigParser()
-

[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-05 Thread John Helmert III
commit: f6fcf4b3d4a640ba54b2eaa2ed68f5f1ef8a11bd
Author: John Helmert III  gentoo  org>
AuthorDate: Tue Jul  6 02:25:48 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Tue Jul  6 02:26:44 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=f6fcf4b3

glsamaker: readability improvements

Signed-off-by: John Helmert III  gentoo.org>

 bin/glsatool | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/bin/glsatool b/bin/glsatool
index f1d69c6..6755f32 100755
--- a/bin/glsatool
+++ b/bin/glsatool
@@ -67,10 +67,10 @@ class GLSATool:
 
 def update_bugs(self, bugs):
 for bug in self.bgo.getbugs(bugs):
-update = {'whiteboard': self.new_whiteboard(bug.whiteboard)}
-update['comment'] = {'comment': 'GLSA request filed.'}
-print('https://bugs.gentoo.org/' + str(bug.id) + ': ' +
-  bug.whiteboard + ' -> ' + update['whiteboard'])
+update = {'whiteboard': self.new_whiteboard(bug.whiteboard),
+  'comment': {'comment': 'GLSA request filed.'}}
+print('https://bugs.gentoo.org/{}: {} -> {}'
+  .format(str(bug.id), bug.whiteboard, update['whiteboard']))
 self.bgo.update_bugs([bug.id], update)
 
 def new_glsa(self, title, bugs):



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-05 Thread John Helmert III
commit: 6dc80e16f0f208b7bbe143160186c930b151d8e1
Author: John Helmert III  gentoo  org>
AuthorDate: Tue Jul  6 02:03:14 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Tue Jul  6 02:03:43 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=6dc80e16

glsatool: new tool

Signed-off-by: John Helmert III  gentoo.org>

 bin/glsatool | 115 +++
 1 file changed, 115 insertions(+)

diff --git a/bin/glsatool b/bin/glsatool
new file mode 100755
index 000..f1d69c6
--- /dev/null
+++ b/bin/glsatool
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+
+from configparser import ConfigParser
+import argparse
+import os
+import re
+
+import bugzilla
+import requests
+from bs4 import BeautifulSoup as bs
+
+from CVETool import CVETool
+
+GLSAMAKER_URI = 'https://glsamaker.gentoo.org'
+
+
+class GLSATool:
+""" Utility to ease GLSA handling in GLSAMaker """
+
+def __init__(self, glsamaker_key, bgo_key):
+self.auth = glsamaker_key
+self.bgo = bugzilla.Bugzilla('https://bugs.gentoo.org',
+ api_key=bgo_key, force_rest=True)
+
+def get_csrf_token(self):
+soup = bs(self.request('/glsas/new'), features='lxml')
+csrf_token = \
+soup.find('input', {'name': 'authenticity_token'})['value']
+return csrf_token
+
+def request(self, path, method='GET', data=None):
+if method == 'GET':
+response = requests.get(GLSAMAKER_URI + path,
+headers={'Authorization':
+ 'Basic ' + self.auth})
+elif method == 'POST':
+if data:
+response = requests.post(GLSAMAKER_URI + path,
+ data=data,
+ headers={'Authorization':
+  'Basic ' + self.auth})
+else:
+response = requests.post(GLSAMAKER_URI + path,
+ headers={'Authorization':
+  'Basic ' + self.auth})
+if not response.ok:
+raise RuntimeError(path + ': ' + str(response.status_code))
+return response.text
+
+def new_whiteboard(self, old_whiteboard):
+regex = re.compile('[A-C~][0-4] \[.*\]')
+severity = old_whiteboard[:2]
+new = ['glsa']
+
+if not regex.match(old_whiteboard):
+# Don't even try to operate on a whiteboard with a strange
+# format
+raise RuntimeError("Bad whiteboard! '" + old_whiteboard + "'")
+
+# Iterate over words within the [] part of whiteboard
+for word in re.sub('[\[\]]', '', old_whiteboard[2:]).split():
+if 'glsa' not in word:
+new += [word]
+if 'cve' not in new:
+new.append('cve')
+return severity + ' [' + ' '.join(new) + ']'
+
+def update_bugs(self, bugs):
+for bug in self.bgo.getbugs(bugs):
+update = {'whiteboard': self.new_whiteboard(bug.whiteboard)}
+update['comment'] = {'comment': 'GLSA request filed.'}
+print('https://bugs.gentoo.org/' + str(bug.id) + ': ' +
+  bug.whiteboard + ' -> ' + update['whiteboard'])
+self.bgo.update_bugs([bug.id], update)
+
+def new_glsa(self, title, bugs):
+data = {
+'title': title + ' [DRAFT]',
+'bugs': ','.join(bugs),
+'access': 'public',
+'import_references': '1',
+'what': 'request',  # ???
+'authenticity_token': self.get_csrf_token()
+}
+self.request('/glsas', method='POST', data=data)
+print("GLSA request filed")
+self.update_bugs(bugs)
+
+
+def glsamaker_key():
+authpath = os.path.join(os.path.expanduser('~'), '.config', 'cvetool_auth')
+if 'CVETOOL_AUTH' in os.environ:
+return os.environ['CVETOOL_AUTH']
+if os.path.isfile(authpath):
+with open(authpath, 'r') as authfile:
+return authfile.readlines()[0]
+
+
+def bgo_key():
+bugzrc = os.path.expanduser("~/.bugzrc")
+config = ConfigParser()
+config.read(bugzrc)
+apikey = config['default']['key']
+return apikey
+
+
+if __name__ == '__main__':
+parser = argparse.ArgumentParser()
+parser.add_argument('-b', '--bugs', required=True, nargs='+')
+parser.add_argument('-t', '--title', required=True)
+args = parser.parse_args()
+auth = glsamaker_key()
+for bug in args.bugs:
+CVETool(auth, 'dobug', [bug])
+GLSATool(auth, bgo_key()).new_glsa(args.title, args.bugs)



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-05 Thread John Helmert III
commit: be4a8b7e8023688a31e931b46fc3ef8651a290a5
Author: John Helmert III  gentoo  org>
AuthorDate: Mon Jul  5 20:27:13 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Mon Jul  5 20:28:01 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=be4a8b7e

glsatool: drop, accidentally added, not ready yet

Signed-off-by: John Helmert III  gentoo.org>

 bin/glsatool | 74 
 1 file changed, 74 deletions(-)

diff --git a/bin/glsatool b/bin/glsatool
deleted file mode 100755
index 4582a40..000
--- a/bin/glsatool
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python
-
-import argparse
-import os
-import re
-import typing
-
-import bugzilla
-import bracex
-import pkgcore.config
-from pkgcore.ebuild import atom
-import requests
-
-from cvetool import CVETool
-
-PKG_SEPARATORS = re.compile(r':\s|[\s,;(){}[\]]')
-GLSAMAKER_URI = 'https://glsamaker.gentoo.org'
-bgo = bugzilla.Bugzilla('https://bugs.gentoo.org')
-repo = pkgcore.config.load_config().repo['gentoo']
-
-
-class GLSATool:
-""" Utility to ease GLSA handling in GLSAMaker """
-
-def __init__(self, auth):
-self.auth = auth
-
-# https://github.com/mgorny/kuroneko/blob/master/kuroneko/scraper.py#L80
-def find_package_specs(s: str) -> typing.Iterable[atom.atom]:
-"""Find potentially valid package specifications in given string."""
-words = set()
-# consider all possible expansions
-for exp in bracex.iexpand(s):
-words.update(PKG_SEPARATORS.split(exp))
-for w in words:
-# skip anything that couldn't be cat/pkg early
-if '/' not in w:
-continue
-try:
-yield atom.atom(w)
-except MalformedAtom:
-continue
-
-def new_glsa(auth, title, bugs):
-post = requests.post(GLSAMAKER_URI + '/glsas',
- data={'title': title + ' [DRAFT]',
-   'bugs': ','.join(bugs),
-   'access': 'public',
-   'import_references': '1',
-   'what': 'request',  # ???
-   'authenticity_token': 
'k75YYdGlcL+dlZS7RKXSVxKaKl2tiiMvwWlReFtKzt3NCKDE2AeskkrZ851xJB7uCBRUTpstV+/aqUTEx3MfIQ=='},
- headers={'Authorization': 'Basic ' + auth})
-if not post.ok:
-import pdb; pdb.set_trace()
-
-
-def get_auth():
-authpath = os.path.join(os.path.expanduser('~'), '.config', 'cvetool_auth')
-if 'CVETOOL_AUTH' in os.environ:
-return os.environ['CVETOOL_AUTH']
-elif os.path.isfile(authpath):
-with open(authpath, 'r') as authfile:
-return authfile.readlines()[0]
-
-
-if __name__ == '__main__':
-parser = argparse.ArgumentParser()
-parser.add_argument('-b', '--bugs', required=True, nargs='+')
-parser.add_argument('-t', '--title', required=True)
-args = parser.parse_args()
-auth = get_auth()
-for bug in args.bugs:
-CVETool(auth, 'dobug', [bug])
-new_glsa(auth, args.title, args.bugs)



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-05 Thread John Helmert III
commit: 5976eb82d7f4af4de9083914cfb728ed1a331e38
Author: John Helmert III  gentoo  org>
AuthorDate: Mon Jul  5 20:10:05 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Mon Jul  5 20:20:36 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=5976eb82

cvetool: reorganize cvetool code into python module and callable script

Signed-off-by: John Helmert III  gentoo.org>

 bin/CVETool.py | 18 ++
 bin/cvetool| 25 ++--
 bin/glsatool   | 74 ++
 3 files changed, 94 insertions(+), 23 deletions(-)

diff --git a/bin/CVETool.py b/bin/CVETool.py
index c5996f6..7a5c576 100644
--- a/bin/CVETool.py
+++ b/bin/CVETool.py
@@ -240,3 +240,21 @@ class CVETool:
 if jsondata:
 return response.json()
 return response.text
+
+
+def cvetool():
+if len(sys.argv) == 1:
+CVETool(None, 'usage', sys.argv[2:])
+
+auth = None
+authpath = os.path.join(os.path.expanduser('~'), '.config', 'cvetool_auth')
+if 'CVETOOL_AUTH' in os.environ:
+auth = os.environ['CVETOOL_AUTH']
+elif os.path.isfile(authpath):
+with open(authpath, 'r') as authfile:
+auth = authfile.readlines()[0]
+elif 'CVETOOL_AUTH' not in os.environ and not sys.argv[1] == 'pw':
+print('CVETOOL_AUTH environment variable missing. Generate its 
contents with the pw subcommand.')
+sys.exit(1)
+
+CVETool(auth, sys.argv[1], sys.argv[2:])

diff --git a/bin/cvetool b/bin/cvetool
index 7e30837..d5aa25f 100755
--- a/bin/cvetool
+++ b/bin/cvetool
@@ -2,32 +2,11 @@
 # Copyright 2016 Alex Legler
 # Distributed under the terms of the GNU General Public License v3
 
-import os
-import re
-import sys
-
-from CVETool import CVETool
-
-def main():
-if len(sys.argv) == 1:
-CVETool(None, 'usage', sys.argv[2:])
-
-auth = None
-authpath = os.path.join(os.path.expanduser('~'), '.config', 'cvetool_auth')
-if 'CVETOOL_AUTH' in os.environ:
-auth = os.environ['CVETOOL_AUTH']
-elif os.path.isfile(authpath):
-with open(authpath, 'r') as authfile:
-auth = authfile.readlines()[0]
-elif 'CVETOOL_AUTH' not in os.environ and not sys.argv[1] == 'pw':
-print('CVETOOL_AUTH environment variable missing. Generate its 
contents with the pw subcommand.')
-sys.exit(1)
-
-CVETool(auth, sys.argv[1], sys.argv[2:])
+from CVETool import CVETool, cvetool
 
 
 if __name__ == "__main__":
 try:
-main()
+cvetool()
 except KeyboardInterrupt:
 print('\n ! Exiting.')

diff --git a/bin/glsatool b/bin/glsatool
new file mode 100755
index 000..4582a40
--- /dev/null
+++ b/bin/glsatool
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+
+import argparse
+import os
+import re
+import typing
+
+import bugzilla
+import bracex
+import pkgcore.config
+from pkgcore.ebuild import atom
+import requests
+
+from cvetool import CVETool
+
+PKG_SEPARATORS = re.compile(r':\s|[\s,;(){}[\]]')
+GLSAMAKER_URI = 'https://glsamaker.gentoo.org'
+bgo = bugzilla.Bugzilla('https://bugs.gentoo.org')
+repo = pkgcore.config.load_config().repo['gentoo']
+
+
+class GLSATool:
+""" Utility to ease GLSA handling in GLSAMaker """
+
+def __init__(self, auth):
+self.auth = auth
+
+# https://github.com/mgorny/kuroneko/blob/master/kuroneko/scraper.py#L80
+def find_package_specs(s: str) -> typing.Iterable[atom.atom]:
+"""Find potentially valid package specifications in given string."""
+words = set()
+# consider all possible expansions
+for exp in bracex.iexpand(s):
+words.update(PKG_SEPARATORS.split(exp))
+for w in words:
+# skip anything that couldn't be cat/pkg early
+if '/' not in w:
+continue
+try:
+yield atom.atom(w)
+except MalformedAtom:
+continue
+
+def new_glsa(auth, title, bugs):
+post = requests.post(GLSAMAKER_URI + '/glsas',
+ data={'title': title + ' [DRAFT]',
+   'bugs': ','.join(bugs),
+   'access': 'public',
+   'import_references': '1',
+   'what': 'request',  # ???
+   'authenticity_token': 
'k75YYdGlcL+dlZS7RKXSVxKaKl2tiiMvwWlReFtKzt3NCKDE2AeskkrZ851xJB7uCBRUTpstV+/aqUTEx3MfIQ=='},
+ headers={'Authorization': 'Basic ' + auth})
+if not post.ok:
+import pdb; pdb.set_trace()
+
+
+def get_auth():
+authpath = os.path.join(os.path.expanduser('~'), '.config', 'cvetool_auth')
+if 'CVETOOL_AUTH' in os.environ:
+return os.environ['CVETOOL_AUTH']
+elif os.path.isfile(authpath):
+with open(authpath, 'r') as authfile:
+return authfile.readlines()[0]
+
+
+if __name__ == 

[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-05 Thread John Helmert III
commit: abe128db3bf0ede3f813de854ccee897941638f1
Author: John Helmert III  gentoo  org>
AuthorDate: Mon Jul  5 18:38:38 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Mon Jul  5 18:38:38 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=abe128db

bin/: split CVETool class into own file

...and rename cvetool.py back to cvetool

Signed-off-by: John Helmert III  gentoo.org>

 bin/{cvetool.py => CVETool.py} | 33 ++---
 bin/cvetool| 33 +
 2 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/bin/cvetool.py b/bin/CVETool.py
old mode 100755
new mode 100644
similarity index 90%
rename from bin/cvetool.py
rename to bin/CVETool.py
index 557c030..c5996f6
--- a/bin/cvetool.py
+++ b/bin/CVETool.py
@@ -1,12 +1,8 @@
-#!/usr/bin/env python3
-# Copyright 2016 Alex Legler
-# Distributed under the terms of the GNU General Public License v3
-
 import re
 import sys
-import os
-from urllib.parse import urlencode
+
 from base64 import b64encode
+from urllib.parse import urlencode
 import requests
 
 GLSAMAKER_URI = 'https://glsamaker.gentoo.org'
@@ -244,28 +240,3 @@ class CVETool:
 if jsondata:
 return response.json()
 return response.text
-
-
-def main():
-if len(sys.argv) == 1:
-CVETool(None, 'usage', sys.argv[2:])
-
-auth = None
-authpath = os.path.join(os.path.expanduser('~'), '.config', 'cvetool_auth')
-if 'CVETOOL_AUTH' in os.environ:
-auth = os.environ['CVETOOL_AUTH']
-elif os.path.isfile(authpath):
-with open(authpath, 'r') as authfile:
-auth = authfile.readlines()[0]
-elif 'CVETOOL_AUTH' not in os.environ and not sys.argv[1] == 'pw':
-print('CVETOOL_AUTH environment variable missing. Generate its 
contents with the pw subcommand.')
-sys.exit(1)
-
-CVETool(auth, sys.argv[1], sys.argv[2:])
-
-
-if __name__ == "__main__":
-try:
-main()
-except KeyboardInterrupt:
-print('\n ! Exiting.')

diff --git a/bin/cvetool b/bin/cvetool
new file mode 100755
index 000..7e30837
--- /dev/null
+++ b/bin/cvetool
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+# Copyright 2016 Alex Legler
+# Distributed under the terms of the GNU General Public License v3
+
+import os
+import re
+import sys
+
+from CVETool import CVETool
+
+def main():
+if len(sys.argv) == 1:
+CVETool(None, 'usage', sys.argv[2:])
+
+auth = None
+authpath = os.path.join(os.path.expanduser('~'), '.config', 'cvetool_auth')
+if 'CVETOOL_AUTH' in os.environ:
+auth = os.environ['CVETOOL_AUTH']
+elif os.path.isfile(authpath):
+with open(authpath, 'r') as authfile:
+auth = authfile.readlines()[0]
+elif 'CVETOOL_AUTH' not in os.environ and not sys.argv[1] == 'pw':
+print('CVETOOL_AUTH environment variable missing. Generate its 
contents with the pw subcommand.')
+sys.exit(1)
+
+CVETool(auth, sys.argv[1], sys.argv[2:])
+
+
+if __name__ == "__main__":
+try:
+main()
+except KeyboardInterrupt:
+print('\n ! Exiting.')



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-05 Thread John Helmert III
commit: 833da1349cff01ccea594ac104d603961b480a71
Author: John Helmert III  gentoo  org>
AuthorDate: Mon Jul  5 01:29:27 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Mon Jul  5 01:30:16 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=833da134

cvetool: rename to cvetool.py

This is necessary so other tools can import the CVETool class itself

Signed-off-by: John Helmert III  gentoo.org>

 bin/{cvetool => cvetool.py} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/bin/cvetool b/bin/cvetool.py
old mode 100755
new mode 100644
similarity index 100%
rename from bin/cvetool
rename to bin/cvetool.py



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-05 Thread John Helmert III
commit: f38466de27e3785cadbfaa45d435dc03445197e9
Author: John Helmert III  gentoo  org>
AuthorDate: Mon Jul  5 01:51:29 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Mon Jul  5 01:52:58 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=f38466de

cvetool: avoid referencing sys.argv in CVETool constructor

This is wrong because we pass in sys.argv in the constructor arguments
anyway, and referring to sys.argv directly breaks consumers that aren't
the cvetool script.

The last use of sys.argv in the constructor is when command is invalid
and self.usage(sys.argv[0]) is called, if you hit this it means you were
calling CVETool programmatically, so surely you can debug it :)

Signed-off-by: John Helmert III  gentoo.org>

 bin/cvetool.py | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/bin/cvetool.py b/bin/cvetool.py
old mode 100644
new mode 100755
index 744e2a5..557c030
--- a/bin/cvetool.py
+++ b/bin/cvetool.py
@@ -36,9 +36,9 @@ class CVETool:
 sys.exit(1)
 
 try:
-self.info(self.cleanup_cve(sys.argv[2]))
+self.info(self.cleanup_cve(args[0]))
 except ValueError:
-print('"{}" is not a valid CVE 
identifier!'.format(sys.argv[2]))
+print('"{}" is not a valid CVE identifier!'.format(args[0]))
 sys.exit(1)
 elif command == 'assign':
 if len(args) < 2:
@@ -53,7 +53,7 @@ class CVETool:
 print('Returns a list of the real CVE IDs')
 sys.exit(1)
 
-self.getcveidlist([self.cleanup_cve(cve) for cve in args[0:]])
+self.getcveidlist([self.cleanup_cve(cve) for cve in args])
 elif command == 'new':
 if len(args) != 1:
 print('Usage: new ')
@@ -61,9 +61,9 @@ class CVETool:
 sys.exit(1)
 
 try:
-self.new(self.cleanup_cve(sys.argv[2]))
+self.new(self.cleanup_cve(args[0]))
 except ValueError:
-print('"{}" is not a valid CVE 
identifier!'.format(sys.argv[2]))
+print('"{}" is not a valid CVE identifier!'.format(args[0]))
 sys.exit(1)
 elif command == 'nfu':
 if len(args) != 1:
@@ -78,14 +78,14 @@ class CVETool:
 print('Generates a base64-encoded credential for storing')
 sys.exit(1)
 
-self.pw(sys.argv[2], sys.argv[3])
+self.pw(args[0], args[1])
 elif command == 'dobug':
 if len(args) != 1:
 print('Usage: dobug ')
 print('Adds and assigns a bug\'s CVEs')
 sys.exit(1)
 
-self.dobug(sys.argv[2])
+self.dobug(args[0])
 else:
 self.usage(sys.argv[0])
 sys.exit(1)



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-05 Thread John Helmert III
commit: b599466bea8a657b2716a96d9c0a355728af4f7c
Author: John Helmert III  gentoo  org>
AuthorDate: Mon Jul  5 01:40:16 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Mon Jul  5 01:43:32 2021 +
URL:https://gitweb.gentoo.org/proj/security.git/commit/?id=b599466b

cvetool: sanity check CVETool args rather than sys.argv

Signed-off-by: John Helmert III  gentoo.org>

 bin/cvetool.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bin/cvetool.py b/bin/cvetool.py
index 233375a..744e2a5 100644
--- a/bin/cvetool.py
+++ b/bin/cvetool.py
@@ -73,14 +73,14 @@ class CVETool:
 
 self.nfu(self.cleanup_cve(args[0]))
 elif command == 'pw':
-if len(sys.argv) != 4:
+if len(args) != 2:
 print('Usage: pw  ')
 print('Generates a base64-encoded credential for storing')
 sys.exit(1)
 
 self.pw(sys.argv[2], sys.argv[3])
 elif command == 'dobug':
-if len(sys.argv) != 3:
+if len(args) != 1:
 print('Usage: dobug ')
 print('Adds and assigns a bug\'s CVEs')
 sys.exit(1)



[gentoo-commits] proj/security:ajak-cvetool commit in: bin/

2021-07-03 Thread John Helmert III
commit: eed0fdb7e16ff4d2b475f7803a6888c8a3c0d7da
Author: John Helmert III  gentoo  org>
AuthorDate: Sun Jul  4 04:41:53 2021 +
Commit: John Helmert III  gentoo  org>
CommitDate: Sun Jul  4 04:41:53 2021 +
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  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 ')
+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: