The unified diff between revisions [13065dec..] and [98cca741..] is displayed below. It can also be downloaded as a raw diff.
#
#
# add_file "policy.py"
# content [fec54191bced3e6c8fcccaaf40868a0d019a5599]
#
# patch "addrhash.py"
# from [86b3852b1b32d5902b03ae26bf9f0d1c86556fe5]
# to [e337a3b9a2b6b89e5e8fa50962021781328339cc]
#
# set "policy.py"
# attr "mtn:execute"
# value "true"
#
============================================================
--- policy.py fec54191bced3e6c8fcccaaf40868a0d019a5599
+++ policy.py fec54191bced3e6c8fcccaaf40868a0d019a5599
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+from Crypto.Hash import MD5
+import addrhash
+import config
+import rfc822
+import sys
+
+if __name__ == '__main__':
+ # verify incoming email addresses; see if they're
+ # trying to brute-force us, and log that. otherwise,
+ # let the mail through and we'll log more about the
+ # message on delivery to that script
+
+ def check(req):
+ if not req.has_key('recipient'):
+ return "DUNNO"
+ try:
+ user = req['recipient']
+ user_at = user.find('@')
+ if user_at == -1:
+ return "DUNNO"
+ user = user[:user_at]
+ addrhash.decode(user)
+ except addrhash.GaisdeException, e:
+ return "REJECT 450 User unknown."
+
+ return "PREPEND X-Gaisde: HMAC-verified"
+
+ req = {}
+ while True:
+ line = sys.stdin.readline()
+ if line == '':
+ break
+ line = line.strip()
+ if not line:
+ try: response = check(req)
+ except: response = "DUNNO"
+ print response
+ req = {}
+ else:
+ sp = line.split('=', 1)
+ if len(sp) != 2:
+ continue
+ req[sp[0]] = sp[1]
+
============================================================
--- addrhash.py 86b3852b1b32d5902b03ae26bf9f0d1c86556fe5
+++ addrhash.py e337a3b9a2b6b89e5e8fa50962021781328339cc
@@ -7,6 +7,9 @@ import base64
import socket
import base64
+class GaisdeException(Exception):
+ pass
+
def get_cipher():
sha = SHA256.new()
sha.update(config.aes_key)
@@ -32,7 +35,7 @@ def strip_hmac_and_verify(val):
def strip_hmac_and_verify(val):
their_mac, val = val[:12], val[12:]
if their_mac != mac_value(val):
- raise Exception("HMAC does not verify!")
+ raise GaisdeException("hmac")
return val
def encode(ip_string):
@@ -41,9 +44,12 @@ def decode(email_address):
return base64.encodestring(enc).rstrip('\n').rstrip('==')
def decode(email_address):
- bytes = base64.decodestring(email_address + '==\n')
+ try:
+ bytes = base64.decodestring(email_address + '==\n')
+ except:
+ raise GaisdeException("base64")
if len(bytes) != 16:
- raise Exception("This is not a valid email address.")
+ raise GaisdeException("length")
decoded = get_cipher().decrypt(bytes)
decoded = strip_hmac_and_verify(decoded)
return our_ntop(decoded)