mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 06:05:37 +00:00
postfix-2.11-20130403
This commit is contained in:
committed by
Viktor Dukhovni
parent
fc52b35219
commit
46a1d9a44f
@@ -18400,3 +18400,13 @@ Apologies for any names omitted.
|
|||||||
|
|
||||||
Cleanup: "zero time limit" corner case in read_wait() and
|
Cleanup: "zero time limit" corner case in read_wait() and
|
||||||
write_wait() emulation. Files: util/poll_fd.c, util/iostuff.h.
|
write_wait() emulation. Files: util/poll_fd.c, util/iostuff.h.
|
||||||
|
|
||||||
|
20130401
|
||||||
|
|
||||||
|
Refactoring: allow smtp_session_alloc() to fail gracefully
|
||||||
|
and report an error.
|
||||||
|
|
||||||
|
20130403
|
||||||
|
|
||||||
|
Documentation: in smtpd.c, the comment that justifies the
|
||||||
|
454 reply for "TLS unavailable" cited the wrong RFC.
|
||||||
|
@@ -8,6 +8,49 @@ Wish list:
|
|||||||
|
|
||||||
Spellcheck and double-word check.
|
Spellcheck and double-word check.
|
||||||
|
|
||||||
|
Begin code revision, after DANE support stabilizes. This
|
||||||
|
should be one pass that changes only names and no code.
|
||||||
|
|
||||||
|
Generally, macro and function names should make a program
|
||||||
|
more clear, not merely reduce the number of programmer
|
||||||
|
keystrokes; similar considerations hold for variable names
|
||||||
|
and constants. Avoid 1-letter names except "for i=1 to
|
||||||
|
some_bound". Instead of bare numbers use named constants
|
||||||
|
in function argument lists.
|
||||||
|
|
||||||
|
Code clarity: replace "valid" with or "dnssec_valid".
|
||||||
|
|
||||||
|
Code clarity: replace obscure macro/function names: for
|
||||||
|
example SMTP_X(XXX) -> VAR_SMTP(XXX), as the purpose is to
|
||||||
|
choose between VAR_SMTP_XXX or VAR_LMTP_XXX; replace
|
||||||
|
digestpl() etc. with names that make clear what operation
|
||||||
|
is being performed (in this case, update a digest with the
|
||||||
|
contents of a buffer with the specified length). Replace r
|
||||||
|
with res_opt, ditto for other 1-letter names.
|
||||||
|
|
||||||
|
Code consistency: replace the VSTRING-based digest output
|
||||||
|
loop with a tls_digest_encode() call.
|
||||||
|
|
||||||
|
Code clarity: rename tls_fingerprint() to tls_cert_fprint()
|
||||||
|
(compute certifate fingerprint). Keep tls_pkey_fprint()
|
||||||
|
(compute public-key fingerprint). Rename tls_fprint() to
|
||||||
|
tls_data_fprint() (compute fingerprint for arbitrary data).
|
||||||
|
|
||||||
|
Collect SMTP client connection-management state in one
|
||||||
|
iterator object, that provides the same information for
|
||||||
|
SMTP reuse policy, TLS policy, and SASL password lookups.
|
||||||
|
|
||||||
|
Unnecessary complexity: the SMTP_SESSION "tls" field is
|
||||||
|
mandatory (always allocated) therefore the content can be
|
||||||
|
a permanent part of the SMTP_SESSION structure, just like
|
||||||
|
SASL-related information. This avoids silly indirections
|
||||||
|
all over the code, as well as awkward smtp_tls_sess_alloc()
|
||||||
|
error semantics.
|
||||||
|
|
||||||
|
Provide an iterator object API that provides consistent
|
||||||
|
search key generation for SMTP reuse policy, TLS policy,
|
||||||
|
and SASL password lookups.
|
||||||
|
|
||||||
We have smtp_host_lookup, smtp_dns_resolver_options, and
|
We have smtp_host_lookup, smtp_dns_resolver_options, and
|
||||||
now smtp_dns_support_level. Of these, smtp_dns_resolver_options
|
now smtp_dns_support_level. Of these, smtp_dns_resolver_options
|
||||||
is orthogonal but the rest has overlap.
|
is orthogonal but the rest has overlap.
|
||||||
@@ -18,6 +61,8 @@ Wish list:
|
|||||||
for several releases before the deprecated feature can be
|
for several releases before the deprecated feature can be
|
||||||
removed.
|
removed.
|
||||||
|
|
||||||
|
End code revision, after DANE support stabilizes.
|
||||||
|
|
||||||
It would be nice if the result from one table lookup could
|
It would be nice if the result from one table lookup could
|
||||||
serve as input for another (e.g. virtual aliases before the
|
serve as input for another (e.g. virtual aliases before the
|
||||||
list of valid recipients). For this to work the magical
|
list of valid recipients). For this to work the magical
|
||||||
|
@@ -462,12 +462,10 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
|
|||||||
: ${CC=cc}
|
: ${CC=cc}
|
||||||
CCARGS="$CCARGS \$(WARN)"
|
CCARGS="$CCARGS \$(WARN)"
|
||||||
# Darwin > 1.3 uses awk and flat_namespace
|
# Darwin > 1.3 uses awk and flat_namespace
|
||||||
# MacOS X 10.8.x (Darwin 12.x) needs libresolv, likely much
|
|
||||||
# older earlier also, but I don't have access to test systems.
|
|
||||||
case $RELEASE in
|
case $RELEASE in
|
||||||
1.[0-3]) AWK=gawk;;
|
1.[0-3]) AWK=gawk;;
|
||||||
?.*|1[0-1].*) AWK=awk; SYSLIBS="-flat_namespace";;
|
*) AWK=awk
|
||||||
*) AWK=awk; SYSLIBS="-lresolv -flat_namespace";;
|
SYSLIBS="$SYSLIBS -flat_namespace";;
|
||||||
esac
|
esac
|
||||||
# Darwin 7 adds IPv6 support, BIND_8_COMPAT, NO_NETINFO
|
# Darwin 7 adds IPv6 support, BIND_8_COMPAT, NO_NETINFO
|
||||||
case $RELEASE in
|
case $RELEASE in
|
||||||
@@ -483,6 +481,11 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
|
|||||||
?.*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_NAMESER8_COMPAT_H";;
|
?.*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_NAMESER8_COMPAT_H";;
|
||||||
*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_ARPA_NAMESER_COMPAT_H";;
|
*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_ARPA_NAMESER_COMPAT_H";;
|
||||||
esac
|
esac
|
||||||
|
# Darwin 12.x (MacOS X 10.8.x), maybe earlier, needs libresolv.
|
||||||
|
case $RELEASE in
|
||||||
|
?.*|1[0-1].*) ;;
|
||||||
|
*) SYSLIBS="$SYSLIBS -lresolv";;
|
||||||
|
esac
|
||||||
# kqueue and/or poll are broken in MacOS X 10.5 (Darwin 9).
|
# kqueue and/or poll are broken in MacOS X 10.5 (Darwin 9).
|
||||||
# kqueue works in Mac OS X 10.8 (Darwin 12).
|
# kqueue works in Mac OS X 10.8 (Darwin 12).
|
||||||
case $RELEASE in
|
case $RELEASE in
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20130331"
|
#define MAIL_RELEASE_DATE "20130403"
|
||||||
#define MAIL_VERSION_NUMBER "2.11"
|
#define MAIL_VERSION_NUMBER "2.11"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@@ -149,6 +149,7 @@ typedef struct SMTP_STATE {
|
|||||||
#define SMTP_MISC_FLAG_COMPLETE_SESSION (1<<8)
|
#define SMTP_MISC_FLAG_COMPLETE_SESSION (1<<8)
|
||||||
#define SMTP_MISC_FLAG_PREF_IPV6 (1<<9)
|
#define SMTP_MISC_FLAG_PREF_IPV6 (1<<9)
|
||||||
#define SMTP_MISC_FLAG_PREF_IPV4 (1<<10)
|
#define SMTP_MISC_FLAG_PREF_IPV4 (1<<10)
|
||||||
|
#define SMTP_MISC_FLAG_NO_TLS (1<<11)
|
||||||
|
|
||||||
#define SMTP_MISC_FLAG_CONN_CACHE_MASK \
|
#define SMTP_MISC_FLAG_CONN_CACHE_MASK \
|
||||||
(SMTP_MISC_FLAG_CONN_LOAD | SMTP_MISC_FLAG_CONN_STORE)
|
(SMTP_MISC_FLAG_CONN_LOAD | SMTP_MISC_FLAG_CONN_STORE)
|
||||||
@@ -259,19 +260,21 @@ typedef struct SMTP_SESSION {
|
|||||||
SMTP_STATE *state; /* back link */
|
SMTP_STATE *state; /* back link */
|
||||||
} SMTP_SESSION;
|
} SMTP_SESSION;
|
||||||
|
|
||||||
extern SMTP_SESSION *smtp_session_alloc(VSTREAM *, const char *, const char *,
|
extern SMTP_SESSION *smtp_session_alloc(DSN_BUF *, const char *, const char *,
|
||||||
const char *, unsigned, time_t, int);
|
const char *, unsigned, int);
|
||||||
|
extern void smtp_session_new_stream(SMTP_SESSION *, VSTREAM *, time_t, int);
|
||||||
|
extern int smtp_sess_tls_check(const char *, const char *, unsigned, int);
|
||||||
extern void smtp_session_free(SMTP_SESSION *);
|
extern void smtp_session_free(SMTP_SESSION *);
|
||||||
extern int smtp_session_passivate(SMTP_SESSION *, VSTRING *, VSTRING *);
|
extern int smtp_session_passivate(SMTP_SESSION *, VSTRING *, VSTRING *);
|
||||||
extern SMTP_SESSION *smtp_session_activate(int, VSTRING *, VSTRING *);
|
extern SMTP_SESSION *smtp_session_activate(int, VSTRING *, VSTRING *);
|
||||||
|
|
||||||
#ifdef USE_TLS
|
#ifdef USE_TLS
|
||||||
extern void smtp_tls_list_init(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* smtp_tls_sess.c
|
* smtp_tls_sess.c
|
||||||
*/
|
*/
|
||||||
extern SMTP_TLS_SESS *smtp_tls_sess_alloc(const char *, const char *,
|
extern void smtp_tls_list_init(void);
|
||||||
|
extern SMTP_TLS_SESS *smtp_tls_sess_alloc(DSN_BUF *, const char *, const char *,
|
||||||
unsigned, int);
|
unsigned, int);
|
||||||
extern SMTP_TLS_SESS *smtp_tls_sess_free(SMTP_TLS_SESS *);
|
extern SMTP_TLS_SESS *smtp_tls_sess_free(SMTP_TLS_SESS *);
|
||||||
|
|
||||||
|
@@ -293,6 +293,17 @@ static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr * sa,
|
|||||||
int saved_errno;
|
int saved_errno;
|
||||||
VSTREAM *stream;
|
VSTREAM *stream;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
|
SMTP_SESSION *session;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Session construction is cheap, and can now tempfail when TLSA lookups
|
||||||
|
* don't work at the DANE security level. This also handles table lookup
|
||||||
|
* errors more gracefully. So construct the session, and then connect. If
|
||||||
|
* the connection fails, tear down the session.
|
||||||
|
*/
|
||||||
|
if ((session = smtp_session_alloc(why, destination, name, addr,
|
||||||
|
port, sess_flags)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
start_time = time((time_t *) 0);
|
start_time = time((time_t *) 0);
|
||||||
if (var_smtp_conn_tmout > 0) {
|
if (var_smtp_conn_tmout > 0) {
|
||||||
@@ -311,6 +322,7 @@ static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr * sa,
|
|||||||
else
|
else
|
||||||
dsb_simple(why, "4.4.1", "connect to %s[%s]: %m", name, addr);
|
dsb_simple(why, "4.4.1", "connect to %s[%s]: %m", name, addr);
|
||||||
close(sock);
|
close(sock);
|
||||||
|
smtp_session_free(session);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
stream = vstream_fdopen(sock, O_RDWR);
|
stream = vstream_fdopen(sock, O_RDWR);
|
||||||
@@ -326,10 +338,13 @@ static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr * sa,
|
|||||||
vstream_tweak_tcp(stream);
|
vstream_tweak_tcp(stream);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bundle up what we have into a nice SMTP_SESSION object.
|
* Update the SMTP_SESSION state with this newly-created stream, and make
|
||||||
|
* it subject to the new-stream connection caching policy (as opposed to
|
||||||
|
* the reused-stream caching policy).
|
||||||
*/
|
*/
|
||||||
return (smtp_session_alloc(stream, destination, name, addr,
|
smtp_session_new_stream(session, stream, start_time, sess_flags);
|
||||||
port, start_time, sess_flags));
|
|
||||||
|
return (session);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* smtp_parse_destination - parse host/port destination */
|
/* smtp_parse_destination - parse host/port destination */
|
||||||
|
@@ -274,6 +274,7 @@ SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, const char *addr,
|
|||||||
* credentials or the wrong TLS policy.
|
* credentials or the wrong TLS policy.
|
||||||
*/
|
*/
|
||||||
if ((var_smtp_tls_per_site && *var_smtp_tls_per_site)
|
if ((var_smtp_tls_per_site && *var_smtp_tls_per_site)
|
||||||
|
|| (var_smtp_tls_policy && *var_smtp_tls_policy)
|
||||||
|| (var_smtp_sasl_passwd && *var_smtp_sasl_passwd))
|
|| (var_smtp_sasl_passwd && *var_smtp_sasl_passwd))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
@@ -6,16 +6,27 @@
|
|||||||
/* SYNOPSIS
|
/* SYNOPSIS
|
||||||
/* #include "smtp.h"
|
/* #include "smtp.h"
|
||||||
/*
|
/*
|
||||||
/* SMTP_SESSION *smtp_session_alloc(stream, dest, host, addr,
|
/* SMTP_SESSION *smtp_session_alloc(why, dest, host, addr,
|
||||||
/* port, start, flags)
|
/* port, flags)
|
||||||
/* VSTREAM *stream;
|
/* DSN_BUF *why;
|
||||||
/* char *dest;
|
/* char *dest;
|
||||||
/* char *host;
|
/* char *host;
|
||||||
/* char *addr;
|
/* char *addr;
|
||||||
/* unsigned port;
|
/* unsigned port;
|
||||||
|
/* int flags;
|
||||||
|
/*
|
||||||
|
/* void smtp_session_new_stream(session, stream, start, flags)
|
||||||
|
/* SMTP_SESSION *session;
|
||||||
|
/* VSTREAM *stream;
|
||||||
/* time_t start;
|
/* time_t start;
|
||||||
/* int flags;
|
/* int flags;
|
||||||
/*
|
/*
|
||||||
|
/* int smtp_sess_tls_check(dest, host, port, valid)
|
||||||
|
/* char *dest;
|
||||||
|
/* char *host;
|
||||||
|
/* unsigned port;
|
||||||
|
/* int valid;
|
||||||
|
/*
|
||||||
/* void smtp_session_free(session)
|
/* void smtp_session_free(session)
|
||||||
/* SMTP_SESSION *session;
|
/* SMTP_SESSION *session;
|
||||||
/*
|
/*
|
||||||
@@ -30,13 +41,24 @@
|
|||||||
/* VSTRING *endp_prop;
|
/* VSTRING *endp_prop;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* smtp_session_alloc() allocates memory for an SMTP_SESSION structure
|
/* smtp_session_alloc() allocates memory for an SMTP_SESSION structure
|
||||||
/* and initializes it with the given stream and destination, host name
|
/* and initializes it with the given destination, host name and address
|
||||||
/* and address information. The host name and address strings are
|
/* information. The host name and address strings are copied. The port
|
||||||
/* copied. The port is in network byte order.
|
/* is in network byte order. When TLS is enabled, smtp_session_alloc()
|
||||||
/* When TLS is enabled, smtp_session_alloc() looks up the
|
/* looks up the per-site TLS policies for TLS enforcement and certificate
|
||||||
/* per-site TLS policies for TLS enforcement and certificate
|
/* verification. The resulting policy is stored into the SMTP_SESSION
|
||||||
/* verification. The resulting policy is stored into the
|
/* object. Table and DNS lookups can fail during TLS policy creation,
|
||||||
/* SMTP_SESSION object.
|
/* when this happens, "why" is updated with the error reason and a null
|
||||||
|
/* session pointer is returned.
|
||||||
|
/*
|
||||||
|
/* smtp_session_new_stream() updates an SMTP_SESSION structure
|
||||||
|
/* with a newly-created stream that was created at the specified
|
||||||
|
/* start time, and makes it subject to the specified connection
|
||||||
|
/* caching policy.
|
||||||
|
/*
|
||||||
|
/* smtp_sess_tls_check() returns true if TLS use is mandatory, invalid
|
||||||
|
/* or indeterminate. The return value is false only if TLS is optional.
|
||||||
|
/* This is not yet used anywhere, it can be used to safely enable TLS
|
||||||
|
/* policy with smtp_reuse_addr().
|
||||||
/*
|
/*
|
||||||
/* smtp_session_free() destroys an SMTP_SESSION structure and its
|
/* smtp_session_free() destroys an SMTP_SESSION structure and its
|
||||||
/* members, making memory available for reuse. It will handle the
|
/* members, making memory available for reuse. It will handle the
|
||||||
@@ -61,6 +83,8 @@
|
|||||||
/* The address of the host that we are connected to.
|
/* The address of the host that we are connected to.
|
||||||
/* .IP port
|
/* .IP port
|
||||||
/* The remote port, network byte order.
|
/* The remote port, network byte order.
|
||||||
|
/* .IP valid
|
||||||
|
/* The DNSSEC validation status of the host name.
|
||||||
/* .IP start
|
/* .IP start
|
||||||
/* The time when this connection was opened.
|
/* The time when this connection was opened.
|
||||||
/* .IP flags
|
/* .IP flags
|
||||||
@@ -72,6 +96,8 @@
|
|||||||
/* Enable re-use of cached SMTP or LMTP connections.
|
/* Enable re-use of cached SMTP or LMTP connections.
|
||||||
/* .IP SMTP_MISC_FLAG_CONN_STORE
|
/* .IP SMTP_MISC_FLAG_CONN_STORE
|
||||||
/* Enable saving of cached SMTP or LMTP connections.
|
/* Enable saving of cached SMTP or LMTP connections.
|
||||||
|
/* .IP SMTP_MISC_FLAG_NO_TLS
|
||||||
|
/* Used only internally in smtp_session.c
|
||||||
/* .RE
|
/* .RE
|
||||||
/* SMTP_MISC_FLAG_CONN_MASK corresponds with both _LOAD and _STORE.
|
/* SMTP_MISC_FLAG_CONN_MASK corresponds with both _LOAD and _STORE.
|
||||||
/* .IP dest_prop
|
/* .IP dest_prop
|
||||||
@@ -117,7 +143,6 @@
|
|||||||
#include <vstream.h>
|
#include <vstream.h>
|
||||||
#include <stringops.h>
|
#include <stringops.h>
|
||||||
#include <valid_hostname.h>
|
#include <valid_hostname.h>
|
||||||
#include <name_code.h>
|
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
|
|
||||||
@@ -134,15 +159,16 @@
|
|||||||
|
|
||||||
/* smtp_session_alloc - allocate and initialize SMTP_SESSION structure */
|
/* smtp_session_alloc - allocate and initialize SMTP_SESSION structure */
|
||||||
|
|
||||||
SMTP_SESSION *smtp_session_alloc(VSTREAM *stream, const char *dest,
|
SMTP_SESSION *smtp_session_alloc(DSN_BUF *why, const char *dest,
|
||||||
const char *host, const char *addr,
|
const char *host, const char *addr,
|
||||||
unsigned port, time_t start,
|
unsigned port, int flags)
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
|
const char *myname = "smtp_session_alloc";
|
||||||
SMTP_SESSION *session;
|
SMTP_SESSION *session;
|
||||||
|
int valid = (flags & SMTP_MISC_FLAG_TLSA_HOST);
|
||||||
|
|
||||||
session = (SMTP_SESSION *) mymalloc(sizeof(*session));
|
session = (SMTP_SESSION *) mymalloc(sizeof(*session));
|
||||||
session->stream = stream;
|
session->stream = 0;
|
||||||
session->dest = mystrdup(dest);
|
session->dest = mystrdup(dest);
|
||||||
session->host = mystrdup(host);
|
session->host = mystrdup(host);
|
||||||
session->addr = mystrdup(addr);
|
session->addr = mystrdup(addr);
|
||||||
@@ -168,29 +194,75 @@ SMTP_SESSION *smtp_session_alloc(VSTREAM *stream, const char *dest,
|
|||||||
|
|
||||||
session->send_proto_helo = 0;
|
session->send_proto_helo = 0;
|
||||||
|
|
||||||
if (flags & SMTP_MISC_FLAG_CONN_STORE)
|
|
||||||
CACHE_THIS_SESSION_UNTIL(start + var_smtp_reuse_time);
|
|
||||||
else
|
|
||||||
DONT_CACHE_THIS_SESSION;
|
|
||||||
session->reuse_count = 0;
|
|
||||||
USE_NEWBORN_SESSION; /* He's not dead Jim! */
|
USE_NEWBORN_SESSION; /* He's not dead Jim! */
|
||||||
|
|
||||||
#ifdef USE_SASL_AUTH
|
#ifdef USE_SASL_AUTH
|
||||||
smtp_sasl_connect(session);
|
smtp_sasl_connect(session);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the destination argument of smtp_tls_sess_alloc() is null, a
|
||||||
|
* trivial TLS policy (level = "none") is returned unconditionally and
|
||||||
|
* the other arguments are not used. Soon the DSN_BUF "why" argument
|
||||||
|
* will be optional when the caller is not interested in the error
|
||||||
|
* status.
|
||||||
|
*/
|
||||||
|
#define NO_DSN_BUF (DSN_BUF *) 0
|
||||||
|
#define NO_DEST (char *) 0
|
||||||
|
#define NO_HOST (char *) 0
|
||||||
|
#define NO_PORT 0
|
||||||
|
#define NO_FLAGS 0
|
||||||
|
|
||||||
#ifdef USE_TLS
|
#ifdef USE_TLS
|
||||||
session->tls_context = 0;
|
session->tls_context = 0;
|
||||||
session->tls_retry_plain = 0;
|
session->tls_retry_plain = 0;
|
||||||
session->tls_nexthop = 0;
|
session->tls_nexthop = 0;
|
||||||
session->tls =
|
if (flags & SMTP_MISC_FLAG_NO_TLS)
|
||||||
smtp_tls_sess_alloc(dest, host, port, flags & SMTP_MISC_FLAG_TLSA_HOST);
|
session->tls = smtp_tls_sess_alloc(NO_DSN_BUF, NO_DEST, NO_HOST,
|
||||||
|
NO_PORT, NO_FLAGS);
|
||||||
|
else {
|
||||||
|
if (why == 0)
|
||||||
|
msg_panic("%s: null error buffer", myname);
|
||||||
|
session->tls = smtp_tls_sess_alloc(why, dest, host, port, valid);
|
||||||
|
}
|
||||||
|
if (!session->tls) {
|
||||||
|
smtp_session_free(session);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
session->state = 0;
|
session->state = 0;
|
||||||
debug_peer_check(host, addr);
|
debug_peer_check(host, addr);
|
||||||
return (session);
|
return (session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* smtp_session_new_stream - finalize session with newly-created connection */
|
||||||
|
|
||||||
|
void smtp_session_new_stream(SMTP_SESSION *session, VSTREAM *stream,
|
||||||
|
time_t start, int flags)
|
||||||
|
{
|
||||||
|
const char *myname = "smtp_session_new_stream";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sanity check.
|
||||||
|
*/
|
||||||
|
if (session->stream != 0)
|
||||||
|
msg_panic("%s: session exists", myname);
|
||||||
|
|
||||||
|
session->stream = stream;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make the session subject to the new-stream connection caching policy,
|
||||||
|
* as opposed to the reused-stream connection caching policy at the
|
||||||
|
* bottom of this module. Both policies are enforced in this file, not
|
||||||
|
* one policy here and the other at some random place in smtp_connect.c.
|
||||||
|
*/
|
||||||
|
if (flags & SMTP_MISC_FLAG_CONN_STORE)
|
||||||
|
CACHE_THIS_SESSION_UNTIL(start + var_smtp_reuse_time);
|
||||||
|
else
|
||||||
|
DONT_CACHE_THIS_SESSION;
|
||||||
|
session->reuse_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* smtp_session_free - destroy SMTP_SESSION structure and contents */
|
/* smtp_session_free - destroy SMTP_SESSION structure and contents */
|
||||||
|
|
||||||
void smtp_session_free(SMTP_SESSION *session)
|
void smtp_session_free(SMTP_SESSION *session)
|
||||||
@@ -232,6 +304,32 @@ void smtp_session_free(SMTP_SESSION *session)
|
|||||||
myfree((char *) session);
|
myfree((char *) session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* smtp_sess_tls_check - does session require tls */
|
||||||
|
|
||||||
|
int smtp_sess_tls_check(const char *dest, const char *host, unsigned port,
|
||||||
|
int valid)
|
||||||
|
{
|
||||||
|
#ifdef USE_TLS
|
||||||
|
static DSN_BUF *why;
|
||||||
|
SMTP_TLS_SESS *tls;
|
||||||
|
|
||||||
|
if (!why)
|
||||||
|
why = dsb_create();
|
||||||
|
|
||||||
|
tls = smtp_tls_sess_alloc(why, dest, host, ntohs(port), valid);
|
||||||
|
dsb_reset(why);
|
||||||
|
|
||||||
|
if (tls && tls->level >= TLS_LEV_NONE && tls->level <= TLS_LEV_MAY)
|
||||||
|
return (0);
|
||||||
|
if (tls)
|
||||||
|
smtp_tls_sess_free(tls);
|
||||||
|
return (1);
|
||||||
|
#else
|
||||||
|
return (0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* smtp_session_passivate - passivate an SMTP_SESSION object */
|
/* smtp_session_passivate - passivate an SMTP_SESSION object */
|
||||||
|
|
||||||
int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
|
int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
|
||||||
@@ -372,11 +470,15 @@ SMTP_SESSION *smtp_session_activate(int fd, VSTRING *dest_prop,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Allright, bundle up what we have sofar.
|
* Allright, bundle up what we have sofar.
|
||||||
|
*
|
||||||
|
* Caller is responsible for not reusing plain-text connections when TLS is
|
||||||
|
* required. With TLS disabled, a trivial TLS policy (level "none") is
|
||||||
|
* returned without fail, with no other ways for session setup to fail,
|
||||||
|
* we assume it must succeed.
|
||||||
*/
|
*/
|
||||||
#define NO_FLAGS 0
|
session = smtp_session_alloc(NO_DSN_BUF, dest, host, addr, port,
|
||||||
|
SMTP_MISC_FLAG_NO_TLS);
|
||||||
session = smtp_session_alloc(vstream_fdopen(fd, O_RDWR), dest, host,
|
session->stream = vstream_fdopen(fd, O_RDWR);
|
||||||
addr, port, (time_t) 0, NO_FLAGS);
|
|
||||||
session->features = (features | SMTP_FEATURE_FROM_CACHE);
|
session->features = (features | SMTP_FEATURE_FROM_CACHE);
|
||||||
CACHE_THIS_SESSION_UNTIL(expire_time);
|
CACHE_THIS_SESSION_UNTIL(expire_time);
|
||||||
session->reuse_count = ++reuse_count;
|
session->reuse_count = ++reuse_count;
|
||||||
|
@@ -8,7 +8,8 @@
|
|||||||
/*
|
/*
|
||||||
/* void smtp_tls_list_init()
|
/* void smtp_tls_list_init()
|
||||||
/*
|
/*
|
||||||
/* SMTP_TLS_SESS *smtp_tls_sess_alloc(dest, host, port, valid)
|
/* SMTP_TLS_SESS *smtp_tls_sess_alloc(why, dest, host, port, valid)
|
||||||
|
/* DSN_BUF *why;
|
||||||
/* char *dest;
|
/* char *dest;
|
||||||
/* char *host;
|
/* char *host;
|
||||||
/* unsigned port;
|
/* unsigned port;
|
||||||
@@ -21,8 +22,12 @@
|
|||||||
/* policy engine.
|
/* policy engine.
|
||||||
/*
|
/*
|
||||||
/* smtp_tls_sess_alloc() allocates memory for an SMTP_TLS_SESS structure
|
/* smtp_tls_sess_alloc() allocates memory for an SMTP_TLS_SESS structure
|
||||||
/* and initializes it based on the given information. NOTE: the
|
/* and initializes it based on the given information. Any required
|
||||||
/* port is in network byte order.
|
/* table and DNS lookups can fail. When this happens, "why" is updated
|
||||||
|
/* with the error reason and a null pointer is returned. NOTE: the
|
||||||
|
/* port is in network byte order. If "dest" is null, no policy checks are
|
||||||
|
/* made, rather a trivial policy with tls disabled is returned (the
|
||||||
|
/* remaining arguments are unused in this case and may be null).
|
||||||
/*
|
/*
|
||||||
/* smtp_tls_sess_free() destroys an SMTP_TLS_SESS structure and its
|
/* smtp_tls_sess_free() destroys an SMTP_TLS_SESS structure and its
|
||||||
/* members. A null pointer is returned for convenience.
|
/* members. A null pointer is returned for convenience.
|
||||||
@@ -126,8 +131,9 @@ static const char *policy_name(int tls_level)
|
|||||||
|
|
||||||
/* tls_site_lookup - look up per-site TLS security level */
|
/* tls_site_lookup - look up per-site TLS security level */
|
||||||
|
|
||||||
static void tls_site_lookup(int *site_level, const char *site_name,
|
static void tls_site_lookup(SMTP_TLS_SESS *tls, int *site_level,
|
||||||
const char *site_class)
|
const char *site_name, const char *site_class,
|
||||||
|
DSN_BUF *why)
|
||||||
{
|
{
|
||||||
const char *lookup;
|
const char *lookup;
|
||||||
|
|
||||||
@@ -154,19 +160,27 @@ static void tls_site_lookup(int *site_level, const char *site_name,
|
|||||||
if (*site_level < TLS_LEV_VERIFY)
|
if (*site_level < TLS_LEV_VERIFY)
|
||||||
*site_level = TLS_LEV_VERIFY;
|
*site_level = TLS_LEV_VERIFY;
|
||||||
} else {
|
} else {
|
||||||
msg_warn("Table %s: ignoring unknown TLS policy '%s' for %s %s",
|
msg_warn("%s: unknown TLS policy '%s' for %s %s",
|
||||||
var_smtp_tls_per_site, lookup, site_class, site_name);
|
tls_per_site->title, lookup, site_class, site_name);
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
|
*site_level = TLS_LEV_INVALID;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else if (tls_per_site->error) {
|
} else if (tls_per_site->error) {
|
||||||
msg_fatal("%s lookup error for %s", tls_per_site->title, site_name);
|
msg_warn("%s: %s \"%s\": per-site table lookup error",
|
||||||
|
tls_per_site->title, site_class, site_name);
|
||||||
|
dsb_simple(why, "4.3.0", "Temporary lookup error");
|
||||||
|
*site_level = TLS_LEV_INVALID;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tls_policy_lookup_one - look up destination TLS policy */
|
/* tls_policy_lookup_one - look up destination TLS policy */
|
||||||
|
|
||||||
static int tls_policy_lookup_one(SMTP_TLS_SESS *tls, int *site_level,
|
static void tls_policy_lookup_one(SMTP_TLS_SESS *tls, int *site_level,
|
||||||
const char *site_name,
|
const char *site_name,
|
||||||
const char *site_class)
|
const char *site_class, DSN_BUF *why)
|
||||||
{
|
{
|
||||||
const char *lookup;
|
const char *lookup;
|
||||||
char *policy;
|
char *policy;
|
||||||
@@ -178,35 +192,37 @@ static int tls_policy_lookup_one(SMTP_TLS_SESS *tls, int *site_level,
|
|||||||
static VSTRING *cbuf;
|
static VSTRING *cbuf;
|
||||||
|
|
||||||
#undef FREE_RETURN
|
#undef FREE_RETURN
|
||||||
#define FREE_RETURN(x) do { myfree(saved_policy); return (x); } while (0)
|
#define FREE_RETURN do { myfree(saved_policy); return; } while (0)
|
||||||
|
|
||||||
|
#define WHERE \
|
||||||
|
vstring_str(vstring_sprintf(cbuf, "%s, %s \"%s\"", \
|
||||||
|
tls_policy->title, site_class, site_name))
|
||||||
|
|
||||||
if ((lookup = maps_find(tls_policy, site_name, 0)) == 0) {
|
|
||||||
if (tls_policy->error) {
|
|
||||||
msg_fatal("%s lookup error for %s",
|
|
||||||
tls_policy->title, site_name);
|
|
||||||
/* XXX session->stream has no longjmp context yet. */
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if (cbuf == 0)
|
if (cbuf == 0)
|
||||||
cbuf = vstring_alloc(10);
|
cbuf = vstring_alloc(10);
|
||||||
|
|
||||||
#define WHERE \
|
if ((lookup = maps_find(tls_policy, site_name, 0)) == 0) {
|
||||||
vstring_str(vstring_sprintf(cbuf, "TLS policy table, %s \"%s\"", \
|
if (tls_policy->error) {
|
||||||
site_class, site_name))
|
msg_warn("%s: policy table lookup error", WHERE);
|
||||||
|
dsb_simple(why, "4.3.0", "Temporary lookup error");
|
||||||
|
*site_level = TLS_LEV_INVALID;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
saved_policy = policy = mystrdup(lookup);
|
saved_policy = policy = mystrdup(lookup);
|
||||||
|
|
||||||
if ((tok = mystrtok(&policy, "\t\n\r ,")) == 0) {
|
if ((tok = mystrtok(&policy, "\t\n\r ,")) == 0) {
|
||||||
msg_warn("%s: invalid empty policy", WHERE);
|
msg_warn("%s: invalid empty policy", WHERE);
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
*site_level = TLS_LEV_INVALID;
|
*site_level = TLS_LEV_INVALID;
|
||||||
FREE_RETURN(1); /* No further lookups */
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
*site_level = tls_level_lookup(tok);
|
*site_level = tls_level_lookup(tok);
|
||||||
if (*site_level == TLS_LEV_INVALID) {
|
if (*site_level == TLS_LEV_INVALID) {
|
||||||
/* tls_level_lookup() logs no warning. */
|
/* tls_level_lookup() logs no warning. */
|
||||||
msg_warn("%s: invalid security level \"%s\"", WHERE, tok);
|
msg_warn("%s: invalid security level \"%s\"", WHERE, tok);
|
||||||
FREE_RETURN(1); /* No further lookups */
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -216,7 +232,7 @@ static int tls_policy_lookup_one(SMTP_TLS_SESS *tls, int *site_level,
|
|||||||
while ((tok = mystrtok(&policy, "\t\n\r ,")) != 0)
|
while ((tok = mystrtok(&policy, "\t\n\r ,")) != 0)
|
||||||
msg_warn("%s: ignoring attribute \"%s\" with TLS disabled",
|
msg_warn("%s: ignoring attribute \"%s\" with TLS disabled",
|
||||||
WHERE, tok);
|
WHERE, tok);
|
||||||
FREE_RETURN(1);
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -225,23 +241,26 @@ static int tls_policy_lookup_one(SMTP_TLS_SESS *tls, int *site_level,
|
|||||||
*/
|
*/
|
||||||
while ((tok = mystrtok(&policy, "\t\n\r ,")) != 0) {
|
while ((tok = mystrtok(&policy, "\t\n\r ,")) != 0) {
|
||||||
if ((err = split_nameval(tok, &name, &val)) != 0) {
|
if ((err = split_nameval(tok, &name, &val)) != 0) {
|
||||||
*site_level = TLS_LEV_INVALID;
|
|
||||||
msg_warn("%s: malformed attribute/value pair \"%s\": %s",
|
msg_warn("%s: malformed attribute/value pair \"%s\": %s",
|
||||||
WHERE, tok, err);
|
WHERE, tok, err);
|
||||||
break;
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
|
*site_level = TLS_LEV_INVALID;
|
||||||
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
/* Only one instance per policy. */
|
/* Only one instance per policy. */
|
||||||
if (!strcasecmp(name, "ciphers")) {
|
if (!strcasecmp(name, "ciphers")) {
|
||||||
if (*val == 0) {
|
if (*val == 0) {
|
||||||
msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
|
msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
*site_level = TLS_LEV_INVALID;
|
*site_level = TLS_LEV_INVALID;
|
||||||
break;
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
if (tls->grade) {
|
if (tls->grade) {
|
||||||
msg_warn("%s: attribute \"%s\" is specified multiple times",
|
msg_warn("%s: attribute \"%s\" is specified multiple times",
|
||||||
WHERE, name);
|
WHERE, name);
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
*site_level = TLS_LEV_INVALID;
|
*site_level = TLS_LEV_INVALID;
|
||||||
break;
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
tls->grade = mystrdup(val);
|
tls->grade = mystrdup(val);
|
||||||
continue;
|
continue;
|
||||||
@@ -251,8 +270,9 @@ static int tls_policy_lookup_one(SMTP_TLS_SESS *tls, int *site_level,
|
|||||||
if (tls->protocols) {
|
if (tls->protocols) {
|
||||||
msg_warn("%s: attribute \"%s\" is specified multiple times",
|
msg_warn("%s: attribute \"%s\" is specified multiple times",
|
||||||
WHERE, name);
|
WHERE, name);
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
*site_level = TLS_LEV_INVALID;
|
*site_level = TLS_LEV_INVALID;
|
||||||
break;
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
tls->protocols = mystrdup(val);
|
tls->protocols = mystrdup(val);
|
||||||
continue;
|
continue;
|
||||||
@@ -264,13 +284,15 @@ static int tls_policy_lookup_one(SMTP_TLS_SESS *tls, int *site_level,
|
|||||||
if (*site_level <= TLS_LEV_ENCRYPT) {
|
if (*site_level <= TLS_LEV_ENCRYPT) {
|
||||||
msg_warn("%s: attribute \"%s\" invalid at security level "
|
msg_warn("%s: attribute \"%s\" invalid at security level "
|
||||||
"\"%s\"", WHERE, name, policy_name(*site_level));
|
"\"%s\"", WHERE, name, policy_name(*site_level));
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
*site_level = TLS_LEV_INVALID;
|
*site_level = TLS_LEV_INVALID;
|
||||||
break;
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
if (*val == 0) {
|
if (*val == 0) {
|
||||||
msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
|
msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
*site_level = TLS_LEV_INVALID;
|
*site_level = TLS_LEV_INVALID;
|
||||||
break;
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
if (tls->matchargv == 0)
|
if (tls->matchargv == 0)
|
||||||
tls->matchargv = argv_split(val, delim);
|
tls->matchargv = argv_split(val, delim);
|
||||||
@@ -283,25 +305,27 @@ static int tls_policy_lookup_one(SMTP_TLS_SESS *tls, int *site_level,
|
|||||||
if (tls->exclusions) {
|
if (tls->exclusions) {
|
||||||
msg_warn("%s: attribute \"%s\" is specified multiple times",
|
msg_warn("%s: attribute \"%s\" is specified multiple times",
|
||||||
WHERE, name);
|
WHERE, name);
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
*site_level = TLS_LEV_INVALID;
|
*site_level = TLS_LEV_INVALID;
|
||||||
break;
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
tls->exclusions = vstring_strcpy(vstring_alloc(10), val);
|
tls->exclusions = vstring_strcpy(vstring_alloc(10), val);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
msg_warn("%s: invalid attribute name: \"%s\"", WHERE, name);
|
|
||||||
*site_level = TLS_LEV_INVALID;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
msg_warn("%s: invalid attribute name: \"%s\"", WHERE, name);
|
||||||
|
dsb_simple(why, "4.7.5", "client TLS configuration problem");
|
||||||
|
*site_level = TLS_LEV_INVALID;
|
||||||
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
FREE_RETURN(1);
|
|
||||||
|
FREE_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tls_policy_lookup - look up destination TLS policy */
|
/* tls_policy_lookup - look up destination TLS policy */
|
||||||
|
|
||||||
static void tls_policy_lookup(SMTP_TLS_SESS *tls, int *site_level,
|
static void tls_policy_lookup(SMTP_TLS_SESS *tls, int *site_level,
|
||||||
const char *site_name,
|
const char *site_name,
|
||||||
const char *site_class)
|
const char *site_class, DSN_BUF *why)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -312,22 +336,13 @@ static void tls_policy_lookup(SMTP_TLS_SESS *tls, int *site_level,
|
|||||||
* sub-domains of the recipient domain.
|
* sub-domains of the recipient domain.
|
||||||
*/
|
*/
|
||||||
if (!valid_hostname(site_name, DONT_GRIPE)) {
|
if (!valid_hostname(site_name, DONT_GRIPE)) {
|
||||||
tls_policy_lookup_one(tls, site_level, site_name, site_class);
|
tls_policy_lookup_one(tls, site_level, site_name, site_class, why);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
do {
|
||||||
/*
|
tls_policy_lookup_one(tls, site_level, site_name, site_class, why);
|
||||||
* XXX For clarity consider using ``do { .. } while'', instead of using
|
} while (*site_level == TLS_LEV_NOTFOUND
|
||||||
* ``while { .. }'' with loop control at the bottom.
|
&& (site_name = strchr(site_name + 1, '.')) != 0);
|
||||||
*/
|
|
||||||
while (1) {
|
|
||||||
/* Try the given domain */
|
|
||||||
if (tls_policy_lookup_one(tls, site_level, site_name, site_class))
|
|
||||||
return;
|
|
||||||
/* Re-try with parent domain */
|
|
||||||
if ((site_name = strchr(site_name + 1, '.')) == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set_cipher_grade - Set cipher grade and exclusions */
|
/* set_cipher_grade - Set cipher grade and exclusions */
|
||||||
@@ -390,10 +405,10 @@ static void set_cipher_grade(SMTP_TLS_SESS *tls)
|
|||||||
|
|
||||||
/* smtp_tls_sess_alloc - session TLS policy parameters */
|
/* smtp_tls_sess_alloc - session TLS policy parameters */
|
||||||
|
|
||||||
SMTP_TLS_SESS *smtp_tls_sess_alloc(const char *dest, const char *host,
|
SMTP_TLS_SESS *smtp_tls_sess_alloc(DSN_BUF *why, const char *dest,
|
||||||
unsigned port, int valid)
|
const char *host, unsigned port, int valid)
|
||||||
{
|
{
|
||||||
const char *myname = "session_tls_init";
|
const char *myname = "smtp_tls_sess_alloc";
|
||||||
int global_level;
|
int global_level;
|
||||||
int site_level;
|
int site_level;
|
||||||
SMTP_TLS_SESS *tls = (SMTP_TLS_SESS *) mymalloc(sizeof(*tls));
|
SMTP_TLS_SESS *tls = (SMTP_TLS_SESS *) mymalloc(sizeof(*tls));
|
||||||
@@ -404,6 +419,9 @@ SMTP_TLS_SESS *smtp_tls_sess_alloc(const char *dest, const char *host,
|
|||||||
tls->exclusions = 0;
|
tls->exclusions = 0;
|
||||||
tls->matchargv = 0;
|
tls->matchargv = 0;
|
||||||
|
|
||||||
|
if (!dest)
|
||||||
|
return (tls);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute the global TLS policy. This is the default policy level when
|
* Compute the global TLS policy. This is the default policy level when
|
||||||
* no per-site policy exists. It also is used to override a wild-card
|
* no per-site policy exists. It also is used to override a wild-card
|
||||||
@@ -433,13 +451,12 @@ SMTP_TLS_SESS *smtp_tls_sess_alloc(const char *dest, const char *host,
|
|||||||
site_level = TLS_LEV_NOTFOUND;
|
site_level = TLS_LEV_NOTFOUND;
|
||||||
|
|
||||||
if (tls_policy) {
|
if (tls_policy) {
|
||||||
tls_policy_lookup(tls, &site_level, dest, "next-hop destination");
|
tls_policy_lookup(tls, &site_level, dest, "next-hop destination", why);
|
||||||
} else if (tls_per_site) {
|
} else if (tls_per_site) {
|
||||||
tls_site_lookup(&site_level, dest, "next-hop destination");
|
tls_site_lookup(tls, &site_level, dest, "next-hop destination", why);
|
||||||
if (strcasecmp(dest, host) != 0)
|
if (site_level != TLS_LEV_INVALID
|
||||||
tls_site_lookup(&site_level, host, "server hostname");
|
&& strcasecmp(dest, host) != 0)
|
||||||
if (msg_verbose)
|
tls_site_lookup(tls, &site_level, host, "server hostname", why);
|
||||||
msg_info("%s TLS level: %s", "site", policy_name(site_level));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Override a wild-card per-site policy with a more specific global
|
* Override a wild-card per-site policy with a more specific global
|
||||||
@@ -460,10 +477,16 @@ SMTP_TLS_SESS *smtp_tls_sess_alloc(const char *dest, const char *host,
|
|||||||
if (site_level == TLS_LEV_MAY && global_level > TLS_LEV_MAY)
|
if (site_level == TLS_LEV_MAY && global_level > TLS_LEV_MAY)
|
||||||
site_level = global_level;
|
site_level = global_level;
|
||||||
}
|
}
|
||||||
if (site_level == TLS_LEV_NOTFOUND)
|
switch (site_level) {
|
||||||
|
case TLS_LEV_INVALID:
|
||||||
|
return (smtp_tls_sess_free(tls));
|
||||||
|
case TLS_LEV_NOTFOUND:
|
||||||
tls->level = global_level;
|
tls->level = global_level;
|
||||||
else
|
break;
|
||||||
|
default:
|
||||||
tls->level = site_level;
|
tls->level = site_level;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use main.cf protocols setting if not set in per-destination table.
|
* Use main.cf protocols setting if not set in per-destination table.
|
||||||
|
@@ -4347,14 +4347,14 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
|||||||
state->port, var_smtpd_tmout);
|
state->port, var_smtpd_tmout);
|
||||||
if (state->tlsproxy == 0) {
|
if (state->tlsproxy == 0) {
|
||||||
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
||||||
/* RFC 4954 Section 6. */
|
/* RFC 3207 Section 4. */
|
||||||
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
|
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
#else /* USE_TLSPROXY */
|
#else /* USE_TLSPROXY */
|
||||||
if (smtpd_tls_ctx == 0) {
|
if (smtpd_tls_ctx == 0) {
|
||||||
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
||||||
/* RFC 4954 Section 6. */
|
/* RFC 3207 Section 4. */
|
||||||
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
|
smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user