]>
Commit | Line | Data |
---|---|---|
f56d33c5 ER |
1 | #!/usr/bin/env python |
2 | # vi: encoding=utf-8 ts=8 sts=4 sw=4 et | |
3 | ||
4 | import sys, os | |
5 | sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules') | |
6 | import ftptree | |
7 | from common import checkdir | |
8 | import ftpio | |
55bd5397 ER |
9 | from config import sign_key |
10 | import rpm | |
aecf6cae | 11 | import subprocess |
f56d33c5 ER |
12 | |
13 | if len(sys.argv) < 3: | |
55bd5397 ER |
14 | print >>sys.stderr, "ERR: not enough parameters given" |
15 | print >>sys.stderr, "sign.py tree package1 [package2...]" | |
16 | sys.exit(1) | |
17 | ||
18 | if sign_key == None: | |
19 | print >>sys.stderr, "ERR: sign_key not defined in config" | |
f56d33c5 ER |
20 | sys.exit(1) |
21 | ||
22 | checkdir(sys.argv[1]) | |
23 | ||
24 | ftpio.connect('sign') | |
25 | ||
26 | if not ftpio.lock(sys.argv[1], True): | |
27 | print "ERR: %s tree already locked" % sys.argv[1] | |
28 | sys.exit(1) | |
29 | ||
55bd5397 ER |
30 | def getSigInfo(hdr): |
31 | """checks signature from an hdr hand back signature information and/or | |
32 | an error code""" | |
33 | # yum-3.2.22/rpmUtils/miscutils.py | |
34 | ||
35 | string = '%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|' | |
36 | siginfo = hdr.sprintf(string) | |
37 | if siginfo == '(none)': | |
38 | return None | |
39 | ||
40 | return siginfo.split(',')[2].lstrip() | |
41 | ||
42 | ||
43 | def is_signed(rpm_file, key): | |
44 | """Returns rpm information is package signed by the same key""" | |
45 | # http://code.activestate.com/recipes/306705/ | |
46 | ts = rpm.ts() | |
47 | ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) | |
48 | fdno = os.open(rpm_file, os.O_RDONLY) | |
49 | hdr = ts.hdrFromFdno(fdno) | |
50 | os.close(fdno) | |
51 | ||
52 | sigid = getSigInfo(hdr) | |
53 | if sigid == None: | |
54 | return None | |
55 | ||
56 | return key == sigid[-len(key):] | |
f56d33c5 | 57 | |
aecf6cae ER |
58 | def signpkgs(files): |
59 | if not os.path.isfile('/usr/bin/gpg'): | |
60 | raise OSError, 'Missing gnupg binary' | |
61 | if not os.path.isfile('/bin/rpm'): | |
62 | raise OSError, 'Missing rpm binary' | |
63 | ||
64 | cmd = ['/bin/rpm', '--resign'] | |
65 | cmd += files | |
66 | rc = subprocess.call(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True) | |
67 | if rc != 0: | |
68 | print >>sys.stderr, "package signing failed" | |
69 | sys.exit(rc) | |
70 | ||
f56d33c5 | 71 | try: |
55bd5397 ER |
72 | tree = ftptree.FtpTree(sys.argv[1]) #, loadall=True) |
73 | tree.mark4moving(sys.argv[2:]) | |
74 | files = tree.rpmfiles() | |
75 | ||
55bd5397 ER |
76 | print "Checking signatures of %d files from %d packages" % (len(files), len(tree.loadedpkgs)) |
77 | sign = [] | |
78 | for file in files: | |
79 | if not is_signed(file, sign_key): | |
80 | sign.append(file) | |
81 | ||
82 | if len(sign) > 0: | |
83 | print "Signing %d packages" % len(sign) | |
aecf6cae | 84 | signpkgs(sign) |
55bd5397 ER |
85 | else: |
86 | print "No packages to sign" | |
87 | ||
f56d33c5 ER |
88 | except ftptree.SomeError: |
89 | # In case of problems we need to unlock the tree before exiting | |
90 | ftpio.unlock(sys.argv[1]) | |
91 | sys.exit(1) | |
92 | ||
93 | ftpio.unlock(sys.argv[1]) |