From f7e3b160692a59571518b24b57021f9ee175929b Mon Sep 17 00:00:00 2001 From: fkrone Date: Sat, 31 Jan 2015 16:08:12 +0100 Subject: [PATCH] Changes to cron, register-handler, settings and templates: - Cron now notifies user what happened (key successfully added/deleted or error) - More options to customize templates - Separating concepts in settings (S/MIME, templates) - Register-handler now only informs on failed PGP submissions (reduce mails to user and false positive mails) --- README.md | 5 +- cron_templates/keyDeleted.md | 1 + cron_templates/registrationError.md | 3 ++ cron_templates/registrationSuccess.md | 1 + gpg-mailgate-web/cron.py | 24 ++++++--- gpg-mailgate.conf.sample | 13 ++++- register-handler.py | 52 ++++++++++--------- register_templates/registrationError.md | 4 ++ .../registrationSuccess.md | 2 - templates/registrationError.md | 3 -- 10 files changed, 70 insertions(+), 38 deletions(-) create mode 100644 cron_templates/keyDeleted.md create mode 100644 cron_templates/registrationError.md create mode 100644 cron_templates/registrationSuccess.md create mode 100644 register_templates/registrationError.md rename templates/ registrationSuccess.md => register_templates/registrationSuccess.md (52%) delete mode 100644 templates/registrationError.md diff --git a/README.md b/README.md index e9a7e43..6bf3c31 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # gpg-mailgate +**Please note: This fork is currently WIP. It is not recommended for use at the moment.** + gpg-mailgate is a content filter for Postfix that automatically encrypts unencrypted incoming email using PGP or S/MIME for select recipients. For installation instructions, please refer to the included INSTALL file. @@ -18,7 +20,7 @@ This is forked from the original project at http://code.google.com/p/gpg-mailgat # Authors -This is a combined work of many developers and contributor:s +This is a combined work of many developers and contributors: * mcmaster * Igor Rzegocki - [GitHub](https://github.com/ajgon/gpg-mailgate) @@ -37,5 +39,6 @@ This is a combined work of many developers and contributor:s * clean up code * rewrite templates for register-handler * rewrite and improve installation instructions +* rewrite readme of gpg-mailgate-web in markdown * rename from gpg-mailgate to openpgp-s-mime-mailgate or something..... * even more magical stuff diff --git a/cron_templates/keyDeleted.md b/cron_templates/keyDeleted.md new file mode 100644 index 0000000..7f6cccf --- /dev/null +++ b/cron_templates/keyDeleted.md @@ -0,0 +1 @@ +Your PGP key has been deleted from our gateway. From now on you will receive mails from us unencrypted. \ No newline at end of file diff --git a/cron_templates/registrationError.md b/cron_templates/registrationError.md new file mode 100644 index 0000000..77750f2 --- /dev/null +++ b/cron_templates/registrationError.md @@ -0,0 +1,3 @@ +Your PGP key could not be validated. Please try again with a valid key. + +Any valid keys from you submitted to the gateway before are now deleted. \ No newline at end of file diff --git a/cron_templates/registrationSuccess.md b/cron_templates/registrationSuccess.md new file mode 100644 index 0000000..898da58 --- /dev/null +++ b/cron_templates/registrationSuccess.md @@ -0,0 +1 @@ +Your PGP key has been imported successfully. Don't be worried if this mail is not encrypted. The following mails will be encrypted. \ No newline at end of file diff --git a/gpg-mailgate-web/cron.py b/gpg-mailgate-web/cron.py index 6ec5647..c58ef6f 100644 --- a/gpg-mailgate-web/cron.py +++ b/gpg-mailgate-web/cron.py @@ -23,7 +23,9 @@ from ConfigParser import RawConfigParser import GnuPG import MySQLdb import smtplib +import markdown from email.MIMEText import MIMEText +from email.mime.multipart import MIMEMultipart def appendLog(msg): if cfg.has_key('logging') and cfg['logging'].has_key('file'): @@ -31,15 +33,20 @@ def appendLog(msg): log.write(msg + "\n") log.close() -def send_msg( mailsubject, mailbody, recipients = None ): - msg = MIMEText(mailbody) - msg["From"] = cfg['smime']['register_email'] +def send_msg( mailsubject, messagefile, recipients = None ): + mailbody = file( cfg['cron']['mail_templates'] + "/" + messagefile).read() + msg = MIMEMultipart("alternative") + + msg["From"] = cfg['cron']['notification_email'] msg["To"] = recipients msg["Subject"] = mailsubject + msg.attach(MIMEText(mailbody, 'plain')) + msg.attach(MIMEText(markdown.markdown(mailbody), 'html')) + relay = ("127.0.0.1", 10028) smtp = smtplib.SMTP(relay[0], relay[1]) - smtp.sendmail( cfg['smime']['register_email'], recipients, msg.as_string() ) + smtp.sendmail( cfg['cron']['notification_email'], recipients, msg.as_string() ) # Read configuration from /etc/gpg-mailgate.conf _cfg = RawConfigParser() @@ -69,15 +76,18 @@ if cfg.has_key('database') and cfg['database'].has_key('enabled') and cfg['datab GnuPG.add_key(cfg['gpg']['keyhome'], row[0]) # import the key to gpg cursor.execute("UPDATE gpgmw_keys SET status = 1 WHERE id = %s", (row[1],)) # mark key as accepted appendLog('Imported key from <' + row[2] + '>') - send_msg( "PGP key registration successful", "Your PGP key has been imported successfully. Don't be worried if this mail is not encrypted. The following mails will be encrypted.", row[2] ) + if cfg['cron'].has_key('send_email') and cfg['cron']['send_email'] == 'yes': + send_msg( "PGP key registration successful", "registrationSuccess.md", row[2] ) else: cursor.execute("DELETE FROM gpgmw_keys WHERE id = %s", (row[1],)) # delete key appendLog('Import confirmation failed for <' + row[2] + '>') - send_msg( "PGP key registration failed", "Your PGP key could not be validated. Please try again with a valid key.", row[2] ) + if cfg['cron'].has_key('send_email') and cfg['cron']['send_email'] == 'yes': + send_msg( "PGP key registration failed", "registrationError.md", row[2] ) else: # delete key so we don't continue processing it cursor.execute("DELETE FROM gpgmw_keys WHERE id = %s", (row[1],)) - send_msg( "PGP key deleted", "Your PGP key has been deleted from our gateway. From now on you will receive mails from us unencrypted.", row[2]) + if cfg['cron'].has_key('send_email') and cfg['cron']['send_email'] == 'yes': + send_msg( "PGP key deleted", "keyDeleted.md", row[2]) connection.commit() diff --git a/gpg-mailgate.conf.sample b/gpg-mailgate.conf.sample index 9f245bf..9b98725 100644 --- a/gpg-mailgate.conf.sample +++ b/gpg-mailgate.conf.sample @@ -16,8 +16,19 @@ keyhome = /var/gpg/.gnupg [smime] # the directory for the S/MIME certificate files cert_path = /var/smime/certs + +[mailregister] +# settings for the register-handler register_email = register@yourdomain.tld -mail_templates = /var/smime/templates +mail_templates = /var/gpgmailgate/register_templates +# URL to webpanel. The server should be able to reach it +webpanel_url = http://yourdomain.tld + +[cron] +# settings for the gpgmw cron job +send_email = yes +notification_email = gpg-mailgate@yourdomain.tld +mail_templates = /var/gpgmailgate/cron_templates [logging] # For logging to syslog. 'file = syslog', otherwise use path to the file. diff --git a/register-handler.py b/register-handler.py index e9da7b5..09677f1 100644 --- a/register-handler.py +++ b/register-handler.py @@ -45,10 +45,11 @@ if __name__ == "__main__": sign_type = 'smime' sign_part = msg_part break - elif msg_part.get_content_type().lower() == "application/pgp-keys": - sign_type = 'pgp' - sign_part = msg_part.get_payload() - break + # This may cause that a non ASCII-armored key will be seen as valid. Other solution is not that efficient though + #elif msg_part.get_content_type().lower() == "application/pgp-keys": + # sign_type = 'pgp' + # sign_part = msg_part.get_payload() + # break elif "-----BEGIN PGP PUBLIC KEY BLOCK-----" in msg_part.get_payload() and "-----END PGP PUBLIC KEY BLOCK-----" in msg_part.get_payload(): msg_content = msg_part.get_payload() start = msg_content.find("-----BEGIN PGP PUBLIC KEY BLOCK-----") @@ -60,16 +61,16 @@ if __name__ == "__main__": if sign_part == None: log("Unable to find PKCS7 signature or public PGP key in registration email") - failure_msg = file( cfg['smime']['mail_templates'] + "/registrationError.md").read() + failure_msg = file( cfg['mailregister']['mail_templates'] + "/registrationError.md").read() msg = MIMEMultipart("alternative") - msg["From"] = cfg['smime']['register_email'] + msg["From"] = cfg['mailregister']['register_email'] msg["To"] = from_addr msg["Subject"] = "S/MIME / OpenPGP registration failed" msg.attach(MIMEText(failure_msg, 'plain')) msg.attach(MIMEText(markdown.markdown(failure_msg), 'html')) - send_msg(msg, cfg['smime']['register_email'], [from_addr]) + send_msg(msg, cfg['mailregister']['register_email'], [from_addr]) sys.exit(0) if sign_type == 'smime': @@ -93,27 +94,30 @@ if __name__ == "__main__": signing_cert = signers[0] signing_cert.save(os.path.join(CERT_PATH, from_addr)) + + # format in user-specific data + # sending success mail only for S/MIME as GPGMW handles this on its own + success_msg = file(cfg['mailregister']['mail_templates']+"/registrationSuccess.md").read() + success_msg = success_msg.replace("[:FROMADDRESS:]",from_addr) + msg = MIMEMultipart("alternative") + msg["From"] = cfg['mailregister']['register_email'] + msg["To"] = from_addr + msg["Subject"] = "S/MIME certificate registration succeeded" + + msg.attach(MIMEText(success_msg, 'plain')) + msg.attach(MIMEText(markdown.markdown(success_msg), 'html')) + + send_msg(msg, cfg['mailregister']['register_email'], [from_addr]) + + log("S/MIME Registration succeeded") elif sign_type == 'pgp': - # send POST to localost on port 11371 which points to our HTTP registration page + # send POST to gpg-mailgate webpanel sig = sign_part payload = {'email': from_addr, 'key': sig} - r = requests.post("http://127.0.0.1:11371", data=payload) - - # format in user-specific data - success_msg = file(cfg['smime']['mail_templates']+"/registrationSuccess.md").read() - success_msg = success_msg.replace("[:FROMADDRESS:]",from_addr) - - msg = MIMEMultipart("alternative") - msg["From"] = cfg['smime']['register_email'] - msg["To"] = from_addr - msg["Subject"] = "S/MIME / OpenPGP key registration succeeded" - - msg.attach(MIMEText(success_msg, 'plain')) - msg.attach(MIMEText(markdown.markdown(success_msg), 'html')) - - log("Registration succeeded") - send_msg(msg, cfg['smime']['register_email'], [from_addr]) + r = requests.post(cfg['mailregister']['webpanel_url'], data=payload) + + log("PGP registration is handed over to GPGMW") # except: # log("Registration exception") # sys.exit(0) diff --git a/register_templates/registrationError.md b/register_templates/registrationError.md new file mode 100644 index 0000000..48edc6a --- /dev/null +++ b/register_templates/registrationError.md @@ -0,0 +1,4 @@ +Could not register a S/MIME certificate or PGP key. + +For S/MIME make sure your message is signed. +For PGP make sure you attach your ASCII-armored public key to the email. diff --git a/templates/ registrationSuccess.md b/register_templates/registrationSuccess.md similarity index 52% rename from templates/ registrationSuccess.md rename to register_templates/registrationSuccess.md index e06e9d3..5e15720 100644 --- a/templates/ registrationSuccess.md +++ b/register_templates/registrationSuccess.md @@ -1,3 +1 @@ Registration was a success. A signature was found in your message, and your S/MIME certificate was saved. - -Mailencrypt.net keeps no logs of message content or metadata (such as To, From, or IP address). diff --git a/templates/registrationError.md b/templates/registrationError.md deleted file mode 100644 index 0caee31..0000000 --- a/templates/registrationError.md +++ /dev/null @@ -1,3 +0,0 @@ -The mailencrypt registration attempt failed. Most likely, the message was not signed, or a application/pkcs7-signature section could not be found. - -Be sure that you're sending your email with signing turned on.