1
0
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:
Ludwig Nussel 2009-06-16 14:46:02 +02:00
parent 25d8ffa0d9
commit 8fb9669ae4
3 changed files with 176 additions and 7 deletions

View File

@ -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
View 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

View File

@ -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,6 +65,7 @@ class Fetcher:
#log(0, '%s: %s' % (errobj.url, str(errobj.exception)))
#log(0, 'Trying other mirror.')
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