Files @ e9c5e116996a
Branch filter:

Location: majic-ansible-roles/roles/mail_server/molecule/default/tests/test_optional.py - annotation

branko
MAR-152: Drop support for Debian 8 Jessie from the database_server role.
b0c92677ba93
277c561f3f52
663c02da41b8
5c5d8636f699
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
d62b3adec462
277c561f3f52
277c561f3f52
d7f5980cc68a
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
226882a5ed41
137b611e9d5e
d7f5980cc68a
277c561f3f52
137b611e9d5e
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
137b611e9d5e
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
137b611e9d5e
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
137b611e9d5e
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
d7f5980cc68a
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
226882a5ed41
137b611e9d5e
137b611e9d5e
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
137b611e9d5e
277c561f3f52
137b611e9d5e
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
137b611e9d5e
277c561f3f52
277c561f3f52
d7f5980cc68a
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
d7f5980cc68a
226882a5ed41
277c561f3f52
137b611e9d5e
277c561f3f52
277c561f3f52
d7f5980cc68a
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
5c5d8636f699
5c5d8636f699
5c5d8636f699
5c5d8636f699
5c5d8636f699
5c5d8636f699
5c5d8636f699
5c5d8636f699
226882a5ed41
137b611e9d5e
d7f5980cc68a
277c561f3f52
277c561f3f52
137b611e9d5e
137b611e9d5e
5c5d8636f699
137b611e9d5e
137b611e9d5e
277c561f3f52
277c561f3f52
f774e938a4ed
277c561f3f52
277c561f3f52
d7f5980cc68a
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
5c5d8636f699
5c5d8636f699
5c5d8636f699
663c02da41b8
277c561f3f52
277c561f3f52
d7f5980cc68a
d7f5980cc68a
6c1d08d39449
277c561f3f52
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
44d578f5e1f3
44d578f5e1f3
d7f5980cc68a
44d578f5e1f3
d7f5980cc68a
44d578f5e1f3
44d578f5e1f3
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
44d578f5e1f3
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
5c5d8636f699
5c5d8636f699
5c5d8636f699
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
5c5d8636f699
5c5d8636f699
5c5d8636f699
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
5c5d8636f699
5c5d8636f699
5c5d8636f699
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
d7f5980cc68a
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
import os
import re
import time
import uuid

import testinfra.utils.ansible_runner


testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-optional')


def test_smtp_tls_files(host):
    """
    Tests if SMTP TLS private key has been deployed correctly.
    """

    hostname = host.run('hostname').stdout.strip()

    with host.sudo():

        tls_file = host.file('/etc/ssl/private/%s_smtp.key' % hostname)
        assert tls_file.is_file
        assert tls_file.user == 'root'
        assert tls_file.group == 'root'
        assert tls_file.mode == 0o640
        assert tls_file.content == open("tests/data/x509/parameters-optional_smtp.key.pem", "r").read().rstrip()

        tls_file = host.file('/etc/ssl/certs/%s_smtp.pem' % hostname)
        assert tls_file.is_file
        assert tls_file.user == 'root'
        assert tls_file.group == 'root'
        assert tls_file.mode == 0o644
        assert tls_file.content == open("tests/data/x509/parameters-optional_smtp.cert.pem", "r").read().rstrip()

        tls_file = host.file('/etc/ssl/private/%s_imap.key' % hostname)
        assert tls_file.is_file
        assert tls_file.user == 'root'
        assert tls_file.group == 'root'
        assert tls_file.mode == 0o640
        assert tls_file.content == open("tests/data/x509/parameters-optional_imap.key.pem", "r").read().rstrip()

        tls_file = host.file('/etc/ssl/certs/%s_imap.pem' % hostname)
        assert tls_file.is_file
        assert tls_file.user == 'root'
        assert tls_file.group == 'root'
        assert tls_file.mode == 0o644
        assert tls_file.content == open("tests/data/x509/parameters-optional_imap.cert.pem", "r").read().rstrip()


def test_certificate_validity_check_configuration(host):
    """
    Tests if certificate validity check configuration file has been deployed
    correctly.
    """

    hostname = host.run('hostname').stdout.strip()

    config = host.file('/etc/check_certificate/%s_smtp.conf' % hostname)
    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644
    assert config.content == "/etc/ssl/certs/%s_smtp.pem" % hostname

    config = host.file('/etc/check_certificate/%s_imap.conf' % hostname)
    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644
    assert config.content == "/etc/ssl/certs/%s_imap.pem" % hostname


def test_mailname_file_content(host):
    """
    Tests the system mail name file content.
    """

    mailname = host.file('/etc/mailname')
    hostname = host.run('hostname').stdout.strip()

    assert mailname.content == hostname


def test_postfix_main_cf_file_content(host):
    """
    Tests if the Postfix main configuration file content is correct.
    """

    # Ugly hack, but not sure how to make it work otherwise. IP
    # address of client1 (jessie/stretch variant).
    distribution_release = host.ansible("setup")["ansible_facts"]["ansible_distribution_release"]
    if distribution_release == "jessie":
        allow_relay_from_ip = "10.31.127.20"
    elif distribution_release == "stretch":
        allow_relay_from_ip = "10.31.127.22"

    hostname = host.run('hostname').stdout.strip()

    config = host.file('/etc/postfix/main.cf')
    config_lines = config.content.split("\n")

    assert "myhostname = %s" % hostname in config_lines
    assert "mydestination = %s, %s, localhost.localdomain, localhost" % (hostname, hostname) in config_lines
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 %s" % allow_relay_from_ip in config_lines
    assert "smtpd_tls_cert_file = /etc/ssl/certs/%s_smtp.pem" % hostname in config_lines
    assert "smtpd_tls_key_file = /etc/ssl/private/%s_smtp.key" % hostname in config_lines
    assert "  reject_rbl bl.spamcop.net" in config_lines
    assert "  reject_rbl zen.spamhaus.org" in config_lines
    assert "smtp_host_lookup = dns, native" in config_lines


def test_local_aliases(host):
    """
    Tests if local aliases are configured correctly.
    """

    message_id = str(uuid.uuid4())

    send = host.run('swaks --header %s --suppress-data --to root@localhost', "Message-Id: <%s>" % message_id)
    time.sleep(1)
    assert send.rc == 0

    with host.sudo():
        mail_log = host.file('/var/log/mail.log')
        pattern = r"dovecot: lda\(john.doe@domain1\): msgid=<%s>: saved mail to INBOX" % message_id
        assert re.search(pattern, mail_log.content) is not None


def test_dovecot_mailbox_directories(host):
    """
    Tests if mailbox directories are created correctly.
    """

    # Deliver two mails in order to make sure the directory structure is
    # created.
    send = host.run('swaks --suppress-data --to john.doe@domain1 --server localhost')
    assert send.rc == 0
    send = host.run('swaks --suppress-data --to jane.doe@domain2 --server localhost')
    assert send.rc == 0

    with host.sudo():

        for directory_path in ["/var/virtmail/domain1",
                               "/var/virtmail/domain1/john.doe",
                               "/var/virtmail/domain1/john.doe/Maildir",
                               "/var/virtmail/domain2",
                               "/var/virtmail/domain2/jane.doe",
                               "/var/virtmail/domain2/jane.doe/Maildir"]:

            directory = host.file(directory_path)

            assert directory.is_directory
            assert directory.user == "virtmail"
            assert directory.group == "virtmail"
            assert directory.mode == 0o700


def test_mail_owner(host):
    """
    Tests creation of mail owner group and user.
    """

    group = host.group("virtmail")
    assert group.exists
    assert group.gid == 5000

    user = host.user("virtmail")
    assert user.exists
    assert user.uid == 5000
    assert user.home == "/var/virtmail"
    assert user.group == "virtmail"
    assert user.groups == ["virtmail"]


def test_imap_tls_configuration(host):
    """
    Tests TLS configuration for IMAP in Dovecot.
    """

    # Test plain connectivity first.
    starttls = host.run('echo "a0001 LOGOUT" | openssl s_client -quiet -starttls imap -connect parameters-optional:143')
    assert starttls.rc == 0
    assert '* BYE Logging out' in starttls.stdout

    tls = host.run('echo "a0001 LOGOUT" | openssl s_client -quiet -connect parameters-optional:993')
    assert tls.rc == 0
    assert '* BYE Logging out' in starttls.stdout

    # Test TLS protocol versions.
    starttls = host.run('echo "a0001 LOGOUT" | openssl s_client -quiet -starttls imap -no_tls1_2 -connect parameters-optional:143')
    assert starttls.rc == 0
    assert '* BYE Logging out' in starttls.stdout

    tls = host.run('echo "a0001 LOGOUT" | openssl s_client -quiet -no_tls1_2 -connect parameters-optional:993')
    assert tls.rc == 0
    assert '* BYE Logging out' in starttls.stdout

    starttls = host.run("echo 'a0001 LOGOUT' | openssl s_client -quiet -starttls imap -no_tls1_1 -no_tls1_2 -connect parameters-optional:143")
    assert starttls.rc != 0
    # First error message from OpenSSL in Debian 8 Jessie, second from
    # OpenSSL in Debian 9 Stretch.
    assert "write:errno=104" in starttls.stderr or 'SSL alert number 70' in starttls.stderr

    tls = host.run("echo 'a0001 LOGOUT' | openssl s_client -quiet -no_tls1_1 -no_tls1_2 -connect parameters-optional:993")
    assert tls.rc != 0
    # First error message from OpenSSL in Debian 8 Jessie, second from
    # OpenSSL in Debian 9 Stretch.
    assert "write:errno=104" in tls.stderr or 'SSL alert number 70' in tls.stderr

    # Test at least one strong TLS cipher.
    starttls_cipher = host.run("echo 'a0001 LOGOUT' | openssl s_client -starttls imap -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:143")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in starttls_cipher.stdout

    tls_cipher = host.run("echo 'a0001 LOGOUT' | openssl s_client -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:993")
    assert tls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in tls_cipher.stdout

    # Test weaker TLS cipher that was explicitly configured
    starttls_cipher = host.run("echo 'a0001 LOGOUT' | openssl s_client -starttls imap -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:143")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA" in starttls_cipher.stdout

    tls_cipher = host.run("echo 'a0001 LOGOUT' | openssl s_client -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:993")
    assert tls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA" in tls_cipher.stdout


def test_dovecot_postmaster(host):
    """
    Tests if Dovecot postmaster has been correctly configured.
    """

    with host.sudo():

        config = host.run("doveadm config")

        assert config.rc == 0
        assert "  postmaster_address = webmaster@parameters-optional" in config.stdout


def test_imap_max_user_connections_per_ip(host):
    """
    Tests if Dovecot per-user connection limit has been set-up correctly.
    """

    with host.sudo():

        config = host.run("doveadm config")

        assert config.rc == 0
        assert "  mail_max_userip_connections = 2" in config.stdout


def test_postfix_tls_configuration(host):
    """
    Tests TLS configuration for SMTP in Postfix.
    """

    # Test TLS protocol versions for default port (all should be enabled).
    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1 -no_tls1_1 -connect parameters-optional:25")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_2 -connect parameters-optional:25")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_2 -no_tls1_1 -connect parameters-optional:25")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    # Test TLS protocol versions for submission port (only TLS 1.1 and TLS 1.2 should be enabled).
    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -connect parameters-optional:587")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_2 -connect parameters-optional:587")
    assert starttls.rc == 0
    assert '221 2.0.0 Bye' in starttls.stdout

    starttls = host.run("echo 'QUIT' | openssl s_client -quiet -starttls smtp -no_tls1_1 -no_tls1_2 -connect parameters-optional:587")
    assert starttls.rc != 0
    # First error message from OpenSSL in Debian 8 Jessie, second from
    # OpenSSL in Debian 9 Stretch.
    assert 'write:errno=104' in starttls.stderr or 'SSL alert number 70' in starttls.stderr

    # Test ciphers for default port (less restrictive).
    starttls_cipher = host.run("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:25")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in starttls_cipher.stdout

    starttls_cipher = host.run("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:25")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA" in starttls_cipher.stdout

    # Test ciphers for submission port (at least one weak cipher was configured).
    starttls_cipher = host.run("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA256 -connect parameters-optional:587")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA256" in starttls_cipher.stdout

    starttls_cipher = host.run("echo 'QUIT' | openssl s_client -starttls smtp -cipher ECDHE-RSA-AES128-SHA -connect parameters-optional:587")
    assert starttls_cipher.rc == 0
    assert "ECDHE-RSA-AES128-SHA" in starttls_cipher.stdout


def test_sieve_tls_configuration(host):
    """
    Tests TLS configuration for SIEVE in Dovecot
    """

    # @TODO: Currently not possible to test since openssl s_client does not
    # support STARTTLS for Sieve.
    pass