Files @ 502fdc081d35
Branch filter:

Location: majic-ansible-roles/roles/mail_server/tests/test_client2.py - annotation

branko
MAR-32: Added initial scaffolding for testing web_server role:

- Added Molecule configuration for for bringing up a couple of instances.
- Added test playbook that sets-up test instances.
- Fixed issues with file mode in tasks (added leading 0).
- Added test data (TLS private keys and certificates).
- Added dummy test file.
17cf34f73ca6
17cf34f73ca6
277c561f3f52
277c561f3f52
17cf34f73ca6
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
277c561f3f52
277c561f3f52
17cf34f73ca6
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
277c561f3f52
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
277c561f3f52
277c561f3f52
17cf34f73ca6
277c561f3f52
277c561f3f52
277c561f3f52
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
17cf34f73ca6
import re

import testinfra.utils.ansible_runner


testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    '.molecule/ansible_inventory').get_hosts('client2')


def test_open_relay(Command):
    """
    Tests if mail server behaves as open relay.
    """

    no_recipients_accepted = 24

    send = Command('swaks --suppress-data --to root@client1 --server parameters-mandatory')
    assert send.rc == no_recipients_accepted
    assert "Relay access denied" in send.stdout

    send = Command('swaks --suppress-data --to root@client1 --server parameters-optional')
    assert send.rc == no_recipients_accepted
    assert "Relay access denied" in send.stdout


def test_mail_delivery(Command):
    """
    Tests if mails can be delivered to valid accounts. Has to be run on client
    with no unauthenticated relay permissions.
    """

    no_recipients_accepted = 24

    # Valid accounts.
    send = Command('swaks --suppress-data --to john.doe@domain1 --server parameters-mandatory')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    send = Command('swaks --suppress-data --to john.doe@domain1 --server parameters-optional')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    send = Command('swaks --suppress-data --to jane.doe@domain2 --server parameters-mandatory')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    send = Command('swaks --suppress-data --to jane.doe@domain2 --server parameters-optional')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    # Invalid accounts.
    send = Command('swaks --suppress-data --to john.doe@domain2 --server parameters-mandatory')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    send = Command('swaks --suppress-data --to john.doe@domain2 --server parameters-optional')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    send = Command('swaks --suppress-data --to jane.doe@domain1 --server parameters-mandatory')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    send = Command('swaks --suppress-data --to jane.doe@domain1 --server parameters-optional')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    # Test for valid mail address that's not allowed by LDAP group membership.
    send = Command('swaks --suppress-data --to nomail@domain1 --server parameters-mandatory')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    send = Command('swaks --suppress-data --to nomail@domain1 --server parameters-optional')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    # Valid aliases.
    send = Command('swaks --suppress-data --to postmaster@domain1 --server parameters-mandatory')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    send = Command('swaks --suppress-data --to postmaster@domain1 --server parameters-optional')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    send = Command('swaks --suppress-data --to webmaster@domain2 --server parameters-mandatory')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    send = Command('swaks --suppress-data --to webmaster@domain2 --server parameters-optional')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    # Invalid aliases.
    send = Command('swaks --suppress-data --to postmaster@domain2 --server parameters-mandatory')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    send = Command('swaks --suppress-data --to postmaster@domain2 --server parameters-optional')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    send = Command('swaks --suppress-data --to webmaster@domain1 --server parameters-mandatory')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout

    send = Command('swaks --suppress-data --to webmaster@domain1 --server parameters-optional')
    assert send.rc == no_recipients_accepted
    assert "Recipient address rejected: User unknown in virtual mailbox table" in send.stdout


def test_smtp_authentication(Command):
    """
    Tests if SMTP authentication works via TLS and allows sending mails to
    anywhere.
    """

    send = Command('swaks -tls --port 587 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-mandatory')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    send = Command('swaks -tls --port 587 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-optional')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout


def test_smtp_authentication_requires_tls(Command):
    """
    Tests if SMTP authentication requires TLS.
    """

    auth_error = 28

    send = Command('swaks --port 587 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-mandatory')
    assert send.rc == auth_error
    assert "Host did not advertise authentication" in send.stderr

    send = Command('swaks --port 587 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-optional')
    assert send.rc == auth_error
    assert "Host did not advertise authentication" in send.stderr


def test_smtp_authentication_requires_submission_port(Command):
    """
    Tests if SMTP authentication cannot be done on regular SMTP port.
    """

    auth_error = 28

    send = Command('swaks --port 25 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-mandatory')
    assert send.rc == auth_error
    assert "Host did not advertise authentication" in send.stderr

    send = Command('swaks -tls --port 25 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-mandatory')
    assert send.rc == auth_error
    assert "Host did not advertise authentication" in send.stderr

    send = Command('swaks --port 25 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-optional')
    assert send.rc == auth_error
    assert "Host did not advertise authentication" in send.stderr

    send = Command('swaks -tls --port 25 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-optional')
    assert send.rc == auth_error
    assert "Host did not advertise authentication" in send.stderr


def test_dovecot_inbox_separator(Command):
    """
    Tests if inbox separator has been configured correctly.
    """

    pattern_slash_separator = re.compile('WARNING:imap-cli:Ignoring "LIST" response part : \([^)]*\) "/" INBOX')
    pattern_dot_separator = re.compile('WARNING:imap-cli:Ignoring "LIST" response part : \([^)]*\) "\." INBOX')

    status = Command("imapcli status -c ~/imapcli-parameters-mandatory-john_doe.conf")
    assert pattern_slash_separator.search(status.stdout) is not None

    status = Command("imapcli status -c ~/imapcli-parameters-optional-john_doe.conf")
    assert pattern_dot_separator.search(status.stdout) is not None


def test_imap_authentication_requires_tls(Command):
    """
    Tests if IMAP authentication requires TLS.
    """

    # No TLS.
    command = Command("echo -e 'a0001 CAPABILITY\na0002 LOGOUT' | nc parameters-mandatory 143")
    assert command.rc == 0
    assert "LOGINDISABLED" in command.stdout

    command = Command("echo -e 'a0001 CAPABILITY\na0002 LOGOUT' | nc parameters-optional 143")
    assert command.rc == 0
    assert "LOGINDISABLED" in command.stdout

    # STARTTLS.
    command = Command("echo -e 'a0001 CAPABILITY\na0002 LOGOUT' | openssl s_client -quiet -connect parameters-mandatory:143 -starttls imap")
    assert command.rc == 0
    assert "LOGINDISABLED" not in command.stdout

    command = Command("echo -e 'a0001 CAPABILITY\na0002 LOGOUT' | openssl s_client -quiet -connect parameters-optional:143 -starttls imap")
    assert command.rc == 0
    assert "LOGINDISABLED" not in command.stdout

    # TLS.
    command = Command("echo -e 'a0001 CAPABILITY\na0002 LOGOUT' | openssl s_client -quiet -connect parameters-mandatory:993")
    assert command.rc == 0
    assert "LOGINDISABLED" not in command.stdout

    command = Command("echo -e 'a0001 CAPABILITY\na0002 LOGOUT' | openssl s_client -quiet -connect parameters-optional:993")
    assert command.rc == 0
    assert "LOGINDISABLED" not in command.stdout


def test_sieve_authentication_requires_tls(Command):
    """
    Tests if SIEVE authentication requires TLS.
    """

    # No TLS.
    command = Command("echo 'LOGOUT' | nc parameters-mandatory 4190")
    assert command.rc == 0
    assert "PLAIN LOGIN" not in command.stdout

    command = Command("echo 'LOGOUT' | nc parameters-optional 4190")
    assert command.rc == 0
    assert "PLAIN LOGIN" not in command.stdout

    # STARTTLS
    command = Command("echo 'johnpassword' | sieve-connect -u john.doe@domain1 --password 0 --server parameters-mandatory --port 4190 --list")
    assert command.rc == 0

    command = Command("echo 'johnpassword' | sieve-connect -u john.doe@domain1 --password 0 --server parameters-optional --port 4190 --list")
    assert command.rc == 0


def test_connectivity(Command, Sudo):
    """
    Tests connectivity to the mail server (ports that should be reachable).
    """

    with Sudo():

        for server in ["parameters-mandatory",
                       "parameters-optional"]:
            for port in [25, 26, 587, 143, 993, 4190]:

                ping = Command('hping3 -S -p %d -c 1 %s' % (port, server))
                assert ping.rc == 0


def test_port_forwarding(Command, Sudo):
    """
    Tests if port forwarding is set-up correctly for submission port.
    """

    send = Command('swaks -tls --port 26 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-mandatory')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout

    send = Command('swaks -tls --port 26 --auth-user john.doe@domain1 --auth-password johnpassword --to root@client1 --server parameters-optional')
    assert send.rc == 0
    assert "Ok: queued as" in send.stdout


def test_dovecot_sieve(Command):
    """
    Tests if Sieve service is available.
    """

    # Test valid users.
    command = Command('echo johnpassword | sieve-connect --list -s parameters-mandatory -p 4190 -u john.doe@domain1 --password 0')
    assert command.rc == 0

    command = Command('echo janepassword | sieve-connect --list -s parameters-optional -p 4190 -u jane.doe@domain2 --password 0')
    assert command.rc == 0

    # Test invalid users.
    command = Command('echo johnpassword | sieve-connect --list -s parameters-mandatory -p 4190 -u john.doe@domain2 --password 0')
    assert command.rc != 0
    assert "Authentication refused by server" in command.stderr

    command = Command('echo janepassword | sieve-connect --list -s parameters-optional -p 4190 -u jane.doe@domain1 --password 0')
    assert command.rc != 0
    assert "Authentication refused by server" in command.stderr