mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 05:38:06 +00:00
postfix-2.6-20080510
This commit is contained in:
parent
aa25e2edae
commit
d3c01305cb
@ -14439,7 +14439,26 @@ Apologies for any names omitted.
|
|||||||
(Postfix 2.1) and smtp/lmtp_generic_maps (Postfix 2.3).
|
(Postfix 2.1) and smtp/lmtp_generic_maps (Postfix 2.3).
|
||||||
File: global/mail_params.h.
|
File: global/mail_params.h.
|
||||||
|
|
||||||
Cleanup: the SMTP server's XFORWARD and XCLIENT support
|
Cleanup: the SMTP server's XFORWARD and XCLIENT support was
|
||||||
was not updated when the smtpd_client_port_logging configuration
|
not updated when the smtpd_client_port_logging configuration
|
||||||
parameter was added. Code by Victor Duchovni. Files:
|
parameter was added. Code by Victor Duchovni. Files:
|
||||||
smtpd/smtpd.c, smtpd/smtpd_peer.c.
|
smtpd/smtpd.c, smtpd/smtpd_peer.c.
|
||||||
|
|
||||||
|
20080508
|
||||||
|
|
||||||
|
Cleanup: delivery status notifications now prepend a
|
||||||
|
Return-Path: message header to the returned message.
|
||||||
|
File: bounce/bounce_notify_util.c.
|
||||||
|
|
||||||
|
20080509
|
||||||
|
|
||||||
|
Bugfix: null-terminate CN comment string after sanitization.
|
||||||
|
File: smtpd/smtpd.c.
|
||||||
|
|
||||||
|
20080510
|
||||||
|
|
||||||
|
Cleanup: when extracting common name and issuer name from
|
||||||
|
TLS certificates, convert the result into UTF-8, and use
|
||||||
|
RFC 2047 encoding when logging these as Received: header
|
||||||
|
comment fields. Based remotely on code by Victor Duchovni.
|
||||||
|
Files: smtpd/smtpd.c, tls/tls_verify.c.
|
||||||
|
@ -126,7 +126,10 @@ Notes:
|
|||||||
how the client was authenticated via TLS. These attributes are empty in
|
how the client was authenticated via TLS. These attributes are empty in
|
||||||
case of no certificate authentication. As of Postfix 2.2.11 these attribute
|
case of no certificate authentication. As of Postfix 2.2.11 these attribute
|
||||||
values are encoded as xtext: some characters are represented by +XX, where
|
values are encoded as xtext: some characters are represented by +XX, where
|
||||||
XX is the two-digit hexadecimal representation of the character value.
|
XX is the two-digit hexadecimal representation of the character value. With
|
||||||
|
Postfix 2.5 and later, the decoded string may contain non-ASCII characters.
|
||||||
|
If so, this is a UTF-8 string; xtext encoding works with the bytes of the
|
||||||
|
UTF-8 string, not the characters.
|
||||||
|
|
||||||
* The "encryption_*" attributes (Postfix 2.3 and later) specify information
|
* The "encryption_*" attributes (Postfix 2.3 and later) specify information
|
||||||
about how the connection is encrypted. With plaintext connections the
|
about how the connection is encrypted. With plaintext connections the
|
||||||
|
@ -17,6 +17,13 @@ Incompatibility with Postfix 2.4 and earlier
|
|||||||
If you upgrade from Postfix 2.4 or earlier, read RELEASE_NOTES-2.5
|
If you upgrade from Postfix 2.4 or earlier, read RELEASE_NOTES-2.5
|
||||||
before proceeding.
|
before proceeding.
|
||||||
|
|
||||||
|
Incompatibility with snapshot 20080510
|
||||||
|
======================================
|
||||||
|
|
||||||
|
In the policy delegation protocol, certificate common name attributes
|
||||||
|
are now xtext encoded UTF-8. The xtext decoded attributes may contain
|
||||||
|
any UTF-8 value including control characters.
|
||||||
|
|
||||||
Incompatibility with snapshot 20080428
|
Incompatibility with snapshot 20080428
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
|
@ -192,14 +192,14 @@
|
|||||||
#
|
#
|
||||||
# REJECT optional text...
|
# REJECT optional text...
|
||||||
# Reject the address etc. that matches the pattern.
|
# Reject the address etc. that matches the pattern.
|
||||||
# Reply with $reject_code optional text... when the
|
# Reply with "$access_map_reject_code optional
|
||||||
# optional text is specified, otherwise reply with a
|
# text..." when the optional text is specified, oth-
|
||||||
# generic error response message.
|
# erwise reply with a generic error response message.
|
||||||
#
|
#
|
||||||
# DEFER_IF_REJECT optional text...
|
# DEFER_IF_REJECT optional text...
|
||||||
# Defer the request if some later restriction would
|
# Defer the request if some later restriction would
|
||||||
# result in a REJECT action. Reply with "450 4.7.1
|
# result in a REJECT action. Reply with "450 4.7.1
|
||||||
# optional text... when the optional text is speci-
|
# optional text..." when the optional text is speci-
|
||||||
# fied, otherwise reply with a generic error response
|
# fied, otherwise reply with a generic error response
|
||||||
# message.
|
# message.
|
||||||
#
|
#
|
||||||
@ -208,7 +208,7 @@
|
|||||||
# DEFER_IF_PERMIT optional text...
|
# DEFER_IF_PERMIT optional text...
|
||||||
# Defer the request if some later restriction would
|
# Defer the request if some later restriction would
|
||||||
# result in a an explicit or implicit PERMIT action.
|
# result in a an explicit or implicit PERMIT action.
|
||||||
# Reply with "450 4.7.1 optional text... when the
|
# Reply with "450 4.7.1 optional text..." when the
|
||||||
# optional text is specified, otherwise reply with a
|
# optional text is specified, otherwise reply with a
|
||||||
# generic error response message.
|
# generic error response message.
|
||||||
#
|
#
|
||||||
|
@ -173,7 +173,10 @@ stress=
|
|||||||
These attributes are empty in case of no certificate authentication.
|
These attributes are empty in case of no certificate authentication.
|
||||||
As of Postfix 2.2.11 these attribute values are encoded as
|
As of Postfix 2.2.11 these attribute values are encoded as
|
||||||
xtext: some characters are represented by +XX, where XX is the
|
xtext: some characters are represented by +XX, where XX is the
|
||||||
two-digit hexadecimal representation of the character value.
|
two-digit hexadecimal representation of the character value. With
|
||||||
|
Postfix 2.5 and later, the decoded string may contain non-ASCII
|
||||||
|
characters. If so, this is a UTF-8 string; xtext encoding works
|
||||||
|
with the bytes of the UTF-8 string, not the characters.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
|
<li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
|
||||||
|
@ -198,14 +198,14 @@ ACCESS(5) ACCESS(5)
|
|||||||
|
|
||||||
<b>REJECT</b> <i>optional text...</i>
|
<b>REJECT</b> <i>optional text...</i>
|
||||||
Reject the address etc. that matches the pattern.
|
Reject the address etc. that matches the pattern.
|
||||||
Reply with <i>$reject</i><b>_</b><i>code optional text...</i> when the
|
Reply with "<b>$<a href="postconf.5.html#access_map_reject_code">access_map_reject_code</a></b> <i>optional</i>
|
||||||
optional text is specified, otherwise reply with a
|
<i>text...</i>" when the optional text is specified, oth-
|
||||||
generic error response message.
|
erwise reply with a generic error response message.
|
||||||
|
|
||||||
<b>DEFER_IF_REJECT</b> <i>optional text...</i>
|
<b>DEFER_IF_REJECT</b> <i>optional text...</i>
|
||||||
Defer the request if some later restriction would
|
Defer the request if some later restriction would
|
||||||
result in a REJECT action. Reply with "<b>450 4.7.1</b>
|
result in a REJECT action. Reply with "<b>450 4.7.1</b>
|
||||||
<i>optional text...</i> when the optional text is speci-
|
<i>optional text...</i>" when the optional text is speci-
|
||||||
fied, otherwise reply with a generic error response
|
fied, otherwise reply with a generic error response
|
||||||
message.
|
message.
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ ACCESS(5) ACCESS(5)
|
|||||||
<b>DEFER_IF_PERMIT</b> <i>optional text...</i>
|
<b>DEFER_IF_PERMIT</b> <i>optional text...</i>
|
||||||
Defer the request if some later restriction would
|
Defer the request if some later restriction would
|
||||||
result in a an explicit or implicit PERMIT action.
|
result in a an explicit or implicit PERMIT action.
|
||||||
Reply with "<b>450 4.7.1</b> <i>optional text...</i> when the
|
Reply with "<b>450 4.7.1</b> <i>optional text...</i>" when the
|
||||||
optional text is specified, otherwise reply with a
|
optional text is specified, otherwise reply with a
|
||||||
generic error response message.
|
generic error response message.
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ esac
|
|||||||
: ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk} \
|
: ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk} \
|
||||||
${WARN='-Wall -Wno-comment -Wformat -Wimplicit -Wmissing-prototypes \
|
${WARN='-Wall -Wno-comment -Wformat -Wimplicit -Wmissing-prototypes \
|
||||||
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
|
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
|
||||||
-Wunused'}
|
-Wunused -Wno-missing-braces'}
|
||||||
|
|
||||||
export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
|
export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
|
||||||
|
|
||||||
|
@ -190,12 +190,13 @@ The reply code "421" causes Postfix to disconnect immediately
|
|||||||
(Postfix version 2.3 and later).
|
(Postfix version 2.3 and later).
|
||||||
.IP "\fBREJECT \fIoptional text...\fR
|
.IP "\fBREJECT \fIoptional text...\fR
|
||||||
Reject the address etc. that matches the pattern. Reply with
|
Reject the address etc. that matches the pattern. Reply with
|
||||||
\fI$reject_code optional text...\fR when the optional text is
|
"\fB$access_map_reject_code \fIoptional text...\fR" when the
|
||||||
|
optional text is
|
||||||
specified, otherwise reply with a generic error response message.
|
specified, otherwise reply with a generic error response message.
|
||||||
.IP "\fBDEFER_IF_REJECT \fIoptional text...\fR
|
.IP "\fBDEFER_IF_REJECT \fIoptional text...\fR
|
||||||
Defer the request if some later restriction would result in a
|
Defer the request if some later restriction would result in a
|
||||||
REJECT action. Reply with "\fB450 4.7.1 \fI optional
|
REJECT action. Reply with "\fB450 4.7.1 \fI optional
|
||||||
text...\fR when the
|
text...\fR" when the
|
||||||
optional text is specified, otherwise reply with a generic error
|
optional text is specified, otherwise reply with a generic error
|
||||||
response message.
|
response message.
|
||||||
.sp
|
.sp
|
||||||
@ -203,7 +204,7 @@ This feature is available in Postfix 2.1 and later.
|
|||||||
.IP "\fBDEFER_IF_PERMIT \fIoptional text...\fR
|
.IP "\fBDEFER_IF_PERMIT \fIoptional text...\fR
|
||||||
Defer the request if some later restriction would result in a
|
Defer the request if some later restriction would result in a
|
||||||
an explicit or implicit PERMIT action.
|
an explicit or implicit PERMIT action.
|
||||||
Reply with "\fB450 4.7.1 \fI optional text...\fR when the
|
Reply with "\fB450 4.7.1 \fI optional text...\fR" when the
|
||||||
optional text is specified, otherwise reply with a generic error
|
optional text is specified, otherwise reply with a generic error
|
||||||
response message.
|
response message.
|
||||||
.sp
|
.sp
|
||||||
|
@ -173,7 +173,10 @@ stress=
|
|||||||
These attributes are empty in case of no certificate authentication.
|
These attributes are empty in case of no certificate authentication.
|
||||||
As of Postfix 2.2.11 these attribute values are encoded as
|
As of Postfix 2.2.11 these attribute values are encoded as
|
||||||
xtext: some characters are represented by +XX, where XX is the
|
xtext: some characters are represented by +XX, where XX is the
|
||||||
two-digit hexadecimal representation of the character value.
|
two-digit hexadecimal representation of the character value. With
|
||||||
|
Postfix 2.5 and later, the decoded string may contain non-ASCII
|
||||||
|
characters. If so, this is a UTF-8 string; xtext encoding works
|
||||||
|
with the bytes of the UTF-8 string, not the characters.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
|
<li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
|
||||||
|
@ -170,12 +170,13 @@
|
|||||||
# (Postfix version 2.3 and later).
|
# (Postfix version 2.3 and later).
|
||||||
# .IP "\fBREJECT \fIoptional text...\fR
|
# .IP "\fBREJECT \fIoptional text...\fR
|
||||||
# Reject the address etc. that matches the pattern. Reply with
|
# Reject the address etc. that matches the pattern. Reply with
|
||||||
# \fI$reject_code optional text...\fR when the optional text is
|
# "\fB$access_map_reject_code \fIoptional text...\fR" when the
|
||||||
|
# optional text is
|
||||||
# specified, otherwise reply with a generic error response message.
|
# specified, otherwise reply with a generic error response message.
|
||||||
# .IP "\fBDEFER_IF_REJECT \fIoptional text...\fR
|
# .IP "\fBDEFER_IF_REJECT \fIoptional text...\fR
|
||||||
# Defer the request if some later restriction would result in a
|
# Defer the request if some later restriction would result in a
|
||||||
# REJECT action. Reply with "\fB450 4.7.1 \fI optional
|
# REJECT action. Reply with "\fB450 4.7.1 \fI optional
|
||||||
# text...\fR when the
|
# text...\fR" when the
|
||||||
# optional text is specified, otherwise reply with a generic error
|
# optional text is specified, otherwise reply with a generic error
|
||||||
# response message.
|
# response message.
|
||||||
# .sp
|
# .sp
|
||||||
@ -183,7 +184,7 @@
|
|||||||
# .IP "\fBDEFER_IF_PERMIT \fIoptional text...\fR
|
# .IP "\fBDEFER_IF_PERMIT \fIoptional text...\fR
|
||||||
# Defer the request if some later restriction would result in a
|
# Defer the request if some later restriction would result in a
|
||||||
# an explicit or implicit PERMIT action.
|
# an explicit or implicit PERMIT action.
|
||||||
# Reply with "\fB450 4.7.1 \fI optional text...\fR when the
|
# Reply with "\fB450 4.7.1 \fI optional text...\fR" when the
|
||||||
# optional text is specified, otherwise reply with a generic error
|
# optional text is specified, otherwise reply with a generic error
|
||||||
# response message.
|
# response message.
|
||||||
# .sp
|
# .sp
|
||||||
|
@ -772,6 +772,16 @@ int bounce_original(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
|
|||||||
return (vstream_ferror(bounce));
|
return (vstream_ferror(bounce));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX The cleanup server removes Return-Path: headers. This should be
|
||||||
|
* done only with mail that enters via a non-SMTP channel, but changing
|
||||||
|
* this now could break other software. Removing Return-Path: could break
|
||||||
|
* digital signatures, though this is unlikely. In any case,
|
||||||
|
* header_checks are more effective when the Return-Path: header is
|
||||||
|
* present, so we prepend one to the bounce message.
|
||||||
|
*/
|
||||||
|
post_mail_fprintf(bounce, "Return-Path: <%s>", STR(bounce_info->sender));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the original message contents. We're doing raw record output here
|
* Copy the original message contents. We're doing raw record output here
|
||||||
* so that we don't throw away binary transparency yet.
|
* so that we don't throw away binary transparency yet.
|
||||||
|
@ -47,6 +47,10 @@
|
|||||||
/*
|
/*
|
||||||
* Header names are given in the preferred capitalization. The lookups are
|
* Header names are given in the preferred capitalization. The lookups are
|
||||||
* case-insensitive.
|
* case-insensitive.
|
||||||
|
*
|
||||||
|
* XXX Removing Return-Path: headers should probably be done only with mail
|
||||||
|
* that enters via a non-SMTP channel. Changing this now could break other
|
||||||
|
* software. See also comments in bounce_notify_util.c.
|
||||||
*/
|
*/
|
||||||
static const HEADER_OPTS header_opts[] = {
|
static const HEADER_OPTS header_opts[] = {
|
||||||
"Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP,
|
"Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP,
|
||||||
|
@ -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 "20080428"
|
#define MAIL_RELEASE_DATE "20080510"
|
||||||
#define MAIL_VERSION_NUMBER "2.6"
|
#define MAIL_VERSION_NUMBER "2.6"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -2496,6 +2496,60 @@ static void rcpt_reset(SMTPD_STATE *state)
|
|||||||
state->rcpt_overshoot = 0;
|
state->rcpt_overshoot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rfc2047_comment_encode - encode comment string */
|
||||||
|
|
||||||
|
static VSTRING *rfc2047_comment_encode(const char *str, const char *charset)
|
||||||
|
{
|
||||||
|
VSTRING *buf = vstring_alloc(30);
|
||||||
|
const unsigned char *cp;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX Most of the RFC 2047 "especials" are not special in RFC*822
|
||||||
|
* comments, but we encode them anyway to avoid complaints.
|
||||||
|
*
|
||||||
|
* XXX In Received: header comments we enclose peer and issuer common names
|
||||||
|
* with "" quotes. This is the cause of several quirks.
|
||||||
|
*
|
||||||
|
* 1) We encode text that contains the " character, even though that
|
||||||
|
* character is not special for RFC*822.
|
||||||
|
*
|
||||||
|
* 2) Long comments look ugly when folded in-between quotes, so we ignore
|
||||||
|
* the recommended limit of 75 characters per encoded word.
|
||||||
|
*
|
||||||
|
* 3) We must encode the the enclosing quotes, to avoid producing invalid
|
||||||
|
* encoded words.
|
||||||
|
*/
|
||||||
|
#define ESPECIALS "()<>@,;:\"/[]?.=" /* Special in RFC 2047 */
|
||||||
|
#define CSPECIALS "\\\"()" /* Special in our comments */
|
||||||
|
|
||||||
|
/* Don't encode if not needed. */
|
||||||
|
for (cp = (unsigned char *) str; /* see below */ ; ++cp) {
|
||||||
|
if ((ch = *cp) == 0) {
|
||||||
|
vstring_sprintf(buf, "\"%s\"", str);
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
|
if (!ISPRINT(ch) || strchr(CSPECIALS, ch))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use quoted-printable (like) encoding with spaces mapped to underscore.
|
||||||
|
*/
|
||||||
|
vstring_sprintf(buf, "=?%s?Q?=%02X", charset, '"');
|
||||||
|
for (cp = (unsigned char *) str; (ch = *cp) != 0; ++cp) {
|
||||||
|
if (!ISPRINT(ch) || strchr(ESPECIALS CSPECIALS, ch)) {
|
||||||
|
vstring_sprintf_append(buf, "=%02X", ch);
|
||||||
|
} else if (ch == ' ') {
|
||||||
|
VSTRING_ADDCH(buf, '_');
|
||||||
|
} else {
|
||||||
|
VSTRING_ADDCH(buf, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vstring_sprintf_append(buf, "=%02X?=", '"');
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
|
|
||||||
/* comment_sanitize - clean up comment string */
|
/* comment_sanitize - clean up comment string */
|
||||||
|
|
||||||
static void comment_sanitize(VSTRING *comment_string)
|
static void comment_sanitize(VSTRING *comment_string)
|
||||||
@ -2526,6 +2580,7 @@ static void comment_sanitize(VSTRING *comment_string)
|
|||||||
}
|
}
|
||||||
while (pc-- > 0)
|
while (pc-- > 0)
|
||||||
VSTRING_ADDCH(comment_string, ')');
|
VSTRING_ADDCH(comment_string, ')');
|
||||||
|
VSTRING_TERMINATE(comment_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* data_cmd - process DATA command */
|
/* data_cmd - process DATA command */
|
||||||
@ -2654,6 +2709,10 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
|||||||
|
|
||||||
#define VSTRING_STRDUP(s) vstring_strcpy(vstring_alloc(strlen(s) + 1), (s))
|
#define VSTRING_STRDUP(s) vstring_strcpy(vstring_alloc(strlen(s) + 1), (s))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Certificate CN information is arbitrary content in the UTF-8
|
||||||
|
* character set.
|
||||||
|
*/
|
||||||
#ifdef USE_TLS
|
#ifdef USE_TLS
|
||||||
if (var_smtpd_tls_received_header && state->tls_context) {
|
if (var_smtpd_tls_received_header && state->tls_context) {
|
||||||
out_fprintf(out_stream, REC_TYPE_NORM,
|
out_fprintf(out_stream, REC_TYPE_NORM,
|
||||||
@ -2663,13 +2722,14 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
|||||||
state->tls_context->cipher_usebits,
|
state->tls_context->cipher_usebits,
|
||||||
state->tls_context->cipher_algbits);
|
state->tls_context->cipher_algbits);
|
||||||
if (TLS_CERT_IS_PRESENT(state->tls_context)) {
|
if (TLS_CERT_IS_PRESENT(state->tls_context)) {
|
||||||
peer_CN = VSTRING_STRDUP(state->tls_context->peer_CN);
|
peer_CN =
|
||||||
comment_sanitize(peer_CN);
|
rfc2047_comment_encode(state->tls_context->peer_CN,
|
||||||
issuer_CN = VSTRING_STRDUP(state->tls_context->issuer_CN ?
|
"utf-8");
|
||||||
state->tls_context->issuer_CN : "");
|
issuer_CN =
|
||||||
comment_sanitize(issuer_CN);
|
rfc2047_comment_encode(state->tls_context->issuer_CN,
|
||||||
|
"utf-8");
|
||||||
out_fprintf(out_stream, REC_TYPE_NORM,
|
out_fprintf(out_stream, REC_TYPE_NORM,
|
||||||
"\t(Client CN \"%s\", Issuer \"%s\" (%s))",
|
"\t(Client CN %s, Issuer %s (%s))",
|
||||||
STR(peer_CN), STR(issuer_CN),
|
STR(peer_CN), STR(issuer_CN),
|
||||||
TLS_CERT_IS_TRUSTED(state->tls_context) ?
|
TLS_CERT_IS_TRUSTED(state->tls_context) ?
|
||||||
"verified OK" : "not verified");
|
"verified OK" : "not verified");
|
||||||
|
@ -180,14 +180,6 @@ typedef struct SMTPD_STATE {
|
|||||||
ssize_t milter_argc;
|
ssize_t milter_argc;
|
||||||
} SMTPD_STATE;
|
} SMTPD_STATE;
|
||||||
|
|
||||||
/*
|
|
||||||
* Construct name[addr] or name[addr]:port as appropriate
|
|
||||||
*/
|
|
||||||
#define SMTPD_BUILD_NAMADDRPORT(name, addr, port) \
|
|
||||||
concatenate((name), "[", (addr), "]", \
|
|
||||||
var_smtpd_client_port_log ? ":" : (char *) 0, \
|
|
||||||
(port), (char *) 0)
|
|
||||||
|
|
||||||
#define SMTPD_FLAG_HANGUP (1<<0) /* disconnect */
|
#define SMTPD_FLAG_HANGUP (1<<0) /* disconnect */
|
||||||
|
|
||||||
#define SMTPD_STATE_XFORWARD_INIT (1<<0) /* xforward preset done */
|
#define SMTPD_STATE_XFORWARD_INIT (1<<0) /* xforward preset done */
|
||||||
@ -287,6 +279,14 @@ extern void smtpd_peer_reset(SMTPD_STATE *state);
|
|||||||
#define SMTPD_PEER_CODE_PERM 5
|
#define SMTPD_PEER_CODE_PERM 5
|
||||||
#define SMTPD_PEER_CODE_FORGED 6
|
#define SMTPD_PEER_CODE_FORGED 6
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Construct name[addr] or name[addr]:port as appropriate
|
||||||
|
*/
|
||||||
|
#define SMTPD_BUILD_NAMADDRPORT(name, addr, port) \
|
||||||
|
concatenate((name), "[", (addr), "]", \
|
||||||
|
var_smtpd_client_port_log ? ":" : (char *) 0, \
|
||||||
|
(port), (char *) 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Choose between normal or forwarded attributes.
|
* Choose between normal or forwarded attributes.
|
||||||
*
|
*
|
||||||
|
@ -1813,7 +1813,6 @@ static int reject_unverified_address(SMTPD_STATE *state, const char *addr,
|
|||||||
SND_DSN : "4.1.1",
|
SND_DSN : "4.1.1",
|
||||||
"<%s>: %s rejected: address verification problem",
|
"<%s>: %s rejected: address verification problem",
|
||||||
reply_name, reply_class);
|
reply_name, reply_class);
|
||||||
rqst_status = SMTPD_CHECK_DUNNO;
|
|
||||||
} else {
|
} else {
|
||||||
switch (rcpt_status) {
|
switch (rcpt_status) {
|
||||||
default:
|
default:
|
||||||
|
@ -30,12 +30,12 @@
|
|||||||
/* tls_peer_CN() returns the text CommonName for the peer
|
/* tls_peer_CN() returns the text CommonName for the peer
|
||||||
/* certificate subject, or an empty string if no CommonName was
|
/* certificate subject, or an empty string if no CommonName was
|
||||||
/* found. The result is allocated with mymalloc() and must be
|
/* found. The result is allocated with mymalloc() and must be
|
||||||
/* freed by the caller.
|
/* freed by the caller; it is arbitrary UTF-8 content.
|
||||||
/*
|
/*
|
||||||
/* tls_issuer_CN() returns the text CommonName for the peer
|
/* tls_issuer_CN() returns the text CommonName for the peer
|
||||||
/* certificate issuer, or an empty string if no CommonName was
|
/* certificate issuer, or an empty string if no CommonName was
|
||||||
/* found. The result is allocated with mymalloc() and must be
|
/* found. The result is allocated with mymalloc() and must be
|
||||||
/* freed by the caller.
|
/* freed by the caller; it is arbitrary UTF-8 content.
|
||||||
/*
|
/*
|
||||||
/* tls_dns_name() returns the string value of a GENERAL_NAME
|
/* tls_dns_name() returns the string value of a GENERAL_NAME
|
||||||
/* from a DNS subjectAltName extension. If non-printable characters
|
/* from a DNS subjectAltName extension. If non-printable characters
|
||||||
@ -278,11 +278,9 @@ static char *tls_text_name(X509_NAME *name, int nid, const char *label,
|
|||||||
int pos;
|
int pos;
|
||||||
X509_NAME_ENTRY *entry;
|
X509_NAME_ENTRY *entry;
|
||||||
ASN1_STRING *entry_str;
|
ASN1_STRING *entry_str;
|
||||||
int typ;
|
int asn1_type;
|
||||||
int len;
|
int utf8_length;
|
||||||
unsigned char *val;
|
unsigned char *utf8_value;
|
||||||
unsigned char *utf;
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
if (name == 0 || (pos = X509_NAME_get_index_by_NID(name, nid, -1)) < 0) {
|
if (name == 0 || (pos = X509_NAME_get_index_by_NID(name, nid, -1)) < 0) {
|
||||||
if (gripe != DONT_GRIPE) {
|
if (gripe != DONT_GRIPE) {
|
||||||
@ -321,96 +319,72 @@ static char *tls_text_name(X509_NAME *name, int nid, const char *label,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Peername checks are security sensitive, carefully scrutinize the
|
* XXX Convert everything into UTF-8. This is a super-set of ASCII, so we
|
||||||
* input!
|
* don't have to bother with separate code paths for ASCII-like content.
|
||||||
|
* If the payload is ASCII then we won't waste lots of CPU cycles
|
||||||
|
* converting it into UTF-8. It's up to OpenSSL to do something
|
||||||
|
* reasonable when converting ASCII formats that contain non-ASCII
|
||||||
|
* content.
|
||||||
|
*
|
||||||
|
* XXX Don't bother optimizing the string length error check. It is not
|
||||||
|
* worth the complexity.
|
||||||
*/
|
*/
|
||||||
typ = ASN1_STRING_type(entry_str);
|
asn1_type = ASN1_STRING_type(entry_str);
|
||||||
len = ASN1_STRING_length(entry_str);
|
if ((utf8_length = ASN1_STRING_to_UTF8(&utf8_value, entry_str)) < 0) {
|
||||||
val = ASN1_STRING_data(entry_str);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* http://www.apps.ietf.org/rfc/rfc3280.html#sec-4.1.2.4 Quick Summary:
|
|
||||||
*
|
|
||||||
* The DirectoryString type is defined as a choice of PrintableString,
|
|
||||||
* TeletexString, BMPString, UTF8String, and UniversalString. The
|
|
||||||
* UTF8String encoding is the preferred encoding, and all certificates
|
|
||||||
* issued after December 31, 2003 MUST use the UTF8String encoding of
|
|
||||||
* DirectoryString (except as noted below).
|
|
||||||
*
|
|
||||||
* XXX: 2007, the above has not happened yet (of course), and we continue to
|
|
||||||
* see new certificates with T61STRING (Teletex) attribute values.
|
|
||||||
*
|
|
||||||
* XXX: 2007, at this time there are only two ASN.1 fixed width multi-byte
|
|
||||||
* string encodings, BMPSTRING (16 bit Unicode) and UniversalString
|
|
||||||
* (32-bit Unicode). The only variable width ASN.1 string encoding is
|
|
||||||
* UTF8 with all the other encodings being 1 byte wide subsets or subsets
|
|
||||||
* of ASCII.
|
|
||||||
*
|
|
||||||
* Relying on this could simplify the code, because we would never convert
|
|
||||||
* unexpected single-byte encodings, but is involves too many cases to be
|
|
||||||
* sure that we have a complete set and the assumptions may become false.
|
|
||||||
* So, we pessimistically convert encodings not blessed by RFC 2459, and
|
|
||||||
* filter out all types that are not string types as a side-effect of
|
|
||||||
* UTF8 conversion (the ASN.1 library knows which types are string types
|
|
||||||
* and how wide they are...).
|
|
||||||
*
|
|
||||||
* XXX: Two possible states after switch, either "utf == val" and it MUST
|
|
||||||
* NOT be freed with OPENSSL_free(), or "utf != val" and it MUST be freed
|
|
||||||
* with OPENSSL_free().
|
|
||||||
*/
|
|
||||||
switch (typ) {
|
|
||||||
case V_ASN1_PRINTABLESTRING: /* X.500 portable ASCII
|
|
||||||
* printables */
|
|
||||||
case V_ASN1_IA5STRING: /* ISO 646 ~ ASCII */
|
|
||||||
case V_ASN1_T61STRING: /* Essentially ISO-Latin */
|
|
||||||
case V_ASN1_UTF8STRING: /* UTF8 */
|
|
||||||
utf = val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* May shrink in wash, but BMPSTRING only shrinks by 50%. Others may
|
|
||||||
* shrink by up to 75%. We Sanity check the length before bothering
|
|
||||||
* to copy any large strings to convert to UTF8, only to find out
|
|
||||||
* they don't fit. So long as no new MB types are introduced, and
|
|
||||||
* weird string encodings unsanctioned by RFC 3280, are used in the
|
|
||||||
* issuer or subject DN, this "conservative" estimate will be exact.
|
|
||||||
*/
|
|
||||||
len >>= (typ == V_ASN1_BMPSTRING) ? 1 : 2;
|
|
||||||
if (len >= CCERT_BUFSIZ) {
|
|
||||||
msg_warn("%s: %s: peer %s too long: %d",
|
|
||||||
myname, TLScontext->namaddr, label, len);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if ((len = ASN1_STRING_to_UTF8(&utf, entry_str)) < 0) {
|
|
||||||
msg_warn("%s: %s: error decoding peer %s of ASN.1 type=%d",
|
msg_warn("%s: %s: error decoding peer %s of ASN.1 type=%d",
|
||||||
myname, TLScontext->namaddr, label, typ);
|
myname, TLScontext->namaddr, label, asn1_type);
|
||||||
tls_print_errors();
|
tls_print_errors();
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#define RETURN(x) do { if (utf!=val) OPENSSL_free(utf); return (x); } while (0)
|
|
||||||
|
|
||||||
if (len >= CCERT_BUFSIZ) {
|
/*
|
||||||
|
* No returns without cleaning up. A good optimizer will replace multiple
|
||||||
|
* blocks of identical code by jumps to just one such block.
|
||||||
|
*/
|
||||||
|
#define TLS_TEXT_NAME_RETURN(x) do { \
|
||||||
|
char *__tls_text_name_temp = (x); \
|
||||||
|
OPENSSL_free(utf8_value); \
|
||||||
|
return (__tls_text_name_temp); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for (cp = utf8_value; (ch = *cp) != 0; cp++) {
|
||||||
|
if (ISASCII(ch) && !ISPRINT(ch)) {
|
||||||
|
msg_warn("%s: %s: non-printable content in peer %s",
|
||||||
|
myname, TLScontext->namaddr, label);
|
||||||
|
TLS_TEXT_NAME_RETURN(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove trailing null characters. They would give false alarms with the
|
||||||
|
* length check and with the embedded null check.
|
||||||
|
*/
|
||||||
|
#define TRIM0(s, l) do { while ((l) > 0 && (s)[(l)-1] == 0) --(l); } while (0)
|
||||||
|
|
||||||
|
TRIM0(utf8_value, utf8_length);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enforce the length limit, because the caller will copy the result into
|
||||||
|
* a fixed-length buffer.
|
||||||
|
*/
|
||||||
|
if (utf8_length >= CCERT_BUFSIZ) {
|
||||||
msg_warn("%s: %s: peer %s too long: %d",
|
msg_warn("%s: %s: peer %s too long: %d",
|
||||||
myname, TLScontext->namaddr, label, len);
|
myname, TLScontext->namaddr, label, utf8_length);
|
||||||
RETURN(0);
|
TLS_TEXT_NAME_RETURN(0);
|
||||||
}
|
}
|
||||||
if (len != strlen((char *) utf)) {
|
|
||||||
msg_warn("%s: %s: internal NUL in peer %s",
|
/*
|
||||||
|
* Don't allow embedded nulls in ASCII or UTF-8 names. OpenSSL is
|
||||||
|
* responsible for producing properly-formatted UTF-8.
|
||||||
|
*/
|
||||||
|
if (utf8_length != strlen((char *) utf8_value)) {
|
||||||
|
msg_warn("%s: %s: NULL character in peer %s",
|
||||||
myname, TLScontext->namaddr, label);
|
myname, TLScontext->namaddr, label);
|
||||||
RETURN(0);
|
TLS_TEXT_NAME_RETURN(0);
|
||||||
}
|
}
|
||||||
for (cp = (char *) utf; *cp; cp++) {
|
TLS_TEXT_NAME_RETURN(mystrdup((char *) utf8_value));
|
||||||
if (!ISASCII(*cp) || !ISPRINT(*cp)) {
|
|
||||||
msg_warn("%s: %s: non-printable characters in peer %s",
|
|
||||||
myname, TLScontext->namaddr, label);
|
|
||||||
RETURN(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cp = mystrdup((char *) utf);
|
|
||||||
RETURN(cp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tls_dns_name - Extract valid DNS name from subjectAltName value */
|
/* tls_dns_name - Extract valid DNS name from subjectAltName value */
|
||||||
@ -421,6 +395,7 @@ const char *tls_dns_name(const GENERAL_NAME * gn,
|
|||||||
const char *myname = "tls_dns_name";
|
const char *myname = "tls_dns_name";
|
||||||
char *cp;
|
char *cp;
|
||||||
const char *dnsname;
|
const char *dnsname;
|
||||||
|
int len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Peername checks are security sensitive, carefully scrutinize the
|
* Peername checks are security sensitive, carefully scrutinize the
|
||||||
@ -443,6 +418,8 @@ const char *tls_dns_name(const GENERAL_NAME * gn,
|
|||||||
* Safe to treat as an ASCII string possibly holding a DNS name
|
* Safe to treat as an ASCII string possibly holding a DNS name
|
||||||
*/
|
*/
|
||||||
dnsname = (char *) ASN1_STRING_data(gn->d.ia5);
|
dnsname = (char *) ASN1_STRING_data(gn->d.ia5);
|
||||||
|
len = ASN1_STRING_length(gn->d.ia5);
|
||||||
|
TRIM0(dnsname, len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Per Dr. Steven Henson of the OpenSSL development team, ASN1_IA5STRING
|
* Per Dr. Steven Henson of the OpenSSL development team, ASN1_IA5STRING
|
||||||
@ -451,7 +428,7 @@ const char *tls_dns_name(const GENERAL_NAME * gn,
|
|||||||
* always appended to make sure that the string is terminated, but the
|
* always appended to make sure that the string is terminated, but the
|
||||||
* ASN.1 length may differ from strlen().
|
* ASN.1 length may differ from strlen().
|
||||||
*/
|
*/
|
||||||
if (ASN1_STRING_length(gn->d.ia5) != strlen(dnsname)) {
|
if (len != strlen(dnsname)) {
|
||||||
msg_warn("%s: %s: internal NUL in subjectAltName",
|
msg_warn("%s: %s: internal NUL in subjectAltName",
|
||||||
myname, TLScontext->namaddr);
|
myname, TLScontext->namaddr);
|
||||||
return 0;
|
return 0;
|
||||||
@ -463,10 +440,9 @@ const char *tls_dns_name(const GENERAL_NAME * gn,
|
|||||||
* compare equal to the expected peername, so being more strict than
|
* compare equal to the expected peername, so being more strict than
|
||||||
* "printable" is likely excessive...
|
* "printable" is likely excessive...
|
||||||
*/
|
*/
|
||||||
for (cp = (char *) dnsname; cp && *cp; cp++)
|
if (*dnsname && !allprint(dnsname)) {
|
||||||
if (!ISASCII(*cp) || !ISPRINT(*cp)) {
|
|
||||||
cp = mystrdup(dnsname);
|
cp = mystrdup(dnsname);
|
||||||
msg_warn("%s: %s: non-printable characters in subjectAltName: %s",
|
msg_warn("%s: %s: non-printable characters in subjectAltName: %.100s",
|
||||||
myname, TLScontext->namaddr, printable(cp, '?'));
|
myname, TLScontext->namaddr, printable(cp, '?'));
|
||||||
myfree(cp);
|
myfree(cp);
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user