1 /*++ 2 /* NAME 3 /* smtpd 3h 4 /* SUMMARY 5 /* smtp server 6 /* SYNOPSIS 7 /* include "smtpd.h" 8 /* DESCRIPTION 9 /* .nf 10 11 /* 12 * System library. 13 */ 14 #include <sys/time.h> 15 #include <unistd.h> 16 17 /* 18 * Utility library. 19 */ 20 #include <vstream.h> 21 #include <vstring.h> 22 #include <argv.h> 23 #include <myaddrinfo.h> 24 25 /* 26 * Global library. 27 */ 28 #include <mail_stream.h> 29 30 /* 31 * Postfix TLS library. 32 */ 33 #include <tls.h> 34 35 /* 36 * Milter library. 37 */ 38 #include <milter.h> 39 40 /* 41 * Variables that keep track of conversation state. There is only one SMTP 42 * conversation at a time, so the state variables can be made global. And 43 * some of this has to be global anyway, so that the run-time error handler 44 * can clean up in case of a fatal error deep down in some library routine. 45 */ 46 typedef struct SMTPD_DEFER { 47 int active; /* is this active */ 48 VSTRING *reason; /* reason for deferral */ 49 VSTRING *dsn; /* DSN detail */ 50 int code; /* SMTP reply code */ 51 int class; /* error notification class */ 52 } SMTPD_DEFER; 53 54 typedef struct { 55 int flags; /* XFORWARD server state */ 56 char *name; /* name for access control */ 57 char *addr; /* address for access control */ 58 char *port; /* port for logging */ 59 char *namaddr; /* name[address]:port */ 60 char *rfc_addr; /* address for RFC 2821 */ 61 char *protocol; /* email protocol */ 62 char *helo_name; /* helo/ehlo parameter */ 63 char *ident; /* local message identifier */ 64 char *domain; /* rewrite context */ 65 } SMTPD_XFORWARD_ATTR; 66 67 typedef struct { 68 int flags; /* see below */ 69 int err; /* cleanup server/queue file errors */ 70 VSTREAM *client; /* SMTP client handle */ 71 VSTRING *buffer; /* SMTP client buffer */ 72 VSTRING *addr_buf; /* internalized address buffer */ 73 char *service; /* for event rate control */ 74 struct timeval arrival_time; /* start of MAIL FROM transaction */ 75 char *name; /* verified client hostname */ 76 char *reverse_name; /* unverified client hostname */ 77 char *addr; /* client host address string */ 78 char *port; /* port for logging */ 79 char *namaddr; /* name[address]:port */ 80 char *rfc_addr; /* address for RFC 2821 */ 81 int addr_family; /* address family */ 82 char *dest_addr; /* Dovecot AUTH, Milter {daemon_addr} */ 83 char *dest_port; /* Milter {daemon_port} */ 84 struct sockaddr_storage sockaddr; /* binary client endpoint */ 85 SOCKADDR_SIZE sockaddr_len; /* binary client endpoint */ 86 struct sockaddr_storage dest_sockaddr; /* binary local endpoint */ 87 SOCKADDR_SIZE dest_sockaddr_len; /* binary local endpoint */ 88 int name_status; /* 2=ok 4=soft 5=hard 6=forged */ 89 int reverse_name_status; /* 2=ok 4=soft 5=hard */ 90 int conn_count; /* connections from this client */ 91 int conn_rate; /* connection rate for this client */ 92 int error_count; /* reset after DOT */ 93 int error_mask; /* client errors */ 94 int notify_mask; /* what to report to postmaster */ 95 char *helo_name; /* client HELO/EHLO argument */ 96 char *queue_id; /* from cleanup server/queue file */ 97 VSTREAM *cleanup; /* cleanup server/queue file handle */ 98 MAIL_STREAM *dest; /* another server/file handle */ 99 int rcpt_count; /* number of accepted recipients */ 100 char *access_denied; /* fixme */ 101 ARGV *history; /* protocol transcript */ 102 char *reason; /* cause of connection loss */ 103 char *sender; /* sender address */ 104 char *encoding; /* owned by mail_cmd() */ 105 char *verp_delims; /* owned by mail_cmd() */ 106 char *recipient; /* recipient address */ 107 char *etrn_name; /* client ETRN argument */ 108 char *protocol; /* SMTP or ESMTP */ 109 char *where; /* protocol stage */ 110 int recursion; /* Kellerspeicherpegelanzeiger */ 111 off_t msg_size; /* MAIL FROM message size */ 112 off_t act_size; /* END-OF-DATA message size */ 113 int junk_cmds; /* counter */ 114 int rcpt_overshoot; /* counter */ 115 char *rewrite_context; /* address rewriting context */ 116 117 /* 118 * SASL specific. 119 */ 120 #ifdef USE_SASL_AUTH 121 struct XSASL_SERVER *sasl_server; 122 VSTRING *sasl_reply; 123 char *sasl_mechanism_list; 124 char *sasl_method; 125 char *sasl_username; 126 char *sasl_sender; 127 #endif 128 129 /* 130 * Specific to smtpd access checks. 131 */ 132 int sender_rcptmap_checked; /* sender validated against maps */ 133 int recipient_rcptmap_checked; /* recipient validated against maps */ 134 int warn_if_reject; /* force reject into warning */ 135 SMTPD_DEFER defer_if_reject; /* force reject into deferral */ 136 SMTPD_DEFER defer_if_permit; /* force permit into deferral */ 137 int defer_if_permit_client; /* force permit into warning */ 138 int defer_if_permit_helo; /* force permit into warning */ 139 int defer_if_permit_sender; /* force permit into warning */ 140 int discard; /* discard message */ 141 char *saved_filter; /* postponed filter action */ 142 char *saved_redirect; /* postponed redirect action */ 143 ARGV *saved_bcc; /* postponed bcc action */ 144 int saved_flags; /* postponed hold/discard */ 145 #ifdef DELAY_ACTION 146 int saved_delay; /* postponed deferred delay */ 147 #endif 148 VSTRING *expand_buf; /* scratch space for $name expansion */ 149 ARGV *prepend; /* prepended headers */ 150 VSTRING *instance; /* policy query correlation */ 151 int seqno; /* policy query correlation */ 152 int ehlo_discard_mask; /* suppressed EHLO features */ 153 char *dsn_envid; /* temporary MAIL FROM state */ 154 int dsn_ret; /* temporary MAIL FROM state */ 155 VSTRING *dsn_buf; /* scratch space for xtext expansion */ 156 VSTRING *dsn_orcpt_buf; /* scratch space for ORCPT parsing */ 157 158 /* 159 * Pass-through proxy client. 160 */ 161 struct SMTPD_PROXY *proxy; 162 char *proxy_mail; /* owned by mail_cmd() */ 163 164 /* 165 * XFORWARD server state. 166 */ 167 SMTPD_XFORWARD_ATTR xforward; /* up-stream logging info */ 168 169 /* 170 * TLS related state. 171 */ 172 #ifdef USE_TLS 173 #ifdef USE_TLSPROXY 174 VSTREAM *tlsproxy; /* tlsproxy(8) temp. handle */ 175 #endif 176 TLS_SESS_STATE *tls_context; /* TLS session state */ 177 #endif 178 179 /* 180 * Milter support. 181 */ 182 const char **milter_argv; /* SMTP command vector */ 183 ssize_t milter_argc; /* SMTP command vector */ 184 const char *milter_reject_text; /* input to call-back from Milter */ 185 MILTERS *milters; /* Milter initialization status. */ 186 187 /* 188 * EHLO temporary space. 189 */ 190 VSTRING *ehlo_buf; 191 ARGV *ehlo_argv; 192 193 /* 194 * BDAT processing state. 195 */ 196 #define SMTPD_BDAT_STAT_NONE 0 /* not processing BDAT */ 197 #define SMTPD_BDAT_STAT_OK 1 /* accepting BDAT chunks */ 198 #define SMTPD_BDAT_STAT_ERROR 2 /* skipping BDAT chunks */ 199 int bdat_state; /* see above */ 200 VSTREAM *bdat_get_stream; /* memory stream from BDAT chunk */ 201 VSTRING *bdat_get_buffer; /* read from memory stream */ 202 int bdat_prev_rec_type; 203 } SMTPD_STATE; 204 205 #define SMTPD_FLAG_HANGUP (1<<0) /* 421/521 disconnect */ 206 #define SMTPD_FLAG_ILL_PIPELINING (1<<1) /* inappropriate pipelining */ 207 #define SMTPD_FLAG_AUTH_USED (1<<2) /* don't reuse SASL state */ 208 #define SMTPD_FLAG_SMTPUTF8 (1<<3) /* RFC 6531/2 transaction */ 209 #define SMTPD_FLAG_NEED_MILTER_ABORT (1<<4) /* undo milter_mail_event() */ 210 211 /* Security: don't reset SMTPD_FLAG_AUTH_USED. */ 212 #define SMTPD_MASK_MAIL_KEEP \ 213 ~(SMTPD_FLAG_SMTPUTF8) /* Fix 20140706 */ 214 215 #define SMTPD_STATE_XFORWARD_INIT (1<<0) /* xforward preset done */ 216 #define SMTPD_STATE_XFORWARD_NAME (1<<1) /* client name received */ 217 #define SMTPD_STATE_XFORWARD_ADDR (1<<2) /* client address received */ 218 #define SMTPD_STATE_XFORWARD_PROTO (1<<3) /* protocol received */ 219 #define SMTPD_STATE_XFORWARD_HELO (1<<4) /* client helo received */ 220 #define SMTPD_STATE_XFORWARD_IDENT (1<<5) /* message identifier */ 221 #define SMTPD_STATE_XFORWARD_DOMAIN (1<<6) /* address context */ 222 #define SMTPD_STATE_XFORWARD_PORT (1<<7) /* client port received */ 223 224 #define SMTPD_STATE_XFORWARD_CLIENT_MASK \ 225 (SMTPD_STATE_XFORWARD_NAME | SMTPD_STATE_XFORWARD_ADDR \ 226 | SMTPD_STATE_XFORWARD_PROTO | SMTPD_STATE_XFORWARD_HELO \ 227 | SMTPD_STATE_XFORWARD_PORT) 228 229 extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *, const char *); 230 extern void smtpd_state_reset(SMTPD_STATE *); 231 232 /* 233 * Conversation stages. This is used for "lost connection after XXX" 234 * diagnostics. 235 */ 236 #define SMTPD_AFTER_CONNECT "CONNECT" 237 #define SMTPD_AFTER_DATA "DATA content" 238 #define SMTPD_AFTER_BDAT "BDAT content" 239 #define SMTPD_AFTER_EOM "END-OF-MESSAGE" 240 241 /* 242 * Other stages. These are sometimes used to change the way information is 243 * logged or what information will be available for access control. 244 */ 245 #define SMTPD_CMD_HELO "HELO" 246 #define SMTPD_CMD_EHLO "EHLO" 247 #define SMTPD_CMD_STARTTLS "STARTTLS" 248 #define SMTPD_CMD_AUTH "AUTH" 249 #define SMTPD_CMD_MAIL "MAIL" 250 #define SMTPD_CMD_RCPT "RCPT" 251 #define SMTPD_CMD_DATA "DATA" 252 #define SMTPD_CMD_BDAT "BDAT" 253 #define SMTPD_CMD_EOD SMTPD_AFTER_EOM /* XXX Was: END-OF-DATA */ 254 #define SMTPD_CMD_RSET "RSET" 255 #define SMTPD_CMD_NOOP "NOOP" 256 #define SMTPD_CMD_VRFY "VRFY" 257 #define SMTPD_CMD_ETRN "ETRN" 258 #define SMTPD_CMD_QUIT "QUIT" 259 #define SMTPD_CMD_XCLIENT "XCLIENT" 260 #define SMTPD_CMD_XFORWARD "XFORWARD" 261 #define SMTPD_CMD_UNKNOWN "UNKNOWN" 262 263 /* 264 * Representation of unknown and non-existent client information. Throughout 265 * Postfix, we use the "unknown" string value for unknown client information 266 * (e.g., unknown remote client hostname), and we use the empty string, null 267 * pointer or "no queue file record" for non-existent client information 268 * (e.g., no HELO command, or local submission). 269 * 270 * Inside the SMTP server, unknown real client attributes are represented by 271 * the string "unknown", and non-existent HELO is represented as a null 272 * pointer. The SMTP server uses this same representation internally for 273 * forwarded client attributes; the XFORWARD syntax makes no distinction 274 * between unknown (remote submission) and non-existent (local submission). 275 * 276 * The SMTP client sends forwarded client attributes only when upstream client 277 * attributes exist (i.e. remote submission). Thus, local submissions will 278 * appear to come from an SMTP-based content filter, which is acceptable. 279 * 280 * Known/unknown client attribute values use the SMTP server's internal 281 * representation in queue files, in queue manager delivery requests, and in 282 * delivery agent $name expansions. 283 * 284 * Non-existent attribute values are never present in queue files. Non-existent 285 * information is represented as empty strings in queue manager delivery 286 * requests and in delivery agent $name expansions. 287 */ 288 #define CLIENT_ATTR_UNKNOWN "unknown" 289 290 #define CLIENT_NAME_UNKNOWN CLIENT_ATTR_UNKNOWN 291 #define CLIENT_ADDR_UNKNOWN CLIENT_ATTR_UNKNOWN 292 #define CLIENT_PORT_UNKNOWN CLIENT_ATTR_UNKNOWN 293 #define CLIENT_NAMADDR_UNKNOWN CLIENT_ATTR_UNKNOWN 294 #define CLIENT_HELO_UNKNOWN 0 295 #define CLIENT_PROTO_UNKNOWN CLIENT_ATTR_UNKNOWN 296 #define CLIENT_IDENT_UNKNOWN 0 297 #define CLIENT_DOMAIN_UNKNOWN 0 298 #define CLIENT_LOGIN_UNKNOWN 0 299 300 #define SERVER_ATTR_UNKNOWN "unknown" 301 302 #define SERVER_ADDR_UNKNOWN SERVER_ATTR_UNKNOWN 303 #define SERVER_PORT_UNKNOWN SERVER_ATTR_UNKNOWN 304 305 #define IS_AVAIL_CLIENT_ATTR(v) ((v) && strcmp((v), CLIENT_ATTR_UNKNOWN)) 306 307 #define IS_AVAIL_CLIENT_NAME(v) IS_AVAIL_CLIENT_ATTR(v) 308 #define IS_AVAIL_CLIENT_ADDR(v) IS_AVAIL_CLIENT_ATTR(v) 309 #define IS_AVAIL_CLIENT_PORT(v) IS_AVAIL_CLIENT_ATTR(v) 310 #define IS_AVAIL_CLIENT_NAMADDR(v) IS_AVAIL_CLIENT_ATTR(v) 311 #define IS_AVAIL_CLIENT_HELO(v) ((v) != 0) 312 #define IS_AVAIL_CLIENT_PROTO(v) IS_AVAIL_CLIENT_ATTR(v) 313 #define IS_AVAIL_CLIENT_IDENT(v) ((v) != 0) 314 #define IS_AVAIL_CLIENT_DOMAIN(v) ((v) != 0) 315 316 /* 317 * If running in stand-alone mode, do not try to talk to Postfix daemons but 318 * write to queue file instead. 319 */ 320 #define SMTPD_STAND_ALONE_STREAM(stream) \ 321 (stream == VSTREAM_IN && getuid() != var_owner_uid) 322 323 #define SMTPD_STAND_ALONE(state) \ 324 (state->client == VSTREAM_IN && getuid() != var_owner_uid) 325 326 /* 327 * If running as proxy front-end, disable actions that require communication 328 * with the cleanup server. 329 */ 330 #define USE_SMTPD_PROXY(state) \ 331 (SMTPD_STAND_ALONE(state) == 0 && *var_smtpd_proxy_filt) 332 333 /* 334 * Are we in a MAIL transaction? 335 */ 336 #define SMTPD_IN_MAIL_TRANSACTION(state) ((state)->sender != 0) 337 338 /* 339 * Are we processing BDAT requests? 340 */ 341 #define SMTPD_PROCESSING_BDAT(state) \ 342 ((state)->bdat_state != SMTPD_BDAT_STAT_NONE) 343 344 /* 345 * SMTPD peer information lookup. 346 */ 347 extern void smtpd_peer_init(SMTPD_STATE *state); 348 extern void smtpd_peer_reset(SMTPD_STATE *state); 349 extern void smtpd_peer_from_default(SMTPD_STATE *); 350 extern int smtpd_peer_from_haproxy(SMTPD_STATE *); 351 352 #define SMTPD_PEER_CODE_OK 2 353 #define SMTPD_PEER_CODE_TEMP 4 354 #define SMTPD_PEER_CODE_PERM 5 355 #define SMTPD_PEER_CODE_FORGED 6 356 357 /* 358 * Construct name[addr] or name[addr]:port as appropriate 359 */ 360 #define SMTPD_BUILD_NAMADDRPORT(name, addr, port) \ 361 concatenate((name), "[", (addr), "]", \ 362 var_smtpd_client_port_log ? ":" : (char *) 0, \ 363 (port), (char *) 0) 364 365 /* 366 * Don't mix information from the current SMTP session with forwarded 367 * information from an up-stream session. 368 */ 369 #define HAVE_FORWARDED_CLIENT_ATTR(s) \ 370 ((s)->xforward.flags & SMTPD_STATE_XFORWARD_CLIENT_MASK) 371 372 #define FORWARD_CLIENT_ATTR(s, a) \ 373 (HAVE_FORWARDED_CLIENT_ATTR(s) ? \ 374 (s)->xforward.a : (s)->a) 375 376 #define FORWARD_ADDR(s) FORWARD_CLIENT_ATTR((s), rfc_addr) 377 #define FORWARD_NAME(s) FORWARD_CLIENT_ATTR((s), name) 378 #define FORWARD_NAMADDR(s) FORWARD_CLIENT_ATTR((s), namaddr) 379 #define FORWARD_PROTO(s) FORWARD_CLIENT_ATTR((s), protocol) 380 #define FORWARD_HELO(s) FORWARD_CLIENT_ATTR((s), helo_name) 381 #define FORWARD_PORT(s) FORWARD_CLIENT_ATTR((s), port) 382 383 /* 384 * Mixing is not a problem with forwarded local message identifiers. 385 */ 386 #define HAVE_FORWARDED_IDENT(s) \ 387 ((s)->xforward.ident != 0) 388 389 #define FORWARD_IDENT(s) \ 390 (HAVE_FORWARDED_IDENT(s) ? \ 391 (s)->xforward.ident : (s)->queue_id) 392 393 /* 394 * Mixing is not a problem with forwarded address rewriting contexts. 395 */ 396 #define FORWARD_DOMAIN(s) \ 397 (((s)->xforward.flags & SMTPD_STATE_XFORWARD_DOMAIN) ? \ 398 (s)->xforward.domain : (s)->rewrite_context) 399 400 extern void smtpd_xforward_init(SMTPD_STATE *); 401 extern void smtpd_xforward_preset(SMTPD_STATE *); 402 extern void smtpd_xforward_reset(SMTPD_STATE *); 403 404 /* 405 * Transparency: before mail is queued, do we check for unknown recipients, 406 * do we allow address mapping, automatic bcc, header/body checks? 407 */ 408 extern int smtpd_input_transp_mask; 409 410 /* 411 * More Milter support. 412 */ 413 extern MILTERS *smtpd_milters; 414 415 /* 416 * Message size multiplication factor for free space check. 417 */ 418 extern double smtpd_space_multf; 419 420 /* 421 * header_from_format support. 422 */ 423 extern int smtpd_hfrom_format; 424 425 /* LICENSE 426 /* .ad 427 /* .fi 428 /* The Secure Mailer license must be distributed with this software. 429 /* AUTHOR(S) 430 /* Wietse Venema 431 /* IBM T.J. Watson Research 432 /* P.O. Box 704 433 /* Yorktown Heights, NY 10598, USA 434 /* 435 /* Wietse Venema 436 /* Google, Inc. 437 /* 111 8th Avenue 438 /* New York, NY 10011, USA 439 /* 440 /* TLS support originally by: 441 /* Lutz Jaenicke 442 /* BTU Cottbus 443 /* Allgemeine Elektrotechnik 444 /* Universitaetsplatz 3-4 445 /* D-03044 Cottbus, Germany 446 /*--*/ 447