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