zephyr_mirror: Send outgoing messages encrypted when zcrypt would.

Our .crypt-table parsing code isn't quite correct, in that we don't
handle either the "zcrypt default" or "zcrypt by class/instance" pair
options (for sending messages in either direction) -- you have to be
zcrypting for an entire class.  I think this makes sense given that on
the Zulip end we can only enforce anything on a stream level.

(imported from commit a7901b1dc025a04a23ee71ecdd499e3f150ba614)
This commit is contained in:
Tim Abbott 2013-08-20 15:23:29 -04:00
parent a47b0e54c3
commit 2c39d17120

View file

@ -304,12 +304,11 @@ def parse_zephyr_body(zephyr_data):
(zsig, body) = ("", zephyr_data)
return (zsig, body)
def decrypt_zephyr(zephyr_class, body):
have_key = False
def parse_crypt_table(zephyr_class, instance):
try:
crypt_table = file(os.path.join(os.environ["HOME"], ".crypt-table"))
except IOError:
return body
return None
for line in crypt_table.readlines():
if line.strip() == "":
@ -323,9 +322,12 @@ def decrypt_zephyr(zephyr_class, body):
groups = match.groupdict()
if groups['class'].lower() == zephyr_class and 'keypath' in groups and \
groups.get("algorithm") == "AES":
have_key = True
break
if not have_key:
return groups["keypath"]
return None
def decrypt_zephyr(zephyr_class, instance, body):
keypath = parse_crypt_table(zephyr_class, instance)
if keypath is None:
# We can't decrypt it, so we just return the original body
return body
@ -344,7 +346,7 @@ def decrypt_zephyr(zephyr_class, body):
"--quiet",
"--no-use-agent",
"--passphrase-file",
groups['keypath']],
keypath],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
@ -388,7 +390,7 @@ def process_notice(notice, log):
body = body.split("\n", 1)[1]
if options.forward_class_messages and notice.opcode.lower() == "crypt":
body = decrypt_zephyr(zephyr_class, body)
body = decrypt_zephyr(zephyr_class, notice.instance.lower(), body)
zeph = { 'time' : str(notice.time),
'sender' : notice.sender,
@ -552,6 +554,31 @@ def send_authed_zephyr(zwrite_args, content):
def send_unauthed_zephyr(zwrite_args, content):
return send_zephyr(zwrite_args + ["-d"], content)
def zcrypt_encrypt_content(zephyr_class, instance, content):
keypath = parse_crypt_table(zephyr_class, instance)
if keypath is None:
return content
# encrypt the message!
p = subprocess.Popen(["gpg",
"--symmetric",
"--no-options",
"--no-default-keyring",
"--keyring=/dev/null",
"--secret-keyring=/dev/null",
"--batch",
"--quiet",
"--no-use-agent",
"--armor",
"--cipher-algo", "AES",
"--passphrase-file",
keypath],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
encrypted, _ = p.communicate(input=content)
return encrypted
def forward_to_zephyr(message):
wrapper = textwrap.TextWrapper(break_long_words=False, break_on_hyphens=False)
wrapped_content = "\n".join("\n".join(wrapper.wrap(line))
@ -599,6 +626,9 @@ def forward_to_zephyr(message):
logger.info("Forwarding message to %s" % (recipients,))
zwrite_args.extend(recipients)
if message['type'] == "stream":
wrapped_content = zcrypt_encrypt_content(zephyr_class, instance, wrapped_content)
if options.test_mode:
logger.debug("Would have forwarded: %s\n%s" %
(zwrite_args, wrapped_content.encode("utf-8")))