1 #! /usr/bin/env python3
3 """*********************************************************************
4 * Edward is free software: you can redistribute it and/or modify *
5 * it under the terms of the GNU Affero Public License as published by *
6 * the Free Software Foundation, either version 3 of the License, or *
7 * (at your option) any later version. *
9 * Edward is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU Affero Public License for more details. *
14 * You should have received a copy of the GNU Affero Public License *
15 * along with Edward. If not, see <http://www.gnu.org/licenses/>. *
17 * Copyright (C) 2014-2015 Andrew Engelbrecht (AGPLv3+) *
18 * Copyright (C) 2014 Josh Drake (AGPLv3+) *
19 * Copyright (C) 2014 Lisa Marie Maginnis (AGPLv3+) *
21 * Special thanks to Josh Drake for writing the original edward bot! :) *
23 ************************************************************************
27 * http://agpl.fsf.org/emailselfdefense.fsf.org/edward/CURRENT/edward.tar.gz
40 txt
= sys
.stdin
.read()
42 msg
= email
.parser
.Parser().parsestr(txt
)
44 print("From: " + msg
['From'])
45 print("Subject: " + msg
['Subject'])
53 for part
in msg
.walk():
54 if part
.get_content_type() == 'multipart':
57 filename
= part
.get_filename()
58 conttype
= part
.get_content_type()
59 descrip_p
= part
.get_params(header
='content-description')
61 charset
= part
.get_content_charset()
62 payload_b
= part
.get_payload(decode
=True)
70 descript
= descrip_p
[0][0]
75 payload
= payload_b
.decode(charset
)
77 if conttype
== "application/pgp-encrypted":
78 if descript
== 'PGP/MIME version identification':
79 if payload
.strip() != "Version: 1":
80 print("*** Warning... unknown pgp/mime version: " \
84 if (filename
== "encrypted.asc") or (conttype
== "pgp/mime"):
85 dec_msg
= decrypt_payload(payload
)
86 print_decrypted(dec_msg
)
88 elif conttype
== "text/plain":
95 def print_decrypted (message
):
100 for chunk
in message
:
101 msg
= email
.parser
.Parser().parsestr(chunk
[0])
111 print("bad sig: " + str(sig
.summary
))
115 timestamp
= time
.localtime(sig
.timestamp
)
120 name
= key
.uids
[0].name
121 e_addr
= key
.uids
[0].email
122 comment
= key
.uids
[0].comment
124 date
= time
.strftime("%a %d %b %Y %I:%M:%S %p %Z", timestamp
)
126 print("sig from: " + name
+ " (" + comment
+ ") <" \
128 print("fingerprint: " + fpr
)
129 print("date: " + date
)
132 def decrypt_payload (payload
):
134 blocks
= split_message(payload
)
135 message
= decrypt_blocks(blocks
)
140 def split_message (text
):
142 pgp_matches
= re
.search( \
143 '(-----BEGIN PGP MESSAGE-----' \
145 '-----END PGP MESSAGE-----)', \
149 if pgp_matches
== None:
152 return pgp_matches
.groups()
155 def decrypt_blocks (blocks
):
162 plain
, sigs
= decrypt_block(block
)
164 message
= message
+ [(plain
, sigs
)]
169 def decrypt_block (block
):
171 block_b
= io
.BytesIO(block
.encode('ASCII'))
172 plain_b
= io
.BytesIO()
175 sigs
= g
.decrypt_verify(block_b
, plain_b
)
177 plain
= plain_b
.getvalue().decode('ASCII')