-TBH_TABLE
-TBINATTR
-TBINATTR_INFO
--Tbind_props
-TBINHASH
-TBINHASH_INFO
-TBIO
-TBYTE_MASK
-TCFG_PARSER
-TCIDR_MATCH
--Tcipher_probe_t
-TCLEANUP_REGION
--TCLEANUP_STAT_DETAIL
-TCLEANUP_STATE
+-TCLEANUP_STAT_DETAIL
-TCLIENT_LIST
-TCLNT_STREAM
-TCONFIG_BOOL_FN_TABLE
-TCRYPTO_EX_DATA
-TCTABLE
-TCTABLE_ENTRY
--Td2i_X509_t
--Tdane_digest
--Tdane_mtype
-TDB_COMMON_CTX
--TDELIVER_ATTR
-TDELIVERED_HDR_INFO
+-TDELIVER_ATTR
-TDELIVER_REQUEST
-TDELTA_TIME
-TDICT
-TEVP_PKEY
-TEXPAND_ATTR
-TFILE
--Tfilter_ctx
-TFORWARD_INFO
--Tgeneral_name_stack_t
-THBC_ACTION_CALL_BACKS
-THBC_CALL_BACKS
-THBC_CHECKS
-THOST
-THTABLE
-THTABLE_INFO
--Tiana_digest
-TINET_ADDR_LIST
+-TINET_ADDR_SIZES
-TINET_PROTO_INFO
-TINSTANCE
-TINST_SELECTION
-TINT32_TYPE
--TINT_TABLE
-TINTV
+-TINT_TABLE
-TJMP_BUF_WRAPPER
-TLDAP
--TLDAP_CONN
-TLDAPMessage
-TLDAPURLDesc
+-TLDAP_CONN
-TLIB_DP
-TLIB_FN
-TLMTP_ATTR
-TMAC_EXP_OP_INFO
-TMAC_HEAD
-TMAC_PARSE
--TMAI_HOSTADDR_STR
--TMAI_HOSTNAME_STR
-TMAIL_ADDR_FORMATTER
-TMAIL_ADDR_MAP_TEST
-TMAIL_PRINT
-TMAIL_SCAN
-TMAIL_STREAM
-TMAIL_VERSION
+-TMAI_HOSTADDR_STR
+-TMAI_HOSTNAME_STR
-TMAI_SERVNAME_STR
-TMAI_SERVPORT_STR
-TMAPS
-TMDB_val
-TMILTER
-TMILTER8
+-TMILTERS
-TMILTER_MACROS
-TMILTER_MSG_CONTEXT
--TMILTERS
-TMIME_ENCODING
-TMIME_INFO
-TMIME_STACK
-TNAME_MASK
-TNBBIO
-TNVTABLE_INFO
--Toff_t
-TOPTIONS
-TPCF_DBMS_INFO
-TPCF_EVAL_CTX
-TPCF_SERVICE_PATTERN
-TPCF_STRING_NV
-TPEER_NAME
--Tpem_load_state_t
-TPGSQL_NAME
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_STATE
-TPLMYSQL
-TPLPGSQL
+-TPOSTMAP_KEY_STATE
-TPOST_MAIL_FCLOSE_STATE
-TPOST_MAIL_STATE
--TPOSTMAP_KEY_STATE
-TPRIVATE_STR_TABLE
-TPSC_CALL_BACK_ENTRY
-TPSC_CLIENT_INFO
-TRECIPIENT
-TRECIPIENT_LIST
-TREC_TYPE_NAME
--Tregex_t
--Tregmatch_t
--TRES_CONTEXT
-TRESOLVE_REPLY
-TRESPONSE
-TREST_TABLE
+-TRES_CONTEXT
-TRWR_CONTEXT
--Tsasl_conn_t
--Tsasl_secret_t
-TSCACHE
-TSCACHE_CLNT
-TSCACHE_MULTI
-TSENDER_LOGIN_MATCH
-TSERVER_AC
-TSESSION
--Tsfsistat
-TSHARED_PATH
--Tsigset_t
-TSINGLE_SERVER
-TSINK_COMMAND
-TSINK_STATE
--Tsize_t
-TSLMDB
-TSMFICTX
--TSM_STATE
--TSMTP_ADDR
--TSMTP_CLI_ATTR
--TSMTP_CMD
-TSMTPD_CMD
-TSMTPD_DEFER
-TSMTPD_ENDPT_LOOKUP_INFO
-TSMTPD_STATE
-TSMTPD_TOKEN
-TSMTPD_XFORWARD_ATTR
+-TSMTP_ADDR
+-TSMTP_CLI_ATTR
+-TSMTP_CMD
-TSMTP_ITERATOR
-TSMTP_RESP
-TSMTP_SASL_AUTH_CACHE
-TSMTP_TLS_POLICY
-TSMTP_TLS_SESS
-TSMTP_TLS_SITE_POLICY
--Tsockaddr
+-TSM_STATE
-TSOCKADDR_SIZE
-TSPAWN_ATTR
--Tssize_t
-TSSL
--Tssl_cipher_stack_t
--Tssl_comp_stack_t
-TSSL_CTX
-TSSL_SESSION
-TSTATE
-TSTRING_TABLE
-TSYS_EXITS_DETAIL
-TTEST_CASE
--Ttime_t
--Ttlsa_filter
+-TTLSMGR_SCACHE
+-TTLSP_STATE
-TTLS_APPL_STATE
-TTLS_CERTS
-TTLS_CLIENT_INIT_PROPS
-TTLS_CLIENT_PARAMS
-TTLS_CLIENT_START_PROPS
--TTLScontext_t
-TTLS_DANE
--TTLSMGR_SCACHE
-TTLS_PKEYS
-TTLS_PRNG_SEED_INFO
-TTLS_PRNG_SRC
--TTLSP_STATE
-TTLS_ROLE
-TTLS_SCACHE
-TTLS_SCACHE_ENTRY
-TTLS_TLSA
-TTLS_USAGE
-TTLS_VINFO
+-TTLScontext_t
-TTOK822
-TTRANSPORT_INFO
-TTRIGGER_SERVER
--Tuint16_t
--Tuint32_t
--Tuint8_t
-TUSER_ATTR
-TVBUF
-TVSTREAM
-TWATCHDOG
-TWATCH_FD
-TX509
+-TX509V3_CTX
-TX509_EXTENSION
-TX509_NAME
--Tx509_stack_t
-TX509_STORE_CTX
--TX509V3_CTX
-TXSASL_CLIENT
-TXSASL_CLIENT_CREATE_ARGS
-TXSASL_CLIENT_IMPL
-TXSASL_SERVER_CREATE_ARGS
-TXSASL_SERVER_IMPL
-TXSASL_SERVER_IMPL_INFO
+-Tbind_props
+-Tcipher_probe_t
+-Td2i_X509_t
+-Tdane_digest
+-Tdane_mtype
+-Tfilter_ctx
+-Tgeneral_name_stack_t
+-Tiana_digest
+-Toff_t
+-Tpem_load_state_t
+-Tregex_t
+-Tregmatch_t
+-Tsasl_conn_t
+-Tsasl_secret_t
+-Tsfsistat
+-Tsigset_t
+-Tsize_t
+-Tsockaddr
+-Tsockaddr_storage
+-Tssize_t
+-Tssl_cipher_stack_t
+-Tssl_comp_stack_t
+-Ttime_t
+-Ttlsa_filter
+-Tuint16_t
+-Tuint32_t
+-Tuint8_t
+-Tx509_stack_t
(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,
+ util/inet_prefix_top.[hc], smtpd/smtpd.c, smtpd/smtpd_peer.c,
mantools/postlink, proto/postconf.proto.
+
+20230313
+
+ Factored out a function that may be generally useful, and
+ made a vstring_alloc() argument more precise to avoid memory
+ reallocation. Files: util/inet_prefix_top.c,
+ util/inet_addr_sizes.[hc].
+
+20230314
+
+ Bugfix (introduced: Postfix 3.5): check_ccert_access did
+ not parse inline map specifications. Report and fix by
+ Sean Gallagher. File: global/map_search.c.
+
+ Cleanup: don't do smtpd_client_*_rate and smtpd_client_*_count
+ address range computations when "/usr/sbin/sendmail -bs"
+ is not talking to a network client. File: smtpd/smtpd_peer.c.
+
+ Cleanup: renamed net_mask_top.* to inet_prefix_top.*.
+
+ Cleanup: updated unit tests. Files: smtpd/smtod_check.c,
+ smtpd/smtpd_server.in, smtpd/smtpd_server.ref.
+
+ Increased the smtpd_client_ipv6_prefix_length to 84 bits,
+ which should prevent anvil exhaustion attacks from a typical
+ /64 consumer network, without penalizing legitimate usage.
<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>
+uses fewer <a href="anvil.8.html">anvil(8)</a> resources 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>
+(default: 84)</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>
+uses fewer the <a href="anvil.8.html">anvil(8)</a> resources to maintain counters. By default,
+aggregation is enabled for IPv6. </p>
<p> This feature is available in Postfix 3.8 and later. </p>
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>
+ <b><a href="postconf.5.html#smtpd_client_ipv6_prefix_length">smtpd_client_ipv6_prefix_length</a> (84)</b>
Aggregate smtpd_client_*_count and smtpd_client_*_rate statis-
tics by IPv6 network blocks with the specified network prefix.
.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.
+uses fewer \fBanvil\fR(8) resources 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)
+.SH smtpd_client_ipv6_prefix_length (default: 84)
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.
+uses fewer the \fBanvil\fR(8) resources 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)
.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"
+.IP "\fBsmtpd_client_ipv6_prefix_length (84)\fR"
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
by IPv6 network blocks with the specified network prefix.
.SH "TARPIT CONTROLS"
<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>
+uses fewer anvil(8) resources 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
+%PARAM smtpd_client_ipv6_prefix_length 84
<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>
+uses fewer the anvil(8) resources to maintain counters. By default,
+aggregation is enabled for IPv6. </p>
<p> This feature is available in Postfix 3.8 and later. </p>
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
+address address string length
postfix postfix c postlog postlog c
postfix postfix c postlog postlog c
util net_mask_top hc smtpd smtpd c smtpd smtpd_peer c
+ util inet_prefix_top hc smtpd smtpd c smtpd smtpd_peer c
ADDRP
iffalse
iftrue
+Stringify
+bitcount
+bytecount
+ipproto
makemanidx
soho
soho
+Aleksandr
+Stankevic
+Gallagher
extern int var_smtpd_cipv4_prefix;
#define VAR_SMTPD_CIPV6_PREFIX "smtpd_client_ipv6_prefix_length"
-#define DEF_SMTPD_CIPV6_PREFIX 72
+#define DEF_SMTPD_CIPV6_PREFIX 84
#define MAX_SMTPD_CIPV6_PREFIX 128
extern int var_smtpd_cipv6_prefix;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20230312"
+#define MAIL_RELEASE_DATE "20230314"
#define MAIL_VERSION_NUMBER "3.8"
#ifdef SNAPSHOT
if ((heap_err = extpar(&bp, CHARS_BRACE, EXTPAR_FLAG_STRIP)) != 0) {
msg_warn("malformed map specification: '%s'", heap_err);
MAP_SEARCH_CREATE_RETURN(0);
- } else if ((map_type_name = mystrtok(&bp, CHARS_COMMA_SP)) == 0) {
+ } else if ((map_type_name = mystrtokq(&bp, CHARS_COMMA_SP,
+ CHARS_BRACE)) == 0) {
msg_warn("empty map specification: '%s'", map_spec);
MAP_SEARCH_CREATE_RETURN(0);
}
{"{type:name {search_order=one, two}}", 1, "type:name", "\01\02"},
{"{type:name {search_order=one, two, bad}}", 0, 0, 0},
{"{inline:{a=b} {search_order=one, two}}", 1, "inline:{a=b}", "\01\02"},
+ {"{inline:{a=b, c=d} {search_order=one, two}}", 1, "inline:{a=b, c=d}", "\01\02"},
{0},
};
TEST_CASE *test_case;
unknown: test case 10: '{type:name {search_order=one, two, bad}}'
unknown: warning: unknown search type 'bad' in '{type:name {search_order=one, two, bad}}'
unknown: test case 11: '{inline:{a=b} {search_order=one, two}}'
+unknown: test case 12: '{inline:{a=b, c=d} {search_order=one, two}}'
+unknown: dict_open_lookup: fail
unknown: dict_open: fail:1maps
unknown: dict_register: fail:1maps(0,lock) 1
"": not found
smtpd_peer.o: ../../include/dns.h
smtpd_peer.o: ../../include/haproxy_srvr.h
smtpd_peer.o: ../../include/htable.h
+smtpd_peer.o: ../../include/inet_prefix_top.h
smtpd_peer.o: ../../include/inet_proto.h
smtpd_peer.o: ../../include/iostuff.h
smtpd_peer.o: ../../include/mail_params.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
/* .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"
+/* .IP "\fBsmtpd_client_ipv6_prefix_length (84)\fR"
/* Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
/* by IPv6 network blocks with the specified network prefix.
/* TARPIT CONTROLS
bool var_smtpd_client_port_log;
char *var_smtpd_dns_re_filter;
bool var_smtpd_tls_ask_ccert;
+int var_smtpd_cipv4_prefix;
+int var_smtpd_cipv6_prefix;
#define int_table test_int_table
VAR_SMTPD_PEERNAME_LOOKUP, DEF_SMTPD_PEERNAME_LOOKUP, &var_smtpd_peername_lookup,
VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, &var_smtpd_client_port_log,
VAR_SMTPD_TLS_ACERT, DEF_SMTPD_TLS_ACERT, &var_smtpd_tls_ask_ccert,
+ VAR_SMTPD_CIPV4_PREFIX, DEF_SMTPD_CIPV4_PREFIX, &var_smtpd_cipv4_prefix,
+ VAR_SMTPD_CIPV6_PREFIX, DEF_SMTPD_CIPV6_PREFIX, &var_smtpd_cipv6_prefix,
0,
};
#include <sock_addr.h>
#include <inet_proto.h>
#include <split_at.h>
-#include <net_mask_top.h>
+#include <inet_prefix_top.h>
/* Global library. */
/*
* Generate 'address' or 'net/mask' index for anvil event aggregation.
+ * Don't do this for non-socket input. See smtpd_peer_not_inet().
*/
- 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);
+ if (state->addr_family != AF_UNSPEC) {
+ af = SOCK_ADDR_FAMILY(&(state->sockaddr));
+ state->anvil_range = inet_prefix_top(af,
+ SOCK_ADDR_ADDRP(&(state->sockaddr)),
+ af == AF_INET ?
+ var_smtpd_cipv4_prefix :
+ var_smtpd_cipv6_prefix);
+ }
}
/* smtpd_peer_reset - destroy peer information */
helo_restrictions check_helo_ns_access,inline:{168.100.3.75=reject}
helo www.porcupine.org
helo example.tld
-helo foo@postfix.org
+helo foo@maildaemon.org
sender_restrictions check_sender_ns_access,inline:{168.100.3.75=reject}
mail foo@www.porcupine.org
mail example.tld
-mail foo@postfix.org
+mail foo@maildaemon.org
recipient_restrictions check_recipient_ns_access,inline:{168.100.3.75=reject}
rcpt foo@www.porcupine.org
rcpt foo@example.tld
-rcpt foo@postfix.org
+rcpt foo@maildaemon.org
#
# Check A access
#
>>> helo example.tld
./smtpd_check: warning: Unable to look up NS host for example.tld: Host not found
OK
->>> helo foo@postfix.org
-./smtpd_check: <queue id>: reject: HELO from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@postfix.org>: Helo command rejected: Access denied; from=<foo@postfix.org> proto=SMTP helo=<foo@postfix.org>
-554 5.7.1 <foo@postfix.org>: Helo command rejected: Access denied
+>>> helo foo@maildaemon.org
+./smtpd_check: <queue id>: reject: HELO from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@maildaemon.org>: Helo command rejected: Access denied; from=<foo@postfix.org> proto=SMTP helo=<foo@maildaemon.org>
+554 5.7.1 <foo@maildaemon.org>: Helo command rejected: Access denied
>>> sender_restrictions check_sender_ns_access,inline:{168.100.3.75=reject}
OK
>>> mail foo@www.porcupine.org
-./smtpd_check: <queue id>: reject: MAIL from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@www.porcupine.org>: Sender address rejected: Access denied; from=<foo@www.porcupine.org> proto=SMTP helo=<foo@postfix.org>
+./smtpd_check: <queue id>: reject: MAIL from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@www.porcupine.org>: Sender address rejected: Access denied; from=<foo@www.porcupine.org> proto=SMTP helo=<foo@maildaemon.org>
554 5.7.1 <foo@www.porcupine.org>: Sender address rejected: Access denied
>>> mail example.tld
./smtpd_check: warning: Unable to look up NS host for example.tld: Host not found
OK
->>> mail foo@postfix.org
-./smtpd_check: <queue id>: reject: MAIL from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@postfix.org>: Sender address rejected: Access denied; from=<foo@postfix.org> proto=SMTP helo=<foo@postfix.org>
-554 5.7.1 <foo@postfix.org>: Sender address rejected: Access denied
+>>> mail foo@maildaemon.org
+./smtpd_check: <queue id>: reject: MAIL from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@maildaemon.org>: Sender address rejected: Access denied; from=<foo@maildaemon.org> proto=SMTP helo=<foo@maildaemon.org>
+554 5.7.1 <foo@maildaemon.org>: Sender address rejected: Access denied
>>> recipient_restrictions check_recipient_ns_access,inline:{168.100.3.75=reject}
OK
>>> rcpt foo@www.porcupine.org
-./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@www.porcupine.org>: Recipient address rejected: Access denied; from=<foo@postfix.org> to=<foo@www.porcupine.org> proto=SMTP helo=<foo@postfix.org>
+./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@www.porcupine.org>: Recipient address rejected: Access denied; from=<foo@maildaemon.org> to=<foo@www.porcupine.org> proto=SMTP helo=<foo@maildaemon.org>
554 5.7.1 <foo@www.porcupine.org>: Recipient address rejected: Access denied
>>> rcpt foo@example.tld
./smtpd_check: warning: Unable to look up NS host for foo@example.tld: Host not found
OK
->>> rcpt foo@postfix.org
-./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@postfix.org>: Recipient address rejected: Access denied; from=<foo@postfix.org> to=<foo@postfix.org> proto=SMTP helo=<foo@postfix.org>
-554 5.7.1 <foo@postfix.org>: Recipient address rejected: Access denied
+>>> rcpt foo@maildaemon.org
+./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <foo@maildaemon.org>: Recipient address rejected: Access denied; from=<foo@maildaemon.org> to=<foo@maildaemon.org> proto=SMTP helo=<foo@maildaemon.org>
+554 5.7.1 <foo@maildaemon.org>: Recipient address rejected: Access denied
>>> #
>>> # Check A access
>>> #
>>> helo_restrictions check_helo_a_access,inline:{168.100.3.2=reject}
OK
>>> helo spike.porcupine.org
-./smtpd_check: <queue id>: reject: HELO from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <spike.porcupine.org>: Helo command rejected: Access denied; from=<foo@postfix.org> proto=SMTP helo=<spike.porcupine.org>
+./smtpd_check: <queue id>: reject: HELO from spike.porcupine.org[168.100.3.2]: 554 5.7.1 <spike.porcupine.org>: Helo command rejected: Access denied; from=<foo@maildaemon.org> proto=SMTP helo=<spike.porcupine.org>
554 5.7.1 <spike.porcupine.org>: Helo command rejected: Access denied
>>> helo www.porcupine.org
OK
>>> client_restrictions check_client_a_access,inline:{168.100.3.2=reject}
OK
>>> client spike.porcupine.org 1.2.3.4
-./smtpd_check: <queue id>: reject: CONNECT from spike.porcupine.org[1.2.3.4]: 554 5.7.1 <spike.porcupine.org[1.2.3.4]>: Client host rejected: Access denied; from=<foo@postfix.org> proto=SMTP helo=<www.porcupine.org>
+./smtpd_check: <queue id>: reject: CONNECT from spike.porcupine.org[1.2.3.4]: 554 5.7.1 <spike.porcupine.org[1.2.3.4]>: Client host rejected: Access denied; from=<foo@maildaemon.org> proto=SMTP helo=<www.porcupine.org>
554 5.7.1 <spike.porcupine.org[1.2.3.4]>: Client host rejected: Access denied
>>> client www.porcupine.org 1.2.3.4
OK
>>> reverse_client_restrictions check_reverse_client_a_access,inline:{168.100.3.2=reject}
bad command
>>> client spike.porcupine.org 1.2.3.4
-./smtpd_check: <queue id>: reject: CONNECT from spike.porcupine.org[1.2.3.4]: 554 5.7.1 <spike.porcupine.org[1.2.3.4]>: Client host rejected: Access denied; from=<foo@postfix.org> proto=SMTP helo=<www.porcupine.org>
+./smtpd_check: <queue id>: reject: CONNECT from spike.porcupine.org[1.2.3.4]: 554 5.7.1 <spike.porcupine.org[1.2.3.4]>: Client host rejected: Access denied; from=<foo@maildaemon.org> proto=SMTP helo=<www.porcupine.org>
554 5.7.1 <spike.porcupine.org[1.2.3.4]>: Client host rejected: Access denied
>>> client www.porcupine.org 1.2.3.4
OK
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 net_mask_top.c
+ mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c inet_prefix_top.c \
+ inet_addr_sizes.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 \
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 net_mask_top.o
+ mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.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.
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 \
- net_mask_top.h
+ inet_prefix_top.h inet_addr_sizes.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)
inet_addr_local.o: sys_defs.h
inet_addr_local.o: vbuf.h
inet_addr_local.o: vstring.h
+inet_addr_sizes.o: inet_addr_sizes.c
+inet_addr_sizes.o: inet_addr_sizes.h
+inet_addr_sizes.o: msg.h
+inet_addr_sizes.o: myaddrinfo.h
+inet_addr_sizes.o: sys_defs.h
inet_connect.o: connect.h
inet_connect.o: host_port.h
inet_connect.o: inet_connect.c
inet_listen.o: sane_accept.h
inet_listen.o: sock_addr.h
inet_listen.o: sys_defs.h
+inet_prefix_top.o: check_arg.h
+inet_prefix_top.o: inet_addr_sizes.h
+inet_prefix_top.o: inet_prefix_top.c
+inet_prefix_top.o: inet_prefix_top.h
+inet_prefix_top.o: mask_addr.h
+inet_prefix_top.o: msg.h
+inet_prefix_top.o: sys_defs.h
+inet_prefix_top.o: vbuf.h
+inet_prefix_top.o: vstring.h
inet_proto.o: check_arg.h
inet_proto.o: inet_proto.c
inet_proto.o: inet_proto.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
--- /dev/null
+/*++
+/* NAME
+/* inet_addr_sizes 3
+/* SUMMARY
+/* get network address size metrics
+/* SYNOPSIS
+/* #include <inet_addr_sizes.h>
+/*
+/* typedef struct {
+/* .in +4
+/* int af; /* network address family (binary) */
+/* char *ipproto_str; /* IP protocol version (string) */
+/* int addr_bitcount; /* bits per address */
+/* int addr_bytecount; /* bytes per address */
+/* int addr_strlen; /* address string length */
+/* int addr_bitcount_strlen;/* addr_bitcount string length */
+/* .in -4
+/* } INET_ADDR_SIZES;
+/*
+/* const INET_ADDR_SIZES *inet_addr_sizes(int family)
+/* DESCRIPTION
+/* inet_addr_sizes() returns address size metrics for the
+/* specified network address family, AF_INET or AF_INET6.
+/* DIAGNOSTICS
+/* inet_addr_sizes() returns a null pointer when the argument
+/* specifies an unexpected address family.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/*--*/
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+#include <string.h>
+
+ /*
+ * Utility library.
+ */
+#include <inet_addr_sizes.h>
+#include <msg.h>
+#include <myaddrinfo.h>
+
+ /*
+ * Stringify a numeric constant and use sizeof() to determine the resulting
+ * string length at compile time. Note that sizeof() includes a null
+ * terminator; the -1 corrects for that.
+ */
+#define _STRINGIFY(x) #x
+#define _STRLEN(x) (sizeof(_STRINGIFY(x)) - 1)
+
+static const INET_ADDR_SIZES table[] = {
+ {AF_INET, "IPv4", MAI_V4ADDR_BITS, MAI_V4ADDR_BYTES, INET_ADDRSTRLEN,
+ _STRLEN(MAI_V4ADDR_BITS)},
+#ifdef HAS_IPV6
+ {AF_INET6, "IPv6", MAI_V6ADDR_BITS, MAI_V6ADDR_BYTES, INET6_ADDRSTRLEN,
+ _STRLEN(MAI_V6ADDR_BITS)},
+#endif
+};
+
+/* inet_addr_sizes - get address size metrics for address family */
+
+const INET_ADDR_SIZES *inet_addr_sizes(int af)
+{
+ const INET_ADDR_SIZES *sp;
+
+ for (sp = table; /* see below */ ; sp++) {
+ if (sp >= table + sizeof(table) / sizeof(*table))
+ return (0);
+ if (sp->af == af)
+ return (sp);
+ }
+}
--- /dev/null
+#ifndef _INET_ADDR_SIZES_H_INCLUDED_
+#define _INET_ADDR_SIZES_H_INCLUDED_
+
+/*++
+/* NAME
+/* inet_addr_sizes 3h
+/* SUMMARY
+/* get network address size metrics
+/* SYNOPSIS
+/* #include <inet_addr_sizes.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * External interface.
+ */
+typedef struct {
+ int af; /* network address family (binary) */
+ char *ipproto_str; /* IP protocol version (string) */
+ int addr_bitcount; /* bits per address */
+ int addr_bytecount; /* bytes per address */
+ int addr_strlen; /* address string length */
+ int addr_bitcount_strlen; /* addr_bitcount string length */
+} INET_ADDR_SIZES;
+
+extern const INET_ADDR_SIZES *inet_addr_sizes(int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/*--*/
+
+#endif
--- /dev/null
+/*++
+/* NAME
+/* inet_prefix_top 3
+/* SUMMARY
+/* convert net/mask to printable string
+/* SYNOPSIS
+/* #include <inet_prefix_top.h>
+/*
+/* char *inet_prefix_top(
+/* int family,
+/* const void *src,
+/* int prefix_len)
+/* DESCRIPTION
+/* inet_prefix_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 <inet_addr_sizes.h>
+#include <inet_prefix_top.h>
+#include <vstring.h>
+
+/* inet_prefix_top - printable net/mask pattern */
+
+char *inet_prefix_top(int af, const void *src, int prefix_len)
+{
+ const char myname[] = "inet_prefix_top";
+ union {
+ struct in_addr in_addr;
+ struct in6_addr in6_addr;
+ } u;
+ VSTRING *buf;
+ const INET_ADDR_SIZES *sp;
+
+ /*
+ * Sanity checks. XXX We use msg_fatal() because mail_conf_int() does not
+ * (yet) support non-negative integers.
+ */
+ if ((sp = inet_addr_sizes(af)) == 0)
+ msg_panic("%s: unexpected address family: %d", myname, af);
+ if (prefix_len > sp->addr_bitcount || prefix_len < 0)
+ msg_fatal("%s: bad %s address prefix length: %d",
+ myname, sp->ipproto_str, prefix_len);
+
+ /*
+ * Strip a copy of the input address. When allocating the result memory,
+ * add 1 for the string terminator from inet_ntop(), or 1 for the '/'
+ * before the prefix. We should not rely on vstring(3)'s safety byte.
+ */
+ memcpy((void *) &u, src, sp->addr_bytecount);
+ if (prefix_len < sp->addr_bitcount) {
+ mask_addr((unsigned char *) &u, sp->addr_bytecount, prefix_len);
+ buf = vstring_alloc(sp->addr_strlen + sp->addr_bitcount_strlen + 1);
+ } else {
+ buf = vstring_alloc(sp->addr_strlen + 1);
+ }
+
+ /*
+ * Convert the result to string, and append the optional /prefix.
+ */
+ 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 < sp->addr_bitcount)
+ vstring_sprintf_append(buf, "/%d", prefix_len);
+ return (vstring_export(buf));
+}
-#ifndef _NET_MASK_TOP_H_INCLUDED_
-#define _NET_MASK_TOP_H_INCLUDED_
+#ifndef _INET_MASK_TOP_H_INCLUDED_
+#define _INET_MASK_TOP_H_INCLUDED_
/*++
/* NAME
-/* net_mask_top 3h
+/* inet_prefix_top 3h
/* SUMMARY
/* convert net/mask to printable string
/* SYNOPSIS
-/* #include <net_mask_top.h>
+/* #include <inet_prefix_top.h>
/* DESCRIPTION
/* .nf
/*
* External interface.
*/
-extern char *net_mask_top(int, const void *, int);
+extern char *inet_prefix_top(int, const void *, int);
/* LICENSE
/* .ad
+++ /dev/null
-/*++
-/* 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));
-}