From 86fb5893998e5cf9bf3d0f1342e99760e9375c0e Mon Sep 17 00:00:00 2001 From: Henri Kuiper Date: Mon, 17 Aug 2015 23:54:32 +0200 Subject: [PATCH 1/3] Added detection for _catchall_ addresses --- validate_email.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/validate_email.py b/validate_email.py index 0f18e3e..327d0c0 100644 --- a/validate_email.py +++ b/validate_email.py @@ -51,6 +51,10 @@ class ServerError(Exception): # even when it's not strictly necessary. This way we don't forget # when it is necessary.) # +# Add-on: +# catchall option added to check if this mailhost is +# serving catch-all addresses. NOT FOUL PROOF +# WSP = r'[\s]' # see 2.2.2. Structured Header Field Bodies CRLF = r'(?:\r\n)' # see 2.2.3. Long Header Fields NO_WS_CTL = r'\x01-\x08\x0b\x0c\x0f-\x1f\x7f' # see 3.2.1. Primitive Tokens @@ -109,7 +113,7 @@ def get_mx_ip(hostname): return MX_DNS_CACHE[hostname] -def validate_email(email, check_mx=False, verify=False, debug=False, smtp_timeout=10): +def validate_email(email, check_mx=False, verify=False, catchall=False, debug=False, smtp_timeout=10): """Indicate whether the given string is a valid email address according to the 'addr-spec' portion of RFC 2822 (see section 3.4.1). Parts of the spec that are marked obsolete are *not* @@ -155,6 +159,16 @@ def validate_email(email, check_mx=False, verify=False, debug=False, smtp_timeou continue smtp.mail('') status, _ = smtp.rcpt(email) + if catchall: + import random, string + smtp.quit() + smtp.connect(mx[1]) + smtp.helo() + smtp.mail('') + status, _ = smtp.rcpt(''.join(random.choice(string.lowercase) for i in range(25)) + '@' + email.split('@')[1]) + if status == 250: + smtp.quit() + return False if status == 250: smtp.quit() return True @@ -193,9 +207,15 @@ def validate_email(email, check_mx=False, verify=False, debug=False, smtp_timeou else: validate = False + noca = raw_input('Accept catch-all? [yN] ') + if noca.strip().lower() == 'y': + noca = False + else: + noca = True + logging.basicConfig() - result = validate_email(email, mx, validate, debug=True, smtp_timeout=1) + result = validate_email(email, mx, validate, noca, debug=True, smtp_timeout=1) if result: print("Valid!") elif result is None: From d5f3dea4c158777457eb9f98ee273e6e74f9f4af Mon Sep 17 00:00:00 2001 From: Henri Kuiper Date: Tue, 18 Aug 2015 00:00:07 +0200 Subject: [PATCH 2/3] Better deact default debug :) --- validate_email.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validate_email.py b/validate_email.py index 327d0c0..7d338d5 100644 --- a/validate_email.py +++ b/validate_email.py @@ -215,7 +215,7 @@ def validate_email(email, check_mx=False, verify=False, catchall=False, debug=Fa logging.basicConfig() - result = validate_email(email, mx, validate, noca, debug=True, smtp_timeout=1) + result = validate_email(email, mx, validate, noca, debug=False, smtp_timeout=1) if result: print("Valid!") elif result is None: From bf826bced34eccf40402fd213ecbf31f1c2a71eb Mon Sep 17 00:00:00 2001 From: Henri Kuiper Date: Tue, 18 Aug 2015 21:53:16 +0200 Subject: [PATCH 3/3] Now with catch all support :) --- validate_email.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/validate_email.py b/validate_email.py index 7d338d5..9fab7b4 100644 --- a/validate_email.py +++ b/validate_email.py @@ -169,6 +169,9 @@ def validate_email(email, check_mx=False, verify=False, catchall=False, debug=Fa if status == 250: smtp.quit() return False + if status == 550: + smtp.quit() + return True if status == 250: smtp.quit() return True