4 from trust
import trust_db
5 from model
import SafeException
10 def __init__(self
, status
):
17 """Returns the ID of the key that must be downloaded to check this signature."""
20 class ValidSig(Signature
):
24 return "Valid signature from " + self
.status
[self
.FINGERPRINT
]
27 return trust_db
.is_trusted(self
.status
[self
.FINGERPRINT
])
29 class BadSig(Signature
):
33 return "BAD signature by " + self
.status
[self
.KEYID
] + \
34 " (the message has been tampered with)"
36 class ErrSig(Signature
):
42 msg
= "ERROR signature by %s: " % self
.status
[self
.KEYID
]
43 rc
= int(self
.status
[self
.RC
])
45 msg
+= "Unknown or unsupported algorithm '%s'" % self
.status
[self
.ALG
]
47 msg
+= "Unknown key. Try 'gpg --recv-key %s'" % self
.status
[self
.KEYID
]
49 msg
+= "Unknown reason code %d" % rc
53 rc
= int(self
.status
[self
.RC
])
55 return self
.status
[self
.KEYID
]
58 def import_key(stream
):
59 errors
= tempfile
.TemporaryFile()
66 os
.dup2(stream
.fileno(), 0)
67 os
.dup2(errors
.fileno(), 2)
68 os
.execlp('gpg', 'gpg', '--quiet', '--import')
75 pid
, status
= os
.waitpid(child
, 0)
79 error_messages
= errors
.read().strip()
83 raise SafeException("Errors from 'gpg --import':\n%s" % error_messages
)
85 def check_stream(stream
):
86 """Pass stream through gpg --decrypt to get the data, the error text,
87 and a list of signatures (good or bad).
88 Returns (data_stream, [Signatures])."""
89 status_r
, status_w
= os
.pipe()
91 data
= tempfile
.TemporaryFile() # Python2.2 does not support 'prefix'
92 errors
= tempfile
.TemporaryFile()
101 os
.dup2(stream
.fileno(), 0)
102 os
.dup2(data
.fileno(), 1)
103 os
.dup2(errors
.fileno(), 2)
104 os
.execlp('gpg', 'gpg', '--decrypt',
105 # Not all versions support this:
106 #'--max-output', str(1024 * 1024),
108 '--status-fd', str(status_w
))
110 traceback
.print_exc()
120 # Should we error out on bad signatures, even if there's a good
123 for line
in os
.fdopen(status_r
):
124 assert line
.endswith('\n')
125 assert line
.startswith('[GNUPG:] ')
127 split_line
= line
.split(' ')
129 args
= split_line
[1:]
130 if code
== 'VALIDSIG':
131 sigs
.append(ValidSig(args
))
132 elif code
== 'BADSIG':
133 sigs
.append(BadSig(args
))
134 elif code
== 'ERRSIG':
135 sigs
.append(ErrSig(args
))
137 pid
, status
= os
.waitpid(child
, 0)
143 error_messages
= errors
.read().strip()
146 if error_messages
and not sigs
:
147 raise SafeException("No signatures found. Errors from GPG:\n%s" % error_messages
)