verify files using rpm bindings and keys supplied by buildservice
[opensuse:osc.git] / osc / checker.py
1 #!/usr/bin/python
2
3 from tempfile import mkdtemp
4 import os
5 from shutil import rmtree
6 import rpm
7 import base64
8
9 class KeyError(Exception):
10         def __init__(self, key, *args):
11                 Exception.__init__(self)
12                 self.args = args
13                 self.key = key
14         def __str__(self):
15                 return ''+self.key+' :'+' '.join(self.args)
16
17 class Checker:
18         def __init__(self):
19                 self.dbdir = mkdtemp(prefix='oscrpmdb')
20                 self.imported = {}
21                 rpm.addMacro('_dbpath', self.dbdir)
22                 self.ts = rpm.TransactionSet()
23                 self.ts.initDB()
24                 self.ts.openDB()
25                 self.ts.setVSFlags(0)
26                 #self.ts.Debug(1)
27
28         def readkeys(self, keys=[]):
29                 rpm.addMacro('_dbpath', self.dbdir)
30                 for key in keys:
31                         self.readkey(key)
32
33                 rpm.delMacro("_dbpath")
34
35 # python is an idiot
36 #       def __del__(self):
37 #               self.cleanup()
38
39         def cleanup(self):
40                 self.ts.closeDB()
41                 rmtree(self.dbdir)
42
43         def readkey(self, file):
44                 if file in self.imported:
45                         return
46
47                 fd = open(file, "r")
48                 line = fd.readline()
49                 if line and line[0:14] == "-----BEGIN PGP":
50                         line = fd.readline()
51                         while line and line != "\n":
52                                 line = fd.readline()
53                         if not line:
54                                 raise KeyError(file, "not a pgp public key")
55                 else:
56                         raise KeyError(file, "not a pgp public key")
57                         
58                 key = ''
59                 line = fd.readline()
60                 while line:
61                         if line[0:12] == "-----END PGP":
62                                 break
63                         line = line.rstrip()
64                         key += line
65                         line = fd.readline()
66                 fd.close()
67                 if not line or line[0:12] != "-----END PGP":
68                         raise KeyError(file, "not a pgp public key")
69
70                 bkey = base64.b64decode(key)
71
72                 r = self.ts.pgpImportPubkey(bkey)
73                 if r != 0:
74                         raise KeyError(file, "failed to import pubkey")
75                 self.imported[file] = 1
76
77         def check(self, pkg):
78                 fd = os.open(pkg, os.O_RDONLY)
79                 hdr = self.ts.hdrFromFdno(fd)
80                 os.close(fd)
81
82 if __name__ == "__main__":
83         import sys
84         keyfiles = []
85         pkgs = []
86         for arg in sys.argv[1:]:
87                 if arg[-4:] == '.rpm':
88                         pkgs.append(arg)
89                 else:
90                         keyfiles.append(arg)
91
92         checker = Checker()
93         try:
94                 checker.readkeys(keyfiles)
95                 for pkg in pkgs:
96                         checker.check(pkg)
97         except Exception, e:
98                 checker.cleanup()
99                 raise e
100