Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""
if tag == "ERR":
d_class = InvalidDiagnosis
elif tag == "DNSWARN":
d_class = DNSDiagnosis
elif tag == "VALID":
d_class = ValidDiagnosis
elif tag == "RFC5321":
d_class = RFC5321Diagnosis
elif tag == "VALID":
d_class = ValidDiagnosis
elif tag == "RFC5321":
d_class = RFC5321Diagnosis
elif tag == "RFC5322":
d_class = RFC5322Diagnosis
elif tag == "CFWS":
d_class = CFWSDiagnosis
elif tag == "DEPREC":
d_class = DeprecatedDiagnosis
else:
d_class = ""
return d_class
return_status.append(
RFC5322Diagnosis('DOMAINLITERAL'))
else:
ipv6 = address_literal[5:]
# Revision 2.7: Daniel Marschall's new IPv6
# testing strategy
match_ip = ipv6.split(Char.COLON)
grp_count = len(match_ip)
index = ipv6.find(Char.DOUBLECOLON)
if index == -1:
# We need exactly the right number of
# groups
if grp_count != max_groups:
return_status.append(
RFC5322Diagnosis('IPV6_GRPCOUNT'))
else:
if index != ipv6.rfind(Char.DOUBLECOLON):
return_status.append(
RFC5322Diagnosis('IPV6_2X2XCOLON'))
else:
if index in [0, len(ipv6) - 2]:
# RFC 4291 allows :: at the start
# or end of an address with 7 other
# groups in addition
max_groups += 1
if grp_count > max_groups:
return_status.append(
RFC5322Diagnosis(
'IPV6_MAXGRPS'))
elif grp_count == max_groups:
# Revision 2.7: Daniel Marschall's new IPv6
# testing strategy
match_ip = ipv6.split(Char.COLON)
grp_count = len(match_ip)
index = ipv6.find(Char.DOUBLECOLON)
if index == -1:
# We need exactly the right number of
# groups
if grp_count != max_groups:
return_status.append(
RFC5322Diagnosis('IPV6_GRPCOUNT'))
else:
if index != ipv6.rfind(Char.DOUBLECOLON):
return_status.append(
RFC5322Diagnosis('IPV6_2X2XCOLON'))
else:
if index in [0, len(ipv6) - 2]:
# RFC 4291 allows :: at the start
# or end of an address with 7 other
# groups in addition
max_groups += 1
if grp_count > max_groups:
return_status.append(
RFC5322Diagnosis(
'IPV6_MAXGRPS'))
elif grp_count == max_groups:
# Eliding a single "::"
return_status.append(
RFC5321Diagnosis(
'IPV6DEPRECATED'))
# the domain part of a Mailbox must be a valid
# domain according to the DNS standards set out in
# RFC 1035, but this *is* implied in several
# places. For instance, wherever the idea of host
# routing is discussed the RFC says that the domain
# must be looked up in the DNS. This would be
# nonsense unless the domain was designed to be a
# valid DNS domain. Hence we must conclude that the
# RFC 1035 restriction on label length also applies
# to RFC 5321 domains.
#
# http://tools.ietf.org/html/rfc1035#section-2.3.4
# labels 63 octets or less
if element_len > 63:
return_status.append(
RFC5322Diagnosis('LABEL_TOOLONG'))
# CFWS is OK again now we're at the beginning of an
# element (although it may be obsolete CFWS)
end_or_die = False
element_len = 0
element_count += 1
atom_list[Context.DOMAIN].append('')
parse_data[Context.DOMAIN] += token
# Domain literal
elif token == Char.OPENSQBRACKET:
if parse_data[Context.DOMAIN] == '':
# Domain literal must be the only component
end_or_die = True
element_len += 1
context_stack.append(context)
context = Context.LITERAL
else:
return False
if parse_data[Context.LOCALPART] == '':
# Fatal error
return_status.append(
InvalidDiagnosis('NOLOCALPART'))
elif element_len == 0:
# Fatal error
return_status.append(InvalidDiagnosis('DOT_END'))
# http://tools.ietf.org/html/rfc5321#section-4.5.3.1.1
# The maximum total length of a user name or other
# local-part is 64 octets.
elif len(parse_data[Context.LOCALPART]) > 64:
return_status.append(
RFC5322Diagnosis('LOCAL_TOOLONG'))
# http://tools.ietf.org/html/rfc5322#section-3.4.1
# Comments and folding white space
# SHOULD NOT be used around the "@" in the addr-spec.
#
# http://tools.ietf.org/html/rfc2119
# 4. SHOULD NOT This phrase, or the phrase "NOT
# RECOMMENDED" mean that there may exist valid
# reasons in particular circumstances when the
# particular behavior is acceptable or even useful,
# but the full implications should be understood and
# the case carefully weighed before implementing any
# behavior described with this label.
elif context_prior in [Context.COMMENT, Context.FWS]:
return_status.append(
DeprecatedDiagnosis('CFWS_NEAR_AT'))
return_status.append(
RFC5321Diagnosis(
'IPV6DEPRECATED'))
# Revision 2.7: Daniel Marschall's new IPv6
# testing strategy
if (ipv6[0] == Char.COLON and
ipv6[1] != Char.COLON):
# Address starts with a single colon
return_status.append(
RFC5322Diagnosis('IPV6_COLONSTRT'))
elif (ipv6[-1] == Char.COLON and
ipv6[-2] != Char.COLON):
# Address ends with a single colon
return_status.append(
RFC5322Diagnosis('IPV6_COLONEND'))
elif ([re.match(r"^[0-9A-Fa-f]{0,4}$", i)
for i in match_ip].count(None) != 0):
# Check for unmatched characters
return_status.append(
RFC5322Diagnosis('IPV6_BADCHAR'))
else:
return_status.append(
RFC5321Diagnosis('ADDRESSLITERAL'))
else:
return_status.append(
RFC5322Diagnosis('DOMAINLITERAL'))
parse_data[Context.DOMAIN] += token
atom_list[Context.DOMAIN][element_count] += token
element_len += 1
context_prior = context
# The maximum total length of a reverse-path or forward-path is
# 256 octets (including the punctuation and element separators).
#
# Thus, even without (obsolete) routing information, the Mailbox
# can only be 254 characters long. This is confirmed by this
# verified erratum to RFC 3696:
#
# http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690
# However, there is a restriction in RFC 2821 on the length of an
# address in MAIL and RCPT commands of 254 characters. Since
# addresses that do not fit in those fields are not normally
# useful, the upper limit on address lengths should normally be
# considered to be 254.
elif len(parse_data[Context.LOCALPART] + Char.AT +
parse_data[Context.DOMAIN]) > 254:
return_status.append(RFC5322Diagnosis('TOOLONG'))
# http://tools.ietf.org/html/rfc1035#section-2.3.4
# labels 63 octets or less
elif element_len > 63:
return_status.append(RFC5322Diagnosis('LABEL_TOOLONG'))
return_status = list(set(return_status))
final_status = max(return_status)
if len(return_status) != 1:
# Remove redundant ValidDiagnosis
return_status.pop(0)
parse_data['status'] = return_status
if final_status < threshold:
final_status = ValidDiagnosis()
elif token == Char.CR:
# Fatal error
return_status.append(InvalidDiagnosis('FWS_CRLF_END'))
elif parse_data[Context.DOMAIN] == '':
# Fatal error
return_status.append(InvalidDiagnosis('NODOMAIN'))
elif element_len == 0:
# Fatal error
return_status.append(InvalidDiagnosis('DOT_END'))
elif hyphen_flag:
# Fatal error
return_status.append(InvalidDiagnosis('DOMAINHYPHENEND'))
# http://tools.ietf.org/html/rfc5321#section-4.5.3.1.2
# The maximum total length of a domain name or number is 255 octets
elif len(parse_data[Context.DOMAIN]) > 255:
return_status.append(RFC5322Diagnosis('DOMAIN_TOOLONG'))
# http://tools.ietf.org/html/rfc5321#section-4.1.2
# Forward-path = Path
#
# Path = "<" [ A-d-l ":" ] Mailbox ">"
#
# http://tools.ietf.org/html/rfc5321#section-4.5.3.1.3
# The maximum total length of a reverse-path or forward-path is
# 256 octets (including the punctuation and element separators).
#
# Thus, even without (obsolete) routing information, the Mailbox
# can only be 254 characters long. This is confirmed by this
# verified erratum to RFC 3696:
#
# http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690
# However, there is a restriction in RFC 2821 on the length of an
# address in MAIL and RCPT commands of 254 characters. Since
# testing strategy
if (ipv6[0] == Char.COLON and
ipv6[1] != Char.COLON):
# Address starts with a single colon
return_status.append(
RFC5322Diagnosis('IPV6_COLONSTRT'))
elif (ipv6[-1] == Char.COLON and
ipv6[-2] != Char.COLON):
# Address ends with a single colon
return_status.append(
RFC5322Diagnosis('IPV6_COLONEND'))
elif ([re.match(r"^[0-9A-Fa-f]{0,4}$", i)
for i in match_ip].count(None) != 0):
# Check for unmatched characters
return_status.append(
RFC5322Diagnosis('IPV6_BADCHAR'))
else:
return_status.append(
RFC5321Diagnosis('ADDRESSLITERAL'))
else:
return_status.append(
RFC5322Diagnosis('DOMAINLITERAL'))
parse_data[Context.DOMAIN] += token
atom_list[Context.DOMAIN][element_count] += token
element_len += 1
context_prior = context
context = context_stack.pop()
elif token == Char.BACKSLASH:
return_status.append(
RFC5322Diagnosis('DOMLIT_OBSDTEXT'))
context_stack.append(context)