1 /* $NetBSD: postscreen.c,v 1.5 2023/12/23 20:30:45 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) will use the result from
297 /* a successful "bare newline" SMTP protocol test.
298 /* .IP "\fBpostscreen_dnsbl_max_ttl (${postscreen_dnsbl_ttl?{$postscreen_dnsbl_ttl}:{1}}h)\fR"
299 /* The maximum amount of time that \fBpostscreen\fR(8) will use the
300 /* result from a successful DNS-based reputation test before a
301 /* client IP address is required to pass that test again.
302 /* .IP "\fBpostscreen_dnsbl_min_ttl (60s)\fR"
303 /* The minimum amount of time that \fBpostscreen\fR(8) will use the
304 /* result from a successful DNS-based reputation test before a
305 /* client IP address is required to pass that test again.
306 /* .IP "\fBpostscreen_greet_ttl (1d)\fR"
307 /* The amount of time that \fBpostscreen\fR(8) will use the result from
308 /* a successful PREGREET test.
309 /* .IP "\fBpostscreen_non_smtp_command_ttl (30d)\fR"
310 /* The amount of time that \fBpostscreen\fR(8) will use the result from
311 /* a successful "non_smtp_command" SMTP protocol test.
312 /* .IP "\fBpostscreen_pipelining_ttl (30d)\fR"
313 /* The amount of time that \fBpostscreen\fR(8) will use the result from
314 /* a successful "pipelining" SMTP protocol test.
315 /* RESOURCE CONTROLS
316 /* .ad
317 /* .fi
318 /* .IP "\fBline_length_limit (2048)\fR"
319 /* Upon input, long lines are chopped up into pieces of at most
320 /* this length; upon delivery, long lines are reconstructed.
321 /* .IP "\fBpostscreen_client_connection_count_limit ($smtpd_client_connection_count_limit)\fR"
322 /* How many simultaneous connections any remote SMTP client is
323 /* allowed to have
324 /* with the \fBpostscreen\fR(8) daemon.
325 /* .IP "\fBpostscreen_command_count_limit (20)\fR"
326 /* The limit on the total number of commands per SMTP session for
327 /* \fBpostscreen\fR(8)'s built-in SMTP protocol engine.
328 /* .IP "\fBpostscreen_command_time_limit (normal: 300s, overload: 10s)\fR"
329 /* The time limit to read an entire command line with \fBpostscreen\fR(8)'s
330 /* built-in SMTP protocol engine.
331 /* .IP "\fBpostscreen_post_queue_limit ($default_process_limit)\fR"
332 /* The number of clients that can be waiting for service from a
333 /* real Postfix SMTP server process.
334 /* .IP "\fBpostscreen_pre_queue_limit ($default_process_limit)\fR"
335 /* The number of non-allowlisted clients that can be waiting for
336 /* a decision whether they will receive service from a real Postfix
337 /* SMTP server
338 /* process.
339 /* .IP "\fBpostscreen_watchdog_timeout (10s)\fR"
340 /* How much time a \fBpostscreen\fR(8) process may take to respond to
341 /* a remote SMTP client command or to perform a cache operation before it
342 /* is terminated by a built-in watchdog timer.
343 /* STARTTLS CONTROLS
344 /* .ad
345 /* .fi
346 /* .IP "\fBpostscreen_tls_security_level ($smtpd_tls_security_level)\fR"
347 /* The SMTP TLS security level for the \fBpostscreen\fR(8) server; when
348 /* a non-empty value is specified, this overrides the obsolete parameters
349 /* postscreen_use_tls and postscreen_enforce_tls.
350 /* .IP "\fBtlsproxy_service_name (tlsproxy)\fR"
351 /* The name of the \fBtlsproxy\fR(8) service entry in master.cf.
352 /* OBSOLETE STARTTLS SUPPORT CONTROLS
353 /* .ad
354 /* .fi
355 /* These parameters are supported for compatibility with
356 /* \fBsmtpd\fR(8) legacy parameters.
357 /* .IP "\fBpostscreen_use_tls ($smtpd_use_tls)\fR"
358 /* Opportunistic TLS: announce STARTTLS support to remote SMTP clients,
359 /* but do not require that clients use TLS encryption.
360 /* .IP "\fBpostscreen_enforce_tls ($smtpd_enforce_tls)\fR"
361 /* Mandatory TLS: announce STARTTLS support to remote SMTP clients, and
362 /* require that clients use TLS encryption.
363 /* MISCELLANEOUS CONTROLS
364 /* .ad
365 /* .fi
366 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
367 /* The default location of the Postfix main.cf and master.cf
368 /* configuration files.
369 /* .IP "\fBdelay_logging_resolution_limit (2)\fR"
370 /* The maximal number of digits after the decimal point when logging
371 /* sub-second delay values.
372 /* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
373 /* The location of all postfix administrative commands.
374 /* .IP "\fBmax_idle (100s)\fR"
375 /* The maximum amount of time that an idle Postfix daemon process waits
376 /* for an incoming connection before terminating voluntarily.
377 /* .IP "\fBprocess_id (read-only)\fR"
378 /* The process ID of a Postfix command or daemon process.
379 /* .IP "\fBprocess_name (read-only)\fR"
380 /* The process name of a Postfix command or daemon process.
381 /* .IP "\fBsyslog_facility (mail)\fR"
382 /* The syslog facility of Postfix logging.
383 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
384 /* A prefix that is prepended to the process name in syslog
385 /* records, so that, for example, "smtpd" becomes "prefix/smtpd".
386 /* .PP
387 /* Available in Postfix 3.3 and later:
388 /* .IP "\fBservice_name (read-only)\fR"
389 /* The master.cf service name of a Postfix daemon process.
390 /* .PP
391 /* Available in Postfix 3.5 and later:
392 /* .IP "\fBinfo_log_address_format (external)\fR"
393 /* The email address form that will be used in non-debug logging
394 /* (info, warning, etc.).
395 /* SEE ALSO
396 /* smtpd(8), Postfix SMTP server
397 /* tlsproxy(8), Postfix TLS proxy server
398 /* dnsblog(8), DNS allow/denylist logger
399 /* postlogd(8), Postfix logging
400 /* syslogd(8), system logging
401 /* README FILES
402 /* .ad
403 /* .fi
404 /* Use "\fBpostconf readme_directory\fR" or "\fBpostconf
405 /* html_directory\fR" to locate this information.
406 /* .nf
407 /* .na
408 /* POSTSCREEN_README, Postfix Postscreen Howto
409 /* LICENSE
410 /* .ad
411 /* .fi
412 /* The Secure Mailer license must be distributed with this software.
413 /* HISTORY
414 /* .ad
415 /* .fi
416 /* This service was introduced with Postfix version 2.8.
417 /*
418 /* Many ideas in \fBpostscreen\fR(8) were explored in earlier
419 /* work by Michael Tokarev, in OpenBSD spamd, and in MailChannels
420 /* Traffic Control.
421 /* AUTHOR(S)
422 /* Wietse Venema
423 /* IBM T.J. Watson Research
424 /* P.O. Box 704
425 /* Yorktown Heights, NY 10598, USA
426 /*
427 /* Wietse Venema
428 /* Google, Inc.
429 /* 111 8th Avenue
430 /* New York, NY 10011, USA
431 /*--*/
432
433 /* System library. */
434
435 #include <sys_defs.h>
436 #include <sys/stat.h>
437 #include <stdlib.h>
438
439 /* Utility library. */
440
441 #include <msg.h>
442 #include <mymalloc.h>
443 #include <events.h>
444 #include <myaddrinfo.h>
445 #include <dict_cache.h>
446 #include <set_eugid.h>
447 #include <vstream.h>
448 #include <name_code.h>
449 #include <inet_proto.h>
450
451 /* Global library. */
452
453 #include <mail_conf.h>
454 #include <mail_params.h>
455 #include <mail_version.h>
456 #include <mail_proto.h>
457 #include <data_redirect.h>
458 #include <string_list.h>
459
460 /* Master server protocols. */
461
462 #include <mail_server.h>
463
464 /* Application-specific. */
465
466 #include <postscreen.h>
467
468 /*
469 * Configuration parameters.
470 */
471 char *var_smtpd_service;
472 char *var_smtpd_banner;
473 bool var_disable_vrfy_cmd;
474 bool var_helo_required;
475
476 char *var_smtpd_cmd_filter;
477 char *var_psc_cmd_filter;
478
479 char *var_smtpd_forbid_cmds;
480 char *var_psc_forbid_cmds;
481
482 char *var_smtpd_ehlo_dis_words;
483 char *var_smtpd_ehlo_dis_maps;
484 char *var_psc_ehlo_dis_words;
485 char *var_psc_ehlo_dis_maps;
486
487 char *var_smtpd_tls_level;
488 bool var_smtpd_use_tls;
489 bool var_smtpd_enforce_tls;
490 char *var_psc_tls_level;
491 bool var_psc_use_tls;
492 bool var_psc_enforce_tls;
493
494 bool var_psc_disable_vrfy;
495 bool var_psc_helo_required;
496
497 char *var_psc_cache_map;
498 int var_psc_cache_scan;
499 int var_psc_cache_ret;
500 int var_psc_post_queue_limit;
501 int var_psc_pre_queue_limit;
502 int var_psc_watchdog;
503
504 char *var_psc_acl;
505 char *var_psc_dnlist_action;
506
507 char *var_psc_greet_ttl;
508 int var_psc_greet_wait;
509
510 char *var_psc_pregr_banner;
511 char *var_psc_pregr_action;
512 int var_psc_pregr_ttl;
513
514 char *var_psc_dnsbl_sites;
515 char *var_psc_dnsbl_reply;
516 int var_psc_dnsbl_thresh;
517 int var_psc_dnsbl_althresh;
518 char *var_psc_dnsbl_action;
519 int var_psc_dnsbl_min_ttl;
520 int var_psc_dnsbl_max_ttl;
521 int var_psc_dnsbl_tmout;
522
523 bool var_psc_pipel_enable;
524 char *var_psc_pipel_action;
525 int var_psc_pipel_ttl;
526
527 bool var_psc_nsmtp_enable;
528 char *var_psc_nsmtp_action;
529 int var_psc_nsmtp_ttl;
530
531 bool var_psc_barlf_enable;
532 char *var_psc_barlf_action;
533 int var_psc_barlf_ttl;
534
535 int var_psc_cmd_count;
536 int var_psc_cmd_time;
537
538 char *var_dnsblog_service;
539 char *var_tlsproxy_service;
540
541 char *var_smtpd_rej_footer;
542 char *var_psc_rej_footer;
543 char *var_psc_rej_ftr_maps;
544
545 int var_smtpd_cconn_limit;
546 int var_psc_cconn_limit;
547
548 char *var_smtpd_exp_filter;
549 char *var_psc_exp_filter;
550
551 char *var_psc_allist_if;
552 char *var_psc_uproxy_proto;
553 int var_psc_uproxy_tmout;
554
555 /*
556 * Global variables.
557 */
558 int psc_check_queue_length; /* connections being checked */
559 int psc_post_queue_length; /* being sent to real SMTPD */
560 DICT_CACHE *psc_cache_map; /* cache table handle */
561 VSTRING *psc_temp; /* scratchpad */
562 char *psc_smtpd_service_name; /* path to real SMTPD */
563 int psc_pregr_action; /* PSC_ACT_DROP/ENFORCE/etc */
564 int psc_dnsbl_action; /* PSC_ACT_DROP/ENFORCE/etc */
565 int psc_pipel_action; /* PSC_ACT_DROP/ENFORCE/etc */
566 int psc_nsmtp_action; /* PSC_ACT_DROP/ENFORCE/etc */
567 int psc_barlf_action; /* PSC_ACT_DROP/ENFORCE/etc */
568 int psc_min_ttl; /* Update with new tests! */
569 STRING_LIST *psc_forbid_cmds; /* CONNECT GET POST */
570 int psc_stress_greet_wait; /* stressed greet wait */
571 int psc_normal_greet_wait; /* stressed greet wait */
572 int psc_stress_cmd_time_limit; /* stressed command limit */
573 int psc_normal_cmd_time_limit; /* normal command time limit */
574 int psc_stress; /* stress level */
575 int psc_lowat_check_queue_length; /* stress low-water mark */
576 int psc_hiwat_check_queue_length; /* stress high-water mark */
577 DICT *psc_dnsbl_reply; /* DNSBL name mapper */
578 HTABLE *psc_client_concurrency; /* per-client concurrency */
579
580 /*
581 * Local variables and functions.
582 */
583 static ARGV *psc_acl; /* permanent allow/denylist */
584 static int psc_dnlist_action; /* PSC_ACT_DROP/ENFORCE/etc */
585 static ADDR_MATCH_LIST *psc_allist_if; /* allowlist interfaces */
586
587 static void psc_endpt_lookup_done(int, VSTREAM *,
588 MAI_HOSTADDR_STR *, MAI_SERVPORT_STR *,
589 MAI_HOSTADDR_STR *, MAI_SERVPORT_STR *);
590
591 /* psc_dump - dump some statistics before exit */
592
psc_dump(char * unused_service,char ** unused_argv)593 static void psc_dump(char *unused_service, char **unused_argv)
594 {
595
596 /*
597 * Dump preliminary cache cleanup statistics when the process commits
598 * suicide while a cache cleanup run is in progress. We can't currently
599 * distinguish between "postfix reload" (we should restart) or "maximal
600 * idle time reached" (we could finish the cache cleanup first).
601 */
602 if (psc_cache_map) {
603 dict_cache_close(psc_cache_map);
604 psc_cache_map = 0;
605 }
606 }
607
608 /* psc_drain - delayed exit after "postfix reload" */
609
psc_drain(char * unused_service,char ** unused_argv)610 static void psc_drain(char *unused_service, char **unused_argv)
611 {
612 int count;
613
614 /*
615 * After "postfix reload", complete work-in-progress in the background,
616 * instead of dropping already-accepted connections on the floor.
617 *
618 * Unfortunately we must close all writable tables, so we can't store or
619 * look up reputation information. The reason is that we don't have any
620 * multi-writer safety guarantees. We also can't use the single-writer
621 * proxywrite service, because its latency guarantees are too weak.
622 *
623 * All error retry counts shall be limited. Instead of blocking here, we
624 * could retry failed fork() operations in the event call-back routines,
625 * but we don't need perfection. The host system is severely overloaded
626 * and service levels are already way down.
627 *
628 * XXX Some Berkeley DB versions break with close-after-fork. Every new
629 * version is an improvement over its predecessor.
630 *
631 * XXX Don't assume that it is OK to share the same LMDB lockfile descriptor
632 * between different processes.
633 */
634 if (psc_cache_map != 0 /* XXX && psc_cache_map
635 requires locking */ ) {
636 dict_cache_close(psc_cache_map);
637 psc_cache_map = 0;
638 }
639 for (count = 0; /* see below */ ; count++) {
640 if (count >= 5) {
641 msg_fatal("fork: %m");
642 } else if (event_server_drain() != 0) {
643 msg_warn("fork: %m");
644 sleep(1);
645 continue;
646 } else {
647 return;
648 }
649 }
650 }
651
652 /* psc_service - handle new client connection */
653
psc_service(VSTREAM * smtp_client_stream,char * unused_service,char ** unused_argv)654 static void psc_service(VSTREAM *smtp_client_stream,
655 char *unused_service,
656 char **unused_argv)
657 {
658
659 /*
660 * For sanity, require that at least one of INET or INET6 is enabled.
661 * Otherwise, we can't look up interface information, and we can't
662 * convert names or addresses.
663 */
664 if (inet_proto_info()->ai_family_list[0] == 0)
665 msg_fatal("all network protocols are disabled (%s = %s)",
666 VAR_INET_PROTOCOLS, var_inet_protocols);
667
668 /*
669 * This program handles all incoming connections, so it must not block.
670 * We use event-driven code for all operations that introduce latency.
671 *
672 * Note: instead of using VSTREAM-level timeouts, we enforce limits on the
673 * total amount of time to receive a complete SMTP command line.
674 */
675 non_blocking(vstream_fileno(smtp_client_stream), NON_BLOCKING);
676
677 /*
678 * Look up the remote SMTP client address and port.
679 */
680 psc_endpt_lookup(smtp_client_stream, psc_endpt_lookup_done);
681 }
682
683 /* psc_warn_compat_respectful_logging - compatibility warning */
684
psc_warn_compat_respectful_logging(PSC_STATE * state)685 static void psc_warn_compat_respectful_logging(PSC_STATE *state)
686 {
687 msg_info("using backwards-compatible default setting "
688 VAR_RESPECTFUL_LOGGING "=no for client [%s]:%s",
689 PSC_CLIENT_ADDR_PORT(state));
690 warn_compat_respectful_logging = 0;
691 }
692
693 /* psc_endpt_lookup_done - endpoint lookup completed */
694
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)695 static void psc_endpt_lookup_done(int endpt_status,
696 VSTREAM *smtp_client_stream,
697 MAI_HOSTADDR_STR *smtp_client_addr,
698 MAI_SERVPORT_STR *smtp_client_port,
699 MAI_HOSTADDR_STR *smtp_server_addr,
700 MAI_SERVPORT_STR *smtp_server_port)
701 {
702 const char *myname = "psc_endpt_lookup_done";
703 PSC_STATE *state;
704 const char *stamp_str;
705 int saved_flags;
706
707 /*
708 * Best effort - if this non-blocking write(2) fails, so be it.
709 */
710 if (endpt_status < 0) {
711 (void) write(vstream_fileno(smtp_client_stream),
712 "421 4.3.2 No system resources\r\n",
713 sizeof("421 4.3.2 No system resources\r\n") - 1);
714 event_server_disconnect(smtp_client_stream);
715 return;
716 }
717 if (msg_verbose > 1)
718 msg_info("%s: sq=%d cq=%d connect from [%s]:%s",
719 myname, psc_post_queue_length, psc_check_queue_length,
720 smtp_client_addr->buf, smtp_client_port->buf);
721
722 msg_info("CONNECT from [%s]:%s to [%s]:%s",
723 smtp_client_addr->buf, smtp_client_port->buf,
724 smtp_server_addr->buf, smtp_server_port->buf);
725
726 /*
727 * Bundle up all the loose session pieces. This zeroes all flags and time
728 * stamps.
729 */
730 state = psc_new_session_state(smtp_client_stream, smtp_client_addr->buf,
731 smtp_client_port->buf,
732 smtp_server_addr->buf,
733 smtp_server_port->buf);
734
735 /*
736 * Reply with 421 when the client has too many open connections.
737 */
738 if (var_psc_cconn_limit > 0
739 && state->client_info->concurrency > var_psc_cconn_limit) {
740 msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: too many connections",
741 state->smtp_client_addr, state->smtp_client_port);
742 PSC_DROP_SESSION_STATE(state,
743 "421 4.7.0 Error: too many connections\r\n");
744 return;
745 }
746
747 /*
748 * Reply with 421 when we can't forward more connections.
749 */
750 if (var_psc_post_queue_limit > 0
751 && psc_post_queue_length >= var_psc_post_queue_limit) {
752 msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: all server ports busy",
753 state->smtp_client_addr, state->smtp_client_port);
754 PSC_DROP_SESSION_STATE(state,
755 "421 4.3.2 All server ports are busy\r\n");
756 return;
757 }
758
759 /*
760 * The permanent allow/denylist has highest precedence.
761 */
762 if (psc_acl != 0) {
763 switch (psc_acl_eval(state, psc_acl, VAR_PSC_ACL)) {
764
765 /*
766 * Permanently denylisted.
767 */
768 case PSC_ACL_ACT_DENYLIST:
769 msg_info("%sLISTED [%s]:%s",
770 var_respectful_logging ? "DENY" : "BLACK",
771 PSC_CLIENT_ADDR_PORT(state));
772 if (warn_compat_respectful_logging)
773 psc_warn_compat_respectful_logging(state);
774 PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_DNLIST_FAIL);
775 switch (psc_dnlist_action) {
776 case PSC_ACT_DROP:
777 PSC_DROP_SESSION_STATE(state,
778 "521 5.3.2 Service currently unavailable\r\n");
779 return;
780 case PSC_ACT_ENFORCE:
781 PSC_ENFORCE_SESSION_STATE(state,
782 "550 5.3.2 Service currently unavailable\r\n");
783 break;
784 case PSC_ACT_IGNORE:
785 PSC_UNFAIL_SESSION_STATE(state, PSC_STATE_FLAG_DNLIST_FAIL);
786
787 /*
788 * Not: PSC_PASS_SESSION_STATE. Repeat this test the next
789 * time.
790 */
791 break;
792 default:
793 msg_panic("%s: unknown denylist action value %d",
794 myname, psc_dnlist_action);
795 }
796 break;
797
798 /*
799 * Permanently allowlisted.
800 */
801 case PSC_ACL_ACT_ALLOWLIST:
802 msg_info("%sLISTED [%s]:%s",
803 var_respectful_logging ? "ALLOW" : "WHITE",
804 PSC_CLIENT_ADDR_PORT(state));
805 if (warn_compat_respectful_logging)
806 psc_warn_compat_respectful_logging(state);
807 psc_conclude(state);
808 return;
809
810 /*
811 * Other: dunno (don't know) or error.
812 */
813 default:
814 break;
815 }
816 }
817
818 /*
819 * The temporary allowlist (i.e. the postscreen cache) has the lowest
820 * precedence. This cache contains information about the results of prior
821 * tests. Allowlist the client when all enabled test results are still
822 * valid.
823 */
824 if ((state->flags & PSC_STATE_MASK_ANY_FAIL) == 0
825 && state->client_info->concurrency == 1
826 && psc_cache_map != 0
827 && (stamp_str = psc_cache_lookup(psc_cache_map, state->smtp_client_addr)) != 0) {
828 saved_flags = state->flags;
829 psc_parse_tests(state, stamp_str, event_time());
830 state->flags |= saved_flags;
831 if (msg_verbose)
832 msg_info("%s: cached + recent flags: %s",
833 myname, psc_print_state_flags(state->flags, myname));
834 if ((state->flags & PSC_STATE_MASK_ANY_TODO_FAIL) == 0) {
835 msg_info("PASS OLD [%s]:%s", PSC_CLIENT_ADDR_PORT(state));
836 psc_conclude(state);
837 return;
838 }
839 } else if (state->client_info->concurrency > 1) {
840 saved_flags = state->flags;
841 psc_todo_tests(state, event_time());
842 state->flags |= saved_flags;
843 if (msg_verbose)
844 msg_info("%s: new + recent flags: %s",
845 myname, psc_print_state_flags(state->flags, myname));
846 } else {
847 saved_flags = state->flags;
848 psc_new_tests(state);
849 state->flags |= saved_flags;
850 if (msg_verbose)
851 msg_info("%s: new + recent flags: %s",
852 myname, psc_print_state_flags(state->flags, myname));
853 }
854
855 /*
856 * Don't allowlist clients that connect to backup MX addresses. Fail
857 * "closed" on error.
858 */
859 if (addr_match_list_match(psc_allist_if, smtp_server_addr->buf) == 0) {
860 state->flags |= (PSC_STATE_FLAG_ALLIST_FAIL | PSC_STATE_FLAG_NOFORWARD);
861 msg_info("%sLIST VETO [%s]:%s", var_respectful_logging ?
862 "ALLOW" : "WHITE", PSC_CLIENT_ADDR_PORT(state));
863 if (warn_compat_respectful_logging)
864 psc_warn_compat_respectful_logging(state);
865 }
866
867 /*
868 * Reply with 421 when we can't analyze more connections. That also means
869 * no deep protocol tests when the noforward flag is raised.
870 */
871 if (var_psc_pre_queue_limit > 0
872 && psc_check_queue_length - psc_post_queue_length
873 >= var_psc_pre_queue_limit) {
874 msg_info("reject: connect from [%s]:%s: all screening ports busy",
875 state->smtp_client_addr, state->smtp_client_port);
876 PSC_DROP_SESSION_STATE(state,
877 "421 4.3.2 All screening ports are busy\r\n");
878 return;
879 }
880
881 /*
882 * If the client has no up-to-date results for some tests, do those tests
883 * first. Otherwise, skip the tests and hand off the connection.
884 */
885 if (state->flags & PSC_STATE_MASK_EARLY_TODO)
886 psc_early_tests(state);
887 else if (state->flags & (PSC_STATE_MASK_SMTPD_TODO | PSC_STATE_FLAG_NOFORWARD))
888 psc_smtpd_tests(state);
889 else
890 psc_conclude(state);
891 }
892
893 /* psc_cache_validator - validate one cache entry */
894
psc_cache_validator(const char * client_addr,const char * stamp_str,void * unused_context)895 static int psc_cache_validator(const char *client_addr,
896 const char *stamp_str,
897 void *unused_context)
898 {
899 PSC_STATE dummy_state;
900 PSC_CLIENT_INFO dummy_client_info;
901
902 /*
903 * This function is called by the cache cleanup pseudo thread.
904 *
905 * When an entry is removed from the cache, the client will be reported as
906 * "NEW" in the next session where it passes all tests again. To avoid
907 * silly logging we remove the cache entry only after all tests have
908 * expired longer ago than the cache retention time.
909 */
910 dummy_state.client_info = &dummy_client_info;
911 psc_parse_tests(&dummy_state, stamp_str, event_time() - var_psc_cache_ret);
912 return ((dummy_state.flags & PSC_STATE_MASK_ANY_TODO) == 0);
913 }
914
915 /* pre_jail_init - pre-jail initialization */
916
pre_jail_init(char * unused_name,char ** unused_argv)917 static void pre_jail_init(char *unused_name, char **unused_argv)
918 {
919 VSTRING *redirect;
920
921 /*
922 * Open read-only maps before dropping privilege, for consistency with
923 * other Postfix daemons.
924 */
925 psc_acl_pre_jail_init(var_mynetworks, VAR_PSC_ACL);
926 if (*var_psc_acl)
927 psc_acl = psc_acl_parse(var_psc_acl, VAR_PSC_ACL);
928 /* Ignore smtpd_forbid_cmds lookup errors. Non-critical feature. */
929 if (*var_psc_forbid_cmds)
930 psc_forbid_cmds = string_list_init(VAR_PSC_FORBID_CMDS,
931 MATCH_FLAG_RETURN,
932 var_psc_forbid_cmds);
933 if (*var_psc_dnsbl_reply)
934 psc_dnsbl_reply = dict_open(var_psc_dnsbl_reply, O_RDONLY,
935 DICT_FLAG_DUP_WARN);
936
937 /*
938 * Never, ever, get killed by a master signal, as that would corrupt the
939 * database when we're in the middle of an update.
940 */
941 if (setsid() < 0)
942 msg_warn("setsid: %m");
943
944 /*
945 * Security: don't create root-owned files that contain untrusted data.
946 * And don't create Postfix-owned files in root-owned directories,
947 * either. We want a correct relationship between (file or directory)
948 * ownership and (file or directory) content. To open files before going
949 * to jail, temporarily drop root privileges.
950 */
951 SAVE_AND_SET_EUGID(var_owner_uid, var_owner_gid);
952 redirect = vstring_alloc(100);
953
954 /*
955 * Keep state in persistent external map. As a safety measure we sync the
956 * database on each update. This hurts on LINUX file systems that sync
957 * all dirty disk blocks whenever any application invokes fsync().
958 *
959 * Start the cache maintenance pseudo thread after dropping privileges.
960 */
961 #define PSC_DICT_OPEN_FLAGS (DICT_FLAG_DUP_REPLACE | DICT_FLAG_SYNC_UPDATE | \
962 DICT_FLAG_OPEN_LOCK)
963
964 if (*var_psc_cache_map)
965 psc_cache_map =
966 dict_cache_open(data_redirect_map(redirect, var_psc_cache_map),
967 O_CREAT | O_RDWR, PSC_DICT_OPEN_FLAGS);
968
969 /*
970 * Clean up and restore privilege.
971 */
972 vstring_free(redirect);
973 RESTORE_SAVED_EUGID();
974
975 /*
976 * Initialize the dummy SMTP engine.
977 */
978 psc_smtpd_pre_jail_init();
979 }
980
981 /* pre_accept - see if tables have changed */
982
pre_accept(char * unused_name,char ** unused_argv)983 static void pre_accept(char *unused_name, char **unused_argv)
984 {
985 static time_t last_event_time;
986 time_t new_event_time;
987 const char *name;
988
989 /*
990 * If some table has changed then stop accepting new connections. Don't
991 * check the tables more than once a second.
992 */
993 new_event_time = event_time();
994 if (new_event_time >= last_event_time + 1
995 && (name = dict_changed_name()) != 0) {
996 msg_info("table %s has changed - finishing in the background", name);
997 event_server_drain();
998 } else {
999 last_event_time = new_event_time;
1000 }
1001 }
1002
1003 /* post_jail_init - post-jail initialization */
1004
post_jail_init(char * unused_name,char ** unused_argv)1005 static void post_jail_init(char *unused_name, char **unused_argv)
1006 {
1007 const NAME_CODE actions[] = {
1008 PSC_NAME_ACT_DROP, PSC_ACT_DROP,
1009 PSC_NAME_ACT_ENFORCE, PSC_ACT_ENFORCE,
1010 PSC_NAME_ACT_IGNORE, PSC_ACT_IGNORE,
1011 PSC_NAME_ACT_CONT, PSC_ACT_IGNORE, /* compatibility */
1012 0, -1,
1013 };
1014 int cache_flags;
1015 const char *tmp;
1016
1017 /*
1018 * This routine runs after the skeleton code has entered the chroot jail.
1019 * Prevent automatic process suicide after a limited number of client
1020 * requests. It is OK to terminate after a limited amount of idle time.
1021 */
1022 var_use_limit = 0;
1023
1024 /*
1025 * Workaround for parameters whose values may contain "$", and that have
1026 * a default of "$parametername". Not sure if it would be a good idea to
1027 * always to this in the mail_conf_raw(3) module.
1028 */
1029 if (*var_psc_rej_footer == '$'
1030 && mail_conf_lookup(var_psc_rej_footer + 1)) {
1031 tmp = mail_conf_eval_once(var_psc_rej_footer);
1032 myfree(var_psc_rej_footer);
1033 var_psc_rej_footer = mystrdup(tmp);
1034 }
1035 if (*var_psc_exp_filter == '$'
1036 && mail_conf_lookup(var_psc_exp_filter + 1)) {
1037 tmp = mail_conf_eval_once(var_psc_exp_filter);
1038 myfree(var_psc_exp_filter);
1039 var_psc_exp_filter = mystrdup(tmp);
1040 }
1041
1042 /*
1043 * Other one-time initialization.
1044 */
1045 psc_temp = vstring_alloc(10);
1046 vstring_sprintf(psc_temp, "%s/%s", MAIL_CLASS_PRIVATE, var_smtpd_service);
1047 psc_smtpd_service_name = mystrdup(STR(psc_temp));
1048 psc_dnsbl_init();
1049 psc_early_init();
1050 psc_smtpd_init();
1051
1052 if ((psc_dnlist_action = name_code(actions, NAME_CODE_FLAG_NONE,
1053 var_psc_dnlist_action)) < 0)
1054 msg_fatal("bad %s value: %s", VAR_PSC_DNLIST_ACTION,
1055 var_psc_dnlist_action);
1056 if ((psc_dnsbl_action = name_code(actions, NAME_CODE_FLAG_NONE,
1057 var_psc_dnsbl_action)) < 0)
1058 msg_fatal("bad %s value: %s", VAR_PSC_DNSBL_ACTION,
1059 var_psc_dnsbl_action);
1060 if ((psc_pregr_action = name_code(actions, NAME_CODE_FLAG_NONE,
1061 var_psc_pregr_action)) < 0)
1062 msg_fatal("bad %s value: %s", VAR_PSC_PREGR_ACTION,
1063 var_psc_pregr_action);
1064 if ((psc_pipel_action = name_code(actions, NAME_CODE_FLAG_NONE,
1065 var_psc_pipel_action)) < 0)
1066 msg_fatal("bad %s value: %s", VAR_PSC_PIPEL_ACTION,
1067 var_psc_pipel_action);
1068 if ((psc_nsmtp_action = name_code(actions, NAME_CODE_FLAG_NONE,
1069 var_psc_nsmtp_action)) < 0)
1070 msg_fatal("bad %s value: %s", VAR_PSC_NSMTP_ACTION,
1071 var_psc_nsmtp_action);
1072 if ((psc_barlf_action = name_code(actions, NAME_CODE_FLAG_NONE,
1073 var_psc_barlf_action)) < 0)
1074 msg_fatal("bad %s value: %s", VAR_PSC_BARLF_ACTION,
1075 var_psc_barlf_action);
1076 /* Fail "closed" on error. */
1077 psc_allist_if = addr_match_list_init(VAR_PSC_ALLIST_IF, MATCH_FLAG_RETURN,
1078 var_psc_allist_if);
1079
1080 /*
1081 * Start the cache maintenance pseudo thread last. Early cleanup makes
1082 * verbose logging more informative (we get positive confirmation that
1083 * the cleanup thread runs).
1084 */
1085 cache_flags = DICT_CACHE_FLAG_STATISTICS;
1086 if (msg_verbose > 1)
1087 cache_flags |= DICT_CACHE_FLAG_VERBOSE;
1088 if (psc_cache_map != 0 && var_psc_cache_scan > 0)
1089 dict_cache_control(psc_cache_map,
1090 CA_DICT_CACHE_CTL_FLAGS(cache_flags),
1091 CA_DICT_CACHE_CTL_INTERVAL(var_psc_cache_scan),
1092 CA_DICT_CACHE_CTL_VALIDATOR(psc_cache_validator),
1093 CA_DICT_CACHE_CTL_CONTEXT((void *) 0),
1094 CA_DICT_CACHE_CTL_END);
1095
1096 /*
1097 * Pre-compute the minimal and maximal TTL.
1098 */
1099 psc_min_ttl =
1100 PSC_MIN(PSC_MIN(var_psc_pregr_ttl, var_psc_dnsbl_min_ttl),
1101 PSC_MIN(PSC_MIN(var_psc_pipel_ttl, var_psc_nsmtp_ttl),
1102 var_psc_barlf_ttl));
1103
1104 /*
1105 * Pre-compute the stress and normal command time limits.
1106 */
1107 mail_conf_update(VAR_STRESS, "yes");
1108 psc_stress_cmd_time_limit =
1109 get_mail_conf_time(VAR_PSC_CMD_TIME, DEF_PSC_CMD_TIME, 1, 0);
1110 psc_stress_greet_wait =
1111 get_mail_conf_time(VAR_PSC_GREET_WAIT, DEF_PSC_GREET_WAIT, 1, 0);
1112
1113 mail_conf_update(VAR_STRESS, "");
1114 psc_normal_cmd_time_limit =
1115 get_mail_conf_time(VAR_PSC_CMD_TIME, DEF_PSC_CMD_TIME, 1, 0);
1116 psc_normal_greet_wait =
1117 get_mail_conf_time(VAR_PSC_GREET_WAIT, DEF_PSC_GREET_WAIT, 1, 0);
1118
1119 psc_lowat_check_queue_length = .7 * var_psc_pre_queue_limit;
1120 psc_hiwat_check_queue_length = .9 * var_psc_pre_queue_limit;
1121 if (msg_verbose)
1122 msg_info(VAR_PSC_CMD_TIME ": stress=%d normal=%d lowat=%d hiwat=%d",
1123 psc_stress_cmd_time_limit, psc_normal_cmd_time_limit,
1124 psc_lowat_check_queue_length, psc_hiwat_check_queue_length);
1125
1126 if (psc_lowat_check_queue_length == 0)
1127 msg_panic("compiler error: 0.7 * %d = %d", var_psc_pre_queue_limit,
1128 psc_lowat_check_queue_length);
1129 if (psc_hiwat_check_queue_length == 0)
1130 msg_panic("compiler error: 0.9 * %d = %d", var_psc_pre_queue_limit,
1131 psc_hiwat_check_queue_length);
1132
1133 /*
1134 * Per-client concurrency.
1135 */
1136 psc_client_concurrency = htable_create(var_psc_pre_queue_limit);
1137 }
1138
1139 MAIL_VERSION_STAMP_DECLARE;
1140
1141 /* main - pass control to the multi-threaded skeleton */
1142
main(int argc,char ** argv)1143 int main(int argc, char **argv)
1144 {
1145
1146 /*
1147 * List smtpd(8) parameters before any postscreen(8) parameters that have
1148 * defaults dependencies on them.
1149 */
1150 static const CONFIG_STR_TABLE str_table[] = {
1151 VAR_SMTPD_SERVICE, DEF_SMTPD_SERVICE, &var_smtpd_service, 1, 0,
1152 VAR_SMTPD_BANNER, DEF_SMTPD_BANNER, &var_smtpd_banner, 1, 0,
1153 VAR_SMTPD_FORBID_CMDS, DEF_SMTPD_FORBID_CMDS, &var_smtpd_forbid_cmds, 0, 0,
1154 VAR_SMTPD_EHLO_DIS_WORDS, DEF_SMTPD_EHLO_DIS_WORDS, &var_smtpd_ehlo_dis_words, 0, 0,
1155 VAR_SMTPD_EHLO_DIS_MAPS, DEF_SMTPD_EHLO_DIS_MAPS, &var_smtpd_ehlo_dis_maps, 0, 0,
1156 VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0,
1157 VAR_SMTPD_CMD_FILTER, DEF_SMTPD_CMD_FILTER, &var_smtpd_cmd_filter, 0, 0,
1158 VAR_PSC_CACHE_MAP, DEF_PSC_CACHE_MAP, &var_psc_cache_map, 0, 0,
1159 VAR_PSC_PREGR_BANNER, DEF_PSC_PREGR_BANNER, &var_psc_pregr_banner, 0, 0,
1160 VAR_PSC_PREGR_ACTION, DEF_PSC_PREGR_ACTION, &var_psc_pregr_action, 1, 0,
1161 VAR_PSC_DNSBL_SITES, DEF_PSC_DNSBL_SITES, &var_psc_dnsbl_sites, 0, 0,
1162 VAR_PSC_DNSBL_ACTION, DEF_PSC_DNSBL_ACTION, &var_psc_dnsbl_action, 1, 0,
1163 VAR_PSC_PIPEL_ACTION, DEF_PSC_PIPEL_ACTION, &var_psc_pipel_action, 1, 0,
1164 VAR_PSC_NSMTP_ACTION, DEF_PSC_NSMTP_ACTION, &var_psc_nsmtp_action, 1, 0,
1165 VAR_PSC_BARLF_ACTION, DEF_PSC_BARLF_ACTION, &var_psc_barlf_action, 1, 0,
1166 VAR_PSC_ACL, DEF_PSC_ACL, &var_psc_acl, 0, 0,
1167 VAR_PSC_DNLIST_ACTION, DEF_PSC_DNLIST_ACTION, &var_psc_dnlist_action, 1, 0,
1168 VAR_PSC_FORBID_CMDS, DEF_PSC_FORBID_CMDS, &var_psc_forbid_cmds, 0, 0,
1169 VAR_PSC_EHLO_DIS_WORDS, DEF_PSC_EHLO_DIS_WORDS, &var_psc_ehlo_dis_words, 0, 0,
1170 VAR_PSC_EHLO_DIS_MAPS, DEF_PSC_EHLO_DIS_MAPS, &var_psc_ehlo_dis_maps, 0, 0,
1171 VAR_PSC_DNSBL_REPLY, DEF_PSC_DNSBL_REPLY, &var_psc_dnsbl_reply, 0, 0,
1172 VAR_PSC_TLS_LEVEL, DEF_PSC_TLS_LEVEL, &var_psc_tls_level, 0, 0,
1173 VAR_PSC_CMD_FILTER, DEF_PSC_CMD_FILTER, &var_psc_cmd_filter, 0, 0,
1174 VAR_DNSBLOG_SERVICE, DEF_DNSBLOG_SERVICE, &var_dnsblog_service, 1, 0,
1175 VAR_TLSPROXY_SERVICE, DEF_TLSPROXY_SERVICE, &var_tlsproxy_service, 1, 0,
1176 VAR_PSC_ALLIST_IF, DEF_PSC_ALLIST_IF, &var_psc_allist_if, 0, 0,
1177 VAR_PSC_UPROXY_PROTO, DEF_PSC_UPROXY_PROTO, &var_psc_uproxy_proto, 0, 0,
1178 VAR_PSC_REJ_FTR_MAPS, DEF_PSC_REJ_FTR_MAPS, &var_psc_rej_ftr_maps, 0, 0,
1179 0,
1180 };
1181 static const CONFIG_INT_TABLE int_table[] = {
1182 VAR_PSC_DNSBL_THRESH, DEF_PSC_DNSBL_THRESH, &var_psc_dnsbl_thresh, 1, 0,
1183 VAR_PSC_CMD_COUNT, DEF_PSC_CMD_COUNT, &var_psc_cmd_count, 1, 0,
1184 VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0,
1185 0,
1186 };
1187 static const CONFIG_NINT_TABLE nint_table[] = {
1188 VAR_PSC_POST_QLIMIT, DEF_PSC_POST_QLIMIT, &var_psc_post_queue_limit, 5, 0,
1189 VAR_PSC_PRE_QLIMIT, DEF_PSC_PRE_QLIMIT, &var_psc_pre_queue_limit, 10, 0,
1190 VAR_PSC_CCONN_LIMIT, DEF_PSC_CCONN_LIMIT, &var_psc_cconn_limit, 0, 0,
1191 VAR_PSC_DNSBL_ALTHRESH, DEF_PSC_DNSBL_ALTHRESH, &var_psc_dnsbl_althresh, 0, 0,
1192 0,
1193 };
1194 static const CONFIG_TIME_TABLE time_table[] = {
1195 VAR_PSC_CMD_TIME, DEF_PSC_CMD_TIME, &var_psc_cmd_time, 1, 0,
1196 VAR_PSC_GREET_WAIT, DEF_PSC_GREET_WAIT, &var_psc_greet_wait, 1, 0,
1197 VAR_PSC_PREGR_TTL, DEF_PSC_PREGR_TTL, &var_psc_pregr_ttl, 1, 0,
1198 VAR_PSC_DNSBL_MIN_TTL, DEF_PSC_DNSBL_MIN_TTL, &var_psc_dnsbl_min_ttl, 1, 0,
1199 VAR_PSC_DNSBL_MAX_TTL, DEF_PSC_DNSBL_MAX_TTL, &var_psc_dnsbl_max_ttl, 1, 0,
1200 VAR_PSC_PIPEL_TTL, DEF_PSC_PIPEL_TTL, &var_psc_pipel_ttl, 1, 0,
1201 VAR_PSC_NSMTP_TTL, DEF_PSC_NSMTP_TTL, &var_psc_nsmtp_ttl, 1, 0,
1202 VAR_PSC_BARLF_TTL, DEF_PSC_BARLF_TTL, &var_psc_barlf_ttl, 1, 0,
1203 VAR_PSC_CACHE_RET, DEF_PSC_CACHE_RET, &var_psc_cache_ret, 1, 0,
1204 VAR_PSC_CACHE_SCAN, DEF_PSC_CACHE_SCAN, &var_psc_cache_scan, 0, 0,
1205 VAR_PSC_WATCHDOG, DEF_PSC_WATCHDOG, &var_psc_watchdog, 10, 0,
1206 VAR_PSC_UPROXY_TMOUT, DEF_PSC_UPROXY_TMOUT, &var_psc_uproxy_tmout, 1, 0,
1207 VAR_PSC_DNSBL_TMOUT, DEF_PSC_DNSBL_TMOUT, &var_psc_dnsbl_tmout, 1, 0,
1208
1209 0,
1210 };
1211 static const CONFIG_BOOL_TABLE bool_table[] = {
1212 VAR_HELO_REQUIRED, DEF_HELO_REQUIRED, &var_helo_required,
1213 VAR_DISABLE_VRFY_CMD, DEF_DISABLE_VRFY_CMD, &var_disable_vrfy_cmd,
1214 VAR_SMTPD_USE_TLS, DEF_SMTPD_USE_TLS, &var_smtpd_use_tls,
1215 VAR_SMTPD_ENFORCE_TLS, DEF_SMTPD_ENFORCE_TLS, &var_smtpd_enforce_tls,
1216 VAR_PSC_PIPEL_ENABLE, DEF_PSC_PIPEL_ENABLE, &var_psc_pipel_enable,
1217 VAR_PSC_NSMTP_ENABLE, DEF_PSC_NSMTP_ENABLE, &var_psc_nsmtp_enable,
1218 VAR_PSC_BARLF_ENABLE, DEF_PSC_BARLF_ENABLE, &var_psc_barlf_enable,
1219 0,
1220 };
1221 static const CONFIG_RAW_TABLE raw_table[] = {
1222 VAR_SMTPD_REJ_FOOTER, DEF_SMTPD_REJ_FOOTER, &var_smtpd_rej_footer, 0, 0,
1223 VAR_PSC_REJ_FOOTER, DEF_PSC_REJ_FOOTER, &var_psc_rej_footer, 0, 0,
1224 VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, 1, 0,
1225 VAR_PSC_EXP_FILTER, DEF_PSC_EXP_FILTER, &var_psc_exp_filter, 1, 0,
1226 0,
1227 };
1228 static const CONFIG_NBOOL_TABLE nbool_table[] = {
1229 VAR_PSC_HELO_REQUIRED, DEF_PSC_HELO_REQUIRED, &var_psc_helo_required,
1230 VAR_PSC_DISABLE_VRFY, DEF_PSC_DISABLE_VRFY, &var_psc_disable_vrfy,
1231 VAR_PSC_USE_TLS, DEF_PSC_USE_TLS, &var_psc_use_tls,
1232 VAR_PSC_ENFORCE_TLS, DEF_PSC_ENFORCE_TLS, &var_psc_enforce_tls,
1233 0,
1234 };
1235
1236 /*
1237 * Fingerprint executables and core dumps.
1238 */
1239 MAIL_VERSION_STAMP_ALLOCATE;
1240
1241 event_server_main(argc, argv, psc_service,
1242 CA_MAIL_SERVER_STR_TABLE(str_table),
1243 CA_MAIL_SERVER_INT_TABLE(int_table),
1244 CA_MAIL_SERVER_NINT_TABLE(nint_table),
1245 CA_MAIL_SERVER_TIME_TABLE(time_table),
1246 CA_MAIL_SERVER_BOOL_TABLE(bool_table),
1247 CA_MAIL_SERVER_RAW_TABLE(raw_table),
1248 CA_MAIL_SERVER_NBOOL_TABLE(nbool_table),
1249 CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
1250 CA_MAIL_SERVER_POST_INIT(post_jail_init),
1251 CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
1252 CA_MAIL_SERVER_SOLITARY,
1253 CA_MAIL_SERVER_SLOW_EXIT(psc_drain),
1254 CA_MAIL_SERVER_EXIT(psc_dump),
1255 CA_MAIL_SERVER_WATCHDOG(&var_psc_watchdog),
1256 0);
1257 }
1258