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 */ 46typedef 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 54typedef 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 67typedef 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 struct sockaddr_storage sockaddr; /* binary client endpoint */ 83 int name_status; /* 2=ok 4=soft 5=hard 6=forged */ 84 int reverse_name_status; /* 2=ok 4=soft 5=hard */ 85 int conn_count; /* connections from this client */ 86 int conn_rate; /* connection rate for this client */ 87 int error_count; /* reset after DOT */ 88 int error_mask; /* client errors */ 89 int notify_mask; /* what to report to postmaster */ 90 char *helo_name; /* client HELO/EHLO argument */ 91 char *queue_id; /* from cleanup server/queue file */ 92 VSTREAM *cleanup; /* cleanup server/queue file handle */ 93 MAIL_STREAM *dest; /* another server/file handle */ 94 int rcpt_count; /* number of accepted recipients */ 95 char *access_denied; /* fixme */ 96 ARGV *history; /* protocol transcript */ 97 char *reason; /* cause of connection loss */ 98 char *sender; /* sender address */ 99 char *encoding; /* owned by mail_cmd() */ 100 char *verp_delims; /* owned by mail_cmd() */ 101 char *recipient; /* recipient address */ 102 char *etrn_name; /* client ETRN argument */ 103 char *protocol; /* SMTP or ESMTP */ 104 char *where; /* protocol stage */ 105 int recursion; /* Kellerspeicherpegelanzeiger */ 106 int chunking; /* APPLE - RFC 3030 */ 107 void *chunking_context; /* APPLE - RFC 3030 */ 108 off_t msg_size; /* MAIL FROM message size */ 109 off_t act_size; /* END-OF-DATA message size */ 110 int junk_cmds; /* counter */ 111 int rcpt_overshoot; /* counter */ 112 char *rewrite_context; /* address rewriting context */ 113 114 /* 115 * SASL specific. 116 */ 117#ifdef USE_SASL_AUTH 118 struct XSASL_SERVER *sasl_server; 119 VSTRING *sasl_reply; 120 char *sasl_mechanism_list; 121 char *sasl_method; 122 char *sasl_username; 123 char *sasl_sender; 124#endif 125 126 /* 127 * Specific to smtpd access checks. 128 */ 129 int sender_rcptmap_checked; /* sender validated against maps */ 130 int recipient_rcptmap_checked; /* recipient validated against maps */ 131 int warn_if_reject; /* force reject into warning */ 132 SMTPD_DEFER defer_if_reject; /* force reject into deferral */ 133 SMTPD_DEFER defer_if_permit; /* force permit into deferral */ 134 int defer_if_permit_client; /* force permit into warning */ 135 int defer_if_permit_helo; /* force permit into warning */ 136 int defer_if_permit_sender; /* force permit into warning */ 137 int discard; /* discard message */ 138 char *saved_filter; /* postponed filter action */ 139 char *saved_redirect; /* postponed redirect action */ 140 char *saved_bcc; /* postponed bcc action */ 141 int saved_flags; /* postponed hold/discard */ 142#ifdef DELAY_ACTION 143 int saved_delay; /* postponed deferred delay */ 144#endif 145 VSTRING *expand_buf; /* scratch space for $name expansion */ 146 ARGV *prepend; /* prepended headers */ 147 VSTRING *instance; /* policy query correlation */ 148 int seqno; /* policy query correlation */ 149 int ehlo_discard_mask; /* suppressed EHLO features */ 150 char *dsn_envid; /* temporary MAIL FROM state */ 151 int dsn_ret; /* temporary MAIL FROM state */ 152 VSTRING *dsn_buf; /* scratch space for xtext expansion */ 153 VSTRING *dsn_orcpt_buf; /* scratch space for ORCPT parsing */ 154 155 /* 156 * Pass-through proxy client. 157 */ 158 struct SMTPD_PROXY *proxy; 159 char *proxy_mail; /* owned by mail_cmd() */ 160 161 /* 162 * XFORWARD server state. 163 */ 164 SMTPD_XFORWARD_ATTR xforward; /* up-stream logging info */ 165 166 /* 167 * TLS related state. 168 */ 169#ifdef USE_TLS 170#ifdef USE_TLSPROXY 171 VSTREAM *tlsproxy; /* tlsproxy(8) temp. handle */ 172#endif 173 TLS_SESS_STATE *tls_context; /* TLS session state */ 174#endif 175 176 /* 177 * Milter support. 178 */ 179 const char **milter_argv; /* SMTP command vector */ 180 ssize_t milter_argc; /* SMTP command vector */ 181 const char *milter_reject_text; /* input to call-back from Milter */ 182 183 /* 184 * EHLO temporary space. 185 */ 186 VSTRING *ehlo_buf; 187 ARGV *ehlo_argv; 188} SMTPD_STATE; 189 190#define SMTPD_FLAG_HANGUP (1<<0) /* 421/521 disconnect */ 191#define SMTPD_FLAG_ILL_PIPELINING (1<<1) /* inappropriate pipelining */ 192#define SMTPD_FLAG_AUTH_USED (1<<2) /* don't reuse SASL state */ 193 194 /* Security: don't reset SMTPD_FLAG_AUTH_USED. */ 195#define SMTPD_MASK_MAIL_KEEP ~0 /* keep all after MAIL reset */ 196 197#define SMTPD_STATE_XFORWARD_INIT (1<<0) /* xforward preset done */ 198#define SMTPD_STATE_XFORWARD_NAME (1<<1) /* client name received */ 199#define SMTPD_STATE_XFORWARD_ADDR (1<<2) /* client address received */ 200#define SMTPD_STATE_XFORWARD_PROTO (1<<3) /* protocol received */ 201#define SMTPD_STATE_XFORWARD_HELO (1<<4) /* client helo received */ 202#define SMTPD_STATE_XFORWARD_IDENT (1<<5) /* message identifier */ 203#define SMTPD_STATE_XFORWARD_DOMAIN (1<<6) /* address context */ 204#define SMTPD_STATE_XFORWARD_PORT (1<<7) /* client port received */ 205 206#define SMTPD_STATE_XFORWARD_CLIENT_MASK \ 207 (SMTPD_STATE_XFORWARD_NAME | SMTPD_STATE_XFORWARD_ADDR \ 208 | SMTPD_STATE_XFORWARD_PROTO | SMTPD_STATE_XFORWARD_HELO \ 209 | SMTPD_STATE_XFORWARD_PORT) 210 211/* APPLE - RFC 3030 */ 212#define SMTPD_CHUNKING (1 << 0) /* BURL or BDAT used */ 213#define SMTPD_CHUNKING_CONT (1 << 1) /* non-LAST used */ 214#define SMTPD_CHUNKING_LAST (1 << 2) /* LAST */ 215#define SMTPD_CHUNKING_BINARYMIME (1 << 3) /* BODY=BINARYMIME */ 216#define SMTPD_CHUNKING_NONZERO (1 << 4) /* read >= 1 byte */ 217 218extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *, const char *); 219extern void smtpd_state_reset(SMTPD_STATE *); 220 221 /* 222 * Conversation stages. This is used for "lost connection after XXX" 223 * diagnostics. 224 */ 225#define SMTPD_AFTER_CONNECT "CONNECT" 226#define SMTPD_AFTER_DATA "DATA content" 227#define SMTPD_AFTER_DOT "END-OF-MESSAGE" 228 229 /* 230 * Other stages. These are sometimes used to change the way information is 231 * logged or what information will be available for access control. 232 */ 233#define SMTPD_CMD_HELO "HELO" 234#define SMTPD_CMD_EHLO "EHLO" 235#define SMTPD_CMD_STARTTLS "STARTTLS" 236#define SMTPD_CMD_AUTH "AUTH" 237#define SMTPD_CMD_MAIL "MAIL" 238#define SMTPD_CMD_RCPT "RCPT" 239#define SMTPD_CMD_DATA "DATA" 240#define SMTPD_CMD_BURL "BURL" /* APPLE - burl */ 241#define SMTPD_CMD_BDAT "BDAT" /* APPLE - RFC 3030 */ 242#define SMTPD_CMD_EOD SMTPD_AFTER_DOT /* XXX Was: END-OF-DATA */ 243#define SMTPD_CMD_RSET "RSET" 244#define SMTPD_CMD_NOOP "NOOP" 245#define SMTPD_CMD_VRFY "VRFY" 246#define SMTPD_CMD_ETRN "ETRN" 247#define SMTPD_CMD_QUIT "QUIT" 248#define SMTPD_CMD_XCLIENT "XCLIENT" 249#define SMTPD_CMD_XFORWARD "XFORWARD" 250#define SMTPD_CMD_UNKNOWN "UNKNOWN" 251 252 /* 253 * Representation of unknown and non-existent client information. Throughout 254 * Postfix, we use the "unknown" string value for unknown client information 255 * (e.g., unknown remote client hostname), and we use the empty string, null 256 * pointer or "no queue file record" for non-existent client information 257 * (e.g., no HELO command, or local submission). 258 * 259 * Inside the SMTP server, unknown real client attributes are represented by 260 * the string "unknown", and non-existent HELO is represented as a null 261 * pointer. The SMTP server uses this same representation internally for 262 * forwarded client attributes; the XFORWARD syntax makes no distinction 263 * between unknown (remote submission) and non-existent (local submission). 264 * 265 * The SMTP client sends forwarded client attributes only when upstream client 266 * attributes exist (i.e. remote submission). Thus, local submissions will 267 * appear to come from an SMTP-based content filter, which is acceptable. 268 * 269 * Known/unknown client attribute values use the SMTP server's internal 270 * representation in queue files, in queue manager delivery requests, and in 271 * delivery agent $name expansions. 272 * 273 * Non-existent attribute values are never present in queue files. Non-existent 274 * information is represented as empty strings in queue manager delivery 275 * requests and in delivery agent $name expansions. 276 */ 277#define CLIENT_ATTR_UNKNOWN "unknown" 278 279#define CLIENT_NAME_UNKNOWN CLIENT_ATTR_UNKNOWN 280#define CLIENT_ADDR_UNKNOWN CLIENT_ATTR_UNKNOWN 281#define CLIENT_PORT_UNKNOWN CLIENT_ATTR_UNKNOWN 282#define CLIENT_NAMADDR_UNKNOWN CLIENT_ATTR_UNKNOWN 283#define CLIENT_HELO_UNKNOWN 0 284#define CLIENT_PROTO_UNKNOWN CLIENT_ATTR_UNKNOWN 285#define CLIENT_IDENT_UNKNOWN 0 286#define CLIENT_DOMAIN_UNKNOWN 0 287#define CLIENT_LOGIN_UNKNOWN 0 288 289#define IS_AVAIL_CLIENT_ATTR(v) ((v) && strcmp((v), CLIENT_ATTR_UNKNOWN)) 290 291#define IS_AVAIL_CLIENT_NAME(v) IS_AVAIL_CLIENT_ATTR(v) 292#define IS_AVAIL_CLIENT_ADDR(v) IS_AVAIL_CLIENT_ATTR(v) 293#define IS_AVAIL_CLIENT_PORT(v) IS_AVAIL_CLIENT_ATTR(v) 294#define IS_AVAIL_CLIENT_NAMADDR(v) IS_AVAIL_CLIENT_ATTR(v) 295#define IS_AVAIL_CLIENT_HELO(v) ((v) != 0) 296#define IS_AVAIL_CLIENT_PROTO(v) IS_AVAIL_CLIENT_ATTR(v) 297#define IS_AVAIL_CLIENT_IDENT(v) ((v) != 0) 298#define IS_AVAIL_CLIENT_DOMAIN(v) ((v) != 0) 299 300 /* 301 * If running in stand-alone mode, do not try to talk to Postfix daemons but 302 * write to queue file instead. 303 */ 304#define SMTPD_STAND_ALONE_STREAM(stream) \ 305 (stream == VSTREAM_IN && getuid() != var_owner_uid) 306 307#define SMTPD_STAND_ALONE(state) \ 308 (state->client == VSTREAM_IN && getuid() != var_owner_uid) 309 310 /* 311 * If running as proxy front-end, disable actions that require communication 312 * with the cleanup server. 313 */ 314#define USE_SMTPD_PROXY(state) \ 315 (SMTPD_STAND_ALONE(state) == 0 && *var_smtpd_proxy_filt) 316 317 /* 318 * SMTPD peer information lookup. 319 */ 320extern void smtpd_peer_init(SMTPD_STATE *state); 321extern void smtpd_peer_reset(SMTPD_STATE *state); 322 323#define SMTPD_PEER_CODE_OK 2 324#define SMTPD_PEER_CODE_TEMP 4 325#define SMTPD_PEER_CODE_PERM 5 326#define SMTPD_PEER_CODE_FORGED 6 327 328 /* 329 * Construct name[addr] or name[addr]:port as appropriate 330 */ 331#define SMTPD_BUILD_NAMADDRPORT(name, addr, port) \ 332 concatenate((name), "[", (addr), "]", \ 333 var_smtpd_client_port_log ? ":" : (char *) 0, \ 334 (port), (char *) 0) 335 336 /* 337 * Don't mix information from the current SMTP session with forwarded 338 * information from an up-stream session. 339 */ 340#define HAVE_FORWARDED_CLIENT_ATTR(s) \ 341 ((s)->xforward.flags & SMTPD_STATE_XFORWARD_CLIENT_MASK) 342 343#define FORWARD_CLIENT_ATTR(s, a) \ 344 (HAVE_FORWARDED_CLIENT_ATTR(s) ? \ 345 (s)->xforward.a : (s)->a) 346 347#define FORWARD_ADDR(s) FORWARD_CLIENT_ATTR((s), rfc_addr) 348#define FORWARD_NAME(s) FORWARD_CLIENT_ATTR((s), name) 349#define FORWARD_NAMADDR(s) FORWARD_CLIENT_ATTR((s), namaddr) 350#define FORWARD_PROTO(s) FORWARD_CLIENT_ATTR((s), protocol) 351#define FORWARD_HELO(s) FORWARD_CLIENT_ATTR((s), helo_name) 352#define FORWARD_PORT(s) FORWARD_CLIENT_ATTR((s), port) 353 354 /* 355 * Mixing is not a problem with forwarded local message identifiers. 356 */ 357#define HAVE_FORWARDED_IDENT(s) \ 358 ((s)->xforward.ident != 0) 359 360#define FORWARD_IDENT(s) \ 361 (HAVE_FORWARDED_IDENT(s) ? \ 362 (s)->xforward.ident : (s)->queue_id) 363 364 /* 365 * Mixing is not a problem with forwarded address rewriting contexts. 366 */ 367#define FORWARD_DOMAIN(s) \ 368 (((s)->xforward.flags & SMTPD_STATE_XFORWARD_DOMAIN) ? \ 369 (s)->xforward.domain : (s)->rewrite_context) 370 371extern void smtpd_xforward_init(SMTPD_STATE *); 372extern void smtpd_xforward_preset(SMTPD_STATE *); 373extern void smtpd_xforward_reset(SMTPD_STATE *); 374 375 /* 376 * Transparency: before mail is queued, do we check for unknown recipients, 377 * do we allow address mapping, automatic bcc, header/body checks? 378 */ 379extern int smtpd_input_transp_mask; 380 381 /* 382 * More Milter support. 383 */ 384extern MILTERS *smtpd_milters; 385 386 /* 387 * Message size multiplication factor for free space check. 388 */ 389extern double smtpd_space_multf; 390 391#ifdef __APPLE_OS_X_SERVER__ 392#define PW_SERVER_NONE 0x0000 393#define PW_SERVER_LOGIN 0x0001 394#define PW_SERVER_PLAIN 0x0002 395#define PW_SERVER_CRAM_MD5 0x0004 396#define PW_SERVER_DIGEST_MD5 0x0008 397#define PW_SERVER_GSSAPI 0x0010 398 399extern int smtpd_pw_server_sasl_opts; 400#endif /* __APPLE_OS_X_SERVER__ */ 401 402/* LICENSE 403/* .ad 404/* .fi 405/* The Secure Mailer license must be distributed with this software. 406/* AUTHOR(S) 407/* Wietse Venema 408/* IBM T.J. Watson Research 409/* P.O. Box 704 410/* Yorktown Heights, NY 10598, USA 411/* 412/* TLS support originally by: 413/* Lutz Jaenicke 414/* BTU Cottbus 415/* Allgemeine Elektrotechnik 416/* Universitaetsplatz 3-4 417/* D-03044 Cottbus, Germany 418/*--*/ 419