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