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  */
471char   *var_smtpd_service;
472char   *var_smtpd_banner;
473bool    var_disable_vrfy_cmd;
474bool    var_helo_required;
475
476char   *var_smtpd_cmd_filter;
477char   *var_psc_cmd_filter;
478
479char   *var_smtpd_forbid_cmds;
480char   *var_psc_forbid_cmds;
481
482char   *var_smtpd_ehlo_dis_words;
483char   *var_smtpd_ehlo_dis_maps;
484char   *var_psc_ehlo_dis_words;
485char   *var_psc_ehlo_dis_maps;
486
487char   *var_smtpd_tls_level;
488bool    var_smtpd_use_tls;
489bool    var_smtpd_enforce_tls;
490char   *var_psc_tls_level;
491bool    var_psc_use_tls;
492bool    var_psc_enforce_tls;
493
494bool    var_psc_disable_vrfy;
495bool    var_psc_helo_required;
496
497char   *var_psc_cache_map;
498int     var_psc_cache_scan;
499int     var_psc_cache_ret;
500int     var_psc_post_queue_limit;
501int     var_psc_pre_queue_limit;
502int     var_psc_watchdog;
503
504char   *var_psc_acl;
505char   *var_psc_dnlist_action;
506
507char   *var_psc_greet_ttl;
508int     var_psc_greet_wait;
509
510char   *var_psc_pregr_banner;
511char   *var_psc_pregr_action;
512int     var_psc_pregr_ttl;
513
514char   *var_psc_dnsbl_sites;
515char   *var_psc_dnsbl_reply;
516int     var_psc_dnsbl_thresh;
517int     var_psc_dnsbl_althresh;
518char   *var_psc_dnsbl_action;
519int     var_psc_dnsbl_min_ttl;
520int     var_psc_dnsbl_max_ttl;
521int     var_psc_dnsbl_tmout;
522
523bool    var_psc_pipel_enable;
524char   *var_psc_pipel_action;
525int     var_psc_pipel_ttl;
526
527bool    var_psc_nsmtp_enable;
528char   *var_psc_nsmtp_action;
529int     var_psc_nsmtp_ttl;
530
531bool    var_psc_barlf_enable;
532char   *var_psc_barlf_action;
533int     var_psc_barlf_ttl;
534
535int     var_psc_cmd_count;
536int     var_psc_cmd_time;
537
538char   *var_dnsblog_service;
539char   *var_tlsproxy_service;
540
541char   *var_smtpd_rej_footer;
542char   *var_psc_rej_footer;
543char   *var_psc_rej_ftr_maps;
544
545int     var_smtpd_cconn_limit;
546int     var_psc_cconn_limit;
547
548char   *var_smtpd_exp_filter;
549char   *var_psc_exp_filter;
550
551char   *var_psc_allist_if;
552char   *var_psc_uproxy_proto;
553int     var_psc_uproxy_tmout;
554
555 /*
556  * Global variables.
557  */
558int     psc_check_queue_length;		/* connections being checked */
559int     psc_post_queue_length;		/* being sent to real SMTPD */
560DICT_CACHE *psc_cache_map;		/* cache table handle */
561VSTRING *psc_temp;			/* scratchpad */
562char   *psc_smtpd_service_name;		/* path to real SMTPD */
563int     psc_pregr_action;		/* PSC_ACT_DROP/ENFORCE/etc */
564int     psc_dnsbl_action;		/* PSC_ACT_DROP/ENFORCE/etc */
565int     psc_pipel_action;		/* PSC_ACT_DROP/ENFORCE/etc */
566int     psc_nsmtp_action;		/* PSC_ACT_DROP/ENFORCE/etc */
567int     psc_barlf_action;		/* PSC_ACT_DROP/ENFORCE/etc */
568int     psc_min_ttl;			/* Update with new tests! */
569STRING_LIST *psc_forbid_cmds;		/* CONNECT GET POST */
570int     psc_stress_greet_wait;		/* stressed greet wait */
571int     psc_normal_greet_wait;		/* stressed greet wait */
572int     psc_stress_cmd_time_limit;	/* stressed command limit */
573int     psc_normal_cmd_time_limit;	/* normal command time limit */
574int     psc_stress;			/* stress level */
575int     psc_lowat_check_queue_length;	/* stress low-water mark */
576int     psc_hiwat_check_queue_length;	/* stress high-water mark */
577DICT   *psc_dnsbl_reply;		/* DNSBL name mapper */
578HTABLE *psc_client_concurrency;		/* per-client concurrency */
579
580 /*
581  * Local variables and functions.
582  */
583static ARGV *psc_acl;			/* permanent allow/denylist */
584static int psc_dnlist_action;		/* PSC_ACT_DROP/ENFORCE/etc */
585static ADDR_MATCH_LIST *psc_allist_if;	/* allowlist interfaces */
586
587static 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
593static 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
610static 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
654static 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
685static 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
695static 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
895static 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
917static 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
983static 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
1005static 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
1139MAIL_VERSION_STAMP_DECLARE;
1140
1141/* main - pass control to the multi-threaded skeleton */
1142
1143int     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