Files @ 17cf34f73ca6
Branch filter:

Location: majic-ansible-roles/roles/mail_server/tests/test_default.py

branko
MAR-28: Implemented additional tests for mail_server role:

- Deploy a number of tools on clients in order to test SMTP, IMAP, and Sieve
services.
- Added one more user to LDAP directory for testing group restrictions.
- Deploy CA certificate on all testing machines for TLS validation purposes.
- Use different custom-configured cipher for mail server ciphers.
- Fixed invalid postmaster address for parameters-optional host.
- Deploy configuration files for use with Imap-CLI on client test machines.
- Updated testing of SMTP server to include checks for users that do not belong
to mail group.
- Extended some SMTP-related tests to cover both test servers.
- Some small fixes in SMTP-related tests for expected output from commands.
- Implemented tests covering Dovecot (IMAP + Sieve) functionality.
- Implemented tests for running/enabled services.
- Implemented tests for ClamAV.
- Implemented tests for firewall and connectivity.
- Implemented tests for Postfix TLS configuration.
- TODO: Tests for Sieve TLS configuration have not been written yet due to
limitation of available tools.
import re

import testinfra.utils.ansible_runner


testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    '.molecule/ansible_inventory').get_hosts(['parameters-mandatory', 'parameters-optiona'])


def test_installed_packages(Package):
    """
    Tests if the necessary packages have been installed.
    """

    assert Package('rsync').is_installed
    assert Package('dovecot-imapd').is_installed
    assert Package('dovecot-ldap').is_installed
    assert Package('dovecot-sieve').is_installed
    assert Package('dovecot-managesieved').is_installed
    assert Package('postfix').is_installed
    assert Package('postfix-ldap').is_installed
    assert Package('swaks').is_installed
    assert Package('clamav-milter').is_installed


def test_removed_packages(Package):
    """
    Tests if certain packages have been removed from the system.
    """
    assert not Package('exim4').is_installed


def test_postfix_user(User):
    """
    Tests if Postfix user has been added to correct group for traversing the TLS
    private key directory.
    """

    assert "ssl-cert" in User('postfix').groups


def test_dovecot_user(User):
    """
    Tests if Dovecot user has been added to correct group for traversing the TLS
    private key directory.
    """

    assert "ssl-cert" in User('dovecot').groups


def test_clamav_milter_configuration(File):
    """
    Tests if ClamAV Milter configuration has been deployed correctly.
    """

    config = File('/etc/clamav/clamav-milter.conf')

    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644


def test_clamav_milter(Command):
    """
    Tests if ClamAV milter is blocking viruses.
    """

    server_did_not_accept_mail = 26

    eicar = 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'

    send_mail = Command("swaks --to john.doe@domain1 --server localhost --attach '%s'" % eicar)

    assert send_mail.rc == server_did_not_accept_mail
    assert 'Your message has been rejected due to a possible virus' in send_mail.stdout


def test_postfix_chroot_directories(File):
    """
    Tests if Postfix chroot directories have been set-up with correct
    permissions.
    """

    directory = File('/var/spool/postfix/var')
    assert directory.is_directory
    assert directory.user == 'root'
    assert directory.group == 'root'
    assert directory.mode == 0o755

    directory = File('/var/spool/postfix/var/run')
    assert directory.is_directory
    assert directory.user == 'root'
    assert directory.group == 'root'
    assert directory.mode == 0o755

    directory = File('/var/spool/postfix/var/run/clamav')
    assert directory.is_directory
    assert directory.user == 'clamav'
    assert directory.group == 'clamav'
    assert directory.mode == 0o755


def test_ldap_tls_truststore_file(File):
    """
    Tests if the LDAP TLS truststore file has been deployed correctly.
    """

    tls_file = File('/etc/ssl/certs/mail_ldap_tls_truststore.pem')
    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/ca.cert.pem", "r").read().rstrip()

    tls_file = File('/var/spool/postfix/etc/ssl/certs/mail_ldap_tls_truststore.pem')
    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/ca.cert.pem", "r").read().rstrip()


def test_mailname_file(File):
    """
    Tests the system mail name file permissions.
    """

    mailname = File('/etc/mailname')

    assert mailname.is_file
    assert mailname.user == 'root'
    assert mailname.group == 'root'
    assert mailname.mode == 0o644


def test_postfix_ldap_configuration_files(File):
    """
    Tests if Postfix LDAP configuration files have been deployed correctly.
    """

    for config_file_path in ['/etc/postfix/ldap-virtual-alias-maps.cf',
                             '/etc/postfix/ldap-virtual-mailbox-domains.cf',
                             '/etc/postfix/ldap-virtual-mailbox-maps.cf']:

        config = File(config_file_path)
        assert config.is_file
        assert config.user == 'root'
        assert config.group == 'postfix'
        assert config.mode == 0o640


def test_postfix_ldap_configuration(Command, Sudo):
    """
    Tests if LDAP configuration can be used to fetch correct query results.
    """

    with Sudo():

        # Test for valid domains.
        command = Command("postmap -q domain1 ldap:/etc/postfix/ldap-virtual-mailbox-domains.cf")
        assert command.rc == 0
        assert command.stdout == "domain1"

        command = Command("postmap -q domain2 ldap:/etc/postfix/ldap-virtual-mailbox-domains.cf")
        assert command.rc == 0
        assert command.stdout == "domain2"

        # Test for invalid domains.
        command = Command("postmap -q domain3 ldap:/etc/postfix/ldap-virtual-mailbox-domains.cf")
        assert command.rc == 1
        assert command.stdout == ""

        # Test for valid mail addresses.
        command = Command("postmap -q 'john.doe@domain1' ldap:/etc/postfix/ldap-virtual-mailbox-maps.cf")
        assert command.rc == 0
        assert command.stdout == 'john.doe@domain1'

        command = Command("postmap -q 'jane.doe@domain2' ldap:/etc/postfix/ldap-virtual-mailbox-maps.cf")
        assert command.rc == 0
        assert command.stdout == 'jane.doe@domain2'

        # Test for invalid mail addresses.
        command = Command("postmap -q 'jane.doe@domain1' ldap:/etc/postfix/ldap-virtual-mailbox-maps.cf")
        assert command.rc == 1
        assert command.stdout == ''

        command = Command("postmap -q 'john.doe@domain2' ldap:/etc/postfix/ldap-virtual-mailbox-maps.cf")
        assert command.rc == 1
        assert command.stdout == ''

        # Test for valid mail address that's not allowed by LDAP group membership.
        command = Command("postmap -q 'nomail@domain1' ldap:/etc/postfix/ldap-virtual-mailbox-maps.cf")
        assert command.rc == 1
        assert command.stdout == ''

        # Test for valid mail aliases.
        command = Command("postmap -q postmaster@domain1 ldap:/etc/postfix/ldap-virtual-alias-maps.cf")
        assert command.rc == 0
        assert command.stdout == "john.doe@domain1"

        command = Command("postmap -q webmaster@domain2 ldap:/etc/postfix/ldap-virtual-alias-maps.cf")
        assert command.rc == 0
        assert command.stdout == "jane.doe@domain2"

        # Test for invalid mail aliases.
        command = Command("postmap -q postmaster@domain2 ldap:/etc/postfix/ldap-virtual-alias-maps.cf")
        assert command.rc == 1
        assert command.stdout == ""

        command = Command("postmap -q webmaster@domain1 ldap:/etc/postfix/ldap-virtual-alias-maps.cf")
        assert command.rc == 1
        assert command.stdout == ""


def test_postfix_main_cf_file(File):
    """
    Tests Postfix main configuration file permissions.
    """

    config = File('/etc/postfix/main.cf')
    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644


def test_postfix_delivery_to_dovecot(Command, File, Sudo):
    """
    Tests if mail received by Postfix is properly delivered to Dovecot.
    """

    # Virtual account.
    send = Command('swaks --suppress-data --to john.doe@domain1 --server parameters-mandatory')
    assert send.rc == 0
    message_id = re.search('Ok: queued as (.*)', send.stdout).group(1)

    with Sudo():
        mail_log = File('/var/log/mail.log')
        pattern = "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_system_authentication_is_disabled(File):
    """
    Tests if Dovecot system-based authentication has been disabled.
    """

    config = File("/etc/dovecot/conf.d/10-auth.conf")

    assert "!include auth-system.conf.ext" not in config.content


def test_dovecot_overrides_configuration_file(File):
    """
    Tests if Dovecot configuration file with overrides has been deployed and has
    correct permissions.
    """

    config = File("/etc/dovecot/conf.d/99-local.conf")

    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644


def test_dovecot_imap_ldap_configuration(Command, Sudo):
    """
    Tests if Dovecot LDAP configuration is correct.
    """

    with Sudo():

        user_does_not_exist = 67

        # Test for valid mail addresses.
        command = Command("doveadm user john.doe@domain1")
        assert command.rc == 0

        command = Command("doveadm user jane.doe@domain2")
        assert command.rc == 0

        # Test for invalid mail addresses.
        command = Command("doveadm user john.doe@domain2")
        assert command.rc == user_does_not_exist

        command = Command("doveadm user jane.doe@domain1")
        assert command.rc == user_does_not_exist

        # Test for mail addresses present in LDAP, but entry not in mail group.
        command = Command("doveadm user nomail@domain1")
        assert command.rc == user_does_not_exist


def test_postfix_master_file(File):
    """
    Tests permissions for Postfix master.cf configuration file.
    """

    config = File('/etc/postfix/master.cf')

    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644


def test_services(Service):
    """
    Tests if all the mail-related servieces are up and running.
    """

    for service_name in ["clamav-daemon",
                         "clamav-freshclam",
                         "clamav-milter",
                         "postfix",
                         "dovecot"]:

        service = Service(service_name)
        assert service.is_running
        assert service.is_enabled


def test_clamav_database_presence(File):
    """
    Tests if ClamAV database is present.
    """

    for database_file in ["/var/lib/clamav/bytecode.cvd",
                          "/var/lib/clamav/daily.cld",
                          "/var/lib/clamav/main.cvd"]:

        database = File(database_file)

        assert database.is_file


def test_firewall_configuration_file(File, Sudo):
    """
    Tests if firewall configuration file has been deployed correctly.
    """

    with Sudo():

        config = File('/etc/ferm/conf.d/20-mail.conf')

        assert config.is_file
        assert config.user == 'root'
        assert config.group == 'root'
        assert config.mode == 0o640