mirror of
https://github.com/openSUSE/osc.git
synced 2025-02-03 10:06:17 +01:00
verify files using rpm bindings and keys supplied by buildservice
The build service is not ready for that yet. Almost all projects that are not built but only imported to the build service have wrong keys. To enable the new code set builtin_signature_check in .oscrc. You may need to manually overwrite wrong _pubkey files in the packagecachedir with correct keys until the build service is fixed.
This commit is contained in:
parent
25d8ffa0d9
commit
8fb9669ae4
12
osc/build.py
12
osc/build.py
@ -63,6 +63,8 @@ class Buildinfo:
|
||||
|
||||
root = tree.getroot()
|
||||
|
||||
self.apiurl = apiurl
|
||||
|
||||
if root.find('error') != None:
|
||||
sys.stderr.write('buildinfo is broken... it says:\n')
|
||||
error = root.find('error').text
|
||||
@ -95,9 +97,13 @@ class Buildinfo:
|
||||
pass
|
||||
|
||||
self.deps = []
|
||||
self.projects = {}
|
||||
self.keys = []
|
||||
for node in root.findall('bdep'):
|
||||
p = Pac(node, self.buildarch, self.pacsuffix,
|
||||
apiurl, localpkgs)
|
||||
if p.project:
|
||||
self.projects[p.project] = 1
|
||||
self.deps.append(p)
|
||||
|
||||
self.vminstall_list = [ dep.name for dep in self.deps if dep.vminstall ]
|
||||
@ -621,13 +627,11 @@ def main(opts, argv):
|
||||
os.symlink(sffn, tffn)
|
||||
|
||||
if bi.pacsuffix == 'rpm':
|
||||
if config['build-type'] == "xen" or config['build-type'] == "kvm":
|
||||
print 'Skipping verification of package signatures due to secure VM build'
|
||||
elif opts.no_verify or opts.noinit:
|
||||
if opts.no_verify or opts.noinit:
|
||||
print 'Skipping verification of package signatures'
|
||||
else:
|
||||
print 'Verifying integrity of cached packages'
|
||||
verify_pacs([ i.fullfilename for i in bi.deps ])
|
||||
verify_pacs([ i.fullfilename for i in bi.deps ], bi.keys)
|
||||
elif bi.pacsuffix == 'deb':
|
||||
if config['build-type'] == "xen" or config['build-type'] == "kvm":
|
||||
print 'Skipping verification of package signatures due to secure VM build'
|
||||
|
100
osc/checker.py
Normal file
100
osc/checker.py
Normal file
@ -0,0 +1,100 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from tempfile import mkdtemp
|
||||
import os
|
||||
from shutil import rmtree
|
||||
import rpm
|
||||
import base64
|
||||
|
||||
class KeyError(Exception):
|
||||
def __init__(self, key, *args):
|
||||
Exception.__init__(self)
|
||||
self.args = args
|
||||
self.key = key
|
||||
def __str__(self):
|
||||
return ''+self.key+' :'+' '.join(self.args)
|
||||
|
||||
class Checker:
|
||||
def __init__(self):
|
||||
self.dbdir = mkdtemp(prefix='oscrpmdb')
|
||||
self.imported = {}
|
||||
rpm.addMacro('_dbpath', self.dbdir)
|
||||
self.ts = rpm.TransactionSet()
|
||||
self.ts.initDB()
|
||||
self.ts.openDB()
|
||||
self.ts.setVSFlags(0)
|
||||
#self.ts.Debug(1)
|
||||
|
||||
def readkeys(self, keys=[]):
|
||||
rpm.addMacro('_dbpath', self.dbdir)
|
||||
for key in keys:
|
||||
self.readkey(key)
|
||||
|
||||
rpm.delMacro("_dbpath")
|
||||
|
||||
# python is an idiot
|
||||
# def __del__(self):
|
||||
# self.cleanup()
|
||||
|
||||
def cleanup(self):
|
||||
self.ts.closeDB()
|
||||
rmtree(self.dbdir)
|
||||
|
||||
def readkey(self, file):
|
||||
if file in self.imported:
|
||||
return
|
||||
|
||||
fd = open(file, "r")
|
||||
line = fd.readline()
|
||||
if line and line[0:14] == "-----BEGIN PGP":
|
||||
line = fd.readline()
|
||||
while line and line != "\n":
|
||||
line = fd.readline()
|
||||
if not line:
|
||||
raise KeyError(file, "not a pgp public key")
|
||||
else:
|
||||
raise KeyError(file, "not a pgp public key")
|
||||
|
||||
key = ''
|
||||
line = fd.readline()
|
||||
while line:
|
||||
if line[0:12] == "-----END PGP":
|
||||
break
|
||||
line = line.rstrip()
|
||||
key += line
|
||||
line = fd.readline()
|
||||
fd.close()
|
||||
if not line or line[0:12] != "-----END PGP":
|
||||
raise KeyError(file, "not a pgp public key")
|
||||
|
||||
bkey = base64.b64decode(key)
|
||||
|
||||
r = self.ts.pgpImportPubkey(bkey)
|
||||
if r != 0:
|
||||
raise KeyError(file, "failed to import pubkey")
|
||||
self.imported[file] = 1
|
||||
|
||||
def check(self, pkg):
|
||||
fd = os.open(pkg, os.O_RDONLY)
|
||||
hdr = self.ts.hdrFromFdno(fd)
|
||||
os.close(fd)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
keyfiles = []
|
||||
pkgs = []
|
||||
for arg in sys.argv[1:]:
|
||||
if arg[-4:] == '.rpm':
|
||||
pkgs.append(arg)
|
||||
else:
|
||||
keyfiles.append(arg)
|
||||
|
||||
checker = Checker()
|
||||
try:
|
||||
checker.readkeys(keyfiles)
|
||||
for pkg in pkgs:
|
||||
checker.check(pkg)
|
||||
except Exception, e:
|
||||
checker.cleanup()
|
||||
raise e
|
||||
|
71
osc/fetch.py
71
osc/fetch.py
@ -9,6 +9,7 @@ from urlgrabber.grabber import URLGrabber, URLGrabError
|
||||
from urlgrabber.mirror import MirrorGroup
|
||||
from core import makeurl
|
||||
from util import packagequery, cpio
|
||||
import conf
|
||||
import tempfile
|
||||
try:
|
||||
from meter import TextMeter
|
||||
@ -37,6 +38,7 @@ class Fetcher:
|
||||
self.progress_obj = None
|
||||
|
||||
|
||||
self.nopac = False
|
||||
self.cachedir = cachedir
|
||||
self.urllist = urllist
|
||||
self.http_debug = http_debug
|
||||
@ -63,8 +65,9 @@ class Fetcher:
|
||||
|
||||
#log(0, '%s: %s' % (errobj.url, str(errobj.exception)))
|
||||
#log(0, 'Trying other mirror.')
|
||||
print 'Trying openSUSE Build Service server for %s (%s), since it is not on %s.' \
|
||||
% (self.curpac, self.curpac.project, errobj.url.split('/')[2])
|
||||
if not self.nopac:
|
||||
print 'Trying openSUSE Build Service server for %s (%s), since it is not on %s.' \
|
||||
% (self.curpac, self.curpac.project, errobj.url.split('/')[2])
|
||||
raise errobj.exception
|
||||
|
||||
|
||||
@ -197,7 +200,27 @@ class Fetcher:
|
||||
if os.path.exists(tmpfile):
|
||||
os.unlink(tmpfile)
|
||||
|
||||
def verify_pacs(pac_list):
|
||||
self.nopac = True
|
||||
for i in buildinfo.projects:
|
||||
dest = "%s/%s/_pubkey" % (self.cachedir, i)
|
||||
if os.path.exists(dest):
|
||||
buildinfo.keys.append(dest)
|
||||
else:
|
||||
url = "%s/source/%s/_pubkey" % (buildinfo.apiurl, i)
|
||||
try:
|
||||
self.gr.urlgrab(url, dest, text="key for %s" % i)
|
||||
buildinfo.keys.append(dest)
|
||||
except KeyboardInterrupt:
|
||||
print 'Cancelled by user (ctrl-c)'
|
||||
print 'Exiting.'
|
||||
if os.path.exists(dest):
|
||||
os.unlink(dest)
|
||||
sys.exit(0)
|
||||
except URLGrabError, e:
|
||||
print "can't fetch key for %s: %s" %(i, e.strerror)
|
||||
self.nopac = False
|
||||
|
||||
def verify_pacs_old(pac_list):
|
||||
"""Take a list of rpm filenames and run rpm -K on them.
|
||||
|
||||
In case of failure, exit.
|
||||
@ -264,3 +287,45 @@ def verify_pacs(pac_list):
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def verify_pacs(pac_list, key_list):
|
||||
"""Take a list of rpm filenames and verify their signatures.
|
||||
|
||||
In case of failure, exit.
|
||||
"""
|
||||
|
||||
# XXX: remove if new code stable
|
||||
if not conf.config.get('builtin_signature_check', False):
|
||||
return verify_pacs_old(pac_list)
|
||||
|
||||
if not pac_list:
|
||||
return
|
||||
|
||||
if not key_list:
|
||||
print "no keys"
|
||||
sys.exit(1)
|
||||
return
|
||||
|
||||
print key_list
|
||||
|
||||
import checker
|
||||
failed = False
|
||||
checker = checker.Checker()
|
||||
try:
|
||||
checker.readkeys(key_list)
|
||||
for pkg in pac_list:
|
||||
try:
|
||||
checker.check(pkg)
|
||||
except Exception, e:
|
||||
failed = True
|
||||
print pkg, ':', e
|
||||
except Exception, e:
|
||||
checker.cleanup()
|
||||
sys.exit(1)
|
||||
|
||||
if failed:
|
||||
checker.cleanup()
|
||||
sys.exit(1)
|
||||
|
||||
checker.cleanup()
|
||||
|
||||
# vim: sw=4 et
|
||||
|
Loading…
Reference in New Issue
Block a user