2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 09:57:34 +00:00

postfix-3.8-20230312

This commit is contained in:
Wietse Venema 2023-03-12 00:00:00 -05:00 committed by Viktor Dukhovni
parent 3474213a2b
commit d88c99caea
27 changed files with 389 additions and 56 deletions

View File

@ -26921,3 +26921,31 @@ Apologies for any names omitted.
example is to capture output from "postmulti -p status" to
figure out which instances are or are not running. Files:
postfix/postfix.c, postlog/postlog.c.
20230209
Cleanup: in smtp_service_addr() refined the loop detection
code for SRV lookup. File: smtp/smtp_addr.c.
Cleanup: renamed macros with invisible side effects and
implicit inputs to upper case. Verified that the compiled
code did not change. File: tls_fprint.c.
20230310
Cleanup: the milter header/body checks logged less text (up
to 60 bytes) than the 'original' header/body checks (up to
200 bytes). Problem reported by Aleksandr Stankevic. Fixed
the same inconsistency in the Postfix SMTP client. Files:
cleanup/cleanup_milter.c, smtp/smtp_proto.c.
20230311
Hardening: the Postfix SMTP server can now aggregate
smtpd_client_*_rate and smtpd_client_*_count statistics by
network block, as specified with smtpd_client_ipv4_prefix_length
(default 32, no aggregation) and smtpd_client_ipv6_prefix_length
(default 72, aggregation by /72 network blocks). The latter
raises the bar for a memory exhaustion attack. Files:
util/net_mask_top.[hc], smtpd/smtpd.c, smtpd/smtpd_peer.c,
mantools/postlink, proto/postconf.proto.

View File

@ -14,6 +14,13 @@ Wish list:
Multi-recipient support in sender/recipient_bcc_maps and
always_bcc.
mail_conf_xxx supprt for non-negative numbers (i.e.
numbers with a lower bound of zero).
Log anvil transgressions with their address range (in
addition to the offending IP address. We should not disclose
to random clients how we aggregate anvil event counters.
Should "postconf -f" pretty-print text inside {}?
Is there any code that calls attr_scan*() and that works

View File

@ -14639,6 +14639,33 @@ This feature is available in Postfix 2.2 and later.
</p>
</DD>
<DT><b><a name="smtpd_client_ipv4_prefix_length">smtpd_client_ipv4_prefix_length</a>
(default: 32)</b></DT><DD>
<p> Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv4 network blocks with the specified network prefix. Aggregation
reduces the <a href="anvil.8.html">anvil(8)</a> resources needed to maintain counters. By
default, aggregation is disabled for IPv4. </p>
<p> This feature is available in Postfix 3.8 and later. </p>
</DD>
<DT><b><a name="smtpd_client_ipv6_prefix_length">smtpd_client_ipv6_prefix_length</a>
(default: 72)</b></DT><DD>
<p> Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv6 network blocks with the specified network prefix. Aggregation
reduces the <a href="anvil.8.html">anvil(8)</a> resources needed to maintain counters. By
default, aggregation is enabled for IPv6.
</p>
<p> This feature is available in Postfix 3.8 and later. </p>
</DD>
<DT><b><a name="smtpd_client_message_rate_limit">smtpd_client_message_rate_limit</a>

View File

@ -962,6 +962,16 @@ SMTPD(8) SMTPD(8)
<b><a href="postconf.5.html#header_from_format">header_from_format</a> (standard)</b>
The format of the Postfix-generated <b>From:</b> header.
Available in Postfix version 3.8 and later:
<b><a href="postconf.5.html#smtpd_client_ipv4_prefix_length">smtpd_client_ipv4_prefix_length</a> (32)</b>
Aggregate smtpd_client_*_count and smtpd_client_*_rate statis-
tics by IPv4 network blocks with the specified network prefix.
<b><a href="postconf.5.html#smtpd_client_ipv6_prefix_length">smtpd_client_ipv6_prefix_length</a> (72)</b>
Aggregate smtpd_client_*_count and smtpd_client_*_rate statis-
tics by IPv6 network blocks with the specified network prefix.
<b>TARPIT CONTROLS</b>
When a remote SMTP client makes errors, the Postfix SMTP server can
insert delays before responding. This can help to slow down run-away

View File

@ -9956,6 +9956,20 @@ parent_domain_matches_subdomains parameter value (Postfix 3.0 and
later).
.PP
This feature is available in Postfix 2.2 and later.
.SH smtpd_client_ipv4_prefix_length (default: 32)
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv4 network blocks with the specified network prefix. Aggregation
reduces the \fBanvil\fR(8) resources needed to maintain counters. By
default, aggregation is disabled for IPv4.
.PP
This feature is available in Postfix 3.8 and later.
.SH smtpd_client_ipv6_prefix_length (default: 72)
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv6 network blocks with the specified network prefix. Aggregation
reduces the \fBanvil\fR(8) resources needed to maintain counters. By
default, aggregation is enabled for IPv6.
.PP
This feature is available in Postfix 3.8 and later.
.SH smtpd_client_message_rate_limit (default: 0)
The maximal number of message delivery requests that any client is
allowed to make to this service per time unit, regardless of whether

View File

@ -841,6 +841,14 @@ DATA and BDAT requests, when deadlines are enabled with
smtpd_per_request_deadline.
.IP "\fBheader_from_format (standard)\fR"
The format of the Postfix\-generated \fBFrom:\fR header.
.PP
Available in Postfix version 3.8 and later:
.IP "\fBsmtpd_client_ipv4_prefix_length (32)\fR"
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv4 network blocks with the specified network prefix.
.IP "\fBsmtpd_client_ipv6_prefix_length (72)\fR"
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv6 network blocks with the specified network prefix.
.SH "TARPIT CONTROLS"
.na
.nf

View File

@ -543,6 +543,8 @@ while (<>) {
s;\bsmtpd_client_port_logging\b;<a href="postconf.5.html#smtpd_client_port_logging">$&</a>;g;
s;\bsmtpd_client_recipient_rate_limit\b;<a href="postconf.5.html#smtpd_client_recipient_rate_limit">$&</a>;g;
s;\bsmtpd_client_new_tls_session_rate_limit\b;<a href="postconf.5.html#smtpd_client_new_tls_session_rate_limit">$&</a>;g;
s;\bsmtpd_client_ipv4_prefix_length\b;<a href="postconf.5.html#smtpd_client_ipv4_prefix_length">$&</a>;g;
s;\bsmtpd_client_ipv6_prefix_length\b;<a href="postconf.5.html#smtpd_client_ipv6_prefix_length">$&</a>;g;
s;\bsmtpd_client_restrictions\b;<a href="postconf.5.html#smtpd_client_restrictions">$&</a>;g;
s;\bsmtpd_command_filter\b;<a href="postconf.5.html#smtpd_command_filter">$&</a>;g;
s;\bsmtpd_data_restrictions\b;<a href="postconf.5.html#smtpd_data_restrictions">$&</a>;g;

View File

@ -18598,3 +18598,22 @@ lookup as if SRV record lookup was not enabled. </p>
to MX or IP address lookup as if SRV record lookup was not enabled. <p>
<p> This feature is available in Postfix 3.8 and later. </p>
%PARAM smtpd_client_ipv4_prefix_length 32
<p> Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv4 network blocks with the specified network prefix. Aggregation
reduces the anvil(8) resources needed to maintain counters. By
default, aggregation is disabled for IPv4. </p>
<p> This feature is available in Postfix 3.8 and later. </p>
%PARAM smtpd_client_ipv6_prefix_length 72
<p> Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv6 network blocks with the specified network prefix. Aggregation
reduces the anvil(8) resources needed to maintain counters. By
default, aggregation is enabled for IPv6.
</p>
<p> This feature is available in Postfix 3.8 and later. </p>

View File

@ -331,3 +331,4 @@ USE_FNV_32BIT USE_FNV_32BIT
void void cleanup_milter_receive state count
struct DICT open const char int int dict_xx_open
Available in in Postfix version 2 3 3 7
length length of 0 31 0 127

View File

@ -35,3 +35,4 @@ proto proto SASL_README html proto SQLITE_README html
tls tls_proxy h tlsproxy tlsproxy c
postfix postfix c postlog postlog c
postfix postfix c postlog postlog c
util net_mask_top hc smtpd smtpd c smtpd smtpd_peer c

View File

@ -1793,3 +1793,6 @@ Korbar
ign
noport
nopref
ADDRP
iffalse
iftrue

View File

@ -47,3 +47,5 @@ modernisms
Bordo
css
makemanidx
soho
soho

View File

@ -244,7 +244,7 @@ static void cleanup_milter_hbc_log(void *context, const char *action,
const CLEANUP_STATE *state = (CLEANUP_STATE *) context;
const char *attr;
vstring_sprintf(state->temp1, "%s: milter-%s-%s: %s %.60s from %s[%s];",
vstring_sprintf(state->temp1, "%s: milter-%s-%s: %s %.200s from %s[%s];",
state->queue_id, where, action, where, line,
state->client_name, state->client_addr);
if (state->sender)

View File

@ -3198,6 +3198,16 @@ extern int var_smtpd_cntls_limit;
#define DEF_SMTPD_CAUTH_LIMIT 0
extern int var_smtpd_cauth_limit;
#define VAR_SMTPD_CIPV4_PREFIX "smtpd_client_ipv4_prefix_length"
#define DEF_SMTPD_CIPV4_PREFIX 32
#define MAX_SMTPD_CIPV4_PREFIX 32
extern int var_smtpd_cipv4_prefix;
#define VAR_SMTPD_CIPV6_PREFIX "smtpd_client_ipv6_prefix_length"
#define DEF_SMTPD_CIPV6_PREFIX 72
#define MAX_SMTPD_CIPV6_PREFIX 128
extern int var_smtpd_cipv6_prefix;
#define VAR_SMTPD_HOGGERS "smtpd_client_event_limit_exceptions"
#define DEF_SMTPD_HOGGERS "${smtpd_client_connection_limit_exceptions:$" VAR_MYNETWORKS "}"
extern char *var_smtpd_hoggers;

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
#define MAIL_RELEASE_DATE "20230308"
#define MAIL_RELEASE_DATE "20230312"
#define MAIL_VERSION_NUMBER "3.8"
#ifdef SNAPSHOT

View File

@ -840,7 +840,6 @@ DNS_RR *smtp_service_addr(const char *name, const char *service, DNS_RR **mxrr,
dsb_status(why, "5.4.4");
break;
}
*found_myself |= (self != 0);
/*
* If permitted, fall back to non-SRV record lookups.
@ -854,5 +853,12 @@ DNS_RR *smtp_service_addr(const char *name, const char *service, DNS_RR **mxrr,
else
addr_list = smtp_host_addr(name, misc_flags, why);
}
/*
* Only if we're not falling back.
*/
else {
*found_myself |= (self != 0);
}
return (addr_list);
}

View File

@ -1146,10 +1146,10 @@ static void smtp_hbc_logger(void *context, const char *action,
const SMTP_STATE *state = (SMTP_STATE *) context;
if (*text) {
msg_info("%s: %s: %s %.60s: %s",
msg_info("%s: %s: %s %.200s: %s",
state->request->queue_id, action, where, content, text);
} else {
msg_info("%s: %s: %s %.60s",
msg_info("%s: %s: %s %.200s",
state->request->queue_id, action, where, content);
}
}

View File

@ -492,6 +492,7 @@ smtpd_peer.o: ../../include/myaddrinfo.h
smtpd_peer.o: ../../include/mymalloc.h
smtpd_peer.o: ../../include/name_code.h
smtpd_peer.o: ../../include/name_mask.h
smtpd_peer.o: ../../include/net_mask_top.h
smtpd_peer.o: ../../include/nvtable.h
smtpd_peer.o: ../../include/sock_addr.h
smtpd_peer.o: ../../include/split_at.h

View File

@ -795,6 +795,14 @@
/* smtpd_per_request_deadline.
/* .IP "\fBheader_from_format (standard)\fR"
/* The format of the Postfix-generated \fBFrom:\fR header.
/* .PP
/* Available in Postfix version 3.8 and later:
/* .IP "\fBsmtpd_client_ipv4_prefix_length (32)\fR"
/* Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
/* by IPv4 network blocks with the specified network prefix.
/* .IP "\fBsmtpd_client_ipv6_prefix_length (72)\fR"
/* Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
/* by IPv6 network blocks with the specified network prefix.
/* TARPIT CONTROLS
/* .ad
/* .fi
@ -1411,6 +1419,8 @@ int var_smtpd_cmail_limit;
int var_smtpd_crcpt_limit;
int var_smtpd_cntls_limit;
int var_smtpd_cauth_limit;
int var_smtpd_cipv4_prefix;
int var_smtpd_cipv6_prefix;
char *var_smtpd_hoggers;
char *var_local_rwr_clients;
char *var_smtpd_ehlo_dis_words;
@ -2054,7 +2064,7 @@ static int smtpd_sasl_auth_cmd_wrapper(SMTPD_STATE *state, int argc,
&& anvil_clnt
&& var_smtpd_cauth_limit > 0
&& !namadr_list_match(hogger_list, state->name, state->addr)
&& anvil_clnt_auth(anvil_clnt, state->service, state->addr,
&& anvil_clnt_auth(anvil_clnt, state->service, state->anvil_range,
&rate) == ANVIL_STAT_OK
&& rate > var_smtpd_cauth_limit) {
state->error_mask |= MAIL_ERROR_POLICY;
@ -2512,7 +2522,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
&& anvil_clnt
&& var_smtpd_cmail_limit > 0
&& !namadr_list_match(hogger_list, state->name, state->addr)
&& anvil_clnt_mail(anvil_clnt, state->service, state->addr,
&& anvil_clnt_mail(anvil_clnt, state->service, state->anvil_range,
&rate) == ANVIL_STAT_OK
&& rate > var_smtpd_cmail_limit) {
state->error_mask |= MAIL_ERROR_POLICY;
@ -2906,7 +2916,7 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
&& anvil_clnt
&& var_smtpd_crcpt_limit > 0
&& !namadr_list_match(hogger_list, state->name, state->addr)
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->addr,
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->anvil_range,
&rate) == ANVIL_STAT_OK
&& rate > var_smtpd_crcpt_limit) {
state->error_mask |= MAIL_ERROR_POLICY;
@ -4230,7 +4240,7 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
&& anvil_clnt
&& var_smtpd_crcpt_limit > 0
&& !namadr_list_match(hogger_list, state->name, state->addr)
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->addr,
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->anvil_range,
&rate) == ANVIL_STAT_OK
&& rate > var_smtpd_crcpt_limit) {
state->error_mask |= MAIL_ERROR_POLICY;
@ -5146,7 +5156,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
&& !xclient_allowed
&& anvil_clnt
&& !namadr_list_match(hogger_list, state->name, state->addr)
&& anvil_clnt_newtls(anvil_clnt, state->service, state->addr,
&& anvil_clnt_newtls(anvil_clnt, state->service, state->anvil_range,
&rate) == ANVIL_STAT_OK
&& rate > var_smtpd_cntls_limit) {
state->error_mask |= MAIL_ERROR_POLICY;
@ -5292,8 +5302,8 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
&& !xclient_allowed
&& anvil_clnt
&& !namadr_list_match(hogger_list, state->name, state->addr)
&& anvil_clnt_newtls_stat(anvil_clnt, state->service, state->addr,
&rate) == ANVIL_STAT_OK
&& anvil_clnt_newtls_stat(anvil_clnt, state->service,
state->anvil_range, &rate) == ANVIL_STAT_OK
&& rate > var_smtpd_cntls_limit) {
state->error_mask |= MAIL_ERROR_POLICY;
msg_warn("Refusing STARTTLS request from %s for service %s",
@ -5560,7 +5570,7 @@ static void smtpd_proto(SMTPD_STATE *state)
&& anvil_clnt
&& !namadr_list_match(hogger_list, state->name, state->addr)
&& anvil_clnt_newtls_stat(anvil_clnt, state->service,
state->addr, &tls_rate) == ANVIL_STAT_OK
state->anvil_range, &tls_rate) == ANVIL_STAT_OK
&& tls_rate > var_smtpd_cntls_limit) {
state->error_mask |= MAIL_ERROR_POLICY;
msg_warn("Refusing TLS service request from %s for service %s",
@ -5586,8 +5596,9 @@ static void smtpd_proto(SMTPD_STATE *state)
&& !xclient_allowed
&& anvil_clnt
&& !namadr_list_match(hogger_list, state->name, state->addr)
&& anvil_clnt_connect(anvil_clnt, state->service, state->addr,
&state->conn_count, &state->conn_rate)
&& anvil_clnt_connect(anvil_clnt, state->service,
state->anvil_range, &state->conn_count,
&state->conn_rate)
== ANVIL_STAT_OK) {
if (var_smtpd_cconn_limit > 0
&& state->conn_count > var_smtpd_cconn_limit) {
@ -5845,7 +5856,7 @@ static void smtpd_proto(SMTPD_STATE *state)
&& !xclient_allowed
&& anvil_clnt
&& !namadr_list_match(hogger_list, state->name, state->addr))
anvil_clnt_disconnect(anvil_clnt, state->service, state->addr);
anvil_clnt_disconnect(anvil_clnt, state->service, state->anvil_range);
/*
* Log abnormal session termination, in case postmaster notification has
@ -6427,6 +6438,8 @@ int main(int argc, char **argv)
VAR_SMTPD_CRCPT_LIMIT, DEF_SMTPD_CRCPT_LIMIT, &var_smtpd_crcpt_limit, 0, 0,
VAR_SMTPD_CNTLS_LIMIT, DEF_SMTPD_CNTLS_LIMIT, &var_smtpd_cntls_limit, 0, 0,
VAR_SMTPD_CAUTH_LIMIT, DEF_SMTPD_CAUTH_LIMIT, &var_smtpd_cauth_limit, 0, 0,
VAR_SMTPD_CIPV4_PREFIX, DEF_SMTPD_CIPV4_PREFIX, &var_smtpd_cipv4_prefix, 0, MAX_SMTPD_CIPV4_PREFIX,
VAR_SMTPD_CIPV6_PREFIX, DEF_SMTPD_CIPV6_PREFIX, &var_smtpd_cipv6_prefix, 0, MAX_SMTPD_CIPV6_PREFIX,
#ifdef USE_TLS
VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0,
#endif

View File

@ -77,6 +77,7 @@ typedef struct {
char *addr; /* client host address string */
char *port; /* port for logging */
char *namaddr; /* name[address]:port */
char *anvil_range; /* client address or network/length */
char *rfc_addr; /* address for RFC 2821 */
int addr_family; /* address family */
char *dest_addr; /* Dovecot AUTH, Milter {daemon_addr} */

View File

@ -139,6 +139,7 @@
#include <sock_addr.h>
#include <inet_proto.h>
#include <split_at.h>
#include <net_mask_top.h>
/* Global library. */
@ -250,10 +251,12 @@ static int smtpd_peer_sockaddr_to_hostaddr(SMTPD_STATE *state)
state->addr = mystrdup(colonp + 1);
state->rfc_addr = mystrdup(colonp + 1);
state->addr_family = AF_INET;
aierr = hostaddr_to_sockaddr(state->addr, (char *) 0, 0, &res0);
aierr =
hostaddr_to_sockaddr(state->addr, state->port, 0, &res0);
if (aierr)
msg_fatal("%s: cannot convert %s from string to binary: %s",
myname, state->addr, MAI_STRERROR(aierr));
msg_fatal("%s: cannot convert [%s]:%s to binary: %s",
myname, state->addr, state->port,
MAI_STRERROR(aierr));
sa_length = res0->ai_addrlen;
if (sa_length > sizeof(state->sockaddr))
sa_length = sizeof(state->sockaddr);
@ -264,10 +267,10 @@ static int smtpd_peer_sockaddr_to_hostaddr(SMTPD_STATE *state)
/*
* Following RFC 2821 section 4.1.3, an IPv6 address literal gets
* a prefix of 'IPv6:'. We do this consistently for all IPv6
* addresses that appear in headers or envelopes. The fact
* that valid_mailhost_addr() enforces the form helps of course.
* We use the form without IPV6: prefix when doing access
* control, or when accessing the connection cache.
* addresses that appear in headers or envelopes. The fact that
* valid_mailhost_addr() enforces the form helps of course. We
* use the form without IPV6: prefix when doing access control,
* or when accessing the connection cache.
*/
else {
state->addr = mystrdup(client_addr.buf);
@ -581,6 +584,7 @@ static void smtpd_peer_from_proxy(SMTPD_STATE *state)
void smtpd_peer_init(SMTPD_STATE *state)
{
int af;
/*
* Initialize.
@ -599,6 +603,7 @@ void smtpd_peer_init(SMTPD_STATE *state)
state->namaddr = 0;
state->rfc_addr = 0;
state->port = 0;
state->anvil_range = 0;
state->dest_addr = 0;
state->dest_port = 0;
@ -633,6 +638,16 @@ void smtpd_peer_init(SMTPD_STATE *state)
*/
state->namaddr = SMTPD_BUILD_NAMADDRPORT(state->name, state->addr,
state->port);
/*
* Generate 'address' or 'net/mask' index for anvil event aggregation.
*/
af = SOCK_ADDR_FAMILY(&(state->sockaddr));
state->anvil_range = net_mask_top(af,
SOCK_ADDR_ADDRP(&(state->sockaddr)),
af == AF_INET ?
var_smtpd_cipv4_prefix :
var_smtpd_cipv6_prefix);
}
/* smtpd_peer_reset - destroy peer information */
@ -655,4 +670,6 @@ void smtpd_peer_reset(SMTPD_STATE *state)
myfree(state->dest_addr);
if (state->dest_port)
myfree(state->dest_port);
if (state->anvil_range)
myfree(state->anvil_range);
}

View File

@ -130,11 +130,11 @@
static const char hexcodes[] = "0123456789ABCDEF";
#define checkok(stillok) (ok = ok && (stillok))
#define digest_object(p) digest_data((unsigned char *)(p), sizeof(*(p)))
#define digest_data(p, l) checkok(digest_bytes(mdctx, (p), (l)))
#define digest_string(s) checkok(digest_chars(mdctx, (s)))
#define digest_dane(tlsa) checkok(tls_digest_tlsa(mdctx, tlsa))
#define CHECK_OK_AND(stillok) (ok = ok && (stillok))
#define CHECK_OK_AND_DIGEST_OBJECT(m, p) \
CHECK_OK_AND_DIGEST_DATA((m), (unsigned char *)(p), sizeof(*(p)))
#define CHECK_OK_AND_DIGEST_DATA(m, p, l) CHECK_OK_AND(digest_bytes((m), (p), (l)))
#define CHECK_OK_AND_DIGEST_CHARS(m, s) CHECK_OK_AND(digest_chars((m), (s)))
/* digest_bytes - hash octet string of given length */
@ -186,13 +186,13 @@ static int tls_digest_tlsa(EVP_MD_CTX *mdctx, TLS_TLSA *tlsa)
arr[i++] = (void *) p;
qsort(arr, n, sizeof(arr[0]), tlsa_cmp);
digest_object(&n);
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &n);
for (i = 0; i < n; ++i) {
digest_object(&arr[i]->usage);
digest_object(&arr[i]->selector);
digest_object(&arr[i]->mtype);
digest_object(&arr[i]->length);
digest_data(arr[i]->data, arr[i]->length);
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &arr[i]->usage);
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &arr[i]->selector);
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &arr[i]->mtype);
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &arr[i]->length);
CHECK_OK_AND_DIGEST_DATA(mdctx, arr[i]->data, arr[i]->length);
}
myfree((void *) arr);
return (ok);
@ -218,15 +218,15 @@ const EVP_MD *tls_digest_byname(const char *mdalg, EVP_MD_CTX **mdctxPtr)
* Note that EVP_MD_CTX_{create,destroy} were renamed to, respectively,
* EVP_MD_CTX_{new,free} in OpenSSL 1.1.0.
*/
checkok(md = EVP_get_digestbyname(mdalg));
CHECK_OK_AND(md = EVP_get_digestbyname(mdalg));
/*
* Sanity check: Newer shared libraries could (hypothetical ABI break)
* allow larger digests, we avoid such poison algorithms.
*/
checkok(EVP_MD_size(md) <= EVP_MAX_MD_SIZE);
checkok(mdctx = EVP_MD_CTX_new());
checkok(EVP_DigestInit_ex(mdctx, md, NULL));
CHECK_OK_AND(EVP_MD_size(md) <= EVP_MAX_MD_SIZE);
CHECK_OK_AND(mdctx = EVP_MD_CTX_new());
CHECK_OK_AND(EVP_DigestInit_ex(mdctx, md, NULL));
if (ok && mdctxPtr != 0)
@ -269,10 +269,10 @@ char *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
/* Salt the session lookup key with the OpenSSL runtime version. */
sslversion = OpenSSL_version_num();
digest_string(props->helo ? props->helo : "");
digest_object(&sslversion);
digest_string(props->protocols);
digest_string(ciphers);
CHECK_OK_AND_DIGEST_CHARS(mdctx, props->helo ? props->helo : "");
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &sslversion);
CHECK_OK_AND_DIGEST_CHARS(mdctx, props->protocols);
CHECK_OK_AND_DIGEST_CHARS(mdctx, ciphers);
/*
* Ensure separation of caches for sessions where DANE trust
@ -280,7 +280,7 @@ char *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
* should always see a certificate validation failure, both on initial
* handshake and on resumption.
*/
digest_object(&TLScontext->must_fail);
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &TLScontext->must_fail);
/*
* DNS-based or synthetic DANE trust settings are potentially used at all
@ -288,11 +288,11 @@ char *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
*/
if (TLScontext->level > TLS_LEV_ENCRYPT
&& props->dane && props->dane->tlsa) {
digest_dane(props->dane->tlsa);
CHECK_OK_AND(tls_digest_tlsa(mdctx, props->dane->tlsa));
} else {
int none = 0; /* Record a TLSA RR count of zero */
digest_object(&none);
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &none);
}
/*
@ -300,11 +300,11 @@ char *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
* selection.
*/
if (TLScontext->level > TLS_LEV_ENCRYPT && TLScontext->peer_sni)
digest_string(TLScontext->peer_sni);
CHECK_OK_AND_DIGEST_CHARS(mdctx, TLScontext->peer_sni);
else
digest_string("");
CHECK_OK_AND_DIGEST_CHARS(mdctx, "");
checkok(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
CHECK_OK_AND(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
EVP_MD_CTX_destroy(mdctx);
if (!ok)
msg_fatal("error computing %s message digest", mdalg);
@ -368,8 +368,8 @@ static char *tls_data_fprint(const unsigned char *buf, int len, const char *mdal
if (tls_digest_byname(mdalg, &mdctx) == 0)
msg_panic("digest algorithm \"%s\" not found", mdalg);
digest_data(buf, len);
checkok(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
CHECK_OK_AND_DIGEST_DATA(mdctx, buf, len);
CHECK_OK_AND(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
EVP_MD_CTX_destroy(mdctx);
if (!ok)
msg_fatal("error computing %s message digest", mdalg);

View File

@ -44,7 +44,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
msg_logger.c logwriter.c unix_dgram_connect.c unix_dgram_listen.c \
byte_mask.c known_tcp_ports.c argv_split_at.c dict_stream.c \
sane_strtol.c hash_fnv.c ldseed.c mkmap_cdb.c mkmap_db.c mkmap_dbm.c \
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c net_mask_top.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@ -90,7 +90,7 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
msg_logger.o logwriter.o unix_dgram_connect.o unix_dgram_listen.o \
byte_mask.o known_tcp_ports.o argv_split_at.o dict_stream.o \
sane_strtol.o hash_fnv.o ldseed.o mkmap_db.o mkmap_dbm.o \
mkmap_fail.o mkmap_open.o
mkmap_fail.o mkmap_open.o net_mask_top.o
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros.
@ -121,7 +121,8 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
slmdb.h compat_va_copy.h dict_pipe.h dict_random.h \
valid_utf8_hostname.h midna_domain.h dict_union.h dict_inline.h \
check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h \
net_mask_top.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
DEFS = -I. -D$(SYSTYPE)
@ -2415,6 +2416,15 @@ nbbio.o: mymalloc.h
nbbio.o: nbbio.c
nbbio.o: nbbio.h
nbbio.o: sys_defs.h
net_mask_top.o: check_arg.h
net_mask_top.o: mask_addr.h
net_mask_top.o: msg.h
net_mask_top.o: myaddrinfo.h
net_mask_top.o: net_mask_top.c
net_mask_top.o: net_mask_top.h
net_mask_top.o: sys_defs.h
net_mask_top.o: vbuf.h
net_mask_top.o: vstring.h
netstring.o: check_arg.h
netstring.o: compat_va_copy.h
netstring.o: msg.h

View File

@ -0,0 +1,120 @@
/*++
/* NAME
/* net_mask_top 3
/* SUMMARY
/* convert net/mask to printable string
/* SYNOPSIS
/* #include <mask_addr.h>
/*
/* char *net_mask_top(
/* int family,
/* const void *src,
/* int prefix_len)
/* DESCRIPTION
/* net_mask_top() prints the network portion of the specified
/* IPv4 or IPv6 address, null bits for the host portion, and
/* the prefix length if it is shorter than the address.
/* The result should be passed to myfree(). The code can
/* handle addresses of any length, and bytes of any width.
/*
/* Arguments:
/* .IP af
/* The address family, as with inet_ntop().
/* .IP src
/* Pointer to storage for an IPv4 or IPv6 address, as with
/* inet_ntop().
/* .IP prefix_len
/* The number of most-significant bits in \fBsrc\fR that should
/* not be cleared.
/* DIAGNOSTICS
/* Panic: unexpected protocol family, bad prefix length. Fatal
/* errors: address conversion error.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/*--*/
/*
* System library.
*/
#include <sys_defs.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
/*
* Utility library.
*/
#include <mask_addr.h>
#include <msg.h>
#include <myaddrinfo.h>
#include <net_mask_top.h>
#include <vstring.h>
/*
* XXX Factor out if we also need this in other places.
*/
struct addr_size {
int af; /* address family (binary) */
char ipproto_str[5]; /* IP protocol version (string) */
int addr_bitcount; /* bits per address */
int addr_bytecount; /* bytes per address */
int addr_strlen; /* string representation length */
int slashdigs_strlen; /* length of /0-31, /0-127 */
};
static struct addr_size addr_sizes[] = {
AF_INET, "IPv4", MAI_V4ADDR_BITS, MAI_V4ADDR_BYTES, INET_ADDRSTRLEN, 3,
#ifdef HAS_IPV6
AF_INET6, "IPv6", MAI_V6ADDR_BITS, MAI_V6ADDR_BYTES, INET6_ADDRSTRLEN, 4,
#endif
};
/* get_addr_size - get bit-banging numbers for address family */
static struct addr_size *get_addr_size(int af)
{
struct addr_size *ap;
for (ap = addr_sizes; /* see below */ ; ap++) {
if (ap >= addr_sizes + sizeof(addr_sizes) / sizeof(struct addr_size))
return (0);
if (ap->af == af)
return (ap);
}
}
/* net_mask_top - printable net/mask pattern */
char *net_mask_top(int af, const void *src, int prefix_len)
{
const char myname[] = "net_mask_top";
union {
struct in_addr in_addr;
struct in6_addr in6_addr;
} u;
VSTRING *buf;
struct addr_size *ap;
if ((ap = get_addr_size(af)) == 0)
msg_panic("%s: unexpected address family: %d", myname, af);
if (prefix_len > ap->addr_bitcount || prefix_len < 0)
msg_fatal("%s: bad %s address prefix length: %d",
myname, ap->ipproto_str, prefix_len);
memcpy((void *) &u, src, ap->addr_bytecount);
if (prefix_len < ap->addr_bitcount) {
mask_addr((unsigned char *) &u, ap->addr_bytecount, prefix_len);
buf = vstring_alloc(ap->addr_strlen + ap->slashdigs_strlen);
} else {
buf = vstring_alloc(ap->addr_strlen);
}
if (inet_ntop(af, &u, vstring_str(buf), vstring_avail(buf)) == 0)
msg_fatal("%s: inet_ntop: %m", myname);
vstring_set_payload_size(buf, strlen(vstring_str(buf)));
if (prefix_len < ap->addr_bitcount)
vstring_sprintf_append(buf, "/%d", prefix_len);
return (vstring_export(buf));
}

View File

@ -0,0 +1,27 @@
#ifndef _NET_MASK_TOP_H_INCLUDED_
#define _NET_MASK_TOP_H_INCLUDED_
/*++
/* NAME
/* net_mask_top 3h
/* SUMMARY
/* convert net/mask to printable string
/* SYNOPSIS
/* #include <net_mask_top.h>
/* DESCRIPTION
/* .nf
/*
* External interface.
*/
extern char *net_mask_top(int, const void *, int);
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/*--*/
#endif

View File

@ -28,6 +28,7 @@
/* struct sockaddr *SOCK_ADDR_PTR(ptr)
/* unsigned char SOCK_ADDR_FAMILY(ptr)
/* unsigned char SOCK_ADDR_LEN(ptr)
/* void *SOCK_ADDR_ADDRP(ptr)
/* unsigned short SOCK_ADDR_PORT(ptr)
/* unsigned short *SOCK_ADDR_PORTP(ptr)
/*
@ -68,7 +69,8 @@
/* address family and length of the real structure that hides
/* inside a generic sockaddr structure. On systems where struct
/* sockaddr has no sa_len member, SOCK_ADDR_LEN() cannot be
/* used as lvalue. SOCK_ADDR_PORT() returns the IPv4 or IPv6
/* used as lvalue. SOCKADDR_ADDRP() returns a pointer to the
/* IPv4 or IPv6 address. SOCK_ADDR_PORT() returns the IPv4 or IPv6
/* port number, in network byte order; it must not be used as
/* lvalue. SOCK_ADDR_PORTP() returns a pointer to the same.
/*

View File

@ -45,6 +45,9 @@ extern int sock_addr_in_loopback(const struct sockaddr *);
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
#endif
#define SOCK_ADDR_ADDRP(sa) \
(SOCK_ADDR_FAMILY(sa) == AF_INET ? \
(void *) &SOCK_ADDR_IN_ADDR(sa) : (void *) &SOCK_ADDR_IN6_ADDR(sa))
#define SOCK_ADDR_PORT(sa) \
(SOCK_ADDR_PTR(sa)->sa_family == AF_INET6 ? \
SOCK_ADDR_IN6_PORT(sa) : SOCK_ADDR_IN_PORT(sa))
@ -78,8 +81,9 @@ extern int sock_addr_in_loopback(const struct sockaddr *);
#define SOCK_ADDR_LEN(sa) sizeof(struct sockaddr_in)
#endif
#define SOCK_ADDR_PORT(sa) SOCK_ADDR_IN_PORT(sa))
#define SOCK_ADDR_PORTP(sa) &SOCK_ADDR_IN_PORT(sa))
#define SOCK_ADDR_ADDRP(sa) (&SOCK_ADDR_IN_ADDR(sa))
#define SOCK_ADDR_PORT(sa) SOCK_ADDR_IN_PORT(sa)
#define SOCK_ADDR_PORTP(sa) (&SOCK_ADDR_IN_PORT(sa))
#define SOCK_ADDR_EQ_ADDR(sa, sb) \
(SOCK_ADDR_FAMILY(sa) == AF_INET && SOCK_ADDR_FAMILY(sb) == AF_INET \