static void smtp_connect_local(SMTP_STATE *state, const char *path) { const char *myname = "smtp_connect_local"; SMTP_ITERATOR *iter = state->iterator; SMTP_SESSION *session; DSN_BUF *why = state->why; /* * Do not silently ignore an unused setting. */ if (*var_fallback_relay) msg_warn("ignoring \"%s = %s\" setting for non-TCP connections", VAR_LMTP_FALLBACK, var_fallback_relay); /* * It's too painful to weave this code into the SMTP connection * management routine. * * Connection cache management is based on the UNIX-domain pathname, without * the "unix:" prefix. */ smtp_cache_policy(state, path); /* * Here we ensure that the iter->addr member refers to a copy of the * UNIX-domain pathname, so that smtp_save_session() will cache the * connection using the pathname as the physical endpoint name. * * We set dest=path for backwards compatibility. */ #define NO_PORT 0 SMTP_ITER_INIT(iter, path, var_myhostname, path, NO_PORT, state); /* * Opportunistic TLS for unix domain sockets does not make much sense, * since the channel is private, mere encryption without authentication * is just wasted cycles and opportunity for breakage. Since we are not * willing to retry after TLS handshake failures here, we downgrade "may" * no "none". Nothing is lost, and much waste is avoided. * * We don't know who is authenticating whom, so if a client cert is * available, "encrypt" may be a sensible policy. Otherwise, we also * downgrade "encrypt" to "none", this time just to avoid waste. * * We use smtp_reuse_nexthop() instead of smtp_reuse_addr(), so that we can * reuse a SASL-authenticated connection (however unlikely this scenario * may be). The smtp_reuse_addr() interface currently supports only reuse * of SASL-unauthenticated connections. */ #ifdef USE_TLS if (!smtp_tls_policy_cache_query(why, state->tls, iter)) { msg_warn("TLS policy lookup error for %s/%s: %s", STR(iter->host), STR(iter->addr), STR(why->reason)); return; } #endif if ((state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD) == 0 || (session = smtp_reuse_nexthop(state, SMTP_KEY_MASK_SCACHE_DEST_LABEL)) == 0) session = smtp_connect_unix(iter, why, state->misc_flags); if ((state->session = session) != 0) { session->state = state; #ifdef USE_TLS session->tls_nexthop = var_myhostname; /* for TLS_LEV_SECURE */ if (state->tls->level == TLS_LEV_MAY) { msg_warn("%s: opportunistic TLS encryption is not appropriate " "for unix-domain destinations.", myname); state->tls->level = TLS_LEV_NONE; } #endif /* All delivery errors bounce or defer. */ state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER; /* * When a TLS handshake fails, the stream is marked "dead" to avoid * further I/O over a broken channel. */ if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0 && smtp_helo(state) != 0) { if (!THIS_SESSION_IS_FORBIDDEN && vstream_ferror(session->stream) == 0 && vstream_feof(session->stream) == 0) smtp_quit(state); } else { smtp_xfer(state); } /* * With opportunistic TLS disabled we don't expect to be asked to * retry connections without TLS, and so we expect the final server * flag to stay on. */ if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_SERVER) == 0) msg_panic("%s: unix-domain destination not final!", myname); smtp_cleanup_session(state); } }
static void smtp_connect_local(SMTP_STATE *state, const char *path) { const char *myname = "smtp_connect_local"; SMTP_SESSION *session; DSN_BUF *why = state->why; /* * It's too painful to weave this code into the SMTP connection * management routine. * * Connection cache management is based on the UNIX-domain pathname, without * the "unix:" prefix. */ smtp_cache_policy(state, path); /* * XXX We assume that the session->addr member refers to a copy of the * UNIX-domain pathname, so that smtp_save_session() will cache the * connection using the pathname as the physical endpoint name. */ #define NO_PORT 0 /* * Opportunistic TLS for unix domain sockets does not make much sense, * since the channel is private, mere encryption without authentication * is just wasted cycles and opportunity for breakage. Since we are not * willing to retry after TLS handshake failures here, we downgrade "may" * no "none". Nothing is lost, and much waste is avoided. * * We don't know who is authenticating whom, so if a client cert is * available, "encrypt" may be a sensible policy. Otherwise, we also * downgrade "encrypt" to "none", this time just to avoid waste. */ if ((state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD) == 0 || (session = smtp_reuse_addr(state, path, NO_PORT)) == 0) session = smtp_connect_unix(path, why, state->misc_flags); if ((state->session = session) != 0) { session->state = state; #ifdef USE_TLS session->tls_nexthop = var_myhostname; /* for TLS_LEV_SECURE */ if (session->tls_level == TLS_LEV_MAY) { msg_warn("%s: opportunistic TLS encryption is not appropriate " "for unix-domain destinations.", myname); session->tls_level = TLS_LEV_NONE; } #endif /* All delivery errors bounce or defer. */ state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER; /* * When a TLS handshake fails, the stream is marked "dead" to avoid * further I/O over a broken channel. */ if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0 && smtp_helo(state) != 0) { if (!THIS_SESSION_IS_DEAD && vstream_ferror(session->stream) == 0 && vstream_feof(session->stream) == 0) smtp_quit(state); } else { smtp_xfer(state); } /* * With opportunistic TLS disabled we don't expect to be asked to * retry connections without TLS, and so we expect the final server * flag to stay on. */ if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_SERVER) == 0) msg_panic("%s: unix-domain destination not final!", myname); smtp_cleanup_session(state); } }