1 /* $NetBSD: smtp.h,v 1.2 2017/02/14 01:16:48 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* smtp 3h 6 /* SUMMARY 7 /* smtp client program 8 /* SYNOPSIS 9 /* #include "smtp.h" 10 /* DESCRIPTION 11 /* .nf 12 13 /* 14 * System library. 15 */ 16 #include <string.h> 17 18 /* 19 * Utility library. 20 */ 21 #include <vstream.h> 22 #include <vstring.h> 23 #include <argv.h> 24 #include <htable.h> 25 #include <dict.h> 26 27 /* 28 * Global library. 29 */ 30 #include <deliver_request.h> 31 #include <scache.h> 32 #include <string_list.h> 33 #include <maps.h> 34 #include <tok822.h> 35 #include <dsn_buf.h> 36 #include <header_body_checks.h> 37 38 /* 39 * Postfix TLS library. 40 */ 41 #include <tls.h> 42 43 /* 44 * Global iterator support. This is updated by the connection-management 45 * loop, and contains dynamic context that appears in lookup keys for SASL 46 * passwords, TLS policy, cached SMTP connections, and cached TLS session 47 * keys. 48 * 49 * For consistency and maintainability, context that is used in more than one 50 * lookup key is formatted with smtp_key_format(). 51 */ 52 typedef struct SMTP_ITERATOR { 53 /* Public members. */ 54 VSTRING *request_nexthop; /* request nexhop or empty */ 55 VSTRING *dest; /* current nexthop */ 56 VSTRING *host; /* hostname or empty */ 57 VSTRING *addr; /* printable address or empty */ 58 unsigned port; /* network byte order or null */ 59 struct DNS_RR *rr; /* DNS resource record or null */ 60 struct DNS_RR *mx; /* DNS resource record or null */ 61 /* Private members. */ 62 VSTRING *saved_dest; /* saved current nexthop */ 63 struct SMTP_STATE *parent; /* parent linkage */ 64 } SMTP_ITERATOR; 65 66 #define SMTP_ITER_INIT(iter, _dest, _host, _addr, _port, state) do { \ 67 vstring_strcpy((iter)->dest, (_dest)); \ 68 vstring_strcpy((iter)->host, (_host)); \ 69 vstring_strcpy((iter)->addr, (_addr)); \ 70 (iter)->port = (_port); \ 71 (iter)->mx = (iter)->rr = 0; \ 72 vstring_strcpy((iter)->saved_dest, ""); \ 73 (iter)->parent = (state); \ 74 } while (0) 75 76 #define SMTP_ITER_CLOBBER(iter, _dest, _host, _addr) do { \ 77 vstring_strcpy((iter)->dest, (_dest)); \ 78 vstring_strcpy((iter)->host, (_host)); \ 79 vstring_strcpy((iter)->addr, (_addr)); \ 80 } while (0) 81 82 #define SMTP_ITER_SAVE_DEST(iter) do { \ 83 vstring_strcpy((iter)->saved_dest, STR((iter)->dest)); \ 84 } while (0) 85 86 #define SMTP_ITER_RESTORE_DEST(iter) do { \ 87 vstring_strcpy((iter)->dest, STR((iter)->saved_dest)); \ 88 } while (0) 89 90 /* 91 * TLS Policy support. 92 */ 93 #ifdef USE_TLS 94 95 typedef struct SMTP_TLS_POLICY { 96 int level; /* TLS enforcement level */ 97 char *protocols; /* Acceptable SSL protocols */ 98 char *grade; /* Cipher grade: "export", ... */ 99 VSTRING *exclusions; /* Excluded SSL ciphers */ 100 ARGV *matchargv; /* Cert match patterns */ 101 DSN_BUF *why; /* Lookup error status */ 102 TLS_DANE *dane; /* DANE TLSA digests */ 103 } SMTP_TLS_POLICY; 104 105 /* 106 * smtp_tls_policy.c 107 */ 108 extern void smtp_tls_list_init(void); 109 extern int smtp_tls_policy_cache_query(DSN_BUF *, SMTP_TLS_POLICY *, SMTP_ITERATOR *); 110 extern void smtp_tls_policy_cache_flush(void); 111 112 /* 113 * Macros must use distinct names for local temporary variables, otherwise 114 * there will be bugs due to shadowing. This happened when an earlier 115 * version of smtp_tls_policy_dummy() invoked smtp_tls_policy_init(), but it 116 * could also happen without macro nesting. 117 * 118 * General principle: use all or part of the macro name in each temporary 119 * variable name. Then, append suffixes to the names if needed. 120 */ 121 #define smtp_tls_policy_dummy(t) do { \ 122 SMTP_TLS_POLICY *_tls_policy_dummy_tmp = (t); \ 123 smtp_tls_policy_init(_tls_policy_dummy_tmp, (DSN_BUF *) 0); \ 124 _tls_policy_dummy_tmp->level = TLS_LEV_NONE; \ 125 } while (0) 126 127 /* This macro is not part of the module external interface. */ 128 #define smtp_tls_policy_init(t, w) do { \ 129 SMTP_TLS_POLICY *_tls_policy_init_tmp = (t); \ 130 _tls_policy_init_tmp->protocols = 0; \ 131 _tls_policy_init_tmp->grade = 0; \ 132 _tls_policy_init_tmp->exclusions = 0; \ 133 _tls_policy_init_tmp->matchargv = 0; \ 134 _tls_policy_init_tmp->why = (w); \ 135 _tls_policy_init_tmp->dane = 0; \ 136 } while (0) 137 138 #endif 139 140 /* 141 * State information associated with each SMTP delivery request. 142 * Session-specific state is stored separately. 143 */ 144 typedef struct SMTP_STATE { 145 int misc_flags; /* processing flags, see below */ 146 VSTREAM *src; /* queue file stream */ 147 const char *service; /* transport name */ 148 DELIVER_REQUEST *request; /* envelope info, offsets */ 149 struct SMTP_SESSION *session; /* network connection */ 150 int status; /* delivery status */ 151 ssize_t space_left; /* output length control */ 152 153 /* 154 * Global iterator. 155 */ 156 SMTP_ITERATOR iterator[1]; /* Usage: state->iterator->member */ 157 158 /* 159 * Global iterator. 160 */ 161 #ifdef USE_TLS 162 SMTP_TLS_POLICY tls[1]; /* Usage: state->tls->member */ 163 #endif 164 165 /* 166 * Connection cache support. 167 */ 168 HTABLE *cache_used; /* cached addresses that were used */ 169 VSTRING *dest_label; /* cached logical/physical binding */ 170 VSTRING *dest_prop; /* binding properties, passivated */ 171 VSTRING *endp_label; /* cached session physical endpoint */ 172 VSTRING *endp_prop; /* endpoint properties, passivated */ 173 174 /* 175 * Flags and counters to control the handling of mail delivery errors. 176 * There is some redundancy for sanity checking. At the end of an SMTP 177 * session all recipients should be marked one way or the other. 178 */ 179 int rcpt_left; /* recipients left over */ 180 int rcpt_drop; /* recipients marked as drop */ 181 int rcpt_keep; /* recipients marked as keep */ 182 183 /* 184 * DSN Support introduced major bloat in error processing. 185 */ 186 DSN_BUF *why; /* on-the-fly formatting buffer */ 187 } SMTP_STATE; 188 189 /* 190 * TODO: use the new SMTP_ITER name space. 191 */ 192 #define SET_NEXTHOP_STATE(state, nexthop) { \ 193 vstring_strcpy((state)->iterator->request_nexthop, nexthop); \ 194 } 195 196 #define FREE_NEXTHOP_STATE(state) { \ 197 STR((state)->iterator->request_nexthop)[0] = 0; \ 198 } 199 200 #define HAVE_NEXTHOP_STATE(state) (STR((state)->iterator->request_nexthop)[0] != 0) 201 202 203 /* 204 * Server features. 205 */ 206 #define SMTP_FEATURE_ESMTP (1<<0) 207 #define SMTP_FEATURE_8BITMIME (1<<1) 208 #define SMTP_FEATURE_PIPELINING (1<<2) 209 #define SMTP_FEATURE_SIZE (1<<3) 210 #define SMTP_FEATURE_STARTTLS (1<<4) 211 #define SMTP_FEATURE_AUTH (1<<5) 212 #define SMTP_FEATURE_XFORWARD_NAME (1<<7) 213 #define SMTP_FEATURE_XFORWARD_ADDR (1<<8) 214 #define SMTP_FEATURE_XFORWARD_PROTO (1<<9) 215 #define SMTP_FEATURE_XFORWARD_HELO (1<<10) 216 #define SMTP_FEATURE_XFORWARD_DOMAIN (1<<11) 217 #define SMTP_FEATURE_BEST_MX (1<<12) /* for next-hop or fall-back */ 218 #define SMTP_FEATURE_RSET_REJECTED (1<<13) /* RSET probe rejected */ 219 #define SMTP_FEATURE_FROM_CACHE (1<<14) /* cached connection */ 220 #define SMTP_FEATURE_DSN (1<<15) /* DSN supported */ 221 #define SMTP_FEATURE_PIX_NO_ESMTP (1<<16) /* PIX smtp fixup mode */ 222 #define SMTP_FEATURE_PIX_DELAY_DOTCRLF (1<<17) /* PIX smtp fixup mode */ 223 #define SMTP_FEATURE_XFORWARD_PORT (1<<18) 224 #define SMTP_FEATURE_EARLY_TLS_MAIL_REPLY (1<<19) /* CVE-2009-3555 */ 225 #define SMTP_FEATURE_XFORWARD_IDENT (1<<20) 226 #define SMTP_FEATURE_SMTPUTF8 (1<<21) /* RFC 6531 */ 227 228 /* 229 * Features that passivate under the endpoint. 230 */ 231 #define SMTP_FEATURE_ENDPOINT_MASK \ 232 (~(SMTP_FEATURE_BEST_MX | SMTP_FEATURE_RSET_REJECTED \ 233 | SMTP_FEATURE_FROM_CACHE)) 234 235 /* 236 * Features that passivate under the logical destination. 237 */ 238 #define SMTP_FEATURE_DESTINATION_MASK (SMTP_FEATURE_BEST_MX) 239 240 /* 241 * Misc flags. 242 */ 243 #define SMTP_MISC_FLAG_LOOP_DETECT (1<<0) 244 #define SMTP_MISC_FLAG_IN_STARTTLS (1<<1) 245 #define SMTP_MISC_FLAG_FIRST_NEXTHOP (1<<2) 246 #define SMTP_MISC_FLAG_FINAL_NEXTHOP (1<<3) 247 #define SMTP_MISC_FLAG_FINAL_SERVER (1<<4) 248 #define SMTP_MISC_FLAG_CONN_LOAD (1<<5) 249 #define SMTP_MISC_FLAG_CONN_STORE (1<<6) 250 #define SMTP_MISC_FLAG_COMPLETE_SESSION (1<<7) 251 #define SMTP_MISC_FLAG_PREF_IPV6 (1<<8) 252 #define SMTP_MISC_FLAG_PREF_IPV4 (1<<9) 253 254 #define SMTP_MISC_FLAG_CONN_CACHE_MASK \ 255 (SMTP_MISC_FLAG_CONN_LOAD | SMTP_MISC_FLAG_CONN_STORE) 256 257 /* 258 * smtp.c 259 */ 260 #define SMTP_HAS_DSN(why) (STR((why)->status)[0] != 0) 261 #define SMTP_HAS_SOFT_DSN(why) (STR((why)->status)[0] == '4') 262 #define SMTP_HAS_HARD_DSN(why) (STR((why)->status)[0] == '5') 263 #define SMTP_HAS_LOOP_DSN(why) \ 264 (SMTP_HAS_DSN(why) && strcmp(STR((why)->status) + 1, ".4.6") == 0) 265 266 #define SMTP_SET_SOFT_DSN(why) (STR((why)->status)[0] = '4') 267 #define SMTP_SET_HARD_DSN(why) (STR((why)->status)[0] = '5') 268 269 extern int smtp_host_lookup_mask; /* host lookup methods to use */ 270 271 #define SMTP_HOST_FLAG_DNS (1<<0) 272 #define SMTP_HOST_FLAG_NATIVE (1<<1) 273 274 extern int smtp_dns_support; /* dns support level */ 275 276 #define SMTP_DNS_INVALID (-1) /* smtp_dns_support_level = <bogus> */ 277 #define SMTP_DNS_DISABLED 0 /* smtp_dns_support_level = disabled */ 278 #define SMTP_DNS_ENABLED 1 /* smtp_dns_support_level = enabled */ 279 #define SMTP_DNS_DNSSEC 2 /* smtp_dns_support_level = dnssec */ 280 281 extern SCACHE *smtp_scache; /* connection cache instance */ 282 extern STRING_LIST *smtp_cache_dest; /* cached destinations */ 283 284 extern MAPS *smtp_ehlo_dis_maps; /* ehlo keyword filter */ 285 286 extern MAPS *smtp_pix_bug_maps; /* PIX workarounds */ 287 288 extern MAPS *smtp_generic_maps; /* make internal address valid */ 289 extern int smtp_ext_prop_mask; /* address externsion propagation */ 290 extern unsigned smtp_dns_res_opt; /* DNS query flags */ 291 292 #ifdef USE_TLS 293 294 extern TLS_APPL_STATE *smtp_tls_ctx; /* client-side TLS engine */ 295 extern int smtp_tls_insecure_mx_policy; /* DANE post insecure MX? */ 296 297 #endif 298 299 extern HBC_CHECKS *smtp_header_checks; /* limited header checks */ 300 extern HBC_CHECKS *smtp_body_checks; /* limited body checks */ 301 302 /* 303 * smtp_session.c 304 */ 305 306 typedef struct SMTP_SESSION { 307 VSTREAM *stream; /* network connection */ 308 SMTP_ITERATOR *iterator; /* dest, host, addr, port */ 309 char *namaddr; /* mail exchanger */ 310 char *helo; /* helo response */ 311 unsigned port; /* network byte order */ 312 char *namaddrport; /* mail exchanger, incl. port */ 313 314 VSTRING *buffer; /* I/O buffer */ 315 VSTRING *scratch; /* scratch buffer */ 316 VSTRING *scratch2; /* scratch buffer */ 317 318 int features; /* server features */ 319 off_t size_limit; /* server limit or unknown */ 320 321 ARGV *history; /* transaction log */ 322 int error_mask; /* error classes */ 323 struct MIME_STATE *mime_state; /* mime state machine */ 324 325 int send_proto_helo; /* XFORWARD support */ 326 327 time_t expire_time; /* session reuse expiration time */ 328 int reuse_count; /* # of times reused (for logging) */ 329 int forbidden; /* No further I/O allowed */ 330 331 #ifdef USE_SASL_AUTH 332 char *sasl_mechanism_list; /* server mechanism list */ 333 char *sasl_username; /* client username */ 334 char *sasl_passwd; /* client password */ 335 struct XSASL_CLIENT *sasl_client; /* SASL internal state */ 336 VSTRING *sasl_reply; /* client response */ 337 #endif 338 339 /* 340 * TLS related state, don't forget to initialize in session_tls_init()! 341 */ 342 #ifdef USE_TLS 343 TLS_SESS_STATE *tls_context; /* TLS library session state */ 344 char *tls_nexthop; /* Nexthop domain for cert checks */ 345 int tls_retry_plain; /* Try plain when TLS handshake fails */ 346 #endif 347 348 SMTP_STATE *state; /* back link */ 349 } SMTP_SESSION; 350 351 extern SMTP_SESSION *smtp_session_alloc(VSTREAM *, SMTP_ITERATOR *, time_t, int); 352 extern void smtp_session_new_stream(SMTP_SESSION *, VSTREAM *, time_t, int); 353 extern int smtp_sess_plaintext_ok(SMTP_ITERATOR *, int); 354 extern void smtp_session_free(SMTP_SESSION *); 355 extern int smtp_session_passivate(SMTP_SESSION *, VSTRING *, VSTRING *); 356 extern SMTP_SESSION *smtp_session_activate(int, SMTP_ITERATOR *, VSTRING *, VSTRING *); 357 358 /* 359 * What's in a name? 360 */ 361 #define SMTP_HNAME(rr) (var_smtp_cname_overr ? (rr)->rname : (rr)->qname) 362 363 /* 364 * smtp_connect.c 365 */ 366 extern int smtp_connect(SMTP_STATE *); 367 368 /* 369 * smtp_proto.c 370 */ 371 extern void smtp_vrfy_init(void); 372 extern int smtp_helo(SMTP_STATE *); 373 extern int smtp_xfer(SMTP_STATE *); 374 extern int smtp_rset(SMTP_STATE *); 375 extern int smtp_quit(SMTP_STATE *); 376 377 extern HBC_CALL_BACKS smtp_hbc_callbacks[]; 378 379 /* 380 * A connection is re-usable if session->expire_time is > 0 and the 381 * expiration time has not been reached. This is subtle because the timer 382 * can expire between sending a command and receiving the reply for that 383 * command. 384 * 385 * But wait, there is more! When SMTP command pipelining is enabled, there are 386 * two protocol loops that execute at very different times: one loop that 387 * generates commands, and one loop that receives replies to those commands. 388 * These will be called "sender loop" and "receiver loop", respectively. At 389 * well-defined protocol synchronization points, the sender loop pauses to 390 * let the receiver loop catch up. 391 * 392 * When we choose to reuse a connection, both the sender and receiver protocol 393 * loops end with "." (mail delivery) or "RSET" (address probe). When we 394 * choose not to reuse, both the sender and receiver protocol loops end with 395 * "QUIT". The problem is that we must make the same protocol choices in 396 * both the sender and receiver loops, even though those loops may execute 397 * at completely different times. 398 * 399 * We "freeze" the choice in the sender loop, just before we generate "." or 400 * "RSET". The reader loop leaves the connection cachable even if the timer 401 * expires by the time the response arrives. The connection cleanup code 402 * will call smtp_quit() for connections with an expired cache expiration 403 * timer. 404 * 405 * We could have made the programmer's life a lot simpler by not making a 406 * choice at all, and always leaving it up to the connection cleanup code to 407 * call smtp_quit() for connections with an expired cache expiration timer. 408 * 409 * As a general principle, neither the sender loop nor the receiver loop must 410 * modify the connection caching state, if that can affect the receiver 411 * state machine for not-yet processed replies to already-generated 412 * commands. This restriction does not apply when we have to exit the 413 * protocol loops prematurely due to e.g., timeout or connection loss, so 414 * that those pending replies will never be received. 415 * 416 * But wait, there is even more! Only the first good connection for a specific 417 * destination may be cached under both the next-hop destination name and 418 * the server address; connections to alternate servers must be cached under 419 * the server address alone. This means we must distinguish between bad 420 * connections and other reasons why connections cannot be cached. 421 */ 422 #define THIS_SESSION_IS_CACHED \ 423 (!THIS_SESSION_IS_FORBIDDEN && session->expire_time > 0) 424 425 #define THIS_SESSION_IS_EXPIRED \ 426 (THIS_SESSION_IS_CACHED \ 427 && (session->expire_time < vstream_ftime(session->stream) \ 428 || (var_smtp_reuse_count > 0 \ 429 && session->reuse_count >= var_smtp_reuse_count))) 430 431 #define THIS_SESSION_IS_THROTTLED \ 432 (!THIS_SESSION_IS_FORBIDDEN && session->expire_time < 0) 433 434 #define THIS_SESSION_IS_FORBIDDEN \ 435 (session->forbidden != 0) 436 437 /* Bring the bad news. */ 438 439 #define DONT_CACHE_THIS_SESSION \ 440 (session->expire_time = 0) 441 442 #define DONT_CACHE_THROTTLED_SESSION \ 443 (session->expire_time = -1) 444 445 #define DONT_USE_FORBIDDEN_SESSION \ 446 (session->forbidden = 1) 447 448 /* Initialization. */ 449 450 #define USE_NEWBORN_SESSION \ 451 (session->forbidden = 0) 452 453 #define CACHE_THIS_SESSION_UNTIL(when) \ 454 (session->expire_time = (when)) 455 456 /* 457 * Encapsulate the following so that we don't expose details of of 458 * connection management and error handling to the SMTP protocol engine. 459 */ 460 #ifdef USE_SASL_AUTH 461 #define HAVE_SASL_CREDENTIALS \ 462 (var_smtp_sasl_enable \ 463 && *var_smtp_sasl_passwd \ 464 && smtp_sasl_passwd_lookup(session)) 465 #else 466 #define HAVE_SASL_CREDENTIALS (0) 467 #endif 468 469 #define PREACTIVE_DELAY \ 470 (session->state->request->msg_stats.active_arrival.tv_sec - \ 471 session->state->request->msg_stats.incoming_arrival.tv_sec) 472 473 #define PLAINTEXT_FALLBACK_OK_AFTER_STARTTLS_FAILURE \ 474 (session->tls_context == 0 \ 475 && state->tls->level == TLS_LEV_MAY \ 476 && PREACTIVE_DELAY >= var_min_backoff_time \ 477 && !HAVE_SASL_CREDENTIALS) 478 479 #define PLAINTEXT_FALLBACK_OK_AFTER_TLS_SESSION_FAILURE \ 480 (session->tls_context != 0 \ 481 && SMTP_RCPT_LEFT(state) > SMTP_RCPT_MARK_COUNT(state) \ 482 && state->tls->level == TLS_LEV_MAY \ 483 && PREACTIVE_DELAY >= var_min_backoff_time \ 484 && !HAVE_SASL_CREDENTIALS) 485 486 /* 487 * XXX The following will not retry recipients that were deferred while the 488 * SMTP_MISC_FLAG_FINAL_SERVER flag was already set. This includes the case 489 * when TLS fails in the middle of a delivery. 490 */ 491 #define RETRY_AS_PLAINTEXT do { \ 492 session->tls_retry_plain = 1; \ 493 state->misc_flags &= ~SMTP_MISC_FLAG_FINAL_SERVER; \ 494 } while (0) 495 496 /* 497 * smtp_chat.c 498 */ 499 typedef struct SMTP_RESP { /* server response */ 500 int code; /* SMTP code */ 501 const char *dsn; /* enhanced status */ 502 char *str; /* full reply */ 503 VSTRING *dsn_buf; /* status buffer */ 504 VSTRING *str_buf; /* reply buffer */ 505 } SMTP_RESP; 506 507 extern void PRINTFLIKE(2, 3) smtp_chat_cmd(SMTP_SESSION *, const char *,...); 508 extern DICT *smtp_chat_resp_filter; 509 extern SMTP_RESP *smtp_chat_resp(SMTP_SESSION *); 510 extern void smtp_chat_init(SMTP_SESSION *); 511 extern void smtp_chat_reset(SMTP_SESSION *); 512 extern void smtp_chat_notify(SMTP_SESSION *); 513 514 #define SMTP_RESP_FAKE(resp, _dsn) \ 515 ((resp)->code = 0, \ 516 (resp)->dsn = (_dsn), \ 517 (resp)->str = DSN_BY_LOCAL_MTA, \ 518 (resp)) 519 520 #define DSN_BY_LOCAL_MTA ((char *) 0) /* DSN issued by local MTA */ 521 522 #define SMTP_RESP_SET_DSN(resp, _dsn) do { \ 523 vstring_strcpy((resp)->dsn_buf, (_dsn)); \ 524 (resp)->dsn = STR((resp)->dsn_buf); \ 525 } while (0) 526 527 /* 528 * These operations implement a redundant mark-and-sweep algorithm that 529 * explicitly accounts for the fate of every recipient. The interface is 530 * documented in smtp_rcpt.c, which also implements the sweeping. The 531 * smtp_trouble.c module does most of the marking after failure. 532 * 533 * When a delivery fails or succeeds, take one of the following actions: 534 * 535 * - Mark the recipient as KEEP (deliver to alternate MTA) and do not update 536 * the delivery request status. 537 * 538 * - Mark the recipient as DROP (remove from delivery request), log whether 539 * delivery succeeded or failed, delete the recipient from the queue file 540 * and/or update defer or bounce logfiles, and update the delivery request 541 * status. 542 * 543 * At the end of a delivery attempt, all recipients must be marked one way or 544 * the other. Failure to do so will trigger a panic. 545 */ 546 #define SMTP_RCPT_STATE_KEEP 1 /* send to backup host */ 547 #define SMTP_RCPT_STATE_DROP 2 /* remove from request */ 548 #define SMTP_RCPT_INIT(state) do { \ 549 (state)->rcpt_drop = (state)->rcpt_keep = 0; \ 550 (state)->rcpt_left = state->request->rcpt_list.len; \ 551 } while (0) 552 553 #define SMTP_RCPT_DROP(state, rcpt) do { \ 554 (rcpt)->u.status = SMTP_RCPT_STATE_DROP; (state)->rcpt_drop++; \ 555 } while (0) 556 557 #define SMTP_RCPT_KEEP(state, rcpt) do { \ 558 (rcpt)->u.status = SMTP_RCPT_STATE_KEEP; (state)->rcpt_keep++; \ 559 } while (0) 560 561 #define SMTP_RCPT_ISMARKED(rcpt) ((rcpt)->u.status != 0) 562 563 #define SMTP_RCPT_LEFT(state) (state)->rcpt_left 564 565 #define SMTP_RCPT_MARK_COUNT(state) ((state)->rcpt_drop + (state)->rcpt_keep) 566 567 extern void smtp_rcpt_cleanup(SMTP_STATE *); 568 extern void smtp_rcpt_done(SMTP_STATE *, SMTP_RESP *, RECIPIENT *); 569 570 /* 571 * smtp_trouble.c 572 */ 573 #define SMTP_THROTTLE 1 574 #define SMTP_NOTHROTTLE 0 575 extern int smtp_sess_fail(SMTP_STATE *); 576 extern int PRINTFLIKE(5, 6) smtp_misc_fail(SMTP_STATE *, int, const char *, 577 SMTP_RESP *, const char *,...); 578 extern void PRINTFLIKE(5, 6) smtp_rcpt_fail(SMTP_STATE *, RECIPIENT *, 579 const char *, SMTP_RESP *, 580 const char *,...); 581 extern int smtp_stream_except(SMTP_STATE *, int, const char *); 582 583 #define smtp_site_fail(state, mta, resp, ...) \ 584 smtp_misc_fail((state), SMTP_THROTTLE, (mta), (resp), __VA_ARGS__) 585 #define smtp_mesg_fail(state, mta, resp, ...) \ 586 smtp_misc_fail((state), SMTP_NOTHROTTLE, (mta), (resp), __VA_ARGS__) 587 588 /* 589 * smtp_unalias.c 590 */ 591 extern const char *smtp_unalias_name(const char *); 592 extern VSTRING *smtp_unalias_addr(VSTRING *, const char *); 593 594 /* 595 * smtp_state.c 596 */ 597 extern SMTP_STATE *smtp_state_alloc(void); 598 extern void smtp_state_free(SMTP_STATE *); 599 600 /* 601 * smtp_map11.c 602 */ 603 extern int smtp_map11_external(VSTRING *, MAPS *, int); 604 extern int smtp_map11_tree(TOK822 *, MAPS *, int); 605 extern int smtp_map11_internal(VSTRING *, MAPS *, int); 606 607 /* 608 * smtp_key.c 609 */ 610 char *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int); 611 612 #define SMTP_KEY_FLAG_SERVICE (1<<0) /* service name */ 613 #define SMTP_KEY_FLAG_SENDER (1<<1) /* sender address */ 614 #define SMTP_KEY_FLAG_REQ_NEXTHOP (1<<2) /* request nexthop */ 615 #define SMTP_KEY_FLAG_NEXTHOP (1<<3) /* current nexthop */ 616 #define SMTP_KEY_FLAG_HOSTNAME (1<<4) /* remote host name */ 617 #define SMTP_KEY_FLAG_ADDR (1<<5) /* remote address */ 618 #define SMTP_KEY_FLAG_PORT (1<<6) /* remote port */ 619 620 #define SMTP_KEY_MASK_ALL \ 621 (SMTP_KEY_FLAG_SERVICE | SMTP_KEY_FLAG_SENDER | \ 622 SMTP_KEY_FLAG_REQ_NEXTHOP | \ 623 SMTP_KEY_FLAG_NEXTHOP | SMTP_KEY_FLAG_HOSTNAME | \ 624 SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT) 625 626 /* 627 * Conditional lookup-key flags for cached connections that may be 628 * SASL-authenticated with a per-{sender, nexthop, or hostname} credential. 629 * Each bit corresponds to one type of smtp_sasl_password_file lookup key, 630 * and is turned on only when the corresponding main.cf parameter is turned 631 * on. 632 */ 633 #define COND_SASL_SMTP_KEY_FLAG_SENDER \ 634 ((var_smtp_sender_auth && *var_smtp_sasl_passwd) ? \ 635 SMTP_KEY_FLAG_SENDER : 0) 636 637 #define COND_SASL_SMTP_KEY_FLAG_NEXTHOP \ 638 (*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_NEXTHOP : 0) 639 640 #define COND_SASL_SMTP_KEY_FLAG_HOSTNAME \ 641 (*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_HOSTNAME : 0) 642 643 /* 644 * Connection-cache destination lookup key. The SENDER attribute is a proxy 645 * for sender-dependent SASL credentials (or absence thereof), and prevents 646 * false connection sharing when different SASL credentials may be required 647 * for different deliveries to the same domain and port. The SERVICE 648 * attribute is a proxy for all request-independent configuration details. 649 */ 650 #define SMTP_KEY_MASK_SCACHE_DEST_LABEL \ 651 (SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \ 652 | SMTP_KEY_FLAG_REQ_NEXTHOP) 653 654 /* 655 * Connection-cache endpoint lookup key. The SENDER, NEXTHOP, and HOSTNAME 656 * attributes are proxies for SASL credentials (or absence thereof), and 657 * prevent false connection sharing when different SASL credentials may be 658 * required for different deliveries to the same IP address and port. 659 */ 660 #define SMTP_KEY_MASK_SCACHE_ENDP_LABEL \ 661 (SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \ 662 | COND_SASL_SMTP_KEY_FLAG_NEXTHOP | COND_SASL_SMTP_KEY_FLAG_HOSTNAME \ 663 | SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT) 664 665 /* 666 * Silly little macros. 667 */ 668 #define STR(s) vstring_str(s) 669 #define LEN(s) VSTRING_LEN(s) 670 671 extern int smtp_mode; 672 673 #define VAR_LMTP_SMTP(x) (smtp_mode ? VAR_SMTP_##x : VAR_LMTP_##x) 674 #define LMTP_SMTP_SUFFIX(x) (smtp_mode ? x##_SMTP : x##_LMTP) 675 676 /* LICENSE 677 /* .ad 678 /* .fi 679 /* The Secure Mailer license must be distributed with this software. 680 /* AUTHOR(S) 681 /* Wietse Venema 682 /* IBM T.J. Watson Research 683 /* P.O. Box 704 684 /* Yorktown Heights, NY 10598, USA 685 /* 686 /* TLS support originally by: 687 /* Lutz Jaenicke 688 /* BTU Cottbus 689 /* Allgemeine Elektrotechnik 690 /* Universitaetsplatz 3-4 691 /* D-03044 Cottbus, Germany 692 /* 693 /* Victor Duchovni 694 /* Morgan Stanley 695 /*--*/ 696