Browse Source

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)
pull/33/head
fkrone 7 years ago
parent
commit
f7e3b16069
  1. 5
      README.md
  2. 1
      cron_templates/keyDeleted.md
  3. 3
      cron_templates/registrationError.md
  4. 1
      cron_templates/registrationSuccess.md
  5. 24
      gpg-mailgate-web/cron.py
  6. 13
      gpg-mailgate.conf.sample
  7. 52
      register-handler.py
  8. 4
      register_templates/registrationError.md
  9. 2
      register_templates/registrationSuccess.md
  10. 3
      templates/registrationError.md

5
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 <mcmaster@aphrodite.hurricanelabs.rsoc>
* Igor Rzegocki <ajgon@irgon.com> - [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

1
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.

3
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.

1
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.

24
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()

13
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.

52
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)

4
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.

2
templates/ registrationSuccess.md → 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).

3
templates/registrationError.md

@ -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.
Loading…
Cancel
Save