Fixup UTF-8 string decoding - Thanks to Casper Bruun

This commit is contained in:
Casper Bruun
2022-12-05 20:07:43 -05:00
committed by Scott Kitterman
parent b4da312ea7
commit 1a0abcddc7
2 changed files with 50 additions and 12 deletions
+16
View File
@@ -101,6 +101,10 @@ class dkimMilter(Milter.Base):
if self.conf.get('Syslog') and self.conf.get('debugLevel') >= 1: if self.conf.get('Syslog') and self.conf.get('debugLevel') >= 1:
syslog.syslog("connect from {0} at {1} {2}" syslog.syslog("connect from {0} at {1} {2}"
.format(hostname, hostaddr, connecttype)) .format(hostname, hostaddr, connecttype))
if self.conf.get('Syslog') and self.conf.get('debugLevel') >= 3:
syslog.syslog("internal_conn: {0}, external_conn: {1}"
.format(self.internal_connection, self.external_connection))
return Milter.CONTINUE return Milter.CONTINUE
# multiple messages can be received on a single connection # multiple messages can be received on a single connection
@@ -108,8 +112,15 @@ class dkimMilter(Milter.Base):
# of each message. # of each message.
@Milter.noreply @Milter.noreply
def envfrom(self, f, *moredata): def envfrom(self, f, *moredata):
try:
f = str(codecs.encode(f, 'UTF-8', 'replace'), 'UTF-8', 'ignore') f = str(codecs.encode(f, 'UTF-8', 'replace'), 'UTF-8', 'ignore')
except TypeError:
f = codecs.encode(f, 'UTF-8', 'replace').decode()
try:
moredata = str(codecs.encode(str(moredata), 'UTF-8', 'replace'), 'UTF-8', 'ignore') moredata = str(codecs.encode(str(moredata), 'UTF-8', 'replace'), 'UTF-8', 'ignore')
except TypeError:
moredata = codecs.encode(str(moredata), 'UTF-8', 'replace').decode()
if self.conf.get('Syslog') and self.conf.get('debugLevel') >= 2: if self.conf.get('Syslog') and self.conf.get('debugLevel') >= 2:
syslog.syslog("mail from: {0} {1}".format(f, moredata)) syslog.syslog("mail from: {0} {1}".format(f, moredata))
self.fp = io.BytesIO() self.fp = io.BytesIO()
@@ -144,7 +155,10 @@ class dkimMilter(Milter.Base):
except IndexError as er: except IndexError as er:
pass # self.author was not a proper email address pass # self.author was not a proper email address
# This keeps non-ascii characters out of the From domain # This keeps non-ascii characters out of the From domain
try:
self.fdomain = str(codecs.encode(self.fdomain, 'ascii', 'replace'), 'ascii', 'ignore') self.fdomain = str(codecs.encode(self.fdomain, 'ascii', 'replace'), 'ascii', 'ignore')
except TypeError:
self.fdomain = codecs.encode(self.fdomain, 'ascii', 'replace').decode('ascii','ignore')
if (self.conf.get('Syslog') and if (self.conf.get('Syslog') and
self.conf.get('debugLevel') >= 1): self.conf.get('debugLevel') >= 1):
syslog.syslog("{0}: {1}".format(name, val)) syslog.syslog("{0}: {1}".format(name, val))
@@ -203,6 +217,8 @@ class dkimMilter(Milter.Base):
syslog.syslog('self.domain: {0}, self.fdomain: {1}, self.iequals: {2}'.format(self.domain, self.fdomain, self.iequals)) syslog.syslog('self.domain: {0}, self.fdomain: {1}, self.iequals: {2}'.format(self.domain, self.fdomain, self.iequals))
if ((self.fdomain in self.domain) and not self.conf.get('Mode') == 'v' if ((self.fdomain in self.domain) and not self.conf.get('Mode') == 'v'
and not self.external_connection): and not self.external_connection):
if (self.conf.get('Syslog') and self.conf.get('debugLevel') >= 3):
syslog.syslog("Signing DKIM")
self.sign_dkim(txt) self.sign_dkim(txt)
if ((self.has_dkim) and (not self.internal_connection) and if ((self.has_dkim) and (not self.internal_connection) and
(self.conf.get('Mode') == 'v' or (self.conf.get('Mode') == 'v' or
+23 -1
View File
@@ -88,17 +88,24 @@ class HostsDataset(object):
if self.item[0] == '!': if self.item[0] == '!':
self.item = item[1:] self.item = item[1:]
self.negative = True self.negative = True
try:
try: try:
self.item = ipaddress.ip_address(str(self.item, "utf-8")) self.item = ipaddress.ip_address(str(self.item, "utf-8"))
except TypeError:
self.item = ipaddress.ip_address(self.item)
if isinstance(self.item, ipaddress.IPv4Address): if isinstance(self.item, ipaddress.IPv4Address):
self.isipv4 = True self.isipv4 = True
elif isinstance(self.item, ipaddress.IPv6Address): elif isinstance(self.item, ipaddress.IPv6Address):
self.isipv6 = True self.isipv6 = True
except ValueError as e: except ValueError as e:
try:
try: try:
self.item = ipaddress.ip_network(str self.item = ipaddress.ip_network(str
(self.item, "utf-8"), (self.item, "utf-8"),
strict=False) strict=False)
except TypeError:
self.item = ipaddress.ip_network(self.item,
strict=False)
if isinstance(self.item, ipaddress.IPv4Network): if isinstance(self.item, ipaddress.IPv4Network):
self.isipv4cidr = True self.isipv4cidr = True
elif isinstance(self.item, ipaddress.IPv6Network): elif isinstance(self.item, ipaddress.IPv6Network):
@@ -114,7 +121,10 @@ class HostsDataset(object):
def match(self, connectip): def match(self, connectip):
'''Check if the connect IP is part of the dataset''' '''Check if the connect IP is part of the dataset'''
try:
source = ipaddress.ip_address(str(connectip, "utf-8")) source = ipaddress.ip_address(str(connectip, "utf-8"))
except TypeError:
source = ipaddress.ip_address(connectip)
for item in self.dataset: for item in self.dataset:
if item.isdomain or item.ishostname: if item.isdomain or item.ishostname:
result = self.matchname(source) # Match host/domains first result = self.matchname(source) # Match host/domains first
@@ -164,13 +174,19 @@ class HostsDataset(object):
if isinstance(source, ipaddress.IPv4Address): if isinstance(source, ipaddress.IPv4Address):
ips = s.dns(name, 'A') ips = s.dns(name, 'A')
for ip in ips: for ip in ips:
try:
ip = ipaddress.IPv4Address(str(ip, 'UTF-8')) ip = ipaddress.IPv4Address(str(ip, 'UTF-8'))
except TypeError:
ip = ipaddress.IPv4Address(ip)
if ip == source: if ip == source:
results.append(name) results.append(name)
if isinstance(source, ipaddress.IPv6Address): if isinstance(source, ipaddress.IPv6Address):
ips = s.dns(name, 'AAAA') ips = s.dns(name, 'AAAA')
for ip in ips: for ip in ips:
try:
ip = ipaddress.IPv6Address(str(ip, 'UTF-8')) ip = ipaddress.IPv6Address(str(ip, 'UTF-8'))
except TypeError:
ip = ipaddress.IPv6Address(ip)
if ip == source: if ip == source:
results.append(name) results.append(name)
return results return results
@@ -439,8 +455,14 @@ def _readConfigFile(path, configData=None, configGlobal={}):
fp.close() fp.close()
try: try:
configData['AuthservID'] = _make_authserv_id(configData.get('AuthservID', 'HOSTNAME')) configData['AuthservID'] = _make_authserv_id(configData.get('AuthservID', 'HOSTNAME'))
except Exception as e:
syslog.syslog("Could not make AuthservID: {}".format(e))
pass
try:
configData['IntHosts'] = HostsDataset(configData['InternalHosts']) configData['IntHosts'] = HostsDataset(configData['InternalHosts'])
except: except Exception as e:
syslog.syslog("Could not make HostDataset from InternalHosts: {}".format(e))
pass pass
return(configData) return(configData)