File: 00_pmilter.t

package info (click to toggle)
libsendmail-pmilter-perl 1.27-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 356 kB
  • sloc: perl: 1,057; makefile: 2
file content (186 lines) | stat: -rw-r--r-- 7,989 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#   Copyright (c) 2002-2004 Todd Vierling <tv@duh.org> <tv@pobox.com>
#   Copyright (c) 2004 Robert Casey <rob.casey@bluebottle.com>
#   Copyright (c) 2016-2018 GWHAYWOOD <comments via cpan please>
#   This file is covered by the terms in the file COPYRIGHT supplied with this
#   software distribution.


BEGIN {

    use Test::More 'tests' => 123;

    use_ok('Sendmail::PMilter');
}


#   Perform some basic tests of the module constructor and available methods

can_ok(
        'Sendmail::PMilter',
                'auto_getconn',
                'auto_setconn',
                'get_max_interpreters',
                'get_max_requests',
                'get_sendmail_cf',
                'get_sendmail_option',
                'get_sendmail_class',
		'ithread_dispatcher',
		'prefork_dispatcher',
		'postfork_dispatcher',
		'sequential_dispatcher',
		'main',
                'new',
                'register',
                'setconn',
                'set_dispatcher',
                'set_listen',
                'set_sendmail_cf',
                'set_socket'
);

ok( my $milter = Sendmail::PMilter->new );
isa_ok( $milter, 'Sendmail::PMilter' );


#   Perform some tests on namespace symbols which should be defined within the 
#   Sendmail::PMilter namespace.  Not tested yet is the export of these symbols 
#   into the caller's namespace - TODO.

my %CONSTANTS = (

	# Reply codes for return by milter callbacks to the MTA.
	'SMFIS_CONTINUE'	=>  100,
	'SMFIS_REJECT'		=>  101,
	'SMFIS_DISCARD'		=>  102,
	'SMFIS_ACCEPT'		=>  103,
	'SMFIS_TEMPFAIL'	=>  104,

	# Protocol flags, which permit a milter to make certain requests to the MTA at the negotiation stage (which
	# takes place at the beginning of processing every message, before the 'connect' callback is called by the MTA).
	'SMFIP_NOCONNECT'	=> 0x00000001,		# MTA should not send connect info
	'SMFIP_NOHELO'		=> 0x00000002,		# MTA should not send HELO info
	'SMFIP_NOMAIL'		=> 0x00000004,		# MTA should not send MAIL info
	'SMFIP_NORCPT'		=> 0x00000008,		# MTA should not send RCPT info
	'SMFIP_NOBODY'		=> 0x00000010,		# MTA should not send body
	'SMFIP_NOHDRS'		=> 0x00000020,		# MTA should not send headers
	'SMFIP_NOEOH'		=> 0x00000040,		# MTA should not send EOH
	'SMFIP_NR_HDR'		=> 0x00000080,		# No reply for headers
	'SMFIP_NOHREPL'		=> 0x00000080,		# No reply for headers (backward compatibility)
	'SMFIP_NOUNKNOWN'	=> 0x00000100,		# MTA should not send unknown commands
	'SMFIP_NODATA'		=> 0x00000200,		# MTA should not send DATA
	'SMFIP_SKIP'		=> 0x00000400,		# MTA understands the 'skip any remaining message body chunks' request (called from EOM callback).
	'SMFIP_RCPT_REJ'	=> 0x00000800,		# MTA should also send recipients rejected e.g. if they are unknown (but not on error conditions).
	'SMFIP_NR_CONN'		=> 0x00001000,		# No reply for CONNECT
	'SMFIP_NR_HELO'		=> 0x00002000,		# No reply for HELO
	'SMFIP_NR_MAIL'		=> 0x00004000,		# No reply for MAIL
	'SMFIP_NR_RCPT'		=> 0x00008000,		# No reply for RCPT
	'SMFIP_NR_DATA'		=> 0x00010000,		# No reply for DATA
	'SMFIP_NR_UNKN'		=> 0x00020000,		# No reply for UNKN
	'SMFIP_NR_EOH'		=> 0x00040000,		# No reply for EOH
	'SMFIP_NR_BODY'		=> 0x00080000,		# No reply for BODY CHUNK
	'SMFIP_HDR_LEADSPC'	=> 0x00100000,		# Header value leading space will be managed by the milter
	'SMFIP_MDS_256K'	=> 0x10000000,		# MILTER_MAX_DATA_SIZE=256K
	'SMFIP_MDS_1M'		=> 0x20000000,		# MILTER_MAX_DATA_SIZE=1M

	# Convenience bit sets of the protocol flags associated with the SMFIP_* flags above, grouped by Milter Protocol Version.
	# 'SMFI_V1_PROT'	=>  0x0000003F,		# Protocol flags for Milter Protocol Version 1.  Milter Protocol Version 1 is obsolete, so we won't bother with it.
	'SMFI_V2_PROT'		=>  0x0000007F,		# Protocol flags for Milter Protocol Version 2.  Milter Protocol Version 2 will soon be obsolete.
	'SMFI_V6_PROT'		=>  0x001FFFFF,		# Protocol flags for Milter Protocol Version 6.

	# Capability flags for negotiation between a milter and an MTA, now largely unused.
	# Since the arrival of Milter Protocol Version 6 with Sendmail 8.14.0 in January 2010,
	# SMFIF_CHGFROM is now the only SMFIF_* flag which must be set in order to enable one
	# of the associated milter requests.
	'SMFIF_NONE'		=>  0x00000000,		# Not normally used.
	'SMFIF_ADDHDRS'		=>  0x00000001,		# Milter may add/insert headers
	'SMFIF_CHGBODY'		=>  0x00000002,		# Milter may replace message body; SMFIF_CHGBODY was introduced with Milter Protocol V2, to eventually replace SMFIF_MODBODY.
	'SMFIF_MODBODY'		=>  0x00000002,		# Milter may replace message body; SMFIF_CHGBODY replaces SMFIF_MODBODY, which will eventually be removed.
	'SMFIF_ADDRCPT'		=>  0x00000004,		# Milter may add recipients
	'SMFIF_DELRCPT'		=>  0x00000008,		# Milter may delete recipients
	'SMFIF_CHGHDRS'		=>  0x00000010,		# Milter may change/delete headers
	'SMFIF_QUARANTINE'	=>  0x00000020,		# Milter may quarantine message
	'SMFIF_CHGFROM'		=>  0x00000040,		# Milter may change "from" (envelope sender)
	'SMFIF_ADDRCPT_PAR'	=>  0x00000080,		# Milter may add recipients (like SMFIF_ADDRCPT, but include extra arguments in the call)
	'SMFIF_SETSYMLIST'	=>  0x00000100,		# Milter may send set of symbols (macros) that it wants

	# Convenience bit sets of the 'actions' associated with the SMFIF_* flags above, grouped by Milter Protocol Version.
	'SMFI_V1_ACTS'		=>  0x0000000F,		# SMFIF_ADDHDRS|SMFIF_CHGBODY|SMFIF_ADDRCPT|SMFIF_DELRCPT
	'SMFI_V2_ACTS'		=>  0x0000003F,		# SMFI_V1_ACTS|SMFIF_CHGHDRS|SMFIF_QUARANTINE
	'SMFI_V6_ACTS'		=>  0x000001FF,		# SMFI_V2_ACTS|SMFIF_CHGFROM|SMFIF_ADDRCPT_PAR|SMFIF_SETSYMLIST
	'SMFI_CURR_ACTS'	=>  0x000001FF,		# SMFI_V6_ACTS (as of July 2019; see mfapi.h and mfdef.h in the Sendmail source)

	'MAXREPLYLEN'		=> 980,			# Maximum length of lines in a reply from the MTA to the client.
	'MAXREPLIES'		=> 32,			# Maximum number of lines in a multi-line reply from the MTA to the client.

);

foreach my $constant (keys %CONSTANTS) {

    no strict 'refs';
    my $symbol = "Sendmail::PMilter::$constant"->();
    ok( defined $symbol, "Sendmail::PMilter::$constant" );
    SKIP: {

        skip("- Sendmail::PMilter::$constant not defined", 1) unless defined $symbol;
        is( $symbol, $CONSTANTS{$constant} );
    }
}


#   Of the module methods, the get_sendmail_cf function is tested first given 
#   the number of other methods dependent upon this method.  By default, this 
#   method should return the Sendmail configuration file as '/etc/mail/sendmail.cf'.

ok( my $cf = $milter->get_sendmail_cf );
ok( defined $cf );
is( $cf, '/etc/mail/sendmail.cf' );


#   Test the corresponding set_sendmail_cf function by setting a new value for 
#   this parameter and then testing the return value from get_sendmail_cf

ok( $milter->set_sendmail_cf('t/files/sendmail.cf') );
is( $milter->get_sendmail_cf, 't/files/sendmail.cf' );
ok( $milter->set_sendmail_cf() );
is( $milter->get_sendmail_cf, '/etc/mail/sendmail.cf' );


#   Test the auto_getconn function using our own set of test sendmail 
#   configuration files - The first test should fail as a result of the name 
#   parameter not having been defined.

eval { $milter->auto_getconn() };
ok( defined $@ );

my @sockets = (
        'local:/var/run/milter.sock',
        'unix:/var/run/milter.sock',
        'inet:3333@localhost',
        'inet6:3333@localhost'
);
foreach my $index (0 .. 4) {

    my $cf = sprintf('t/files/sendmail%d.cf', $index);
    SKIP: {

        skip("- Missing file $cf", 3) unless -e $cf;
        ok( $milter->set_sendmail_cf($cf), $cf );
        my $socket = shift @sockets;
        ok( 
                ( ! defined $socket ) or 
                ( my $milter_socket = $milter->auto_getconn('test-milter') ) 
        );
        is( $milter_socket, $socket, defined $socket ? $socket : '(undef)' );


        #   Test the creation of the milter connection socket with the setconn function 
        #   for each of the test sendmail configuration files parsed.

    }
}


1;


__END__