diff --git a/postfix/.indent.pro b/postfix/.indent.pro index 1f8431f0d..4ba45d081 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -20,7 +20,6 @@ -TBH_TABLE -TBINATTR -TBINATTR_INFO --Tbind_props -TBINHASH -TBINHASH_INFO -TBIO @@ -38,10 +37,9 @@ -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 @@ -65,12 +63,9 @@ -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 @@ -156,9 +151,7 @@ -TEVP_PKEY -TEXPAND_ATTR -TFILE --Tfilter_ctx -TFORWARD_INFO --Tgeneral_name_stack_t -THBC_ACTION_CALL_BACKS -THBC_CALL_BACKS -THBC_CHECKS @@ -171,19 +164,19 @@ -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 @@ -199,14 +192,14 @@ -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 @@ -225,9 +218,9 @@ -TMDB_val -TMILTER -TMILTER8 +-TMILTERS -TMILTER_MACROS -TMILTER_MSG_CONTEXT --TMILTERS -TMIME_ENCODING -TMIME_INFO -TMIME_STACK @@ -253,7 +246,6 @@ -TNAME_MASK -TNBBIO -TNVTABLE_INFO --Toff_t -TOPTIONS -TPCF_DBMS_INFO -TPCF_EVAL_CTX @@ -267,7 +259,6 @@ -TPCF_SERVICE_PATTERN -TPCF_STRING_NV -TPEER_NAME --Tpem_load_state_t -TPGSQL_NAME -TPICKUP_INFO -TPIPE_ATTR @@ -275,9 +266,9 @@ -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 @@ -305,15 +296,11 @@ -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 @@ -330,19 +317,12 @@ -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 @@ -354,6 +334,9 @@ -TSMTPD_STATE -TSMTPD_TOKEN -TSMTPD_XFORWARD_ATTR +-TSMTP_ADDR +-TSMTP_CLI_ATTR +-TSMTP_CMD -TSMTP_ITERATOR -TSMTP_RESP -TSMTP_SASL_AUTH_CACHE @@ -362,13 +345,10 @@ -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 @@ -376,20 +356,17 @@ -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 @@ -400,12 +377,10 @@ -TTLS_TLSA -TTLS_USAGE -TTLS_VINFO +-TTLScontext_t -TTOK822 -TTRANSPORT_INFO -TTRIGGER_SERVER --Tuint16_t --Tuint32_t --Tuint8_t -TUSER_ATTR -TVBUF -TVSTREAM @@ -415,11 +390,10 @@ -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 @@ -436,3 +410,31 @@ -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 diff --git a/postfix/HISTORY b/postfix/HISTORY index 245645be3..7aeaffb70 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -26947,5 +26947,31 @@ Apologies for any names omitted. (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. diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 10816cb9a..848b30685 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -14646,8 +14646,8 @@ This feature is available in Postfix 2.2 and later.

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.

+uses fewer anvil(8) resources to maintain counters. By default, +aggregation is disabled for IPv4.

This feature is available in Postfix 3.8 and later.

@@ -14655,13 +14655,12 @@ default, aggregation is disabled for IPv4.

smtpd_client_ipv6_prefix_length -(default: 72)
+(default: 84)

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. -

+uses fewer the anvil(8) resources to maintain counters. By default, +aggregation is enabled for IPv6.

This feature is available in Postfix 3.8 and later.

diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index ecf775cf8..b7ec136c3 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -968,7 +968,7 @@ SMTPD(8) SMTPD(8) Aggregate smtpd_client_*_count and smtpd_client_*_rate statis- tics by IPv4 network blocks with the specified network prefix. - smtpd_client_ipv6_prefix_length (72) + smtpd_client_ipv6_prefix_length (84) Aggregate smtpd_client_*_count and smtpd_client_*_rate statis- tics by IPv6 network blocks with the specified network prefix. diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 2d84788ba..45b363824 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -9959,15 +9959,15 @@ 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. +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) diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index 3062953e3..7519c53b4 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -846,7 +846,7 @@ 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" +.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" diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index d661dda65..dffeab87f 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -18603,17 +18603,16 @@ to MX or IP address lookup as if SRV record lookup was not enabled.

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.

+uses fewer anvil(8) resources to maintain counters. By default, +aggregation is disabled for IPv4.

This feature is available in Postfix 3.8 and later.

-%PARAM smtpd_client_ipv6_prefix_length 72 +%PARAM smtpd_client_ipv6_prefix_length 84

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. -

+uses fewer the anvil(8) resources to maintain counters. By default, +aggregation is enabled for IPv6.

This feature is available in Postfix 3.8 and later.

diff --git a/postfix/proto/stop.double-cc b/postfix/proto/stop.double-cc index 09a32d874..8efd133ee 100644 --- a/postfix/proto/stop.double-cc +++ b/postfix/proto/stop.double-cc @@ -332,3 +332,4 @@ 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 +address address string length diff --git a/postfix/proto/stop.double-history b/postfix/proto/stop.double-history index ff1eceaf4..18511878d 100644 --- a/postfix/proto/stop.double-history +++ b/postfix/proto/stop.double-history @@ -36,3 +36,4 @@ proto proto SASL_README html proto SQLITE_README html 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 diff --git a/postfix/proto/stop.spell-cc b/postfix/proto/stop.spell-cc index ec3df3008..c642c7a32 100644 --- a/postfix/proto/stop.spell-cc +++ b/postfix/proto/stop.spell-cc @@ -1796,3 +1796,7 @@ nopref ADDRP iffalse iftrue +Stringify +bitcount +bytecount +ipproto diff --git a/postfix/proto/stop.spell-history b/postfix/proto/stop.spell-history index 9cca6240f..c248a4c8c 100644 --- a/postfix/proto/stop.spell-history +++ b/postfix/proto/stop.spell-history @@ -49,3 +49,6 @@ css makemanidx soho soho +Aleksandr +Stankevic +Gallagher diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index d83c9eb50..7c80add97 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -3204,7 +3204,7 @@ extern int var_smtpd_cauth_limit; 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; diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index e07da4233..5c8aaba43 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20230312" +#define MAIL_RELEASE_DATE "20230314" #define MAIL_VERSION_NUMBER "3.8" #ifdef SNAPSHOT diff --git a/postfix/src/global/map_search.c b/postfix/src/global/map_search.c index be4b42b33..b10f7d516 100644 --- a/postfix/src/global/map_search.c +++ b/postfix/src/global/map_search.c @@ -158,7 +158,8 @@ const MAP_SEARCH *map_search_create(const char *map_spec) 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); } @@ -308,6 +309,7 @@ int main(int argc, char **argv) {"{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; diff --git a/postfix/src/global/map_search.ref b/postfix/src/global/map_search.ref index f072f253e..a296e4e4a 100644 --- a/postfix/src/global/map_search.ref +++ b/postfix/src/global/map_search.ref @@ -19,3 +19,4 @@ unknown: test case 9: '{type:name {search_order=one, two}}' 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}}' diff --git a/postfix/src/global/maps.ref b/postfix/src/global/maps.ref index 84033c7d8..2d3ad20ee 100644 --- a/postfix/src/global/maps.ref +++ b/postfix/src/global/maps.ref @@ -1,3 +1,4 @@ +unknown: dict_open_lookup: fail unknown: dict_open: fail:1maps unknown: dict_register: fail:1maps(0,lock) 1 "": not found diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index 422cbac5a..7fdfe1286 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -481,6 +481,7 @@ smtpd_peer.o: ../../include/check_arg.h 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 @@ -492,7 +493,6 @@ 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 diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 7580629a0..2276e65f6 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -800,7 +800,7 @@ /* .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 diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index b6a2aced6..b5ce4a94f 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -5810,6 +5810,8 @@ bool var_smtpd_peername_lookup; 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 @@ -5845,6 +5847,8 @@ static const INT_TABLE 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, }; diff --git a/postfix/src/smtpd/smtpd_peer.c b/postfix/src/smtpd/smtpd_peer.c index f21203544..838af9cb9 100644 --- a/postfix/src/smtpd/smtpd_peer.c +++ b/postfix/src/smtpd/smtpd_peer.c @@ -139,7 +139,7 @@ #include #include #include -#include +#include /* Global library. */ @@ -641,13 +641,16 @@ void smtpd_peer_init(SMTPD_STATE *state) /* * 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 */ diff --git a/postfix/src/smtpd/smtpd_server.in b/postfix/src/smtpd/smtpd_server.in index 691b8c682..f002fc16c 100644 --- a/postfix/src/smtpd/smtpd_server.in +++ b/postfix/src/smtpd/smtpd_server.in @@ -27,15 +27,15 @@ rcpt foo@postfix.org 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 # diff --git a/postfix/src/smtpd/smtpd_server.ref b/postfix/src/smtpd/smtpd_server.ref index b396a57b6..182d0d90c 100644 --- a/postfix/src/smtpd/smtpd_server.ref +++ b/postfix/src/smtpd/smtpd_server.ref @@ -53,52 +53,52 @@ OK >>> 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: : reject: HELO from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Helo command rejected: Access denied; from= proto=SMTP helo= -554 5.7.1 : Helo command rejected: Access denied +>>> helo foo@maildaemon.org +./smtpd_check: : reject: HELO from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Helo command rejected: Access denied; from= proto=SMTP helo= +554 5.7.1 : 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: : reject: MAIL from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Sender address rejected: Access denied; from= proto=SMTP helo= +./smtpd_check: : reject: MAIL from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Sender address rejected: Access denied; from= proto=SMTP helo= 554 5.7.1 : 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: : reject: MAIL from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Sender address rejected: Access denied; from= proto=SMTP helo= -554 5.7.1 : Sender address rejected: Access denied +>>> mail foo@maildaemon.org +./smtpd_check: : reject: MAIL from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Sender address rejected: Access denied; from= proto=SMTP helo= +554 5.7.1 : 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: : reject: RCPT from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Recipient address rejected: Access denied; from= to= proto=SMTP helo= +./smtpd_check: : reject: RCPT from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Recipient address rejected: Access denied; from= to= proto=SMTP helo= 554 5.7.1 : 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: : reject: RCPT from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Recipient address rejected: Access denied; from= to= proto=SMTP helo= -554 5.7.1 : Recipient address rejected: Access denied +>>> rcpt foo@maildaemon.org +./smtpd_check: : reject: RCPT from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Recipient address rejected: Access denied; from= to= proto=SMTP helo= +554 5.7.1 : 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: : reject: HELO from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Helo command rejected: Access denied; from= proto=SMTP helo= +./smtpd_check: : reject: HELO from spike.porcupine.org[168.100.3.2]: 554 5.7.1 : Helo command rejected: Access denied; from= proto=SMTP helo= 554 5.7.1 : 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: : reject: CONNECT from spike.porcupine.org[1.2.3.4]: 554 5.7.1 : Client host rejected: Access denied; from= proto=SMTP helo= +./smtpd_check: : reject: CONNECT from spike.porcupine.org[1.2.3.4]: 554 5.7.1 : Client host rejected: Access denied; from= proto=SMTP helo= 554 5.7.1 : 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: : reject: CONNECT from spike.porcupine.org[1.2.3.4]: 554 5.7.1 : Client host rejected: Access denied; from= proto=SMTP helo= +./smtpd_check: : reject: CONNECT from spike.porcupine.org[1.2.3.4]: 554 5.7.1 : Client host rejected: Access denied; from= proto=SMTP helo= 554 5.7.1 : Client host rejected: Access denied >>> client www.porcupine.org 1.2.3.4 OK diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index 4592f6a50..3e3ea9ab8 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -44,7 +44,8 @@ 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 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 \ @@ -90,7 +91,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 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. @@ -122,7 +123,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.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 \ - 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) @@ -2024,6 +2025,11 @@ inet_addr_local.o: sock_addr.h 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 @@ -2048,6 +2054,15 @@ inet_listen.o: mymalloc.h 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 @@ -2416,15 +2431,6 @@ 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 diff --git a/postfix/src/util/inet_addr_sizes.c b/postfix/src/util/inet_addr_sizes.c new file mode 100644 index 000000000..e788c2222 --- /dev/null +++ b/postfix/src/util/inet_addr_sizes.c @@ -0,0 +1,77 @@ +/*++ +/* NAME +/* inet_addr_sizes 3 +/* SUMMARY +/* get network address size metrics +/* SYNOPSIS +/* #include +/* +/* 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 +#include + + /* + * Utility library. + */ +#include +#include +#include + + /* + * 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); + } +} diff --git a/postfix/src/util/inet_addr_sizes.h b/postfix/src/util/inet_addr_sizes.h new file mode 100644 index 000000000..c937c7842 --- /dev/null +++ b/postfix/src/util/inet_addr_sizes.h @@ -0,0 +1,36 @@ +#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 +/* 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 diff --git a/postfix/src/util/inet_prefix_top.c b/postfix/src/util/inet_prefix_top.c new file mode 100644 index 000000000..56da5ddac --- /dev/null +++ b/postfix/src/util/inet_prefix_top.c @@ -0,0 +1,102 @@ +/*++ +/* NAME +/* inet_prefix_top 3 +/* SUMMARY +/* convert net/mask to printable string +/* SYNOPSIS +/* #include +/* +/* 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 +#include +#include +#include +#include + + /* + * Utility library. + */ +#include +#include +#include +#include +#include + +/* 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)); +} diff --git a/postfix/src/util/net_mask_top.h b/postfix/src/util/inet_prefix_top.h similarity index 60% rename from postfix/src/util/net_mask_top.h rename to postfix/src/util/inet_prefix_top.h index 8f043f5b7..f604ee300 100644 --- a/postfix/src/util/net_mask_top.h +++ b/postfix/src/util/inet_prefix_top.h @@ -1,20 +1,20 @@ -#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 +/* #include /* DESCRIPTION /* .nf /* * External interface. */ -extern char *net_mask_top(int, const void *, int); +extern char *inet_prefix_top(int, const void *, int); /* LICENSE /* .ad diff --git a/postfix/src/util/net_mask_top.c b/postfix/src/util/net_mask_top.c deleted file mode 100644 index 5483fcaa9..000000000 --- a/postfix/src/util/net_mask_top.c +++ /dev/null @@ -1,120 +0,0 @@ -/*++ -/* NAME -/* net_mask_top 3 -/* SUMMARY -/* convert net/mask to printable string -/* SYNOPSIS -/* #include -/* -/* 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 -#include -#include -#include -#include - - /* - * Utility library. - */ -#include -#include -#include -#include -#include - -/* - * 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)); -}