File Coverage

blib/lib/Sendmail/PMilter.pm
Criterion Covered Total %
statement 234 535 43.7
branch 6 152 3.9
condition 3 44 6.8
subroutine 76 99 76.7
pod 18 19 94.7
total 337 849 39.6


line stmt bran cond sub pod time code
1             =pod
2              
3             =head1 LICENSE
4              
5             Copyright (c) 2016-2024 G.W. Haywood. All rights reserved.
6             With thanks to all those who have trodden these paths before,
7             including
8             Copyright (c) 2002-2004 Todd Vierling. All rights reserved.
9              
10             Redistribution and use in source and binary forms, with or without
11             modification, are permitted provided that the following conditions are met:
12              
13             1. Redistributions of source code must retain the above copyright notices,
14             this list of conditions and the following disclaimer.
15              
16             2. Redistributions in binary form must reproduce the above copyright
17             notices, this list of conditions and the following disclaimer in the
18             documentation and/or other materials provided with the distribution.
19              
20             3. Neither the name of the author nor the names of contributors may be used
21             to endorse or promote products derived from this software without specific
22             prior written permission. In the case of G.W. Haywood this permission is
23             hereby now granted.
24              
25             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26             AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27             IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28             ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29             LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30             CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31             SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32             INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33             CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34             ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35             POSSIBILITY OF SUCH DAMAGE.
36              
37             =cut
38              
39             package Sendmail::PMilter;
40              
41 1     1   135082 use 5.014; # Don't use 5.016 yet. That would enable feature 'unicode_strings', and we
  1         4  
42             # probably aren't quite ready for that. We're counting *characters* passed
43             # between us and Sendmail, and Sendmail thinks that they're *bytes*.
44              
45 1     1   1567 use parent 'Exporter';
  1         347  
  1         9  
46 1     1   65 use strict;
  1         2  
  1         31  
47 1     1   4 use warnings;
  1         4  
  1         52  
48 1     1   6 use Carp;
  1         2  
  1         63  
49 1     1   511 use Errno;
  1         1914  
  1         57  
50 1     1   541 use IO::Select;
  1         1985  
  1         60  
51 1     1   614 use POSIX;
  1         10548  
  1         6  
52 1     1   4363 use Socket;
  1         5292  
  1         616  
53 1     1   537 use Symbol;
  1         1375  
  1         77  
54 1     1   869 use UNIVERSAL;
  1         18  
  1         90  
55              
56             our $VERSION = '1.27';
57             $VERSION = eval $VERSION;
58              
59             our $DEBUG = 0;
60              
61             =pod
62              
63             =head1 NAME
64              
65             Sendmail::PMilter - Perl binding of Sendmail Milter protocol
66              
67             =head1 SYNOPSIS
68              
69             use Sendmail::PMilter;
70              
71             my $milter = new Sendmail::PMilter;
72              
73             $milter->auto_setconn(NAME);
74             $milter->register(NAME, { CALLBACKS }[, FLAGS]);
75             $milter->main();
76              
77             =head1 DESCRIPTION
78              
79             Sendmail::PMilter is a mail filtering API implementing the Sendmail
80             Milter Protocol in Perl. This allows the administrator of Sendmail
81             (and perhaps other MTAs which implement the Milter Protocol) to use
82             pure Perl code to filter and modify mail during an SMTP connection.
83              
84             Over the years, the protocol which governs the communication between
85             qSendmail and its milters has passed through a number of revisions.
86              
87             This documentation is for Sendmail::PMilter versions 1.20 and later,
88             which now supports Milter Protocol Version 6. This is a substantial
89             upgrade from earlier versions, which at best supported up to Milter
90             Protocol Version 2 - this was first seen in Sendmail version 8.14.0
91             which was released on January 31st 2007.
92              
93             Sendmail::PMilter now uses neither the original Sendmail::Milter (it
94             is obsolete, badly flawed and unmaintained) nor the Sendmail::Milter
95             which was packaged with earlier versions of Sendmail::PMilter as a
96             temporary workaround for the broken original.
97              
98             For communications between the MTA and the milter, a 'dispatcher' acts
99             as a go-between. This must be chosen when the milter is initialized,
100             before it serves requests. Several dispatchers are provided within
101             the Sendmail::PMilter module, but in versions before 1.20 all the
102             dispatchers suffered from issues of varying gravity. The 'prefork'
103             dispatcher (see DISPATCHERS below) has now been extensively exercised
104             by the current maintainer, but although the others have been patched
105             from issue reports going back more than a decade from the time of
106             writing (June 2019) THEY HAVE NOT BEEN TESTED. Feedback via the CPAN
107             issue tracking system is encouraged. If you have developed your own
108             dispatcher you can either pass a code reference to set_dispatcher() or
109             set an environment variable to point to it. Sendmail::PMilter will
110             then use it instead of a built-in dispatcher.
111              
112             =head1 METHODS
113              
114             =cut
115              
116             ##### Protocol constants
117             # The SMFIS_* values here are not the same as those used in the Sendmail sources
118             # (see mfapi.h) so that hopefully "0" and "1" won't be used as response codes by
119             # mistake. The other protocol constants below are unchanged from those used in
120             # the Sendmail sources.
121              
122 1     1   6 use constant SMFIS_CONTINUE => 100;
  1         2  
  1         104  
123 1     1   5 use constant SMFIS_REJECT => 101;
  1         2  
  1         47  
124 1     1   5 use constant SMFIS_DISCARD => 102;
  1         2  
  1         41  
125 1     1   30 use constant SMFIS_ACCEPT => 103;
  1         3  
  1         47  
126 1     1   5 use constant SMFIS_TEMPFAIL => 104;
  1         2  
  1         38  
127 1     1   4 use constant SMFIS_MSG_LOOP => 105;
  1         2  
  1         35  
128 1     1   5 use constant SMFIS_ALL_OPTS => 110;
  1         2  
  1         38  
129              
130             # Milter progessing 'places' (see mfapi.h, values are the same).
131 1     1   4 use constant SMFIM_CONNECT => 0; # connect
  1         2  
  1         35  
132 1     1   4 use constant SMFIM_HELO => 1; # HELO/EHLO
  1         3  
  1         34  
133 1     1   4 use constant SMFIM_ENVFROM => 2; # MAIL FROM
  1         3  
  1         33  
134 1     1   5 use constant SMFIM_ENVRCPT => 3; # RCPT TO
  1         1  
  1         36  
135 1     1   4 use constant SMFIM_DATA => 4; # DATA
  1         2  
  1         34  
136 1     1   6 use constant SMFIM_EOM => 5; # END OF MESSAGE (final dot)
  1         2  
  1         48  
137 1     1   4 use constant SMFIM_EOH => 6; # END OF HEADER
  1         2  
  1         49  
138              
139             # Some of these things have been switched around from their order of
140             # presentation in the Sendmail sources but the values are the same.
141             ######################################################################
142             # Taken from .../sendmail-8.15.2/include/libmilter/mfdef.h
143             ######################################################################
144             #if _FFR_MDS_NEGOTIATE
145             # define MILTER_MDS_64K ((64 * 1024) - 1)
146             # define MILTER_MDS_256K ((256 * 1024) - 1)
147             # define MILTER_MDS_1M ((1024 * 1024) - 1)
148             #endif /* _FFR_MDS_NEGOTIATE */
149             ######################################################################
150             # These so-called 'protocols' apply to the SMFIP_* flags:
151             #define SMFI_V1_PROT 0x0000003FL The protocol of V1 filter. We won't bother with V1, it's obsolete.
152             #define SMFI_V2_PROT 0x0000007FL The protocol of V2 filter
153 1     1   13 use constant SMFI_V2_PROT => 0x0000007F; # The protocol flags available in Milter Protocol Version 2.
  1         2  
  1         39  
154             #use constant SMFI_V4_PROT => 0x000003FF; # The protocol flags available in Milter Protocol Version 4.
155 1     1   5 use constant SMFI_V6_PROT => 0x001FFFFF; # The protocol flags available in Milter Protocol Version 6.
  1         2  
  1         80  
156 1     1   6 use constant SMFI_CURR_PROT => 0x001FFFFF; # The protocol flags available in the current Milter Protocol Version (which at July 2019 is Version 6).
  1         2  
  1         44  
157             ######################################################################
158             # What the MTA can send/filter wants in protocol
159 1     1   5 use constant SMFIP_NOCONNECT => 0x00000001; # MTA should not send connect info
  1         2  
  1         49  
160 1     1   23 use constant SMFIP_NOHELO => 0x00000002; # MTA should not send HELO info
  1         2  
  1         41  
161 1     1   5 use constant SMFIP_NOMAIL => 0x00000004; # MTA should not send MAIL info
  1         2  
  1         45  
162 1     1   4 use constant SMFIP_NORCPT => 0x00000008; # MTA should not send RCPT info
  1         2  
  1         77  
163 1     1   5 use constant SMFIP_NOBODY => 0x00000010; # MTA should not send body
  1         2  
  1         70  
164 1     1   4 use constant SMFIP_NOHDRS => 0x00000020; # MTA should not send headers
  1         2  
  1         47  
165 1     1   4 use constant SMFIP_NOEOH => 0x00000040; # MTA should not send EOH
  1         2  
  1         39  
166 1     1   6 use constant SMFIP_NR_HDR => 0x00000080; # No reply for headers
  1         1  
  1         46  
167 1     1   4 use constant SMFIP_NOHREPL => 0x00000080; # No reply for headers (backward compatibility, do not use, same as SMFIP_NR_HDR)
  1         2  
  1         37  
168 1     1   4 use constant SMFIP_NOUNKNOWN => 0x00000100; # MTA should not send unknown commands
  1         15  
  1         39  
169 1     1   5 use constant SMFIP_NODATA => 0x00000200; # MTA should not send DATA
  1         2  
  1         55  
170 1     1   4 use constant SMFIP_SKIP => 0x00000400; # MTA understands SMFIS_SKIP called from EOM callback.
  1         3  
  1         57  
171 1     1   5 use constant SMFIP_RCPT_REJ => 0x00000800; # MTA should also send rejected RCPTs
  1         1  
  1         39  
172 1     1   4 use constant SMFIP_NR_CONN => 0x00001000; # No reply for connect
  1         2  
  1         35  
173 1     1   4 use constant SMFIP_NR_HELO => 0x00002000; # No reply for HELO
  1         1  
  1         44  
174 1     1   4 use constant SMFIP_NR_MAIL => 0x00004000; # No reply for MAIL
  1         2  
  1         64  
175 1     1   6 use constant SMFIP_NR_RCPT => 0x00008000; # No reply for RCPT
  1         1  
  1         55  
176 1     1   5 use constant SMFIP_NR_DATA => 0x00010000; # No reply for DATA
  1         2  
  1         37  
177 1     1   13 use constant SMFIP_NR_UNKN => 0x00020000; # No reply for UNKN
  1         3  
  1         38  
178 1     1   4 use constant SMFIP_NR_EOH => 0x00040000; # No reply for eoh
  1         2  
  1         84  
179 1     1   6 use constant SMFIP_NR_BODY => 0x00080000; # No reply for body chunk
  1         2  
  1         58  
180 1     1   4 use constant SMFIP_HDR_LEADSPC => 0x00100000; # header value leading space
  1         2  
  1         38  
181 1     1   4 use constant SMFIP_MDS_256K => 0x10000000; # MILTER_MAX_DATA_SIZE=256K
  1         18  
  1         62  
182 1     1   5 use constant SMFIP_MDS_1M => 0x20000000; # MILTER_MAX_DATA_SIZE=1M
  1         2  
  1         79  
183             ######################################################################
184             # If no negotiate callback is registered, these are the defaults. Basically
185             # everything is enabled except SMFIP_RCPT_REJ and MILTER_MAX_DATA_SIZE_*
186             # Sendmail and Postfix behave differently:
187             # Postfix does not use the constants SMFIP_MDS_256K and SMFIP_MDS_1M.
188 1     1   4 use constant SMFIP_ALL_NO_CB => (SMFIP_NOCONNECT|SMFIP_NOHELO|SMFIP_NOMAIL|SMFIP_NORCPT|SMFIP_NOBODY|SMFIP_NOHDRS|SMFIP_NOEOH|SMFIP_NOUNKNOWN|SMFIP_NODATA|SMFIP_SKIP|SMFIP_HDR_LEADSPC);
  1         2  
  1         77  
189 1     1   5 use constant SMFIP_ALL_NO_REPLY => (SMFIP_NR_HDR|SMFIP_NR_CONN|SMFIP_NR_HELO|SMFIP_NR_MAIL|SMFIP_NR_RCPT|SMFIP_NR_DATA|SMFIP_NR_UNKN|SMFIP_NR_EOH|SMFIP_NR_BODY);
  1         2  
  1         62  
190 1     1   4 use constant SMFIP_DEFAULTS => ~(SMFIP_ALL_NO_CB|SMFIP_ALL_NO_REPLY);
  1         2  
  1         48  
191             ######################################################################
192             # Taken from .../sendmail-8.15.2/include/libmilter/mfapi.h, and
193             # reformatted a little.
194             ######################################################################
195             # These so-called 'actions' apply to the SMFIF_* flags:
196             #define SMFI_V1_ACTS 0x0000000FL The actions of V1 filter
197             #define SMFI_V2_ACTS 0x0000003FL The actions of V2 filter
198             #define SMFI_CURR_ACTS 0x000001FFL actions of current version
199             ######################################################################
200             #define SMFIF_NONE 0x00000000L no flags
201             #define SMFIF_ADDHDRS 0x00000001L filter may add headers
202             #define SMFIF_CHGBODY 0x00000002L filter may replace body
203             #define SMFIF_MODBODY SMFIF_CHGBODY backwards compatible
204             #define SMFIF_ADDRCPT 0x00000004L filter may add recipients
205             #define SMFIF_DELRCPT 0x00000008L filter may delete recipients
206             #define SMFIF_CHGHDRS 0x00000010L filter may change/delete headers
207             #define SMFIF_QUARANTINE 0x00000020L filter may quarantine envelope <<========= "envelope"???
208             #define SMFIF_CHGFROM 0x00000040L filter may change "from" (envelope sender)
209             #define SMFIF_ADDRCPT_PAR 0x00000080L add recipients incl. args
210             #define SMFIF_SETSYMLIST 0x00000100L filter can send set of symbols (macros) that it wants
211             ######################################################################
212             # Capability FLAG value Available in milter protocol version (*)
213 1     1   5 use constant SMFIF_NONE => 0x0000; # Unused (*) There's a bit of a muddle about V3,
  1         2  
  1         45  
214 1     1   5 use constant SMFIF_ADDHDRS => 0x0001; # V1 Add headers but nobody's using it any more.
  1         2  
  1         79  
215 1     1   6 use constant SMFIF_MODBODY => 0x0002; # V1 Change body (for compatibility with old code, use SMFIF_CHGBODY in new code)
  1         2  
  1         44  
216 1     1   4 use constant SMFIF_CHGBODY => SMFIF_MODBODY; # V2 Change body
  1         2  
  1         84  
217 1     1   6 use constant SMFIF_ADDRCPT => 0x0004; # V1 Add recipient
  1         2  
  1         46  
218 1     1   5 use constant SMFIF_DELRCPT => 0x0008; # V1 Delete recipient
  1         2  
  1         51  
219 1     1   4 use constant SMFIF_CHGHDRS => 0x0010; # V2 Change headers
  1         2  
  1         47  
220 1     1   5 use constant SMFIF_QUARANTINE => 0x0020; # V2 quarantine entire message - last of the V2 flags
  1         1  
  1         38  
221 1     1   4 use constant SMFIF_CHGFROM => 0x0040; # V6 Change envelope sender
  1         1  
  1         45  
222 1     1   4 use constant SMFIF_ADDRCPT_PAR => 0x0080; # V6 Add recipients incl. args
  1         2  
  1         37  
223 1     1   5 use constant SMFIF_SETSYMLIST => 0x0100; # V6 Filter can send set of symbols (macros) that it wants
  1         2  
  1         99  
224              
225 1     1   6 use constant SMFI_V1_ACTS => SMFIF_ADDHDRS|SMFIF_CHGBODY|SMFIF_ADDRCPT|SMFIF_DELRCPT;
  1         2  
  1         69  
226 1     1   5 use constant SMFI_V2_ACTS => SMFI_V1_ACTS|SMFIF_CHGHDRS|SMFIF_QUARANTINE;
  1         3  
  1         51  
227 1     1   5 use constant SMFI_V6_ACTS => SMFI_V2_ACTS|SMFIF_CHGFROM|SMFIF_ADDRCPT_PAR|SMFIF_SETSYMLIST;
  1         2  
  1         64  
228 1     1   4 use constant SMFI_CURR_ACTS => SMFI_V6_ACTS; # All capabilities. See mfapi.h and mfdef.h
  1         2  
  1         58  
229              
230             # See libmilter/smfi.c
231 1     1   5 use constant MAXREPLYLEN => 980;
  1         1  
  1         53  
232 1     1   5 use constant MAXREPLIES => 32;
  1         2  
  1         3658  
233              
234             ##### Symbols exported to the caller
235              
236             my $smflags =
237             ' SMFIP_DEFAULTS SMFIP_NOCONNECT SMFIP_NOHELO SMFIP_NOMAIL SMFIP_NORCPT SMFIP_NOBODY SMFIP_NOHDRS SMFIP_NOEOH SMFIP_NOUNKNOWN SMFIP_NODATA SMFIP_RCPT_REJ SMFIP_SKIP
238             SMFIP_NR_CONN SMFIP_NR_HELO SMFIP_NR_MAIL SMFIP_NR_RCPT SMFIP_NR_DATA SMFIP_NR_HDR SMFIP_NR_EOH SMFIP_NR_BODY SMFIP_NR_UNKN SMFIP_HDR_LEADSPC SMFIP_MDS_256K SMFIP_MDS_1M
239             SMFIM_CONNECT SMFIM_HELO SMFIM_ENVFROM SMFIM_ENVRCPT SMFIM_DATA SMFIM_EOM SMFIM_EOH
240             SMFIS_CONTINUE SMFIS_REJECT SMFIS_DISCARD SMFIS_ACCEPT SMFIS_TEMPFAIL SMFIS_MSG_LOOP SMFIS_ALL_OPTS
241             SMFIF_NONE SMFIF_ADDHDRS SMFIF_CHGBODY SMFIF_ADDRCPT SMFIF_DELRCPT SMFIF_CHGHDRS SMFIF_QUARANTINE SMFIF_CHGFROM SMFIF_ADDRCPT_PAR SMFIF_SETSYMLIST
242             SMFI_V2_ACTS SMFI_V6_ACTS SMFI_CURR_ACTS SMFI_V2_PROT SMFI_V6_PROT SMFI_CURR_PROT
243             MAXREPLYLEN MAXREPLIES
244             ';
245             our @smflags = eval "qw/ $smflags /;";
246             our @dispatchers = qw/ ithread_dispatcher postfork_dispatcher prefork_dispatcher sequential_dispatcher /;
247             my @callback_names = qw/ negotiate connect helo envfrom envrcpt data header eoh body eom close abort unknown /;
248             our %DEFAULT_CALLBACKS = map { $_ => $_.'_callback' } @callback_names;
249             # Don't export anything by default.
250             our @EXPORT = ();
251             # Everything else is OK. I have tried.
252             our @EXPORT_OK = qw/
253             SMFIP_DEFAULTS SMFIP_NOCONNECT SMFIP_NOHELO SMFIP_NOMAIL SMFIP_NORCPT SMFIP_NOBODY SMFIP_NOHDRS SMFIP_NOEOH SMFIP_NOUNKNOWN SMFIP_NODATA SMFIP_RCPT_REJ SMFIP_SKIP
254             SMFIP_NR_CONN SMFIP_NR_HELO SMFIP_NR_MAIL SMFIP_NR_RCPT SMFIP_NR_DATA SMFIP_NR_HDR SMFIP_NR_EOH SMFIP_NR_BODY SMFIP_NR_UNKN SMFIP_HDR_LEADSPC SMFIP_MDS_256K SMFIP_MDS_1M
255             SMFIM_CONNECT SMFIM_HELO SMFIM_ENVFROM SMFIM_ENVRCPT SMFIM_DATA SMFIM_EOM SMFIM_EOH
256             SMFIS_CONTINUE SMFIS_REJECT SMFIS_DISCARD SMFIS_ACCEPT SMFIS_TEMPFAIL SMFIS_MSG_LOOP SMFIS_ALL_OPTS
257             SMFIF_NONE SMFIF_ADDHDRS SMFIF_CHGBODY SMFIF_ADDRCPT SMFIF_DELRCPT SMFIF_CHGHDRS SMFIF_QUARANTINE SMFIF_CHGFROM SMFIF_ADDRCPT_PAR SMFIF_SETSYMLIST
258             SMFI_V2_ACTS SMFI_V6_ACTS SMFI_CURR_ACTS SMFI_V2_PROT SMFI_V6_PROT SMFI_CURR_PROT
259             MAXREPLYLEN MAXREPLIES
260             ithread_dispatcher postfork_dispatcher prefork_dispatcher sequential_dispatcher
261             negotiate_callback connect_callback helo_callback envfrom_callback envrcpt_callback data_callback header_callback eoh_callback body_callback eom_callback close_callback abort_callback unknown_callback
262             /;
263              
264             # Three export tags for flags, dispatchers and callbacks.
265             our %EXPORT_TAGS = ( all => [ @smflags ], dispatchers => [ @dispatchers ], callbacks => [ (values %DEFAULT_CALLBACKS) ] );
266              
267             our $enable_chgfrom = 0;
268              
269             ##### Methods
270              
271             sub new ($) {
272 1     1 0 240099 bless {}, shift;
273             }
274              
275             =pod
276              
277             =over 4
278              
279             =item get_max_interpreters()
280              
281             Returns the maximum number of interpreters passed to C. This is
282             only useful when called from within the dispatcher, as it is not set before
283             C is called.
284              
285             =cut
286              
287             sub get_max_interpreters ($) {
288 0     0 1 0 my $this = shift;
289              
290 0 0       0 $this->{max_interpreters} || 0;
291             }
292              
293             =pod
294              
295             =item get_max_requests()
296              
297             Returns the maximum number of requests per interpreter passed to C.
298             This is only useful when called from within the dispatcher, as it is not set
299             before C is called.
300              
301             =cut
302              
303             sub get_max_requests ($) {
304 0     0 1 0 my $this = shift;
305              
306 0 0       0 $this->{max_requests} || 0;
307             }
308              
309             =pod
310              
311             =item main([MAXCHILDREN[, MAXREQ]])
312              
313             This is the last method called in the main block of a milter program. If
314             successful, this call never returns; the protocol engine is launched and
315             begins accepting connections.
316              
317             MAXCHILDREN (default 0, meaning unlimited) specifies the maximum number of
318             connections that may be serviced simultaneously. If a connection arrives
319             with the number of active connections above this limit, the milter will
320             immediately return a temporary failure condition and close the connection.
321             Passing a value for MAXCHILDREN is optional.
322              
323             MAXREQ (default 0, meaning unlimited) is the maximum number of requests that
324             a child may service before being recycled. It is not guaranteed that the
325             interpreter will service this many requests, only that it will not go over
326             the limit. MAXCHILDREN must be given if MAXREQ is to be set.
327              
328             Any callback which Cs will have its output sent to C, followed by
329             a clean shutdown of the milter connection. To catch any warnings generated
330             by the callbacks, and any error messages caused by a C, set
331             C<$SIG{__WARN__}> to a user-defined subroutine. (See L.)
332              
333             =cut
334              
335             sub main ($;$$$) {
336 0     0 1 0 require Sendmail::PMilter::Context;
337              
338 0         0 my $this = shift;
339 0 0       0 croak 'main: socket not bound' unless defined($this->{socket});
340 0 0       0 croak 'main: callbacks not registered' unless defined($this->{callbacks});
341 0 0       0 croak 'main: milter protocol version not defined' unless defined($this->{'milter protocol version'});
342              
343 0         0 my $max_interpreters = shift;
344 0         0 my $max_requests = shift;
345              
346 0 0 0     0 $this->{max_interpreters} = $max_interpreters if (defined($max_interpreters) && $max_interpreters =~ /^\d+$/); # This test doesn't permit an empty string.
347 0 0 0     0 $this->{max_requests} = $max_requests if (defined($max_requests) && $max_requests =~ /^\d+$/);
348              
349 0         0 my $dispatcher = $this->{dispatcher};
350              
351 0 0       0 unless (defined($dispatcher)) {
352 0   0     0 my $dispatcher_name = ($ENV{PMILTER_DISPATCHER} || 'postfork').'_dispatcher';
353 0         0 $dispatcher = &{\&{qualify_to_ref($dispatcher_name, 'Sendmail::PMilter')}};
  0         0  
  0         0  
354             }
355              
356             my $handler = sub {
357 0     0   0 my $ctx = new Sendmail::PMilter::Context(shift, $this->{callbacks}, $this->{callback_flags}, $this->{'milter protocol version'});
358              
359 0         0 $ctx->main();
360 0         0 };
361              
362 0         0 &$dispatcher($this, $this->{socket}, $handler);
363 0         0 undef;
364             }
365              
366             =pod
367              
368             =item register(NAME, CALLBACKS[, FLAGS])
369              
370             Sets up the main milter loop configuration.
371              
372             NAME is the name of the milter. This should be the same name as passed to
373             auto_getconn() or auto_setconn(), but this PMilter implementation does not
374             enforce this.
375              
376             CALLBACKS is a hash reference containing one or more callback subroutines.
377             For example
378              
379             my %callbacks =
380             (
381             'negotiate' => \&my_negotiate_callback,
382             'connect' => \&my_connect_callback,
383             'helo' => \&my_helo_callback,
384             'envfrom' => \&my_envfrom_callback,
385             'close' => \&my_close_callback,
386             'abort' => \&my_abort_callback,
387             );
388             $milter->register( $milter_name, \%callbacks );
389              
390             If a callback is not named in this hashref, the caller's package will be
391             searched for subroutines named "CALLBACK_callback", where CALLBACK is the
392             name of the callback function.
393              
394             FLAGS is accepted for backward compatibility with older versions of
395             this module. Consider it deprecated. Set it to SMFI_V6_PROT for all
396             available 'actions' in any recent (last few years) Sendmail version.
397              
398             If no C callback is registered, then by default the protocol
399             steps available are as described in .../libmilter/engine.c in the
400             Sendmail sources. This means all the registered CALLBACKS plus the
401             SKIP function call which is allowed in the End Of Message callback.
402             Note that SMFIP_RCPT_REJ is specifically not included.
403              
404             C must be called successfully exactly once. If called a second
405             time, the previously registered callbacks will be erased.
406              
407             Returns 1 on success, undef on failure.
408              
409             =cut
410              
411             sub register ($$$;$) {
412 0     0 1 0 my $this = shift;
413 0         0 $this->{name} = shift;
414              
415 0 0       0 carp 'register: no name supplied' unless defined($this->{name});
416 0 0       0 carp 'register: passed ref as name argument' if ref($this->{name});
417              
418 0         0 my $callbacks = shift;
419 0         0 my $pkg = caller;
420              
421 0 0       0 croak 'register: callbacks is undef' unless defined($callbacks);
422 0 0       0 croak 'register: callbacks not hash ref' unless UNIVERSAL::isa($callbacks, 'HASH');
423              
424             # make internal copy, and convert to code references
425 0         0 $callbacks = { %$callbacks };
426              
427 0         0 foreach my $cbname (keys %DEFAULT_CALLBACKS) {
428 0         0 my $cb = $callbacks->{$cbname};
429 0 0 0     0 if (defined($cb) && !UNIVERSAL::isa($cb, 'CODE')) {
430 0         0 $cb = qualify_to_ref($cb, $pkg);
431 0 0       0 if (exists(&$cb)) {
432 0         0 $callbacks->{$cbname} = \&$cb;
433             } else {
434 0         0 delete $callbacks->{$cbname};
435             }
436             }
437             }
438              
439 0         0 $this->{callbacks} = $callbacks;
440 0   0     0 $this->{callback_flags} = shift || 0;
441             # MILTER PROTOCOL VERSION
442 0 0       0 $this->{'milter protocol version'} = ($this->{callback_flags} & ~0x3F) ? 6 : 2;
443 0         0 1;
444             }
445              
446             =pod
447              
448             =item setconn(DESC[, PERMS])
449              
450             Sets up the server socket with connection descriptor DESC. This is
451             identical to the descriptor syntax used by the "X" milter configuration
452             lines in sendmail.cf (if using Sendmail). This should be one of the
453             following:
454              
455             =over 2
456              
457             =item local:PATH
458              
459             A local ("UNIX") socket on the filesystem, named PATH. This has some smarts
460             that will auto-delete the pathname if it seems that the milter is not
461             currently running (but this currently contains a race condition that may not
462             be fixable; at worst, there could be two milters running with one never
463             receiving connections).
464              
465             =item inet:PORT[@HOST]
466              
467             An IPv4 socket, bound to address HOST (default INADDR_ANY), on port PORT.
468             It is not recommended to open milter engines to the world, so the @HOST part
469             should be specified.
470              
471             =item inet6:PORT[@HOST]
472              
473             An IPv6 socket, bound to address HOST (default INADDR_ANY), on port PORT.
474             This requires IPv6 support and the Perl IO::Socket::IP package to be installed.
475             It is not recommended to open milter engines to the world, so the @HOST part
476             SHOULD be specified.
477              
478             =item PERMS
479              
480             Optional permissions mask.
481              
482             =back
483              
484             Returns a true value on success, undef on failure.
485              
486             =cut
487              
488             sub setconn ($$) {
489 0     0 1 0 my $this = shift;
490 0         0 my $conn = shift;
491 0         0 my $perms = shift;
492 0   0     0 my $backlog = $this->{backlog} || 5;
493 0         0 my $socket;
494              
495 0 0       0 croak "setconn: $conn: unspecified protocol"
496             unless ($conn =~ /^([^:]+):([^:@]+)(?:@([^:@]+|\[[0-9a-f:\.]+\]))?$/);
497              
498 0 0 0     0 if ($1 eq 'local' || $1 eq 'unix') {
    0          
    0          
499 0         0 require IO::Socket::UNIX;
500              
501 0         0 my $path = $2;
502 0         0 my $addr = sockaddr_un($path);
503 0         0 my $oldumask = umask;
504              
505 0 0       0 croak "setconn: $conn: path not absolute"
506             unless ($path =~ m,^/,,);
507              
508 0 0       0 if ($perms)
509             {
510 0         0 umask 0777 - $perms;
511             }
512              
513 0 0 0     0 if (-e $path && ! -S $path) { # exists, not a socket
514 0         0 $! = Errno::EEXIST;
515             } else {
516 0         0 $socket = IO::Socket::UNIX->new(Type => SOCK_STREAM);
517             }
518              
519             # Some systems require you to unlink an orphaned inode.
520             # There's a race condition here, but it's unfortunately
521             # not easily fixable. Using an END{} block doesn't
522             # always work, and that's too wonky with fork() anyway.
523              
524 0 0 0     0 if (defined($socket) && !$socket->bind($addr)) {
525 0 0       0 if ($socket->connect($addr)) {
526 0         0 close $socket;
527 0         0 undef $socket;
528 0         0 $! = Errno::EADDRINUSE;
529             } else {
530 0         0 unlink $path; # race condition
531 0 0       0 $socket->bind($addr) || undef $socket;
532             }
533             }
534              
535 0         0 umask $oldumask;
536            
537 0 0       0 if (defined($socket)) {
538 0 0       0 $socket->listen($backlog) || croak "setconn: listen $conn: $!";
539             }
540             } elsif ($1 eq 'inet') {
541 0         0 require IO::Socket::INET;
542              
543 0         0 $socket = IO::Socket::INET->new(
544             Proto => 'tcp',
545             ReuseAddr => 1,
546             Listen => $backlog,
547             LocalPort => $2,
548             LocalAddr => $3
549             );
550             } elsif ($1 eq 'inet6') {
551 0         0 require IO::Socket::IP;
552              
553 0         0 $socket = IO::Socket::IP->new(
554             Proto => 'tcp',
555             ReuseAddr => 1,
556             Listen => $backlog,
557             LocalService => $2,
558             LocalHost => $3
559             );
560             } else {
561 0         0 croak "setconn: $conn: unknown protocol";
562             }
563              
564 0 0       0 if (defined($socket)) {
565 0         0 $this->set_socket($socket);
566             } else {
567 0         0 carp "setconn: $conn: $!";
568 0         0 undef;
569             }
570             }
571              
572             =pod
573              
574             =item set_dispatcher(CODEREF)
575              
576             Sets the dispatcher used to accept socket connections and hand them off to
577             the protocol engine. This allows pluggable resource allocation so that the
578             milter script may use fork, threads, or any other such means of handling
579             milter connections. See C below for more information.
580              
581             The subroutine (code) reference will be called by C when the
582             listening socket object is prepared and ready to accept connections. It
583             will be passed the arguments:
584              
585             MILTER, LSOCKET, HANDLER
586              
587             MILTER is the milter object currently running. LSOCKET is a listening
588             socket (an instance of C), upon which C should be
589             called. HANDLER is a subroutine reference which should be called, passing
590             the socket object returned by C<< LSOCKET->accept() >>.
591              
592             Note that the dispatcher may also be set from one of the off-the-shelf
593             dispatchers noted in this document by setting the PMILTER_DISPATCHER
594             environment variable. See C, below.
595              
596             =cut
597              
598             sub set_dispatcher($&) {
599 0     0 1 0 my $this = shift;
600              
601 0         0 $this->{dispatcher} = shift;
602 0         0 1;
603             }
604              
605             =pod
606              
607             =item set_listen(BACKLOG)
608              
609             Set the socket listen backlog to BACKLOG. The default is 5 connections if
610             not set explicitly by this method. Only useful before calling C.
611              
612             =cut
613              
614             sub set_listen ($$) {
615 0     0 1 0 my $this = shift;
616 0         0 my $backlog = shift;
617              
618 0 0       0 croak 'set_listen: socket already bound' if defined($this->{socket});
619              
620 0         0 $this->{backlog} = $backlog;
621 0         0 1;
622             }
623              
624             =pod
625              
626             =item set_socket(SOCKET)
627              
628             Rather than calling C, this method may be called explicitly to
629             set the C instance used to accept inbound connections.
630              
631             =cut
632              
633             sub set_socket ($$) {
634 0     0 1 0 my $this = shift;
635 0         0 my $socket = shift;
636              
637 0 0       0 croak 'set_socket: socket already bound' if defined($this->{socket});
638 0 0       0 croak 'set_socket: not an IO::Socket instance' unless UNIVERSAL::isa($socket, 'IO::Socket');
639              
640 0         0 $this->{socket} = $socket;
641 0         0 1;
642             }
643              
644             =pod
645              
646             =back
647              
648             =head1 SENDMAIL-SPECIFIC METHODS
649              
650             The following methods are only useful if Sendmail is the MTA connecting to
651             this milter. Other MTAs likely don't use Sendmail's configuration file, so
652             these methods would not be useful with them.
653              
654             =over 4
655              
656             =item auto_getconn(NAME[, CONFIG])
657              
658             Returns the connection descriptor for milter NAME in Sendmail configuration
659             file CONFIG (default C or whatever was set by
660             C). This can then be passed to setconn(), below.
661              
662             Returns a true value on success, undef on failure.
663              
664             =cut
665              
666             sub auto_getconn ($$;$) {
667 5     5 1 12 my $this = shift;
668 5   100     23 my $milter = shift || die "milter name not supplied\n";
669 4   33     17 my $cf = shift || $this->get_sendmail_cf();
670 4         14 local *CF;
671              
672 4 50       1734 open(CF, '<'.$cf) || die "open $cf: $!";
673              
674 4         655 while () {
675 4         42 s/\s+$//; # also trims newlines
676              
677 4 50       33 s/^X([^,\s]+),\s*// || next;
678 4 50       19 ($milter eq $1) || next;
679              
680 4         23 while (s/^(.)=([^,\s]+)(,\s*|\Z)//) {
681 4 50       16 if ($1 eq 'S') {
682 4         51 close(CF);
683 4         46 return $2;
684             }
685             }
686             }
687              
688 0         0 close(CF);
689 0         0 undef;
690             }
691              
692             =pod
693              
694             =item auto_setconn(NAME[, CONFIG])
695              
696             Creates the server connection socket for milter NAME in Sendmail
697             configuration file CONFIG.
698              
699             Essentially, does:
700              
701             $milter->setconn($milter->auto_getconn(NAME, CONFIG))
702              
703             Returns a true value on success, undef on failure.
704              
705             =cut
706              
707             sub auto_setconn ($$;$) {
708 0     0 1 0 my $this = shift;
709 0         0 my $name = shift;
710 0         0 my $conn = $this->auto_getconn($name, shift);
711              
712 0 0       0 if (defined($conn)) {
713 0         0 $this->setconn($conn);
714             } else {
715 0         0 carp "auto_setconn: no connection for $name found";
716 0         0 undef;
717             }
718             }
719              
720             =pod
721              
722             =item get_sendmail_cf()
723              
724             Returns the pathname of the Sendmail configuration file. If this has
725             been set by C, then that is the value returned.
726             Otherwise the default pathname C is returned.
727              
728             =cut
729              
730             sub get_sendmail_cf ($) {
731 7     7 1 846 my $this = shift;
732              
733 7 100       96 $this->{sendmail_cf} || '/etc/mail/sendmail.cf';
734             }
735              
736             =pod
737              
738             =item get_sendmail_class(CLASS[, CONFIG])
739              
740             Returns a list containing all members of the Sendmail class CLASS, in
741             Sendmail configuration file CONFIG (default C or
742             whatever is set by C). Typically this is used to look up
743             the entries in class "w", the local hostnames class.
744              
745             =cut
746              
747             sub get_sendmail_class ($$;$) {
748 0     0 1 0 my $this = shift;
749 0         0 my $class = shift;
750 0   0     0 my $cf = shift || $this->get_sendmail_cf();
751 0         0 my %entries;
752 0         0 local *CF;
753              
754 0 0       0 open(CF, '<'.$cf) || croak "get_sendmail_class: open $cf: $!";
755              
756 0         0 while () {
757 0         0 s/\s+$//; # also trims newlines
758              
759 0 0       0 if (s/^C\s*$class\s*//) {
    0          
760 0         0 foreach (split(/\s+/)) {
761 0         0 $entries{$_} = 1;
762             }
763             } elsif (s/^F\s*$class\s*(-o)?\s*//) {
764 0         0 my $required = !defined($1);
765 0         0 local *I;
766              
767 0 0       0 croak "get_sendmail_class: class $class lookup resulted in pipe: $_" if (/^\|/);
768              
769 0 0       0 if (open(I, '<'.$_)) {
    0          
770 0         0 while () {
771 0         0 s/#.*$//;
772 0         0 s/\s+$//;
773 0 0       0 next if /^$/;
774 0         0 $entries{$_} = 1;
775             }
776 0         0 close(I);
777             } elsif ($required) {
778 0         0 croak "get_sendmail_class: class $class lookup: $_: $!";
779             }
780             }
781             }
782              
783 0         0 close(CF);
784 0         0 keys %entries;
785             }
786              
787             =pod
788              
789             =item get_sendmail_option(OPTION[, CONFIG])
790              
791             Returns a list containing the first occurrence of Sendmail option
792             OPTION in Sendmail configuration file CONFIG (default C,
793             or whatever has been set by C). Returns the
794             value of the option or undef if it is not found. This can be used
795             to learn configuration parameters such as Milter.maxdatasize.
796              
797             =cut
798              
799             sub get_sendmail_option ($$;$) {
800 0     0 1 0 my $this = shift;
801 0         0 my $option = shift;
802 0   0     0 my $cf = shift || $this->get_sendmail_cf();
803 0         0 my %entries;
804 0         0 local *CF;
805 0 0       0 open(CF, '<'.$cf) || croak "get_sendmail_option: open $cf: $!";
806 0         0 while () {
807 0         0 s/\s+$//; # also trims newlines
808 0 0       0 if (/^O\s*$option=(\d+)/) { return $1; }
  0         0  
809             }
810 0         0 close(CF);
811 0         0 undef;
812             }
813              
814             =pod
815              
816             =item set_sendmail_cf(FILENAME)
817              
818             Set the default filename used by C, C, and
819             C to find Sendmail-specific configuration data. If not
820             explicitly set by this method, it defaults to C.
821             Returns 1.
822              
823             =cut
824              
825             sub set_sendmail_cf ($) {
826 7     7 1 4397 my $this = shift;
827              
828 7         22 $this->{sendmail_cf} = shift;
829 7         31 1;
830             }
831              
832             ### off-the-shelf dispatchers
833              
834             =pod
835              
836             =back
837              
838             =head1 DISPATCHERS
839              
840             Milter requests may be dispatched to the protocol handler in a pluggable
841             manner (see the description for the C method above).
842             C offers some off-the-shelf dispatchers that use
843             different methods of resource allocation.
844              
845             Each of these is referenced as a non-object function, and return a value
846             that may be passed directly to C.
847              
848             =over 4
849              
850             =item Sendmail::PMilter::ithread_dispatcher()
851              
852             =item (environment) PMILTER_DISPATCHER=ithread
853              
854             June 2019: This dispatcher has not been tested adequately.
855              
856             The C dispatcher spins up a new thread upon each connection to
857             the milter socket. This provides a thread-based model that may be more
858             resource efficient than the similar C dispatcher. This requires
859             that the Perl interpreter be compiled with C<-Duseithreads>, and uses the
860             C module (available on Perl 5.8 or later only).
861              
862             =cut
863              
864             sub ithread_dispatcher {
865 0     0 1   require threads;
866 0           require threads::shared;
867 0           require Thread::Semaphore;
868              
869 0           my $nchildren = 0;
870              
871 0           threads::shared::share($nchildren);
872              
873             sub {
874 0     0     my $this = shift;
875 0           my $lsocket = shift;
876 0           my $handler = shift;
877 0           my $maxchildren = $this->get_max_interpreters();
878 0           my $child_sem;
879              
880 0 0         if ($maxchildren) {
881 0           $child_sem = Thread::Semaphore->new($maxchildren);
882             }
883            
884 0 0         my $siginfo = exists($SIG{INFO}) ? 'INFO' : 'USR1';
885             local $SIG{$siginfo} = sub {
886 0           warn "Number of active children: $nchildren\n";
887 0           };
888              
889             my $child_sub = sub {
890 0           my $socket = shift;
891              
892 0           eval {
893 0           &$handler($socket);
894 0           $socket->close();
895             };
896 0           my $died = $@;
897              
898 0           lock($nchildren);
899 0           $nchildren--;
900 0 0         if ($child_sem) {
901 0           $child_sem->up();
902             }
903 0 0         warn $died if $died;
904 0           };
905              
906 0           while (1) {
907 0           my $socket = $lsocket->accept();
908 0 0         next if $!{EINTR};
909              
910 0 0         warn "$$: incoming connection\n" if ($DEBUG > 0);
911              
912 0 0 0       if ($child_sem and ! $child_sem->down_nb()) {
913 0           warn "pausing for high load: children $nchildren >= max $maxchildren";
914 0           my $start = time();
915 0           $child_sem->down();
916 0           my $end = time();
917 0           warn sprintf("paused for %.1f seconds due to high load", $end - $start);
918             }
919              
920             # scoping block for lock()
921             {
922 0           lock($nchildren);
  0            
923 0   0       my $t = threads->create($child_sub, $socket) || die "thread creation failed: $!\n";
924 0           $t->detach;
925 0           threads->yield();
926 0           $nchildren++;
927             }
928             }
929 0           };
930             }
931              
932             =pod
933              
934             =item Sendmail::PMilter::prefork_dispatcher([PARAMS])
935              
936             =item (environment) PMILTER_DISPATCHER=prefork
937              
938             June 2019: This dispatcher has been tested extensively by the maintainer.
939              
940             The C dispatcher forks the main Perl process before accepting
941             connections, and uses the main process to monitor the children. This
942             should be appropriate for steady traffic flow sites. Note that if
943             MAXINTERP is not set in the call to C or in PARAMS, an internal
944             default of 10 processes will be used; similarly, if MAXREQ is not set, 100
945             requests will be served per child.
946              
947             Currently the child process pool is fixed in size: discarded children will
948             be replaced immediately.
949              
950             PARAMS, if specified, is a hash of key-value pairs defining parameters for
951             the dispatcher. The available parameters that may be set are:
952              
953             =over 2
954              
955             =item child_init
956              
957             subroutine reference that will be called after each child process is forked.
958             It will be passed the C object.
959              
960             =item child_exit
961              
962             subroutine reference that will be called just before each child process
963             terminates. It will be passed the C object plus current requests
964             handled and maximum requests per child.
965              
966             =item milter_exit
967              
968             subroutine reference that will be called just before the milter
969             terminates. It will be passed the C object.
970              
971             =item max_children
972              
973             Maximum number of child processes active at any time. Equivalent to the
974             MAXINTERP option to main() -- if not set in the main() call, this value
975             will be used.
976              
977             =item max_requests_per_child
978              
979             Maximum number of requests a child process may service before being
980             recycled. Equivalent to the MAXREQ option to main() -- if not set in the
981             main() call, this value will be used.
982              
983             =back
984              
985             =cut
986              
987             sub prefork_dispatcher (@) {
988 0     0 1   my %params = @_;
989 0           my %children;
990             my $curr_requests;
991 0           my $max_requests;
992              
993             my $child_dispatcher = sub {
994 0     0     my $this = shift;
995 0           my $lsocket = shift;
996 0           my $handler = shift;
997 0   0       $max_requests = $this->get_max_requests() || $params{max_requests_per_child} || 100;
998 0           $curr_requests = 0;
999              
1000 0           local $SIG{PIPE} = 'IGNORE'; # so close_callback will be reached
1001              
1002 0 0         my $siginfo = exists($SIG{INFO}) ? 'INFO' : 'USR1';
1003             local $SIG{$siginfo} = sub {
1004 0           warn "$$: requests handled: $curr_requests\n";
1005 0           };
1006              
1007             # call child_init handler if present
1008 0 0         if (defined $params{child_init}) {
1009 0           my $method = $params{child_init};
1010 0           $this->$method();
1011             }
1012 0           eval {
1013 0           while ($curr_requests < $max_requests) {
1014 0           my $socket = $lsocket->accept();
1015 0 0         next if $!{EINTR};
1016 0 0         warn "$$: incoming connection\n" if ($DEBUG > 0);
1017 0           $curr_requests++;
1018 0           &$handler($socket);
1019 0           $socket->close();
1020             }
1021             };
1022 0 0         if ($@) {
1023 0           warn "Exiting cause die";
1024             }
1025 0           };
1026              
1027             # Propagate some signals down to the entire process group.
1028             my $killall = sub {
1029 0     0     my $sig = shift;
1030 0           my $this = $_[0];
1031              
1032             # call milter_exit handler if present
1033 0 0         if (defined $params{milter_exit}) {
1034 0           my $method = $params{milter_exit};
1035 0           $this->$method();
1036             }
1037 0           kill 'TERM', keys %children;
1038 0           exit 0;
1039 0           };
1040              
1041 0           setpgrp();
1042              
1043             sub {
1044 0     0     my $this = $_[0];
1045 0   0       my $maxchildren = $this->get_max_interpreters() || $params{max_children} || 10;
1046              
1047 0           $SIG{INT} = $killall;
1048 0           $SIG{QUIT} = $killall;
1049 0           $SIG{TERM} = $killall;
1050              
1051 0           while (1) {
1052 0           while (scalar keys %children < $maxchildren) {
1053 0           my $pid = fork();
1054 0 0         die "fork: $!" unless defined($pid);
1055              
1056 0 0         if ($pid) {
1057 0           $children{$pid} = 1;
1058             } else {
1059             # setup child_exit handler if present
1060 0 0         if (defined $params{child_exit}) {
1061             # INTR signal usually invoked by CTRL + C
1062             # Don't do anything in child and let's parent to
1063             # signal children with TERM
1064 0           $SIG{INT} = 'IGNORE';
1065              
1066             # QUIT and TERM should terminate the children but
1067             # parent also sends TERM to all children (dups are
1068             # possible. If using systemd, consier using:
1069             # KillMode=mixed
1070             # As workaround we will restore these signals to its
1071             # default, avoiding dup execution.
1072             $SIG{QUIT} = $SIG{TERM} = sub {
1073 0           my $sig_name = shift;
1074              
1075 0           $SIG{QUIT} = $SIG{TERM} = 'DEFAULT';
1076 0           my $method = $params{child_exit};
1077 0           $this->$method($curr_requests, $max_requests);
1078              
1079             # If signal is QUIT, core dump must be issued.
1080             # As we now have set it to default, simply call it.
1081 0 0         if ($sig_name eq 'QUIT') {
1082 0           kill 'QUIT', $$;
1083             }
1084 0           exit;
1085 0           };
1086             } else {
1087             # Perl reset these to IGNORE. Set to defaults.
1088 0           $SIG{INT} = 'DEFAULT';
1089 0           $SIG{QUIT} = 'DEFAULT';
1090 0           $SIG{TERM} = 'DEFAULT';
1091             }
1092 0           &$child_dispatcher(@_);
1093              
1094             # curr_requests = max_requests
1095 0           kill 'TERM', $$;
1096             }
1097             }
1098              
1099             # Wait for a pid to exit, then loop back up to fork.
1100 0           my $pid = wait();
1101 0 0         delete $children{$pid} if ($pid > 0);
1102             }
1103 0           };
1104             }
1105              
1106             =pod
1107              
1108             =item Sendmail::PMilter::postfork_dispatcher()
1109              
1110             =item (environment) PMILTER_DISPATCHER=postfork
1111              
1112             June 2019: This dispatcher has not been tested adequately.
1113              
1114             This is the default dispatcher for PMilter if no explicit dispatcher is set.
1115              
1116             The C dispatcher forks the main Perl process upon each connection
1117             to the milter socket. This is adequate for machines that get bursty but
1118             otherwise mostly idle mail traffic, as the idle-time resource consumption is
1119             very low.
1120              
1121             If the maximum number of interpreters is running when a new connection
1122             comes in, this dispatcher blocks until a slot becomes available for a
1123             new interpreter.
1124              
1125             =cut
1126              
1127             sub postfork_dispatcher () {
1128 0     0 1   my $nchildren = 0;
1129 0           my $sigchld;
1130              
1131             $sigchld = sub {
1132 0     0     my $pid;
1133 0           $nchildren-- while (($pid = waitpid(-1, WNOHANG)) > 0);
1134 0           $SIG{CHLD} = $sigchld;
1135 0           };
1136              
1137             sub {
1138 0     0     my $this = shift;
1139 0           my $lsocket = shift;
1140 0           my $handler = shift;
1141 0           my $maxchildren = $this->get_max_interpreters();
1142              
1143             # Decrement child count on child exit.
1144 0           local $SIG{CHLD} = $sigchld;
1145              
1146 0 0         my $siginfo = exists($SIG{INFO}) ? 'INFO' : 'USR1';
1147             local $SIG{$siginfo} = sub {
1148 0           warn "Number of active children: $nchildren\n";
1149 0           };
1150              
1151 0           while (1) {
1152 0           my $socket = $lsocket->accept();
1153 0 0         next if !$socket;
1154              
1155 0 0         warn "$$: incoming connection\n" if ($DEBUG > 0);
1156              
1157             # If the load's too high, fail and go back to top of loop.
1158 0           my $paused = undef;
1159 0           while ($maxchildren) {
1160 0           my $cnchildren = $nchildren; # make constant
1161              
1162 0 0         if ($cnchildren >= $maxchildren) {
1163 0           warn "pausing for high load: children $cnchildren >= max $maxchildren";
1164 0 0         if ( ! $paused ) { $paused = time(); }
  0            
1165 0           pause();
1166             }
1167             else {
1168 0           last;
1169             }
1170             }
1171 0 0         if ($paused) {
1172 0           warn sprintf( "paused for %.1f seconds due to high load", time() - $paused );
1173             }
1174              
1175 0           my $pid = fork();
1176              
1177 0 0         if ($pid < 0) {
    0          
1178 0           die "fork: $!\n";
1179             } elsif ($pid) {
1180 0           $nchildren++;
1181 0 0         $socket->close() if defined($socket);
1182             } else {
1183 0           $lsocket->close();
1184 0           undef $lsocket;
1185 0           undef $@;
1186 0           $SIG{PIPE} = 'IGNORE'; # so close_callback will be reached
1187 0           $SIG{CHLD} = 'DEFAULT';
1188 0           $SIG{$siginfo} = 'DEFAULT';
1189              
1190 0           &$handler($socket);
1191 0 0         $socket->close() if defined($socket);
1192 0           exit 0;
1193             }
1194             }
1195 0           };
1196             }
1197              
1198             =pod
1199              
1200             =item Sendmail::PMilter::sequential_dispatcher()
1201              
1202             =item (environment) PMILTER_DISPATCHER=sequential
1203              
1204             June 2019: This dispatcher has not been tested adequately.
1205              
1206             The C dispatcher forces one request to be served at a time,
1207             making other requests wait on the socket for the next pass through the loop.
1208             This is not suitable for most production installations, but may be quite
1209             useful for milter debugging or other software development purposes.
1210              
1211             Note that, because the default socket backlog is 5 connections, if you
1212             use this dispatcher it may be wise to increase this backlog by calling
1213             C before entering C.
1214              
1215             =cut
1216              
1217             sub sequential_dispatcher () {
1218             sub {
1219 0     0     my $this = shift;
1220 0           my $lsocket = shift;
1221 0           my $handler = shift;
1222 0           local $SIG{PIPE} = 'IGNORE'; # so close_callback will be reached
1223              
1224 0           while (1) {
1225 0           my $socket = $lsocket->accept();
1226 0 0         next if $!{EINTR};
1227              
1228 0 0         warn "$$: incoming connection\n" if ($DEBUG > 0);
1229              
1230 0           &$handler($socket);
1231 0           $socket->close();
1232             }
1233 0     0 1   };
1234             }
1235              
1236             1;
1237             __END__