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