wilde: utils/testing send_filtertest_emails_new.py,NONE,1.1

cvs at kolab.org cvs at kolab.org
Thu Jul 1 16:25:48 CEST 2010


Author: wilde

Update of /kolabrepository/utils/testing
In directory doto:/tmp/cvs-serv1379

Added Files:
	send_filtertest_emails_new.py 
Log Message:
Added new Kolab Filter test script.
This is heavily based on the old one but improved in some details and
with new tests to fit the current status of kolab/issue954.


--- NEW FILE: send_filtertest_emails_new.py ---
#!/usr/bin/env python
"""Create and send testmails for envelope <-> header checks for Kolab2 Server.

You need to specify --maildomain and --username on the command line
with the real values for a test account on your server.

For test cases which need authentication you have to specify
--password and maybe --loginname (if loginname is not given
username at maildomain is used).

This script needs to be run from a system which is "out of bounds" for
the kolab-server, so the option "Accept Internet Mail" must be set on
the server and the system running this script MUST NOT be in the
"Privileged Networks" of the kolab server (or local, that is
127.0.0.1).  The Mail Filter tests are not performed on hosts in
Privileged Networks!

This script is Free Software under the GNU General Public License >=v2.
Bernhard Reiter <bernhard at intevation.de>
Sascha Wilde <wilde at intevation.de>
"""
#20041217 Bernhard initial

# This script is heavily based on send_filtertest_emails.py but it has
# been changed to test cases according to the diagram from the german
# operatin manual
# <http://www.kolab.org/doc/Allgemeine-Betriebsdokumentation-KolabServer22_20080103_1.0.pdf>
# page 50 and to variouse cases described in kolab/issue954.
#
# Documentation and some functionality was reworked, too...
__version__="$Revision: 1.1 $"[10:-1]

import sys
import time

import smtplib
import string
import getopt
import traceback
import random

def send_mail(envelope_from, envelope_to, header_from, header_to,
              test_number=-1, smtp_host="localhost", smtp_port = None,
	      loginname = None, password = None,
              text = "this is a kolab testmail", expect_reject = False):

    basemsg=("From: %s\r\nTo: %s\r\n%%s\r\n" % 
                (header_from, string.join(header_to, ", "))
            )

    headers="MIME-Version: 1.0\r\n"+ \
    "Content-Type: text/plain;\r\n"+ \
    "        charset=\"UTF-8\"\r\n"+ \
    "Content-Transfer-Encoding: 8bit\r\n"

    subject="Subject: Mail Filter Test %d\r\n" % int(test_number)

    head=basemsg % (headers + subject)

    msg = head + "Kolab Mail Filter sender checks.\n" + text + "\n"

    try:
        server=smtplib.SMTP(smtp_host, smtp_port)
	if loginname != None and password != None:
	    server.starttls()
	    server.login(loginname,password)

        server.set_debuglevel(1)

        server.sendmail(envelope_from,envelope_to,msg)
        sys.stdout.write(".")
        sys.stdout.flush()

        server.quit()
    except:
	if not expect_reject:
	    print "Error sending mail %d" % (test_number,)
	    traceback.print_exc()
	else:
	    print "Could not send mail %d" % (test_number,) + \
	    "\nBody: " + text + \
	    "\nThis was EXPECTED!"


def assemble_email_address(username, domain, realname = None):
    """Assemble an email address from a realname, a username and a domain.

    If realname is given and not None, the return value is a string with
    realname followed by a space and the emailaddress username at domain in
    angle brackets.  If realname is omitted or None, the return value is
    just the email address username at domain.
    """
    if realname is not None:
        return "%(realname)s <%(username)s@%(domain)s>" % locals()
    else:
        return "%(username)s@%(domain)s" % locals()


def main(argv):
    # default values for the parameters

    # Domain used in the email addresses
    maildomain = None

    # username.  username at maildomain will be the email address used
    username = None

    # alias.  alias at maildomain should be a valid alias or delegate for
    #         username at maildomain
    alias = None

    # smtp username
    loginname = None

    # password. smtp password for username at maildomain
    password = None

    # The real name part of an email address,
    # i.e. "realname <username at maildomain>"
    realname = None

    # SMTP host and port to use when sending the test mails
    smtp_host = None
    smtp_port = 25

    # parse the command line
    opts, args = getopt.getopt(argv[1:], 'h:p:',
                               ["smtp-host=", "smtp-port=",
                                "maildomain=", "username=", "alias=",
			        "loginname=", "password=", "realname=",
                                'version'])
    for optchar, value in opts:
        if optchar in ("-h", "--smtp-host"):
            smtp_host = value
        elif optchar in ("-p", "--smtp-port"):
            smtp_port = int(value)
        elif optchar == "--maildomain":
            maildomain = value
        elif optchar == "--username":
            username = value
        elif optchar == "--alias":
            alias = value
        elif optchar == "--loginname":
            loginname = value
	elif optchar == "--password":
	    password = value
        elif optchar == "--realname":
            realname = value
        elif optchar == "--version":
            print __version__
            return
        else:
            print >>sys.stderr, "unknown option %r" % optchar


    error = False
    if maildomain is None:
        print >>sys.stderr, "--maildomain missing"
        error = True
    if username is None:
        print >>sys.stderr, "--username missing"
        error = True
    if smtp_host is None:
        print >>sys.stderr, "--smtp-host missing"
        error = True

    if not error and '@' in username:
        print >>sys.stderr, "error: \"@\" in username!"
        error = True

    if error:
        sys.exit(1)

    envelope_to = assemble_email_address(username, maildomain, realname)
    header_to= [assemble_email_address(username, maildomain)]

    envelope_from = envelope_to
    header_from = assemble_email_address(username, maildomain)
    subdom_header_from = assemble_email_address(username, "sub."+maildomain)

    nonexistent_local_address = assemble_email_address(
	''.join([random.choice(string.letters + string.digits) for i in range(10)]),
	maildomain)

    if alias != None:
	alias_address = assemble_email_address(alias, maildomain)

    if loginname is None:
	loginname = envelope_from

    # Tests
    # number : expected behaviour to pass the test : description

    # Authenticated tests

    if password is None:
	print >>sys.stderr, "No password was given, skipping authenticated tests!"
    else:
	# 0: delivered: Are we functional? Does the default case work?
	send_mail(envelope_from, envelope_to, header_from, header_to, 0,
		  smtp_host = smtp_host, smtp_port = smtp_port, 
		  loginname = loginname, password = password,
		  text = "Regualr authenticated mail" + 
		  "Expected result: delivery")
	
	# 1: delivered: different letter cases in the header_from
	send_mail(envelope_from, envelope_to, header_from.swapcase(), header_to, 1,
		  smtp_host = smtp_host, smtp_port = smtp_port,
		  loginname = loginname, password = password,
		  text = "Authenticated mail with changed case in From-header.\n" + 
		  "Expected result: delivery")

	# 2: bounce mail: envelope_from is ok, but header_from is forged external
	send_mail(envelope_from, envelope_to, "rumpelstilzchen at big.invalid", 
		  header_to, 2,
		  smtp_host = smtp_host, smtp_port = smtp_port,
		  loginname = loginname, password = password,
		  text = "Authenticated mail with forged external From-header.\n" + 
		  "Expected result: bounce")

	# 3: bounce mail: envelope_from is ok, but header_from is forged nonexistent local
	send_mail(envelope_from, envelope_to, nonexistent_local_address, 
		  header_to, 3,
		  smtp_host = smtp_host, smtp_port = smtp_port,
		  loginname = loginname, password = password,
		  text = "Authenticated mail with forged local From-header.\n" + 
		  "Expected result: bounce")

	# 4: reject mail: envelope_from is forged external, header_from is ok
	send_mail( "rumpelstilzchen at big.invalid", envelope_to, header_from,
		   header_to, 4,
		   smtp_host = smtp_host, smtp_port = smtp_port,
		   loginname = loginname, password = password,
		   text = "Authenticated mail with forged external envelope-sender.\n" + 
		   "Expected result: rejected by postfix", expect_reject = True)

	# 5: reject mail: envelope_from is forged local, header_from is ok
	send_mail(nonexistent_local_address, envelope_to, header_from,
		  header_to, 5,
		  smtp_host = smtp_host, smtp_port = smtp_port,
		  loginname = loginname, password = password,
		  text = "Authenticated mail with forged local envelope-sender.\n" + 
		  "Expected result: rejected by postfix", expect_reject = True)

	if alias is None:
	    print >>sys.stderr, "No alias was given, skipping alias tests!"
	else:
	    # 6: delivered: envelope_from and header_from are an alias for user
	    send_mail(alias_address, envelope_to, alias_address, header_to, 6,
		      smtp_host = smtp_host, smtp_port = smtp_port,
		      loginname = loginname, password = password,
		      text = "Authenticated mail, env-sender and From-header being alias.\n" + 
		      "Expected result: delivery")

	    # 7: bounce?: envelope_from is an alias for user, but from
	    #    is primary user address
	    #    msg25586, kolab/issue954
	    send_mail(alias_address, envelope_to, header_from, header_to, 7,
		      smtp_host = smtp_host, smtp_port = smtp_port,
		      loginname = loginname, password = password,
		      text = "Authenticated mail, env-sender alias, From-header user.\n" + 
		      "Expected result: bounce?")

	    # 8: bounce?: envelope_from is primary user address, but from
	    #    is an (valid) alias
	    #    msg25586, kolab/issue954
	    send_mail(envelope_from, envelope_to, alias_address, header_to, 8,
		      smtp_host = smtp_host, smtp_port = smtp_port,
		      loginname = loginname, password = password,
		      text = "Authenticated mail, env-sender user, From-header alias.\n" + 
		      "Expected result: bounce?")
	
# forged envelope intern an extern...

	# # 3: delivered, no mailer-daemon in kolabfilter log: 
	# #                    issue774 (null senders not handled by kolabfilter...)
	# # Doesn't work currently, rewriting is missing.
	# send_mail("<>", envelope_to, "some at non-existing.invalid", header_to, 3,
	# 	  smtp_host = smtp_host, smtp_port = smtp_port,
	# 	  loginname = loginname, password = password,
	# 	  text = "Kolab filter testmail.\nExpected result: delivery, from header rewritten")

	# # 3.1: delivered, mailer-daemon like mail with legal From:
	# send_mail("<>", envelope_to, header_from, header_to, 3.1,
	# 	  smtp_host = smtp_host, smtp_port = smtp_port,
	# 	  loginname = loginname, password = password,
	# 	  text = "Kolab filter testmail.\nExpected result: delivery, from header rewritten")
	
	# # 4: reject, user can't use sender address "x-commit..."
	# send_mail("x-commits-bounces-+y=malinglist.org at example.org", envelope_to, 
	# 	  header_from, header_to, 4,
	# 	  smtp_host = smtp_host, smtp_port = smtp_port,
	# 	  loginname = loginname, password = password,
	# 	  text = "Kolab filter testmail.\nExpected result: reject")

	# # 5: reject, user can't use from address "$user at sub.$domain"
	# send_mail( envelope_from, envelope_to, 
	# 	   subdom_header_from, header_to, 5,
	# 	   smtp_host = smtp_host, smtp_port = smtp_port,
	# 	   loginname = loginname, password = password,
	# 	   text = "Kolab filter testmail.\nExpected result: reject")

    
    # Unauthenticated tests

    # # 10: reject: unauthenticated user trying to send
    # send_mail(envelope_from, envelope_to, header_from, header_to, 10,
    #           smtp_host = smtp_host, smtp_port = smtp_port, 
    #           text = "Kolab filter testmail.\nExpected result: reject")

    # # 11: delivered, no mailer-daemon in kolabfilter log: 
    # #                    issue774 (null senders not handled by kolabfilter...)
    # send_mail("<>", envelope_to, "some at non-existing.invalid", header_to, 11,
    #           smtp_host = smtp_host, smtp_port = smtp_port,
    #           text = "Kolab filter testmail.\nExpected result: delivery")

    # # 12: delivered, no Invalid From: header in postfix log:
    # # issue783 (envelope header from check has problems with mailinglists)
    # send_mail("x-commits-bounces-+y=malinglist.org at example.org", envelope_to, 
    #           header_from, header_to, 12,
    #           smtp_host = smtp_host, smtp_port = smtp_port,
    #           text = "Kolab filter testmail.\nExpected result: delivery, from header rewritten")

    # # 12.1: delivered, no Invalid From: header in postfix log:
    # send_mail("blah at example.org", envelope_to,
    #           "\"\\\\blah\\\"\" <steffen.hansen at sulaco.hrhansen.dk>", header_to, 12.1,
    #           smtp_host = smtp_host, smtp_port = smtp_port,
    #           text = "Kolab filter testmail.\nExpected result: delivery, from header rewritten")

    # # 13: if( verify_subdomains) rewrite, user can't use from header "$user at sub.$domain"
    # # 13: if( !verify_subdomains) delivered
    # send_mail( "someone at non-existing.invalid", envelope_to, 
    #           subdom_header_from, header_to, 13,
    #           smtp_host = smtp_host, smtp_port = smtp_port,
    #           text = "Kolab filter testmail.\nExpected result: if( verify_subdomains) from header rewritten, else delivered")

if __name__=="__main__":
    main(sys.argv)





More information about the commits mailing list