1 /*        $NetBSD: postscreen.c,v 1.6 2025/02/25 19:15:48 christos Exp $        */
2 
3 /*++
4 /* NAME
5 /*        postscreen 8
6 /* SUMMARY
7 /*        Postfix zombie blocker
8 /* SYNOPSIS
9 /*        \fBpostscreen\fR [generic Postfix daemon options]
10 /* DESCRIPTION
11 /*        The Postfix \fBpostscreen\fR(8) server provides additional
12 /*        protection against mail server overload. One \fBpostscreen\fR(8)
13 /*        process handles multiple inbound SMTP connections, and decides
14 /*        which clients may talk to a Postfix SMTP server process.
15 /*        By keeping spambots away, \fBpostscreen\fR(8) leaves more
16 /*        SMTP server processes available for legitimate clients, and
17 /*        delays the onset of server overload conditions.
18 /*
19 /*        This program should not be used on SMTP ports that receive
20 /*        mail from end-user clients (MUAs). In a typical deployment,
21 /*        \fBpostscreen\fR(8) handles the MX service on TCP port 25, and
22 /*        \fBsmtpd\fR(8) receives mail from MUAs on the \fBsubmission\fR
23 /*        service (TCP port 587) which requires client authentication.
24 /*        Alternatively, a site could set up a dedicated, non-postscreen,
25 /*        "port 25" server that provides \fBsubmission\fR service and
26 /*        client authentication, but no MX service.
27 /*
28 /*        \fBpostscreen\fR(8) maintains a temporary allowlist for
29 /*        clients that have passed a number of tests.  When an SMTP
30 /*        client IP address is allowlisted, \fBpostscreen\fR(8) hands
31 /*        off the connection immediately to a Postfix SMTP server
32 /*        process. This minimizes the overhead for legitimate mail.
33 /*
34 /*        By default, \fBpostscreen\fR(8) logs statistics and hands
35 /*        off each connection to a Postfix SMTP server process, while
36 /*        excluding clients in mynetworks from all tests (primarily,
37 /*        to avoid problems with non-standard SMTP implementations
38 /*        in network appliances).  This default mode blocks no clients,
39 /*        and is useful for non-destructive testing.
40 /*
41 /*        In a typical production setting, \fBpostscreen\fR(8) is
42 /*        configured to reject mail from clients that fail one or
43 /*        more tests. \fBpostscreen\fR(8) logs rejected mail with the
44 /*        client address, helo, sender and recipient information.
45 /*
46 /*        \fBpostscreen\fR(8) is not an SMTP proxy; this is intentional.
47 /*        The purpose is to keep spambots away from Postfix SMTP
48 /*        server processes, while minimizing overhead for legitimate
49 /*        traffic.
50 /* SECURITY
51 /* .ad
52 /* .fi
53 /*        The \fBpostscreen\fR(8) server is moderately security-sensitive.
54 /*        It talks to untrusted clients on the network. The process
55 /*        can be run chrooted at fixed low privilege.
56 /* STANDARDS
57 /*        RFC 821 (SMTP protocol)
58 /*        RFC 1123 (Host requirements)
59 /*        RFC 1652 (8bit-MIME transport)
60 /*        RFC 1869 (SMTP service extensions)
61 /*        RFC 1870 (Message Size Declaration)
62 /*        RFC 1985 (ETRN command)
63 /*        RFC 2034 (SMTP Enhanced Status Codes)
64 /*        RFC 2821 (SMTP protocol)
65 /*        Not: RFC 2920 (SMTP Pipelining)
66 /*        RFC 3030 (CHUNKING without BINARYMIME)
67 /*        RFC 3207 (STARTTLS command)
68 /*        RFC 3461 (SMTP DSN Extension)
69 /*        RFC 3463 (Enhanced Status Codes)
70 /*        RFC 5321 (SMTP protocol, including multi-line 220 banners)
71 /* DIAGNOSTICS
72 /*        Problems and transactions are logged to \fBsyslogd\fR(8)
73 /*        or \fBpostlogd\fR(8).
74 /* BUGS
75 /*        The \fBpostscreen\fR(8) built-in SMTP protocol engine
76 /*        currently does not announce support for AUTH, XCLIENT or
77 /*        XFORWARD.
78 /*        If you need to make these services available
79 /*        on port 25, then do not enable the optional "after 220
80 /*        server greeting" tests.
81 /*
82 /*        The optional "after 220 server greeting" tests may result in
83 /*        unexpected delivery delays from senders that retry email delivery
84 /*        from a different IP address.  Reason: after passing these tests a
85 /*        new client must disconnect, and reconnect from the same IP
86 /*        address before it can deliver mail. See POSTSCREEN_README, section
87 /*        "Tests after the 220 SMTP server greeting", for a discussion.
88 /* CONFIGURATION PARAMETERS
89 /* .ad
90 /* .fi
91 /*        Changes to main.cf are not picked up automatically, as
92 /*        \fBpostscreen\fR(8) processes may run for several hours.
93 /*        Use the command "postfix reload" after a configuration
94 /*        change.
95 /*
96 /*        The text below provides only a parameter summary. See
97 /*        \fBpostconf\fR(5) for more details including examples.
98 /*
99 /*        NOTE: Some \fBpostscreen\fR(8) parameters implement
100 /*        stress-dependent behavior.  This is supported only when the
101 /*        default parameter value is stress-dependent (that is, it
102 /*        looks like ${stress?{X}:{Y}}, or it is the $\fIname\fR
103 /*        of an smtpd parameter with a stress-dependent default).
104 /*        Other parameters always evaluate as if the \fBstress\fR
105 /*        parameter value is the empty string.
106 /* COMPATIBILITY CONTROLS
107 /* .ad
108 /* .fi
109 /* .IP "\fBpostscreen_command_filter ($smtpd_command_filter)\fR"
110 /*        A mechanism to transform commands from remote SMTP clients.
111 /* .IP "\fBpostscreen_discard_ehlo_keyword_address_maps ($smtpd_discard_ehlo_keyword_address_maps)\fR"
112 /*        Lookup tables, indexed by the remote SMTP client address, with
113 /*        case insensitive lists of EHLO keywords (pipelining, starttls, auth,
114 /*        etc.) that the \fBpostscreen\fR(8) server will not send in the EHLO response
115 /*        to a remote SMTP client.
116 /* .IP "\fBpostscreen_discard_ehlo_keywords ($smtpd_discard_ehlo_keywords)\fR"
117 /*        A case insensitive list of EHLO keywords (pipelining, starttls,
118 /*        auth, etc.) that the \fBpostscreen\fR(8) server will not send in the EHLO
119 /*        response to a remote SMTP client.
120 /* .PP
121 /*        Available in Postfix version 3.1 and later:
122 /* .IP "\fBdns_ncache_ttl_fix_enable (no)\fR"
123 /*        Enable a workaround for future libc incompatibility.
124 /* .PP
125 /*        Available in Postfix version 3.4 and later:
126 /* .IP "\fBpostscreen_reject_footer_maps ($smtpd_reject_footer_maps)\fR"
127 /*        Optional lookup table for information that is appended after a 4XX
128 /*        or 5XX \fBpostscreen\fR(8) server response.
129 /* .PP
130 /*        Available in Postfix 3.6 and later:
131 /* .IP "\fBrespectful_logging (see 'postconf -d' output)\fR"
132 /*        Avoid logging that implies white is better than black.
133 /* TROUBLE SHOOTING CONTROLS
134 /* .ad
135 /* .fi
136 /* .IP "\fBpostscreen_expansion_filter (see 'postconf -d' output)\fR"
137 /*        List of characters that are permitted in postscreen_reject_footer
138 /*        attribute expansions.
139 /* .IP "\fBpostscreen_reject_footer ($smtpd_reject_footer)\fR"
140 /*        Optional information that is appended after a 4XX or 5XX
141 /*        \fBpostscreen\fR(8) server
142 /*        response.
143 /* .IP "\fBsoft_bounce (no)\fR"
144 /*        Safety net to keep mail queued that would otherwise be returned to
145 /*        the sender.
146 /* BEFORE-POSTSCREEN PROXY AGENT
147 /* .ad
148 /* .fi
149 /*        Available in Postfix version 2.10 and later:
150 /* .IP "\fBpostscreen_upstream_proxy_protocol (empty)\fR"
151 /*        The name of the proxy protocol used by an optional before-postscreen
152 /*        proxy agent.
153 /* .IP "\fBpostscreen_upstream_proxy_timeout (5s)\fR"
154 /*        The time limit for the proxy protocol specified with the
155 /*        postscreen_upstream_proxy_protocol parameter.
156 /* PERMANENT ALLOW/DENYLIST TEST
157 /* .ad
158 /* .fi
159 /*        This test is executed immediately after a remote SMTP client
160 /*        connects. If a client is permanently allowlisted, the client
161 /*        will be handed off immediately to a Postfix SMTP server
162 /*        process.
163 /* .IP "\fBpostscreen_access_list (permit_mynetworks)\fR"
164 /*        Permanent allow/denylist for remote SMTP client IP addresses.
165 /* .IP "\fBpostscreen_blacklist_action (ignore)\fR"
166 /*        Renamed to postscreen_denylist_action in Postfix 3.6.
167 /* MAIL EXCHANGER POLICY TESTS
168 /* .ad
169 /* .fi
170 /*        When \fBpostscreen\fR(8) is configured to monitor all primary
171 /*        and backup MX addresses, it can refuse to allowlist clients
172 /*        that connect to a backup MX address only. For small sites,
173 /*        this requires configuring primary and backup MX addresses
174 /*        on the same MTA. Larger sites would have to share the
175 /*        \fBpostscreen\fR(8) cache between primary and backup MTAs,
176 /*        which would introduce a common point of failure.
177 /* .IP "\fBpostscreen_allowlist_interfaces (static:all)\fR"
178 /*        A list of local \fBpostscreen\fR(8) server IP addresses where a
179 /*        non-allowlisted remote SMTP client can obtain \fBpostscreen\fR(8)'s temporary
180 /*        allowlist status.
181 /* BEFORE 220 GREETING TESTS
182 /* .ad
183 /* .fi
184 /*        These tests are executed before the remote SMTP client
185 /*        receives the "220 servername" greeting. If no tests remain
186 /*        after the successful completion of this phase, the client
187 /*        will be handed off immediately to a Postfix SMTP server
188 /*        process.
189 /* .IP "\fBdnsblog_service_name (dnsblog)\fR"
190 /*        The name of the \fBdnsblog\fR(8) service entry in master.cf.
191 /* .IP "\fBpostscreen_dnsbl_action (ignore)\fR"
192 /*        The action that \fBpostscreen\fR(8) takes when a remote SMTP client's combined
193 /*        DNSBL score is equal to or greater than a threshold (as defined
194 /*        with the postscreen_dnsbl_sites and postscreen_dnsbl_threshold
195 /*        parameters).
196 /* .IP "\fBpostscreen_dnsbl_reply_map (empty)\fR"
197 /*        A mapping from an actual DNSBL domain name which includes a secret
198 /*        password, to the DNSBL domain name that postscreen will reply with
199 /*        when it rejects mail.
200 /* .IP "\fBpostscreen_dnsbl_sites (empty)\fR"
201 /*        Optional list of patterns with DNS allow/denylist domains, filters
202 /*        and weight
203 /*        factors.
204 /* .IP "\fBpostscreen_dnsbl_threshold (1)\fR"
205 /*        The inclusive lower bound for blocking a remote SMTP client, based on
206 /*        its combined DNSBL score as defined with the postscreen_dnsbl_sites
207 /*        parameter.
208 /* .IP "\fBpostscreen_greet_action (ignore)\fR"
209 /*        The action that \fBpostscreen\fR(8) takes when a remote SMTP client speaks
210 /*        before its turn within the time specified with the postscreen_greet_wait
211 /*        parameter.
212 /* .IP "\fBpostscreen_greet_banner ($smtpd_banner)\fR"
213 /*        The \fItext\fR in the optional "220-\fItext\fR..." server
214 /*        response that
215 /*        \fBpostscreen\fR(8) sends ahead of the real Postfix SMTP server's "220
216 /*        text..." response, in an attempt to confuse bad SMTP clients so
217 /*        that they speak before their turn (pre-greet).
218 /* .IP "\fBpostscreen_greet_wait (normal: 6s, overload: 2s)\fR"
219 /*        The amount of time that \fBpostscreen\fR(8) will wait for an SMTP
220 /*        client to send a command before its turn, and for DNS blocklist
221 /*        lookup results to arrive (default: up to 2 seconds under stress,
222 /*        up to 6 seconds otherwise).
223 /* .IP "\fBsmtpd_service_name (smtpd)\fR"
224 /*        The internal service that \fBpostscreen\fR(8) hands off allowed
225 /*        connections to.
226 /* .PP
227 /*        Available in Postfix version 2.11 and later:
228 /* .IP "\fBpostscreen_dnsbl_whitelist_threshold (0)\fR"
229 /*        Renamed to postscreen_dnsbl_allowlist_threshold in Postfix 3.6.
230 /* .PP
231 /*        Available in Postfix version 3.0 and later:
232 /* .IP "\fBpostscreen_dnsbl_timeout (10s)\fR"
233 /*        The time limit for DNSBL or DNSWL lookups.
234 /* .PP
235 /*        Available in Postfix version 3.6 and later:
236 /* .IP "\fBpostscreen_denylist_action (ignore)\fR"
237 /*        The action that \fBpostscreen\fR(8) takes when a remote SMTP client is
238 /*        permanently denylisted with the postscreen_access_list parameter.
239 /* .IP "\fBpostscreen_allowlist_interfaces (static:all)\fR"
240 /*        A list of local \fBpostscreen\fR(8) server IP addresses where a
241 /*        non-allowlisted remote SMTP client can obtain \fBpostscreen\fR(8)'s temporary
242 /*        allowlist status.
243 /* .IP "\fBpostscreen_dnsbl_allowlist_threshold (0)\fR"
244 /*        Allow a remote SMTP client to skip "before" and "after 220
245 /*        greeting" protocol tests, based on its combined DNSBL score as
246 /*        defined with the postscreen_dnsbl_sites parameter.
247 /* AFTER 220 GREETING TESTS
248 /* .ad
249 /* .fi
250 /*        These tests are executed after the remote SMTP client
251 /*        receives the "220 servername" greeting. If a client passes
252 /*        all tests during this phase, it will receive a 4XX response
253 /*        to all RCPT TO commands. After the client reconnects, it
254 /*        will be allowed to talk directly to a Postfix SMTP server
255 /*        process.
256 /* .IP "\fBpostscreen_bare_newline_action (ignore)\fR"
257 /*        The action that \fBpostscreen\fR(8) takes when a remote SMTP client sends
258 /*        a bare newline character, that is, a newline not preceded by carriage
259 /*        return.
260 /* .IP "\fBpostscreen_bare_newline_enable (no)\fR"
261 /*        Enable "bare newline" SMTP protocol tests in the \fBpostscreen\fR(8)
262 /*        server.
263 /* .IP "\fBpostscreen_disable_vrfy_command ($disable_vrfy_command)\fR"
264 /*        Disable the SMTP VRFY command in the \fBpostscreen\fR(8) daemon.
265 /* .IP "\fBpostscreen_forbidden_commands ($smtpd_forbidden_commands)\fR"
266 /*        List of commands that the \fBpostscreen\fR(8) server considers in
267 /*        violation of the SMTP protocol.
268 /* .IP "\fBpostscreen_helo_required ($smtpd_helo_required)\fR"
269 /*        Require that a remote SMTP client sends HELO or EHLO before
270 /*        commencing a MAIL transaction.
271 /* .IP "\fBpostscreen_non_smtp_command_action (drop)\fR"
272 /*        The action that \fBpostscreen\fR(8) takes when a remote SMTP client sends
273 /*        non-SMTP commands as specified with the postscreen_forbidden_commands
274 /*        parameter.
275 /* .IP "\fBpostscreen_non_smtp_command_enable (no)\fR"
276 /*        Enable "non-SMTP command" tests in the \fBpostscreen\fR(8) server.
277 /* .IP "\fBpostscreen_pipelining_action (enforce)\fR"
278 /*        The action that \fBpostscreen\fR(8) takes when a remote SMTP client
279 /*        sends
280 /*        multiple commands instead of sending one command and waiting for
281 /*        the server to respond.
282 /* .IP "\fBpostscreen_pipelining_enable (no)\fR"
283 /*        Enable "pipelining" SMTP protocol tests in the \fBpostscreen\fR(8)
284 /*        server.
285 /* CACHE CONTROLS
286 /* .ad
287 /* .fi
288 /* .IP "\fBpostscreen_cache_cleanup_interval (12h)\fR"
289 /*        The amount of time between \fBpostscreen\fR(8) cache cleanup runs.
290 /* .IP "\fBpostscreen_cache_map (btree:$data_directory/postscreen_cache)\fR"
291 /*        Persistent storage for the \fBpostscreen\fR(8) server decisions.
292 /* .IP "\fBpostscreen_cache_retention_time (7d)\fR"
293 /*        The amount of time that \fBpostscreen\fR(8) will cache an expired
294 /*        temporary allowlist entry before it is removed.
295 /* .IP "\fBpostscreen_bare_newline_ttl (30d)\fR"
296 /*        The amount of time that \fBpostscreen\fR(8) remembers that a client
297 /*        IP address passed a "bare newline" SMTP protocol test, before it
298 /*        address is required to pass that test again.
299 /* .IP "\fBpostscreen_dnsbl_max_ttl (${postscreen_dnsbl_ttl?{$postscreen_dnsbl_ttl}:{1}}h)\fR"
300 /*        The maximum amount of time that \fBpostscreen\fR(8) remembers that a
301 /*        client IP address passed a DNS-based reputation test, before it is
302 /*        required to pass that test again.
303 /* .IP "\fBpostscreen_dnsbl_min_ttl (60s)\fR"
304 /*        The minimum amount of time that \fBpostscreen\fR(8) remembers that a
305 /*        client IP address passed a DNS-based reputation test, before it
306 /*        is required to pass that test again.
307 /* .IP "\fBpostscreen_greet_ttl (1d)\fR"
308 /*        The amount of time that \fBpostscreen\fR(8) remembers that a client
309 /*        IP address passed a PREGREET test, before it is required to pass
310 /*        that test again.
311 /* .IP "\fBpostscreen_non_smtp_command_ttl (30d)\fR"
312 /*        The amount of time that \fBpostscreen\fR(8) remembers that a client
313 /*        IP address passed a "non_smtp_command" SMTP protocol test, before
314 /*        it is required to pass that test again.
315 /* .IP "\fBpostscreen_pipelining_ttl (30d)\fR"
316 /*        The amount of time that \fBpostscreen\fR(8) remembers that a client
317 /*        IP address passed a "pipelining" SMTP protocol test, before it is
318 /*        required to pass that test again.
319 /* RESOURCE CONTROLS
320 /* .ad
321 /* .fi
322 /* .IP "\fBline_length_limit (2048)\fR"
323 /*        Upon input, long lines are chopped up into pieces of at most
324 /*        this length; upon delivery, long lines are reconstructed.
325 /* .IP "\fBpostscreen_client_connection_count_limit ($smtpd_client_connection_count_limit)\fR"
326 /*        How many simultaneous connections any remote SMTP client is
327 /*        allowed to have
328 /*        with the \fBpostscreen\fR(8) daemon.
329 /* .IP "\fBpostscreen_command_count_limit (20)\fR"
330 /*        The limit on the total number of commands per SMTP session for
331 /*        \fBpostscreen\fR(8)'s built-in SMTP protocol engine.
332 /* .IP "\fBpostscreen_command_time_limit (normal: 300s, overload: 10s)\fR"
333 /*        The time limit to read an entire command line with \fBpostscreen\fR(8)'s
334 /*        built-in SMTP protocol engine.
335 /* .IP "\fBpostscreen_post_queue_limit ($default_process_limit)\fR"
336 /*        The number of clients that can be waiting for service from a
337 /*        real Postfix SMTP server process.
338 /* .IP "\fBpostscreen_pre_queue_limit ($default_process_limit)\fR"
339 /*        The number of non-allowlisted clients that can be waiting for
340 /*        a decision whether they will receive service from a real Postfix
341 /*        SMTP server
342 /*        process.
343 /* .IP "\fBpostscreen_watchdog_timeout (10s)\fR"
344 /*        How much time a \fBpostscreen\fR(8) process may take to respond to
345 /*        a remote SMTP client command or to perform a cache operation before it
346 /*        is terminated by a built-in watchdog timer.
347 /* STARTTLS CONTROLS
348 /* .ad
349 /* .fi
350 /* .IP "\fBpostscreen_tls_security_level ($smtpd_tls_security_level)\fR"
351 /*        The SMTP TLS security level for the \fBpostscreen\fR(8) server; when
352 /*        a non-empty value is specified, this overrides the obsolete parameters
353 /*        postscreen_use_tls and postscreen_enforce_tls.
354 /* .IP "\fBtlsproxy_service_name (tlsproxy)\fR"
355 /*        The name of the \fBtlsproxy\fR(8) service entry in master.cf.
356 /* OBSOLETE STARTTLS SUPPORT CONTROLS
357 /* .ad
358 /* .fi
359 /*        These parameters are supported for compatibility with
360 /*        \fBsmtpd\fR(8) legacy parameters.
361 /* .IP "\fBpostscreen_use_tls ($smtpd_use_tls)\fR"
362 /*        Opportunistic TLS: announce STARTTLS support to remote SMTP clients,
363 /*        but do not require that clients use TLS encryption.
364 /* .IP "\fBpostscreen_enforce_tls ($smtpd_enforce_tls)\fR"
365 /*        Mandatory TLS: announce STARTTLS support to remote SMTP clients, and
366 /*        require that clients use TLS encryption.
367 /* MISCELLANEOUS CONTROLS
368 /* .ad
369 /* .fi
370 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
371 /*        The default location of the Postfix main.cf and master.cf
372 /*        configuration files.
373 /* .IP "\fBdelay_logging_resolution_limit (2)\fR"
374 /*        The maximal number of digits after the decimal point when logging
375 /*        sub-second delay values.
376 /* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
377 /*        The location of all postfix administrative commands.
378 /* .IP "\fBmax_idle (100s)\fR"
379 /*        The maximum amount of time that an idle Postfix daemon process waits
380 /*        for an incoming connection before terminating voluntarily.
381 /* .IP "\fBprocess_id (read-only)\fR"
382 /*        The process ID of a Postfix command or daemon process.
383 /* .IP "\fBprocess_name (read-only)\fR"
384 /*        The process name of a Postfix command or daemon process.
385 /* .IP "\fBsyslog_facility (mail)\fR"
386 /*        The syslog facility of Postfix logging.
387 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
388 /*        A prefix that is prepended to the process name in syslog
389 /*        records, so that, for example, "smtpd" becomes "prefix/smtpd".
390 /* .PP
391 /*        Available in Postfix 3.3 and later:
392 /* .IP "\fBservice_name (read-only)\fR"
393 /*        The master.cf service name of a Postfix daemon process.
394 /* .PP
395 /*        Available in Postfix 3.5 and later:
396 /* .IP "\fBinfo_log_address_format (external)\fR"
397 /*        The email address form that will be used in non-debug logging
398 /*        (info, warning, etc.).
399 /* SEE ALSO
400 /*        smtpd(8), Postfix SMTP server
401 /*        tlsproxy(8), Postfix TLS proxy server
402 /*        dnsblog(8), DNS allow/denylist logger
403 /*        postlogd(8), Postfix logging
404 /*        syslogd(8), system logging
405 /* README FILES
406 /* .ad
407 /* .fi
408 /*        Use "\fBpostconf readme_directory\fR" or "\fBpostconf
409 /*        html_directory\fR" to locate this information.
410 /* .nf
411 /* .na
412 /*        POSTSCREEN_README, Postfix Postscreen Howto
413 /* LICENSE
414 /* .ad
415 /* .fi
416 /*        The Secure Mailer license must be distributed with this software.
417 /* HISTORY
418 /* .ad
419 /* .fi
420 /*        This service was introduced with Postfix version 2.8.
421 /*
422 /*        Many ideas in \fBpostscreen\fR(8) were explored in earlier
423 /*        work by Michael Tokarev, in OpenBSD spamd, and in MailChannels
424 /*        Traffic Control.
425 /* AUTHOR(S)
426 /*        Wietse Venema
427 /*        IBM T.J. Watson Research
428 /*        P.O. Box 704
429 /*        Yorktown Heights, NY 10598, USA
430 /*
431 /*        Wietse Venema
432 /*        Google, Inc.
433 /*        111 8th Avenue
434 /*        New York, NY 10011, USA
435 /*--*/
436 
437 /* System library. */
438 
439 #include <sys_defs.h>
440 #include <sys/stat.h>
441 #include <stdlib.h>
442 
443 /* Utility library. */
444 
445 #include <msg.h>
446 #include <mymalloc.h>
447 #include <events.h>
448 #include <myaddrinfo.h>
449 #include <dict_cache.h>
450 #include <set_eugid.h>
451 #include <vstream.h>
452 #include <name_code.h>
453 #include <inet_proto.h>
454 
455 /* Global library. */
456 
457 #include <mail_conf.h>
458 #include <mail_params.h>
459 #include <mail_version.h>
460 #include <mail_proto.h>
461 #include <data_redirect.h>
462 #include <string_list.h>
463 
464 /* Master server protocols. */
465 
466 #include <mail_server.h>
467 
468 /* Application-specific. */
469 
470 #include <postscreen.h>
471 
472  /*
473   * Configuration parameters.
474   */
475 char   *var_smtpd_service;
476 char   *var_smtpd_banner;
477 bool    var_disable_vrfy_cmd;
478 bool    var_helo_required;
479 
480 char   *var_smtpd_cmd_filter;
481 char   *var_psc_cmd_filter;
482 
483 char   *var_smtpd_forbid_cmds;
484 char   *var_psc_forbid_cmds;
485 
486 char   *var_smtpd_ehlo_dis_words;
487 char   *var_smtpd_ehlo_dis_maps;
488 char   *var_psc_ehlo_dis_words;
489 char   *var_psc_ehlo_dis_maps;
490 
491 char   *var_smtpd_tls_level;
492 bool    var_smtpd_use_tls;
493 bool    var_smtpd_enforce_tls;
494 char   *var_psc_tls_level;
495 bool    var_psc_use_tls;
496 bool    var_psc_enforce_tls;
497 
498 bool    var_psc_disable_vrfy;
499 bool    var_psc_helo_required;
500 
501 char   *var_psc_cache_map;
502 int     var_psc_cache_scan;
503 int     var_psc_cache_ret;
504 int     var_psc_post_queue_limit;
505 int     var_psc_pre_queue_limit;
506 int     var_psc_watchdog;
507 
508 char   *var_psc_acl;
509 char   *var_psc_dnlist_action;
510 
511 char   *var_psc_greet_ttl;
512 int     var_psc_greet_wait;
513 
514 char   *var_psc_pregr_banner;
515 char   *var_psc_pregr_action;
516 int     var_psc_pregr_ttl;
517 
518 char   *var_psc_dnsbl_sites;
519 char   *var_psc_dnsbl_reply;
520 int     var_psc_dnsbl_thresh;
521 int     var_psc_dnsbl_althresh;
522 char   *var_psc_dnsbl_action;
523 int     var_psc_dnsbl_min_ttl;
524 int     var_psc_dnsbl_max_ttl;
525 int     var_psc_dnsbl_tmout;
526 
527 bool    var_psc_pipel_enable;
528 char   *var_psc_pipel_action;
529 int     var_psc_pipel_ttl;
530 
531 bool    var_psc_nsmtp_enable;
532 char   *var_psc_nsmtp_action;
533 int     var_psc_nsmtp_ttl;
534 
535 bool    var_psc_barlf_enable;
536 char   *var_psc_barlf_action;
537 int     var_psc_barlf_ttl;
538 
539 int     var_psc_cmd_count;
540 int     var_psc_cmd_time;
541 
542 char   *var_dnsblog_service;
543 char   *var_tlsproxy_service;
544 
545 char   *var_smtpd_rej_footer;
546 char   *var_psc_rej_footer;
547 char   *var_psc_rej_ftr_maps;
548 
549 int     var_smtpd_cconn_limit;
550 int     var_psc_cconn_limit;
551 
552 char   *var_smtpd_exp_filter;
553 char   *var_psc_exp_filter;
554 
555 char   *var_psc_allist_if;
556 char   *var_psc_uproxy_proto;
557 int     var_psc_uproxy_tmout;
558 
559  /*
560   * Global variables.
561   */
562 int     psc_check_queue_length;                   /* connections being checked */
563 int     psc_post_queue_length;                    /* being sent to real SMTPD */
564 DICT_CACHE *psc_cache_map;              /* cache table handle */
565 VSTRING *psc_temp;                      /* scratchpad */
566 char   *psc_smtpd_service_name;                   /* path to real SMTPD */
567 int     psc_pregr_action;               /* PSC_ACT_DROP/ENFORCE/etc */
568 int     psc_dnsbl_action;               /* PSC_ACT_DROP/ENFORCE/etc */
569 int     psc_pipel_action;               /* PSC_ACT_DROP/ENFORCE/etc */
570 int     psc_nsmtp_action;               /* PSC_ACT_DROP/ENFORCE/etc */
571 int     psc_barlf_action;               /* PSC_ACT_DROP/ENFORCE/etc */
572 int     psc_min_ttl;                              /* Update with new tests! */
573 STRING_LIST *psc_forbid_cmds;           /* CONNECT GET POST */
574 int     psc_stress_greet_wait;                    /* stressed greet wait */
575 int     psc_normal_greet_wait;                    /* stressed greet wait */
576 int     psc_stress_cmd_time_limit;      /* stressed command limit */
577 int     psc_normal_cmd_time_limit;      /* normal command time limit */
578 int     psc_stress;                     /* stress level */
579 int     psc_lowat_check_queue_length;   /* stress low-water mark */
580 int     psc_hiwat_check_queue_length;   /* stress high-water mark */
581 DICT   *psc_dnsbl_reply;                /* DNSBL name mapper */
582 HTABLE *psc_client_concurrency;                   /* per-client concurrency */
583 
584  /*
585   * Local variables and functions.
586   */
587 static ARGV *psc_acl;                             /* permanent allow/denylist */
588 static int psc_dnlist_action;           /* PSC_ACT_DROP/ENFORCE/etc */
589 static ADDR_MATCH_LIST *psc_allist_if;  /* allowlist interfaces */
590 
591 static void psc_endpt_lookup_done(int, VSTREAM *,
592                                            MAI_HOSTADDR_STR *, MAI_SERVPORT_STR *,
593                                           MAI_HOSTADDR_STR *, MAI_SERVPORT_STR *);
594 
595 /* psc_dump - dump some statistics before exit */
596 
psc_dump(char * unused_service,char ** unused_argv)597 static void psc_dump(char *unused_service, char **unused_argv)
598 {
599 
600     /*
601      * Dump preliminary cache cleanup statistics when the process commits
602      * suicide while a cache cleanup run is in progress. We can't currently
603      * distinguish between "postfix reload" (we should restart) or "maximal
604      * idle time reached" (we could finish the cache cleanup first).
605      */
606     if (psc_cache_map) {
607           dict_cache_close(psc_cache_map);
608           psc_cache_map = 0;
609     }
610 }
611 
612 /* psc_drain - delayed exit after "postfix reload" */
613 
psc_drain(char * unused_service,char ** unused_argv)614 static void psc_drain(char *unused_service, char **unused_argv)
615 {
616     int     count;
617 
618     /*
619      * After "postfix reload", complete work-in-progress in the background,
620      * instead of dropping already-accepted connections on the floor.
621      *
622      * Unfortunately we must close all writable tables, so we can't store or
623      * look up reputation information. The reason is that we don't have any
624      * multi-writer safety guarantees. We also can't use the single-writer
625      * proxywrite service, because its latency guarantees are too weak.
626      *
627      * All error retry counts shall be limited. Instead of blocking here, we
628      * could retry failed fork() operations in the event call-back routines,
629      * but we don't need perfection. The host system is severely overloaded
630      * and service levels are already way down.
631      *
632      * XXX Some Berkeley DB versions break with close-after-fork. Every new
633      * version is an improvement over its predecessor.
634      *
635      * XXX Don't assume that it is OK to share the same LMDB lockfile descriptor
636      * between different processes.
637      */
638     if (psc_cache_map != 0                        /* XXX && psc_cache_map
639               requires locking */ ) {
640           dict_cache_close(psc_cache_map);
641           psc_cache_map = 0;
642     }
643     for (count = 0; /* see below */ ; count++) {
644           if (count >= 5) {
645               msg_fatal("fork: %m");
646           } else if (event_server_drain() != 0) {
647               msg_warn("fork: %m");
648               sleep(1);
649               continue;
650           } else {
651               return;
652           }
653     }
654 }
655 
656 /* psc_service - handle new client connection */
657 
psc_service(VSTREAM * smtp_client_stream,char * unused_service,char ** unused_argv)658 static void psc_service(VSTREAM *smtp_client_stream,
659                                       char *unused_service,
660                                       char **unused_argv)
661 {
662 
663     /*
664      * For sanity, require that at least one of INET or INET6 is enabled.
665      * Otherwise, we can't look up interface information, and we can't
666      * convert names or addresses.
667      */
668     if (inet_proto_info()->ai_family_list[0] == 0)
669           msg_fatal("all network protocols are disabled (%s = %s)",
670                       VAR_INET_PROTOCOLS, var_inet_protocols);
671 
672     /*
673      * This program handles all incoming connections, so it must not block.
674      * We use event-driven code for all operations that introduce latency.
675      *
676      * Note: instead of using VSTREAM-level timeouts, we enforce limits on the
677      * total amount of time to receive a complete SMTP command line.
678      */
679     non_blocking(vstream_fileno(smtp_client_stream), NON_BLOCKING);
680 
681     /*
682      * Look up the remote SMTP client address and port.
683      */
684     psc_endpt_lookup(smtp_client_stream, psc_endpt_lookup_done);
685 }
686 
687 /* psc_warn_compat_respectful_logging - compatibility warning */
688 
psc_warn_compat_respectful_logging(PSC_STATE * state)689 static void psc_warn_compat_respectful_logging(PSC_STATE *state)
690 {
691     msg_info("using backwards-compatible default setting "
692                VAR_RESPECTFUL_LOGGING "=no for client [%s]:%s",
693                PSC_CLIENT_ADDR_PORT(state));
694     warn_compat_respectful_logging = 0;
695 }
696 
697 /* psc_endpt_lookup_done - endpoint lookup completed */
698 
psc_endpt_lookup_done(int endpt_status,VSTREAM * smtp_client_stream,MAI_HOSTADDR_STR * smtp_client_addr,MAI_SERVPORT_STR * smtp_client_port,MAI_HOSTADDR_STR * smtp_server_addr,MAI_SERVPORT_STR * smtp_server_port)699 static void psc_endpt_lookup_done(int endpt_status,
700                                                   VSTREAM *smtp_client_stream,
701                                                   MAI_HOSTADDR_STR *smtp_client_addr,
702                                                   MAI_SERVPORT_STR *smtp_client_port,
703                                                   MAI_HOSTADDR_STR *smtp_server_addr,
704                                                   MAI_SERVPORT_STR *smtp_server_port)
705 {
706     const char *myname = "psc_endpt_lookup_done";
707     PSC_STATE *state;
708     const char *stamp_str;
709     int     saved_flags;
710 
711     /*
712      * Best effort - if this non-blocking write(2) fails, so be it.
713      */
714     if (endpt_status < 0) {
715           (void) write(vstream_fileno(smtp_client_stream),
716                          "421 4.3.2 No system resources\r\n",
717                          sizeof("421 4.3.2 No system resources\r\n") - 1);
718           event_server_disconnect(smtp_client_stream);
719           return;
720     }
721     if (msg_verbose > 1)
722           msg_info("%s: sq=%d cq=%d connect from [%s]:%s",
723                      myname, psc_post_queue_length, psc_check_queue_length,
724                      smtp_client_addr->buf, smtp_client_port->buf);
725 
726     msg_info("CONNECT from [%s]:%s to [%s]:%s",
727                smtp_client_addr->buf, smtp_client_port->buf,
728                smtp_server_addr->buf, smtp_server_port->buf);
729 
730     /*
731      * Bundle up all the loose session pieces. This zeroes all flags and time
732      * stamps.
733      */
734     state = psc_new_session_state(smtp_client_stream, smtp_client_addr->buf,
735                                           smtp_client_port->buf,
736                                           smtp_server_addr->buf,
737                                           smtp_server_port->buf);
738 
739     /*
740      * Reply with 421 when the client has too many open connections.
741      */
742     if (var_psc_cconn_limit > 0
743           && state->client_info->concurrency > var_psc_cconn_limit) {
744           msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: too many connections",
745                      state->smtp_client_addr, state->smtp_client_port);
746           PSC_DROP_SESSION_STATE(state,
747                                      "421 4.7.0 Error: too many connections\r\n");
748           return;
749     }
750 
751     /*
752      * Reply with 421 when we can't forward more connections.
753      */
754     if (var_psc_post_queue_limit > 0
755           && psc_post_queue_length >= var_psc_post_queue_limit) {
756           msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: all server ports busy",
757                      state->smtp_client_addr, state->smtp_client_port);
758           PSC_DROP_SESSION_STATE(state,
759                                      "421 4.3.2 All server ports are busy\r\n");
760           return;
761     }
762 
763     /*
764      * The permanent allow/denylist has highest precedence.
765      */
766     if (psc_acl != 0) {
767           switch (psc_acl_eval(state, psc_acl, VAR_PSC_ACL)) {
768 
769               /*
770                * Permanently denylisted.
771                */
772           case PSC_ACL_ACT_DENYLIST:
773               msg_info("%sLISTED [%s]:%s",
774                          var_respectful_logging ? "DENY" : "BLACK",
775                          PSC_CLIENT_ADDR_PORT(state));
776               if (warn_compat_respectful_logging)
777                     psc_warn_compat_respectful_logging(state);
778               PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_DNLIST_FAIL);
779               switch (psc_dnlist_action) {
780               case PSC_ACT_DROP:
781                     PSC_DROP_SESSION_STATE(state,
782                                    "521 5.3.2 Service currently unavailable\r\n");
783                     return;
784               case PSC_ACT_ENFORCE:
785                     PSC_ENFORCE_SESSION_STATE(state,
786                                    "550 5.3.2 Service currently unavailable\r\n");
787                     break;
788               case PSC_ACT_IGNORE:
789                     PSC_UNFAIL_SESSION_STATE(state, PSC_STATE_FLAG_DNLIST_FAIL);
790 
791                     /*
792                      * Not: PSC_PASS_SESSION_STATE. Repeat this test the next
793                      * time.
794                      */
795                     break;
796               default:
797                     msg_panic("%s: unknown denylist action value %d",
798                                 myname, psc_dnlist_action);
799               }
800               break;
801 
802               /*
803                * Permanently allowlisted.
804                */
805           case PSC_ACL_ACT_ALLOWLIST:
806               msg_info("%sLISTED [%s]:%s",
807                          var_respectful_logging ? "ALLOW" : "WHITE",
808                          PSC_CLIENT_ADDR_PORT(state));
809               if (warn_compat_respectful_logging)
810                     psc_warn_compat_respectful_logging(state);
811               psc_conclude(state);
812               return;
813 
814               /*
815                * Other: dunno (don't know) or error.
816                */
817           default:
818               break;
819           }
820     }
821 
822     /*
823      * The temporary allowlist (i.e. the postscreen cache) has the lowest
824      * precedence. This cache contains information about the results of prior
825      * tests. Allowlist the client when all enabled test results are still
826      * valid.
827      */
828     if ((state->flags & PSC_STATE_MASK_ANY_FAIL) == 0
829           && state->client_info->concurrency == 1
830           && psc_cache_map != 0
831           && (stamp_str = psc_cache_lookup(psc_cache_map, state->smtp_client_addr)) != 0) {
832           saved_flags = state->flags;
833           psc_parse_tests(state, stamp_str, event_time());
834           state->flags |= saved_flags;
835           if (msg_verbose)
836               msg_info("%s: cached + recent flags: %s",
837                          myname, psc_print_state_flags(state->flags, myname));
838           if ((state->flags & PSC_STATE_MASK_ANY_TODO_FAIL) == 0) {
839               msg_info("PASS OLD [%s]:%s", PSC_CLIENT_ADDR_PORT(state));
840               psc_conclude(state);
841               return;
842           }
843     } else if (state->client_info->concurrency > 1) {
844           saved_flags = state->flags;
845           psc_todo_tests(state, event_time());
846           state->flags |= saved_flags;
847           if (msg_verbose)
848               msg_info("%s: new + recent flags: %s",
849                          myname, psc_print_state_flags(state->flags, myname));
850     } else {
851           saved_flags = state->flags;
852           psc_new_tests(state);
853           state->flags |= saved_flags;
854           if (msg_verbose)
855               msg_info("%s: new + recent flags: %s",
856                          myname, psc_print_state_flags(state->flags, myname));
857     }
858 
859     /*
860      * Don't allowlist clients that connect to backup MX addresses. Fail
861      * "closed" on error.
862      */
863     if (addr_match_list_match(psc_allist_if, smtp_server_addr->buf) == 0) {
864           state->flags |= (PSC_STATE_FLAG_ALLIST_FAIL | PSC_STATE_FLAG_NOFORWARD);
865           msg_info("%sLIST VETO [%s]:%s", var_respectful_logging ?
866                      "ALLOW" : "WHITE", PSC_CLIENT_ADDR_PORT(state));
867           if (warn_compat_respectful_logging)
868               psc_warn_compat_respectful_logging(state);
869     }
870 
871     /*
872      * Reply with 421 when we can't analyze more connections. That also means
873      * no deep protocol tests when the noforward flag is raised.
874      */
875     if (var_psc_pre_queue_limit > 0
876           && psc_check_queue_length - psc_post_queue_length
877           >= var_psc_pre_queue_limit) {
878           msg_info("reject: connect from [%s]:%s: all screening ports busy",
879                      state->smtp_client_addr, state->smtp_client_port);
880           PSC_DROP_SESSION_STATE(state,
881                                      "421 4.3.2 All screening ports are busy\r\n");
882           return;
883     }
884 
885     /*
886      * If the client has no up-to-date results for some tests, do those tests
887      * first. Otherwise, skip the tests and hand off the connection.
888      */
889     if (state->flags & PSC_STATE_MASK_EARLY_TODO)
890           psc_early_tests(state);
891     else if (state->flags & (PSC_STATE_MASK_SMTPD_TODO | PSC_STATE_FLAG_NOFORWARD))
892           psc_smtpd_tests(state);
893     else
894           psc_conclude(state);
895 }
896 
897 /* psc_cache_validator - validate one cache entry */
898 
psc_cache_validator(const char * client_addr,const char * stamp_str,void * unused_context)899 static int psc_cache_validator(const char *client_addr,
900                                              const char *stamp_str,
901                                              void *unused_context)
902 {
903     PSC_STATE dummy_state;
904     PSC_CLIENT_INFO dummy_client_info;
905 
906     /*
907      * This function is called by the cache cleanup pseudo thread.
908      *
909      * When an entry is removed from the cache, the client will be reported as
910      * "NEW" in the next session where it passes all tests again. To avoid
911      * silly logging we remove the cache entry only after all tests have
912      * expired longer ago than the cache retention time.
913      */
914     dummy_state.client_info = &dummy_client_info;
915     psc_parse_tests(&dummy_state, stamp_str, event_time() - var_psc_cache_ret);
916     return ((dummy_state.flags & PSC_STATE_MASK_ANY_TODO) == 0);
917 }
918 
919 /* pre_jail_init - pre-jail initialization */
920 
pre_jail_init(char * unused_name,char ** unused_argv)921 static void pre_jail_init(char *unused_name, char **unused_argv)
922 {
923     VSTRING *redirect;
924 
925     /*
926      * Open read-only maps before dropping privilege, for consistency with
927      * other Postfix daemons.
928      */
929     psc_acl_pre_jail_init(var_mynetworks, VAR_PSC_ACL);
930     if (*var_psc_acl)
931           psc_acl = psc_acl_parse(var_psc_acl, VAR_PSC_ACL);
932     /* Ignore smtpd_forbid_cmds lookup errors. Non-critical feature. */
933     if (*var_psc_forbid_cmds)
934           psc_forbid_cmds = string_list_init(VAR_PSC_FORBID_CMDS,
935                                                      MATCH_FLAG_RETURN,
936                                                      var_psc_forbid_cmds);
937     if (*var_psc_dnsbl_reply)
938           psc_dnsbl_reply = dict_open(var_psc_dnsbl_reply, O_RDONLY,
939                                             DICT_FLAG_DUP_WARN);
940 
941     /*
942      * Never, ever, get killed by a master signal, as that would corrupt the
943      * database when we're in the middle of an update.
944      */
945     if (setsid() < 0)
946           msg_warn("setsid: %m");
947 
948     /*
949      * Security: don't create root-owned files that contain untrusted data.
950      * And don't create Postfix-owned files in root-owned directories,
951      * either. We want a correct relationship between (file or directory)
952      * ownership and (file or directory) content. To open files before going
953      * to jail, temporarily drop root privileges.
954      */
955     SAVE_AND_SET_EUGID(var_owner_uid, var_owner_gid);
956     redirect = vstring_alloc(100);
957 
958     /*
959      * Keep state in persistent external map. As a safety measure we sync the
960      * database on each update. This hurts on LINUX file systems that sync
961      * all dirty disk blocks whenever any application invokes fsync().
962      *
963      * Start the cache maintenance pseudo thread after dropping privileges.
964      */
965 #define PSC_DICT_OPEN_FLAGS (DICT_FLAG_DUP_REPLACE | DICT_FLAG_SYNC_UPDATE | \
966               DICT_FLAG_OPEN_LOCK)
967 
968     if (*var_psc_cache_map)
969           psc_cache_map =
970               dict_cache_open(data_redirect_map(redirect, var_psc_cache_map),
971                                   O_CREAT | O_RDWR, PSC_DICT_OPEN_FLAGS);
972 
973     /*
974      * Clean up and restore privilege.
975      */
976     vstring_free(redirect);
977     RESTORE_SAVED_EUGID();
978 
979     /*
980      * Initialize the dummy SMTP engine.
981      */
982     psc_smtpd_pre_jail_init();
983 }
984 
985 /* pre_accept - see if tables have changed */
986 
pre_accept(char * unused_name,char ** unused_argv)987 static void pre_accept(char *unused_name, char **unused_argv)
988 {
989     static time_t last_event_time;
990     time_t  new_event_time;
991     const char *name;
992 
993     /*
994      * If some table has changed then stop accepting new connections. Don't
995      * check the tables more than once a second.
996      */
997     new_event_time = event_time();
998     if (new_event_time >= last_event_time + 1
999           && (name = dict_changed_name()) != 0) {
1000           msg_info("table %s has changed - finishing in the background", name);
1001           event_server_drain();
1002     } else {
1003           last_event_time = new_event_time;
1004     }
1005 }
1006 
1007 /* post_jail_init - post-jail initialization */
1008 
post_jail_init(char * unused_name,char ** unused_argv)1009 static void post_jail_init(char *unused_name, char **unused_argv)
1010 {
1011     const NAME_CODE actions[] = {
1012           PSC_NAME_ACT_DROP, PSC_ACT_DROP,
1013           PSC_NAME_ACT_ENFORCE, PSC_ACT_ENFORCE,
1014           PSC_NAME_ACT_IGNORE, PSC_ACT_IGNORE,
1015           PSC_NAME_ACT_CONT, PSC_ACT_IGNORE,      /* compatibility */
1016           0, -1,
1017     };
1018     int     cache_flags;
1019     const char *tmp;
1020 
1021     /*
1022      * This routine runs after the skeleton code has entered the chroot jail.
1023      * Prevent automatic process suicide after a limited number of client
1024      * requests. It is OK to terminate after a limited amount of idle time.
1025      */
1026     var_use_limit = 0;
1027 
1028     /*
1029      * Workaround for parameters whose values may contain "$", and that have
1030      * a default of "$parametername". Not sure if it would be a good idea to
1031      * always to this in the mail_conf_raw(3) module.
1032      */
1033     if (*var_psc_rej_footer == '$'
1034           && mail_conf_lookup(var_psc_rej_footer + 1)) {
1035           tmp = mail_conf_eval_once(var_psc_rej_footer);
1036           myfree(var_psc_rej_footer);
1037           var_psc_rej_footer = mystrdup(tmp);
1038     }
1039     if (*var_psc_exp_filter == '$'
1040           && mail_conf_lookup(var_psc_exp_filter + 1)) {
1041           tmp = mail_conf_eval_once(var_psc_exp_filter);
1042           myfree(var_psc_exp_filter);
1043           var_psc_exp_filter = mystrdup(tmp);
1044     }
1045 
1046     /*
1047      * Other one-time initialization.
1048      */
1049     psc_temp = vstring_alloc(10);
1050     vstring_sprintf(psc_temp, "%s/%s", MAIL_CLASS_PRIVATE, var_smtpd_service);
1051     psc_smtpd_service_name = mystrdup(STR(psc_temp));
1052     psc_dnsbl_init();
1053     psc_early_init();
1054     psc_smtpd_init();
1055 
1056     if ((psc_dnlist_action = name_code(actions, NAME_CODE_FLAG_NONE,
1057                                                var_psc_dnlist_action)) < 0)
1058           msg_fatal("bad %s value: %s", VAR_PSC_DNLIST_ACTION,
1059                       var_psc_dnlist_action);
1060     if ((psc_dnsbl_action = name_code(actions, NAME_CODE_FLAG_NONE,
1061                                               var_psc_dnsbl_action)) < 0)
1062           msg_fatal("bad %s value: %s", VAR_PSC_DNSBL_ACTION,
1063                       var_psc_dnsbl_action);
1064     if ((psc_pregr_action = name_code(actions, NAME_CODE_FLAG_NONE,
1065                                               var_psc_pregr_action)) < 0)
1066           msg_fatal("bad %s value: %s", VAR_PSC_PREGR_ACTION,
1067                       var_psc_pregr_action);
1068     if ((psc_pipel_action = name_code(actions, NAME_CODE_FLAG_NONE,
1069                                               var_psc_pipel_action)) < 0)
1070           msg_fatal("bad %s value: %s", VAR_PSC_PIPEL_ACTION,
1071                       var_psc_pipel_action);
1072     if ((psc_nsmtp_action = name_code(actions, NAME_CODE_FLAG_NONE,
1073                                               var_psc_nsmtp_action)) < 0)
1074           msg_fatal("bad %s value: %s", VAR_PSC_NSMTP_ACTION,
1075                       var_psc_nsmtp_action);
1076     if ((psc_barlf_action = name_code(actions, NAME_CODE_FLAG_NONE,
1077                                               var_psc_barlf_action)) < 0)
1078           msg_fatal("bad %s value: %s", VAR_PSC_BARLF_ACTION,
1079                       var_psc_barlf_action);
1080     /* Fail "closed" on error. */
1081     psc_allist_if = addr_match_list_init(VAR_PSC_ALLIST_IF, MATCH_FLAG_RETURN,
1082                                                    var_psc_allist_if);
1083 
1084     /*
1085      * Start the cache maintenance pseudo thread last. Early cleanup makes
1086      * verbose logging more informative (we get positive confirmation that
1087      * the cleanup thread runs).
1088      */
1089     cache_flags = DICT_CACHE_FLAG_STATISTICS;
1090     if (msg_verbose > 1)
1091           cache_flags |= DICT_CACHE_FLAG_VERBOSE;
1092     if (psc_cache_map != 0 && var_psc_cache_scan > 0)
1093           dict_cache_control(psc_cache_map,
1094                                  CA_DICT_CACHE_CTL_FLAGS(cache_flags),
1095                                  CA_DICT_CACHE_CTL_INTERVAL(var_psc_cache_scan),
1096                                  CA_DICT_CACHE_CTL_VALIDATOR(psc_cache_validator),
1097                                  CA_DICT_CACHE_CTL_CONTEXT((void *) 0),
1098                                  CA_DICT_CACHE_CTL_END);
1099 
1100     /*
1101      * Pre-compute the minimal and maximal TTL.
1102      */
1103     psc_min_ttl =
1104           PSC_MIN(PSC_MIN(var_psc_pregr_ttl, var_psc_dnsbl_min_ttl),
1105                     PSC_MIN(PSC_MIN(var_psc_pipel_ttl, var_psc_nsmtp_ttl),
1106                               var_psc_barlf_ttl));
1107 
1108     /*
1109      * Pre-compute the stress and normal command time limits.
1110      */
1111     mail_conf_update(VAR_STRESS, "yes");
1112     psc_stress_cmd_time_limit =
1113           get_mail_conf_time(VAR_PSC_CMD_TIME, DEF_PSC_CMD_TIME, 1, 0);
1114     psc_stress_greet_wait =
1115           get_mail_conf_time(VAR_PSC_GREET_WAIT, DEF_PSC_GREET_WAIT, 1, 0);
1116 
1117     mail_conf_update(VAR_STRESS, "");
1118     psc_normal_cmd_time_limit =
1119           get_mail_conf_time(VAR_PSC_CMD_TIME, DEF_PSC_CMD_TIME, 1, 0);
1120     psc_normal_greet_wait =
1121           get_mail_conf_time(VAR_PSC_GREET_WAIT, DEF_PSC_GREET_WAIT, 1, 0);
1122 
1123     psc_lowat_check_queue_length = .7 * var_psc_pre_queue_limit;
1124     psc_hiwat_check_queue_length = .9 * var_psc_pre_queue_limit;
1125     if (msg_verbose)
1126           msg_info(VAR_PSC_CMD_TIME ": stress=%d normal=%d lowat=%d hiwat=%d",
1127                      psc_stress_cmd_time_limit, psc_normal_cmd_time_limit,
1128                      psc_lowat_check_queue_length, psc_hiwat_check_queue_length);
1129 
1130     if (psc_lowat_check_queue_length == 0)
1131           msg_panic("compiler error: 0.7 * %d = %d", var_psc_pre_queue_limit,
1132                       psc_lowat_check_queue_length);
1133     if (psc_hiwat_check_queue_length == 0)
1134           msg_panic("compiler error: 0.9 * %d = %d", var_psc_pre_queue_limit,
1135                       psc_hiwat_check_queue_length);
1136 
1137     /*
1138      * Per-client concurrency.
1139      */
1140     psc_client_concurrency = htable_create(var_psc_pre_queue_limit);
1141 }
1142 
1143 MAIL_VERSION_STAMP_DECLARE;
1144 
1145 /* main - pass control to the multi-threaded skeleton */
1146 
main(int argc,char ** argv)1147 int     main(int argc, char **argv)
1148 {
1149 
1150     /*
1151      * List smtpd(8) parameters before any postscreen(8) parameters that have
1152      * defaults dependencies on them.
1153      */
1154     static const CONFIG_STR_TABLE str_table[] = {
1155           VAR_SMTPD_SERVICE, DEF_SMTPD_SERVICE, &var_smtpd_service, 1, 0,
1156           VAR_SMTPD_BANNER, DEF_SMTPD_BANNER, &var_smtpd_banner, 1, 0,
1157           VAR_SMTPD_FORBID_CMDS, DEF_SMTPD_FORBID_CMDS, &var_smtpd_forbid_cmds, 0, 0,
1158           VAR_SMTPD_EHLO_DIS_WORDS, DEF_SMTPD_EHLO_DIS_WORDS, &var_smtpd_ehlo_dis_words, 0, 0,
1159           VAR_SMTPD_EHLO_DIS_MAPS, DEF_SMTPD_EHLO_DIS_MAPS, &var_smtpd_ehlo_dis_maps, 0, 0,
1160           VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0,
1161           VAR_SMTPD_CMD_FILTER, DEF_SMTPD_CMD_FILTER, &var_smtpd_cmd_filter, 0, 0,
1162           VAR_PSC_CACHE_MAP, DEF_PSC_CACHE_MAP, &var_psc_cache_map, 0, 0,
1163           VAR_PSC_PREGR_BANNER, DEF_PSC_PREGR_BANNER, &var_psc_pregr_banner, 0, 0,
1164           VAR_PSC_PREGR_ACTION, DEF_PSC_PREGR_ACTION, &var_psc_pregr_action, 1, 0,
1165           VAR_PSC_DNSBL_SITES, DEF_PSC_DNSBL_SITES, &var_psc_dnsbl_sites, 0, 0,
1166           VAR_PSC_DNSBL_ACTION, DEF_PSC_DNSBL_ACTION, &var_psc_dnsbl_action, 1, 0,
1167           VAR_PSC_PIPEL_ACTION, DEF_PSC_PIPEL_ACTION, &var_psc_pipel_action, 1, 0,
1168           VAR_PSC_NSMTP_ACTION, DEF_PSC_NSMTP_ACTION, &var_psc_nsmtp_action, 1, 0,
1169           VAR_PSC_BARLF_ACTION, DEF_PSC_BARLF_ACTION, &var_psc_barlf_action, 1, 0,
1170           VAR_PSC_ACL, DEF_PSC_ACL, &var_psc_acl, 0, 0,
1171           VAR_PSC_DNLIST_ACTION, DEF_PSC_DNLIST_ACTION, &var_psc_dnlist_action, 1, 0,
1172           VAR_PSC_FORBID_CMDS, DEF_PSC_FORBID_CMDS, &var_psc_forbid_cmds, 0, 0,
1173           VAR_PSC_EHLO_DIS_WORDS, DEF_PSC_EHLO_DIS_WORDS, &var_psc_ehlo_dis_words, 0, 0,
1174           VAR_PSC_EHLO_DIS_MAPS, DEF_PSC_EHLO_DIS_MAPS, &var_psc_ehlo_dis_maps, 0, 0,
1175           VAR_PSC_DNSBL_REPLY, DEF_PSC_DNSBL_REPLY, &var_psc_dnsbl_reply, 0, 0,
1176           VAR_PSC_TLS_LEVEL, DEF_PSC_TLS_LEVEL, &var_psc_tls_level, 0, 0,
1177           VAR_PSC_CMD_FILTER, DEF_PSC_CMD_FILTER, &var_psc_cmd_filter, 0, 0,
1178           VAR_DNSBLOG_SERVICE, DEF_DNSBLOG_SERVICE, &var_dnsblog_service, 1, 0,
1179           VAR_TLSPROXY_SERVICE, DEF_TLSPROXY_SERVICE, &var_tlsproxy_service, 1, 0,
1180           VAR_PSC_ALLIST_IF, DEF_PSC_ALLIST_IF, &var_psc_allist_if, 0, 0,
1181           VAR_PSC_UPROXY_PROTO, DEF_PSC_UPROXY_PROTO, &var_psc_uproxy_proto, 0, 0,
1182           VAR_PSC_REJ_FTR_MAPS, DEF_PSC_REJ_FTR_MAPS, &var_psc_rej_ftr_maps, 0, 0,
1183           0,
1184     };
1185     static const CONFIG_INT_TABLE int_table[] = {
1186           VAR_PSC_DNSBL_THRESH, DEF_PSC_DNSBL_THRESH, &var_psc_dnsbl_thresh, 1, 0,
1187           VAR_PSC_CMD_COUNT, DEF_PSC_CMD_COUNT, &var_psc_cmd_count, 1, 0,
1188           VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0,
1189           0,
1190     };
1191     static const CONFIG_NINT_TABLE nint_table[] = {
1192           VAR_PSC_POST_QLIMIT, DEF_PSC_POST_QLIMIT, &var_psc_post_queue_limit, 5, 0,
1193           VAR_PSC_PRE_QLIMIT, DEF_PSC_PRE_QLIMIT, &var_psc_pre_queue_limit, 10, 0,
1194           VAR_PSC_CCONN_LIMIT, DEF_PSC_CCONN_LIMIT, &var_psc_cconn_limit, 0, 0,
1195           VAR_PSC_DNSBL_ALTHRESH, DEF_PSC_DNSBL_ALTHRESH, &var_psc_dnsbl_althresh, 0, 0,
1196           0,
1197     };
1198     static const CONFIG_TIME_TABLE time_table[] = {
1199           VAR_PSC_CMD_TIME, DEF_PSC_CMD_TIME, &var_psc_cmd_time, 1, 0,
1200           VAR_PSC_GREET_WAIT, DEF_PSC_GREET_WAIT, &var_psc_greet_wait, 1, 0,
1201           VAR_PSC_PREGR_TTL, DEF_PSC_PREGR_TTL, &var_psc_pregr_ttl, 1, 0,
1202           VAR_PSC_DNSBL_MIN_TTL, DEF_PSC_DNSBL_MIN_TTL, &var_psc_dnsbl_min_ttl, 1, 0,
1203           VAR_PSC_DNSBL_MAX_TTL, DEF_PSC_DNSBL_MAX_TTL, &var_psc_dnsbl_max_ttl, 1, 0,
1204           VAR_PSC_PIPEL_TTL, DEF_PSC_PIPEL_TTL, &var_psc_pipel_ttl, 1, 0,
1205           VAR_PSC_NSMTP_TTL, DEF_PSC_NSMTP_TTL, &var_psc_nsmtp_ttl, 1, 0,
1206           VAR_PSC_BARLF_TTL, DEF_PSC_BARLF_TTL, &var_psc_barlf_ttl, 1, 0,
1207           VAR_PSC_CACHE_RET, DEF_PSC_CACHE_RET, &var_psc_cache_ret, 1, 0,
1208           VAR_PSC_CACHE_SCAN, DEF_PSC_CACHE_SCAN, &var_psc_cache_scan, 0, 0,
1209           VAR_PSC_WATCHDOG, DEF_PSC_WATCHDOG, &var_psc_watchdog, 10, 0,
1210           VAR_PSC_UPROXY_TMOUT, DEF_PSC_UPROXY_TMOUT, &var_psc_uproxy_tmout, 1, 0,
1211           VAR_PSC_DNSBL_TMOUT, DEF_PSC_DNSBL_TMOUT, &var_psc_dnsbl_tmout, 1, 0,
1212 
1213           0,
1214     };
1215     static const CONFIG_BOOL_TABLE bool_table[] = {
1216           VAR_HELO_REQUIRED, DEF_HELO_REQUIRED, &var_helo_required,
1217           VAR_DISABLE_VRFY_CMD, DEF_DISABLE_VRFY_CMD, &var_disable_vrfy_cmd,
1218           VAR_SMTPD_USE_TLS, DEF_SMTPD_USE_TLS, &var_smtpd_use_tls,
1219           VAR_SMTPD_ENFORCE_TLS, DEF_SMTPD_ENFORCE_TLS, &var_smtpd_enforce_tls,
1220           VAR_PSC_PIPEL_ENABLE, DEF_PSC_PIPEL_ENABLE, &var_psc_pipel_enable,
1221           VAR_PSC_NSMTP_ENABLE, DEF_PSC_NSMTP_ENABLE, &var_psc_nsmtp_enable,
1222           VAR_PSC_BARLF_ENABLE, DEF_PSC_BARLF_ENABLE, &var_psc_barlf_enable,
1223           0,
1224     };
1225     static const CONFIG_RAW_TABLE raw_table[] = {
1226           VAR_SMTPD_REJ_FOOTER, DEF_SMTPD_REJ_FOOTER, &var_smtpd_rej_footer, 0, 0,
1227           VAR_PSC_REJ_FOOTER, DEF_PSC_REJ_FOOTER, &var_psc_rej_footer, 0, 0,
1228           VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, 1, 0,
1229           VAR_PSC_EXP_FILTER, DEF_PSC_EXP_FILTER, &var_psc_exp_filter, 1, 0,
1230           0,
1231     };
1232     static const CONFIG_NBOOL_TABLE nbool_table[] = {
1233           VAR_PSC_HELO_REQUIRED, DEF_PSC_HELO_REQUIRED, &var_psc_helo_required,
1234           VAR_PSC_DISABLE_VRFY, DEF_PSC_DISABLE_VRFY, &var_psc_disable_vrfy,
1235           VAR_PSC_USE_TLS, DEF_PSC_USE_TLS, &var_psc_use_tls,
1236           VAR_PSC_ENFORCE_TLS, DEF_PSC_ENFORCE_TLS, &var_psc_enforce_tls,
1237           0,
1238     };
1239 
1240     /*
1241      * Fingerprint executables and core dumps.
1242      */
1243     MAIL_VERSION_STAMP_ALLOCATE;
1244 
1245     event_server_main(argc, argv, psc_service,
1246                           CA_MAIL_SERVER_STR_TABLE(str_table),
1247                           CA_MAIL_SERVER_INT_TABLE(int_table),
1248                           CA_MAIL_SERVER_NINT_TABLE(nint_table),
1249                           CA_MAIL_SERVER_TIME_TABLE(time_table),
1250                           CA_MAIL_SERVER_BOOL_TABLE(bool_table),
1251                           CA_MAIL_SERVER_RAW_TABLE(raw_table),
1252                           CA_MAIL_SERVER_NBOOL_TABLE(nbool_table),
1253                           CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
1254                           CA_MAIL_SERVER_POST_INIT(post_jail_init),
1255                           CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
1256                           CA_MAIL_SERVER_SOLITARY,
1257                           CA_MAIL_SERVER_SLOW_EXIT(psc_drain),
1258                           CA_MAIL_SERVER_EXIT(psc_dump),
1259                           CA_MAIL_SERVER_WATCHDOG(&var_psc_watchdog),
1260                           0);
1261 }
1262