]> TLD Linux GIT Repositories - tld-builder.git/blob - TLD_Builder/gpg.py
- more python3 fixes, dropped python2 support
[tld-builder.git] / TLD_Builder / gpg.py
1 # vi: encoding=utf-8 ts=8 sts=4 sw=4 et
2
3 import log
4 import subprocess
5 import re
6 import sys
7 from io import StringIO
8 import util
9 import os
10 import pipeutil
11
12 def get_keys(buf):
13     """Extract keys from gpg message
14
15     """
16
17     if not os.path.isfile('/usr/bin/gpg'):
18         log.error("missing gnupg binary: /usr/bin/gpg")
19         raise OSError('Missing gnupg binary')
20
21     d_stdout = None
22     d_stderr = None
23     cmd = ['/usr/bin/gpg', '--batch', '--no-tty', '--decrypt']
24     gpg_run = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
25     try:
26         d_stdout, d_stderr = gpg_run.communicate(util.to_bytes(buf))
27     except OSError as e:
28         log.error("gnupg run, does gpg binary exist? : %s" % e)
29         raise
30
31     rx = re.compile("^gpg:.*using\s[DR]SA\skey\s(?:ID\s)?(\w+)")
32     keys = []
33
34     for l in util.to_str(d_stderr).split('\n'):
35         m = rx.match(l)
36         if m:
37             keys.append(m.group(1))
38
39     return keys
40
41 def verify_sig(buf):
42     """Check signature.
43
44     Given email as file-like object, return (signer-emails, signed-body).
45     where signer-emails is lists of strings, and signed-body is StringIO
46     object.
47     """
48
49     if not os.path.isfile('/usr/bin/gpg'):
50         log.error("missing gnupg binary: /usr/bin/gpg")
51         raise OSError('Missing gnupg binary')
52
53     d_stdout = None
54     d_stderr = None
55     cmd = ['/usr/bin/gpg', '--batch', '--no-tty', '--decrypt']
56     gpg_run = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
57     try:
58         d_stdout, d_stderr = gpg_run.communicate(util.to_bytes(buf))
59     except OSError as e:
60         log.error("gnupg run failed, does gpg binary exist? : %s" % e)
61         raise
62
63     rx = re.compile("^gpg: (Good signature from|                aka) .*<([^>]+)>")
64     emails = []
65     for l in util.to_str(d_stderr).split('\n'):
66         m = rx.match(l)
67         if m:
68             emails.append(m.group(2))
69     if not emails:
70         log.error("gnupg signature check failed: %s" % d_stderr)
71     return (emails, d_stdout)
72
73 def sign(buf):
74     if not os.path.isfile('/usr/bin/gpg'):
75         log.error("missing gnupg binary: /usr/bin/gpg")
76         raise OSError('Missing gnupg binary')
77
78     d_stdout = None
79     d_stderr = None
80     cmd = ['/usr/bin/gpg', '--batch', '--no-tty', '--clearsign']
81     # TODO: check for gpg return code!
82     gpg_run = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
83     try:
84         d_stdout, d_stderr = gpg_run.communicate(util.to_bytes(buf))
85     except OSError as e:
86         log.error("gnupg signing failed, does gpg binary exist? : %s" % e)
87         raise
88
89     if len(d_stderr):
90         log.error("gpg: %s" % util.to_str(d_stderr))
91
92     return d_stdout