Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
bc6d706dc7
|
|||
|
5212201cd1
|
|||
|
1130ec8e95
|
|||
|
5dd76e327c
|
|||
|
d5f030151f
|
|||
|
d7f8f40e03
|
|||
|
ed5575bd2d
|
|||
|
0f4da248e7
|
|||
|
9e7106ff0b
|
|||
|
91144643f3
|
|||
|
a4c2ec3952
|
|||
|
375728e452
|
@@ -2,7 +2,7 @@
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
|
||||
EAPI=7
|
||||
PYTHON_COMPAT=( python3_{9,10} )
|
||||
PYTHON_COMPAT=( python3_{9..10} )
|
||||
DISTUTILS_USE_SETUPTOOLS=rdepend
|
||||
|
||||
SCM=""
|
||||
@@ -37,7 +37,7 @@ RDEPEND="
|
||||
lxml? ( dev-python/lxml[${PYTHON_USEDEP}] )
|
||||
dev-python/netaddr[${PYTHON_USEDEP}]
|
||||
dev-python/peewee[${PYTHON_USEDEP}]
|
||||
dev-python/pymilter[${PYTHON_USEDEP}]"
|
||||
>=dev-python/pymilter-1.5[${PYTHON_USEDEP}]"
|
||||
|
||||
python_install_all() {
|
||||
distutils-r1_python_install_all
|
||||
|
||||
@@ -27,7 +27,7 @@ __all__ = [
|
||||
"whitelist",
|
||||
"QuarantineMilter"]
|
||||
|
||||
__version__ = "2.0.2"
|
||||
__version__ = "2.0.6"
|
||||
|
||||
from pyquarantine import _runtime_patches
|
||||
|
||||
@@ -100,7 +100,7 @@ class QuarantineMilter(Milter.Base):
|
||||
self.logger.warning(f"unable to serialize message as bytes: {e}")
|
||||
try:
|
||||
self.logger.warning("try to serialize as str and encode")
|
||||
data = self.msg.as_string().encode("ascii", errors="replace")
|
||||
data = self.msg.as_string().encode(errors="replace")
|
||||
except Exception as e:
|
||||
self.logger.error(
|
||||
f"unable to serialize message, giving up: {e}")
|
||||
@@ -208,6 +208,7 @@ class QuarantineMilter(Milter.Base):
|
||||
|
||||
return Milter.CONTINUE
|
||||
|
||||
@Milter.decode("replace")
|
||||
def envfrom(self, mailfrom, *str):
|
||||
try:
|
||||
self.mailfrom = "@".join(parse_addr(mailfrom)).lower()
|
||||
@@ -219,6 +220,7 @@ class QuarantineMilter(Milter.Base):
|
||||
|
||||
return Milter.CONTINUE
|
||||
|
||||
@Milter.decode("replace")
|
||||
def envrcpt(self, to, *str):
|
||||
try:
|
||||
self.rcpts.add("@".join(parse_addr(to)).lower())
|
||||
@@ -243,6 +245,7 @@ class QuarantineMilter(Milter.Base):
|
||||
|
||||
return Milter.CONTINUE
|
||||
|
||||
@Milter.decode("replace")
|
||||
def header(self, field, value):
|
||||
try:
|
||||
# remove CR and LF from address fields, otherwise pythons
|
||||
@@ -262,7 +265,7 @@ class QuarantineMilter(Milter.Base):
|
||||
field = field.encode("ascii", errors="replace")
|
||||
value = value.encode("ascii", errors="replace")
|
||||
|
||||
self.fp.write(field + b": " + value + b"\r\n")
|
||||
self.fp.write(field.encode() + b": " + value.encode() + b"\r\n")
|
||||
except Exception as e:
|
||||
self.logger.exception(
|
||||
f"an exception occured in header method: {e}")
|
||||
|
||||
@@ -21,14 +21,18 @@ import shutil
|
||||
import sys
|
||||
|
||||
|
||||
SYSTEMD_PATH = "/lib/systemd/system"
|
||||
SYSTEMD_PATHS = ["/lib/systemd/system", "/usr/lib/systemd/system"]
|
||||
OPENRC = "/sbin/openrc"
|
||||
|
||||
|
||||
def _systemd_files(pkg_dir, name):
|
||||
for path in SYSTEMD_PATHS:
|
||||
if os.path.isdir(path):
|
||||
break
|
||||
|
||||
return [
|
||||
(f"{pkg_dir}/misc/systemd/{name}-milter.service",
|
||||
f"{SYSTEMD_PATH}/{name}-milter.service", True)]
|
||||
f"{path}/{name}-milter.service", True)]
|
||||
|
||||
|
||||
def _openrc_files(pkg_dir, name):
|
||||
@@ -117,7 +121,11 @@ def _check_root():
|
||||
|
||||
|
||||
def _check_systemd():
|
||||
systemd = os.path.isdir(SYSTEMD_PATH)
|
||||
for path in SYSTEMD_PATHS:
|
||||
systemd = os.path.isdir(path)
|
||||
if systemd:
|
||||
break
|
||||
|
||||
if systemd:
|
||||
logging.info("systemd detected")
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# along with pyquarantine. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from sys import version_info
|
||||
import encodings
|
||||
|
||||
|
||||
@@ -150,27 +151,45 @@ def get_obs_local_part(value):
|
||||
setattr(email._header_value_parser, "get_obs_local_part", get_obs_local_part)
|
||||
|
||||
|
||||
# https://bugs.python.org/issue30681
|
||||
#######################################
|
||||
# add charset alias for windows-874 #
|
||||
#######################################
|
||||
#
|
||||
# fix: https://github.com/python/cpython/pull/22090
|
||||
# https://bugs.python.org/issue17254
|
||||
#
|
||||
# fix: https://github.com/python/cpython/pull/10237
|
||||
|
||||
import email.errors
|
||||
from email.errors import HeaderDefect
|
||||
aliases = encodings.aliases.aliases
|
||||
|
||||
for alias in ["windows-874", "windows_874"]:
|
||||
if alias not in aliases:
|
||||
aliases[alias] = "cp874"
|
||||
|
||||
setattr(encodings.aliases, "aliases", aliases)
|
||||
|
||||
|
||||
class InvalidDateDefect(HeaderDefect):
|
||||
if version_info.major == 3 and version_info.minor < 10:
|
||||
# https://bugs.python.org/issue30681
|
||||
#
|
||||
# fix: https://github.com/python/cpython/pull/22090
|
||||
|
||||
import email.errors
|
||||
from email.errors import HeaderDefect
|
||||
|
||||
|
||||
class InvalidDateDefect(HeaderDefect):
|
||||
"""Header has unparseable or invalid date"""
|
||||
|
||||
|
||||
setattr(email.errors, "InvalidDateDefect", InvalidDateDefect)
|
||||
setattr(email.errors, "InvalidDateDefect", InvalidDateDefect)
|
||||
|
||||
|
||||
import email.utils
|
||||
from email.utils import _parsedate_tz
|
||||
import datetime
|
||||
import email.utils
|
||||
from email.utils import _parsedate_tz
|
||||
import datetime
|
||||
|
||||
|
||||
def parsedate_to_datetime(data):
|
||||
def parsedate_to_datetime(data):
|
||||
parsed_date_tz = _parsedate_tz(data)
|
||||
if parsed_date_tz is None:
|
||||
raise ValueError('Invalid date value or format "%s"' % str(data))
|
||||
@@ -181,14 +200,14 @@ def parsedate_to_datetime(data):
|
||||
tzinfo=datetime.timezone(datetime.timedelta(seconds=tz)))
|
||||
|
||||
|
||||
setattr(email.utils, "parsedate_to_datetime", parsedate_to_datetime)
|
||||
setattr(email.utils, "parsedate_to_datetime", parsedate_to_datetime)
|
||||
|
||||
|
||||
import email.headerregistry
|
||||
from email import utils, _header_value_parser as parser
|
||||
import email.headerregistry
|
||||
from email import utils, _header_value_parser as parser
|
||||
|
||||
@classmethod
|
||||
def parse(cls, value, kwds):
|
||||
@classmethod
|
||||
def parse(cls, value, kwds):
|
||||
if not value:
|
||||
kwds['defects'].append(errors.HeaderMissingRequiredValue())
|
||||
kwds['datetime'] = None
|
||||
@@ -209,21 +228,4 @@ def parse(cls, value, kwds):
|
||||
kwds['parse_tree'] = cls.value_parser(kwds['decoded'])
|
||||
|
||||
|
||||
setattr(email.headerregistry.DateHeader, "parse", parse)
|
||||
|
||||
|
||||
#######################################
|
||||
# add charset alias for windows-874 #
|
||||
#######################################
|
||||
#
|
||||
# https://bugs.python.org/issue17254
|
||||
#
|
||||
# fix: https://github.com/python/cpython/pull/10237
|
||||
|
||||
aliases = encodings.aliases.aliases
|
||||
|
||||
for alias in ["windows-874", "windows_874"]:
|
||||
if alias not in aliases:
|
||||
aliases[alias] = "cp874"
|
||||
|
||||
setattr(encodings.aliases, "aliases", aliases)
|
||||
setattr(email.headerregistry.DateHeader, "parse", parse)
|
||||
|
||||
@@ -162,8 +162,9 @@ class MilterMessage(MIMEPart):
|
||||
def inject_body_part(part, content, subtype="plain"):
|
||||
parts = []
|
||||
text_body = None
|
||||
text_content = None
|
||||
if subtype == "html":
|
||||
text_body = part.get_body(preferencelist=("plain"))
|
||||
text_body, text_content = part.get_body_content("plain")
|
||||
|
||||
for p in part.iter_parts():
|
||||
if text_body and p == text_body:
|
||||
@@ -173,8 +174,8 @@ def inject_body_part(part, content, subtype="plain"):
|
||||
boundary = part.get_boundary()
|
||||
p_subtype = part.get_content_subtype()
|
||||
part.clear_content()
|
||||
if text_body:
|
||||
part.set_content(content)
|
||||
if text_content != None:
|
||||
part.set_content(text_content)
|
||||
part.add_alternative(content, subtype=subtype)
|
||||
else:
|
||||
part.set_content(content, subtype=subtype)
|
||||
|
||||
@@ -135,7 +135,7 @@ def main():
|
||||
sysloghandler = logging.handlers.SysLogHandler(
|
||||
address="/dev/log", facility=logging.handlers.SysLogHandler.LOG_MAIL)
|
||||
sysloghandler.setFormatter(
|
||||
logging.Formatter("pyquarantine: %(message)s"))
|
||||
logging.Formatter(f"{name}[%(process)d]: %(message)s"))
|
||||
root_logger.addHandler(sysloghandler)
|
||||
|
||||
logger.info("milter starting")
|
||||
|
||||
6
setup.py
6
setup.py
@@ -18,7 +18,7 @@ setup(name = "pyquarantine",
|
||||
# 3 - Alpha
|
||||
# 4 - Beta
|
||||
# 5 - Production/Stable
|
||||
"Development Status :: 4 - Beta",
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python",
|
||||
@@ -48,6 +48,6 @@ setup(name = "pyquarantine",
|
||||
]
|
||||
)
|
||||
],
|
||||
install_requires = ["pymilter", "jsonschema", "netaddr", "beautifulsoup4[lxml]", "peewee"],
|
||||
python_requires = ">=3.8"
|
||||
install_requires = ["pymilter >= 1.5", "jsonschema", "netaddr", "beautifulsoup4[lxml]", "peewee"],
|
||||
python_requires = ">=3.9"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user