EPN: Don't downgrade security

If an administrator requests `smtp_security=starttls`, but SMTP
server disables STARTTLS, then EPN downgrade security to `none`,
which means plain text. Administrator doesn't expect such behavior.

Fixes: https://pagure.io/freeipa/issue/8578
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
Stanislav Levin 2020-11-12 14:45:50 +03:00 committed by Alexander Bokovoy
parent be006ad6c4
commit 94adee3c73
2 changed files with 74 additions and 24 deletions

View File

@ -685,20 +685,14 @@ class MTAClient:
e,
)
if (
self._conn.has_extn("STARTTLS")
and self._security_protocol.lower() == "starttls"
):
if self._security_protocol.lower() == "starttls":
try:
self._conn.starttls()
self._conn.ehlo()
except smtplib.SMTPException as e:
logger.error(
raise RuntimeError(
"IPA-EPN: Unable to create an encrypted session to "
"%s:%s: %s",
self._smtp_hostname,
self._smtp_port,
e,
"%s:%s: %s" % (self._smtp_hostname, self._smtp_port, e)
)
if self._username and self._password:

View File

@ -43,6 +43,25 @@ logger = logging.getLogger(__name__)
EPN_PKG = ["*ipa-client-epn"]
STARTTLS_EPN_CONF = textwrap.dedent(
"""\
[global]
smtp_user={user}
smtp_password={password}
smtp_security=starttls
"""
)
SSL_EPN_CONF = textwrap.dedent(
"""\
[global]
smtp_user={user}
smtp_password={password}
smtp_port=465
smtp_security=ssl
"""
)
def datetime_to_generalized_time(dt):
"""Convert datetime to LDAP_GENERALIZED_TIME_FORMAT
@ -93,6 +112,11 @@ def configure_postfix(host, realm):
postconf(host, 'broken_sasl_auth_clients = yes')
postconf(host, 'smtpd_sasl_authenticated_header = yes')
postconf(host, 'smtpd_sasl_local_domain = %s' % realm)
# TLS will not be used
postconf(host, 'smtpd_tls_security_level = none')
# disable procmail if exists, make use of default local(8) delivery agent
postconf(host, "mailbox_command=")
host.run_command(["systemctl", "restart", "saslauthd"])
@ -144,6 +168,8 @@ def configure_starttls(host):
)
postconf(host, 'smtpd_tls_received_header = yes')
postconf(host, 'smtpd_tls_session_cache_timeout = 3600s')
# announce STARTTLS support to remote SMTP clients, not require
postconf(host, 'smtpd_tls_security_level = may')
host.run_command(["systemctl", "restart", "postfix"])
@ -319,6 +345,43 @@ class TestEPN(IntegrationTest):
stderr_text
assert rc > 0
def test_EPN_no_security_downgrade_starttls(self):
"""Configure postfix without starttls and test no auth happens
"""
epn_conf = STARTTLS_EPN_CONF.format(
user=self.master.config.admin_name,
password=self.master.config.admin_password,
)
self.master.put_file_contents('/etc/ipa/epn.conf', epn_conf)
(unused, stderr_text, rc) = self._check_epn_output(
self.master, mailtest=True,
raiseonerr=False, validatejson=False
)
expected_msg = "IPA-EPN: Unable to create an encrypted session to"
assert expected_msg in stderr_text
assert rc > 0
def test_EPN_no_security_downgrade_tls(self):
"""Configure postfix without tls and test no auth happens
"""
epn_conf = SSL_EPN_CONF.format(
user=self.master.config.admin_name,
password=self.master.config.admin_password,
)
self.master.put_file_contents('/etc/ipa/epn.conf', epn_conf)
(unused, stderr_text, rc) = self._check_epn_output(
self.master, mailtest=True,
raiseonerr=False, validatejson=False
)
expected_msg = (
"IPA-EPN: Could not connect to the configured SMTP "
"server"
)
assert expected_msg in stderr_text
assert rc > 0
def test_EPN_smoketest_1(self):
"""No users except admin. Check --dry-run output.
With the default configuration, the result should be an empty list.
@ -611,13 +674,10 @@ class TestEPN(IntegrationTest):
def test_EPN_starttls(self, cleanupmail):
"""Configure with starttls and test delivery
"""
epn_conf = textwrap.dedent('''
[global]
smtp_user={user}
smtp_password={password}
smtp_security=starttls
'''.format(user=self.master.config.admin_name,
password=self.master.config.admin_password))
epn_conf = STARTTLS_EPN_CONF.format(
user=self.master.config.admin_name,
password=self.master.config.admin_password,
)
self.master.put_file_contents('/etc/ipa/epn.conf', epn_conf)
configure_starttls(self.master)
@ -629,14 +689,10 @@ class TestEPN(IntegrationTest):
def test_EPN_ssl(self, cleanupmail):
"""Configure with ssl and test delivery
"""
epn_conf = textwrap.dedent('''
[global]
smtp_user={user}
smtp_password={password}
smtp_port=465
smtp_security=ssl
'''.format(user=self.master.config.admin_name,
password=self.master.config.admin_password))
epn_conf = SSL_EPN_CONF.format(
user=self.master.config.admin_name,
password=self.master.config.admin_password,
)
self.master.put_file_contents('/etc/ipa/epn.conf', epn_conf)
configure_ssl(self.master)