From: Wietse Venema Date: Mon, 12 Jan 2015 05:00:00 +0000 (-0500) Subject: postfix-2.12-20150112-nonprod X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9952d0c9f53359354eb3d744adc3bf84c020afa5;p=thirdparty%2Fpostfix.git postfix-2.12-20150112-nonprod --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 9871221ca..6126f4ba9 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -21326,7 +21326,7 @@ Apologies for any names omitted. mysql_table(5), pgsql_table(5) and sqlite_table(5), virtual_alias_domains, virtual_mailbox_domains. -20140111 +20150111 Cleanup: simplified the interposition layer that adds UTF-8 support to Postfix lookup tables. Files: util/dict_utf8.c. @@ -21345,3 +21345,14 @@ Apologies for any names omitted. smtpd_tls_session_cache_database, transport_maps, virtual_alias_maps, virtual_gid_maps, virtual_mailbox_maps, virtual_uid_maps. + +20150112 + + Support for UTF-8 casefolding in match_lists. Instead of + using strcasecmp(), casefold all string constant patterns + during initialization, and casefold a search string at the + beginning of the search, and use strcmp() for comparison. + Files: util/casefold.c util/dict.h, util/dict_utf8.c, + util/match_list.c, util/match_list.h, util/match_ops.c, + util/stringops.h, global/addr_match_list.c, global/domain_list.c, + global/namadr_list.c, global/string_list.c. diff --git a/postfix/README_FILES/SMTPUTF8_README b/postfix/README_FILES/SMTPUTF8_README index 8dc081a1f..f03b3a0d8 100644 --- a/postfix/README_FILES/SMTPUTF8_README +++ b/postfix/README_FILES/SMTPUTF8_README @@ -218,13 +218,6 @@ name or email address in mydestination, relay_domains, access maps, transport_maps, etc., and when maintaining tables with the postmap(1) and postalias(1) commands. -NNoo ccaassee--iinnsseennssiittiivvee mmaattcchhiinngg ooff nnoonn--AASSCCIIII ssttrriinngg ppaatttteerrnnss iinn mmaattcchhlliissttss.. - -Postfix currently does not yet implement case-insensitive string comparison for -non-ASCII string patterns in list features such as mydestination, -relay_domains, etc. For now, use "inline:{string}" instead of "string". This -limitation will be removed before the stable release. - CCoommppaattiibbiilliittyy wwiitthh pprree--SSMMTTPPUUTTFF88 eennvviirroonnmmeennttss MMaaiilliinngg lliissttss wwiitthh UUTTFF--88 aanndd nnoonn--UUTTFF--88 ssuubbssccrriibbeerrss diff --git a/postfix/WISHLIST b/postfix/WISHLIST index a8f3b85b9..26f80b1d1 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -8,6 +8,8 @@ Wish list: Things to do after the stable release: + Add context argument for better match_list diagnostics. + Expose UTF8 flag in server_acl API. Some applications such as postscreen don't need UTF8 support. diff --git a/postfix/html/SMTPUTF8_README.html b/postfix/html/SMTPUTF8_README.html index 33c101be7..546b9c4a8 100644 --- a/postfix/html/SMTPUTF8_README.html +++ b/postfix/html/SMTPUTF8_README.html @@ -298,14 +298,6 @@ domain name or email address in mydestin maps, transport_maps, etc., and when maintaining tables with the postmap(1) and postalias(1) commands.

-

No case-insensitive matching of non-ASCII string patterns in matchlists.

- -

Postfix currently does not yet implement case-insensitive string -comparison for non-ASCII string patterns in list features such as -mydestination, relay_domains, etc. For now, use "inline:{string}" -instead of "string". This limitation will be removed before the -stable release.

-

Compatibility with pre-SMTPUTF8 environments

diff --git a/postfix/proto/SMTPUTF8_README.html b/postfix/proto/SMTPUTF8_README.html index 9461ea6b5..40f594b4e 100644 --- a/postfix/proto/SMTPUTF8_README.html +++ b/postfix/proto/SMTPUTF8_README.html @@ -298,14 +298,6 @@ domain name or email address in mydestination, relay_domains, access maps, transport_maps, etc., and when maintaining tables with the postmap(1) and postalias(1) commands.

-

No case-insensitive matching of non-ASCII string patterns in matchlists.

- -

Postfix currently does not yet implement case-insensitive string -comparison for non-ASCII string patterns in list features such as -mydestination, relay_domains, etc. For now, use "inline:{string}" -instead of "string". This limitation will be removed before the -stable release.

-

Compatibility with pre-SMTPUTF8 environments

diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index e994fb9f5..ab6b8a1ec 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -688,8 +688,11 @@ abounce.o: mail_proto.h abounce.o: msg_stats.h abounce.o: recipient_list.h addr_match_list.o: ../../include/argv.h +addr_match_list.o: ../../include/check_arg.h addr_match_list.o: ../../include/match_list.h addr_match_list.o: ../../include/sys_defs.h +addr_match_list.o: ../../include/vbuf.h +addr_match_list.o: ../../include/vstring.h addr_match_list.o: addr_match_list.c addr_match_list.o: addr_match_list.h anvil_clnt.o: ../../include/attr.h @@ -878,9 +881,12 @@ db_common.o: db_common.c db_common.o: db_common.h db_common.o: string_list.h debug_peer.o: ../../include/argv.h +debug_peer.o: ../../include/check_arg.h debug_peer.o: ../../include/match_list.h debug_peer.o: ../../include/msg.h debug_peer.o: ../../include/sys_defs.h +debug_peer.o: ../../include/vbuf.h +debug_peer.o: ../../include/vstring.h debug_peer.o: debug_peer.c debug_peer.o: debug_peer.h debug_peer.o: mail_params.h @@ -1107,8 +1113,11 @@ dict_sqlite.o: dict_sqlite.c dict_sqlite.o: dict_sqlite.h dict_sqlite.o: string_list.h domain_list.o: ../../include/argv.h +domain_list.o: ../../include/check_arg.h domain_list.o: ../../include/match_list.h domain_list.o: ../../include/sys_defs.h +domain_list.o: ../../include/vbuf.h +domain_list.o: ../../include/vstring.h domain_list.o: domain_list.c domain_list.o: domain_list.h dot_lockfile.o: ../../include/check_arg.h @@ -1842,8 +1851,11 @@ mark_corrupt.o: mark_corrupt.h mark_corrupt.o: msg_stats.h mark_corrupt.o: recipient_list.h match_parent_style.o: ../../include/argv.h +match_parent_style.o: ../../include/check_arg.h match_parent_style.o: ../../include/match_list.h match_parent_style.o: ../../include/sys_defs.h +match_parent_style.o: ../../include/vbuf.h +match_parent_style.o: ../../include/vstring.h match_parent_style.o: mail_params.h match_parent_style.o: match_parent_style.c match_parent_style.o: match_parent_style.h @@ -2090,8 +2102,11 @@ mypwd.o: ../../include/sys_defs.h mypwd.o: mypwd.c mypwd.o: mypwd.h namadr_list.o: ../../include/argv.h +namadr_list.o: ../../include/check_arg.h namadr_list.o: ../../include/match_list.h namadr_list.o: ../../include/sys_defs.h +namadr_list.o: ../../include/vbuf.h +namadr_list.o: ../../include/vstring.h namadr_list.o: namadr_list.c namadr_list.o: namadr_list.h off_cvt.o: ../../include/check_arg.h @@ -2491,8 +2506,11 @@ stream2rec.o: rec_type.h stream2rec.o: record.h stream2rec.o: stream2rec.c string_list.o: ../../include/argv.h +string_list.o: ../../include/check_arg.h string_list.o: ../../include/match_list.h string_list.o: ../../include/sys_defs.h +string_list.o: ../../include/vbuf.h +string_list.o: ../../include/vstring.h string_list.o: string_list.c string_list.o: string_list.h strip_addr.o: ../../include/mymalloc.h diff --git a/postfix/src/global/addr_match_list.c b/postfix/src/global/addr_match_list.c index 946cf4ae3..fdc95d012 100644 --- a/postfix/src/global/addr_match_list.c +++ b/postfix/src/global/addr_match_list.c @@ -88,6 +88,7 @@ #include #include #include +#include /* util_utf8_enable */ static void usage(char *progname) { @@ -113,6 +114,8 @@ int main(int argc, char **argv) } if (argc != optind + 2) usage(argv[0]); + dict_allow_surrogate = 1; + util_utf8_enable = 1; list = addr_match_list_init(MATCH_FLAG_PARENT | MATCH_FLAG_RETURN, argv[optind]); addr = argv[optind + 1]; if (strcmp(addr, "-") == 0) { diff --git a/postfix/src/global/domain_list.c b/postfix/src/global/domain_list.c index 8433caaf7..c64f4de38 100644 --- a/postfix/src/global/domain_list.c +++ b/postfix/src/global/domain_list.c @@ -88,6 +88,7 @@ #include #include #include +#include /* util_utf8_enable */ static void usage(char *progname) { @@ -113,6 +114,8 @@ int main(int argc, char **argv) } if (argc != optind + 2) usage(argv[0]); + dict_allow_surrogate = 1; + util_utf8_enable = 1; list = domain_list_init(MATCH_FLAG_PARENT | MATCH_FLAG_RETURN, argv[optind]); host = argv[optind + 1]; vstream_printf("%s: %s\n", host, domain_list_match(list, host) ? diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 27ad964d2..c97ed8e87 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 "20150111" +#define MAIL_RELEASE_DATE "20150112" #define MAIL_VERSION_NUMBER "2.12" #ifdef SNAPSHOT diff --git a/postfix/src/global/namadr_list.c b/postfix/src/global/namadr_list.c index fc7f681ed..eebfa68db 100644 --- a/postfix/src/global/namadr_list.c +++ b/postfix/src/global/namadr_list.c @@ -95,6 +95,7 @@ #include #include #include +#include /* util_utf8_enable */ static void usage(char *progname) { @@ -122,6 +123,7 @@ int main(int argc, char **argv) if (argc != optind + 3) usage(argv[0]); dict_allow_surrogate = 1; + util_utf8_enable = 1; list = namadr_list_init(MATCH_FLAG_PARENT | MATCH_FLAG_RETURN, argv[optind]); host = argv[optind + 1]; addr = argv[optind + 2]; diff --git a/postfix/src/global/string_list.c b/postfix/src/global/string_list.c index a24e4e179..b5dda32e8 100644 --- a/postfix/src/global/string_list.c +++ b/postfix/src/global/string_list.c @@ -81,6 +81,7 @@ #include #include #include +#include /* util_utf8_enable */ static void usage(char *progname) { @@ -106,6 +107,8 @@ int main(int argc, char **argv) } if (argc != optind + 2) usage(argv[0]); + dict_allow_surrogate = 1; + util_utf8_enable = 1; list = string_list_init(MATCH_FLAG_RETURN, argv[optind]); string = argv[optind + 1]; vstream_printf("%s: %s\n", string, string_list_match(list, string) ? diff --git a/postfix/src/util/casefold.c b/postfix/src/util/casefold.c index ed4b493a6..99acf7572 100644 --- a/postfix/src/util/casefold.c +++ b/postfix/src/util/casefold.c @@ -7,6 +7,7 @@ /* #include /* /* char *casefold( +/* int utf8_request, /* VSTRING *src, /* const char *src, /* CONST_CHAR_STAR *err) @@ -29,6 +30,8 @@ /* range), not even when running inside an empty chroot jail. /* /* Arguments: +/* .IP utf8_request +/* Perform UTF-8 case folding. /* .IP src /* Null-terminated input string. /* .IP dest @@ -69,7 +72,8 @@ /* casefold - casefold an UTF-8 string */ -char *casefold(VSTRING *dest, const char *src, CONST_CHAR_STAR *err) +char *casefold(int utf8_req, VSTRING *dest, const char *src, + CONST_CHAR_STAR *err) { #ifdef NO_EAI @@ -91,7 +95,7 @@ char *casefold(VSTRING *dest, const char *src, CONST_CHAR_STAR *err) /* * All-ASCII input. */ - if (allascii(src)) { + if (utf8_req == 0 || allascii(src)) { vstring_strcpy(dest, src); return (lowercase(STR(dest))); } @@ -183,14 +187,14 @@ int main(int argc, char **argv) char *conv_res; const char *fold_err; char *cmd; - int codepoint, first, last; + int codepoint, first, last, utf8_req; if (setlocale(LC_ALL, "C") == 0) msg_fatal("setlocale(LC_ALL, C) failed: %m"); msg_vstream_init(argv[0], VSTREAM_ERR); - util_utf8_enable = 1; + utf8_req = util_utf8_enable = 1; VSTRING_SPACE(buffer, 256); /* chroot pathname */ @@ -207,7 +211,7 @@ int main(int argc, char **argv) * Null-terminated string. */ if (strcmp(cmd, "fold") == 0) { - if ((conv_res = casefold(dest, bp, &fold_err)) != 0) + if ((conv_res = casefold(utf8_req, dest, bp, &fold_err)) != 0) msg_info("\"%s\" ->fold \"%s\"", bp, conv_res); else msg_warn("cannot casefold \"%s\": %s", bp, fold_err); @@ -229,7 +233,7 @@ int main(int argc, char **argv) msg_info("U+%X -> %s", codepoint, STR(buffer)); if (valid_utf8_string(STR(buffer), LEN(buffer)) == 0) msg_fatal("bad utf-8 encoding for U+%X", codepoint); - if (casefold(dest, STR(buffer), &fold_err) == 0) + if (casefold(utf8_req, dest, STR(buffer), &fold_err) == 0) msg_warn("casefold error for U+%X: %s", codepoint, fold_err); } diff --git a/postfix/src/util/dict.h b/postfix/src/util/dict.h index b86bad8ac..0c3c464a6 100644 --- a/postfix/src/util/dict.h +++ b/postfix/src/util/dict.h @@ -269,6 +269,7 @@ extern DICT *PRINTFLIKE(5, 6) dict_surrogate(const char *, const char *, int, in * This name is reserved for matchlist error handling. */ #define DICT_TYPE_NOFILE "non-existent" +#define DICT_TYPE_NOUTF8 "non-UTF-8" /* * Duplicated from vstream(3). This should probably be abstracted out. diff --git a/postfix/src/util/dict_utf8.c b/postfix/src/util/dict_utf8.c index eecabf68a..9a6c7b68d 100644 --- a/postfix/src/util/dict_utf8.c +++ b/postfix/src/util/dict_utf8.c @@ -34,9 +34,7 @@ /* configuration error. /* /* The dict_utf8_check* functions may be invoked to perform -/* UTF-8 validity checks when util_utf8_enable is non-zero and -/* DICT_FLAG_UTF8_ENABLE is set. Otherwise both functions -/* always report success. +/* UTF-8 validity checks when util_utf8_enable is non-zero. /* /* dict_utf8_check_fold() optionally folds a string, and checks /* it for UTF-8 validity. The result is the possibly-folded @@ -130,7 +128,8 @@ char *dict_utf8_check_fold(DICT *dict, const char *string, DICT_FLAG_FOLD_FIX : DICT_FLAG_FOLD_MUL)) { if (dict->fold_buf == 0) dict->fold_buf = vstring_alloc(10); - return (casefold(dict->fold_buf, string, err)); + return (casefold(dict->flags & DICT_FLAG_UTF8_ACTIVE, + dict->fold_buf, string, err)); } /* @@ -278,14 +277,20 @@ static int dict_utf8_delete(DICT *dict, const char *key) DICT *dict_utf8_activate(DICT *dict) { + const char myname[] = "dict_utf8_activate"; DICT_UTF8_BACKUP *backup; /* * Sanity check. */ + if (util_utf8_enable == 0) + msg_panic("%s: Unicode support is not available", myname); + if ((dict->flags & DICT_FLAG_UTF8_REQUEST) == 0) + msg_panic("%s: %s:%s does not request Unicode support", + myname, dict->type, dict->name); if (dict->flags & DICT_FLAG_UTF8_ACTIVE) - msg_panic("dict_utf8_activate: %s:%s is already encapsulated", - dict->type, dict->name); + msg_panic("%s: %s:%s Unicode support is already activated", + myname, dict->type, dict->name); /* * Unlike dict_debug(3) we do not put a proxy dict object in front of the diff --git a/postfix/src/util/match_list.c b/postfix/src/util/match_list.c index 962656211..f0a3f90ab 100644 --- a/postfix/src/util/match_list.c +++ b/postfix/src/util/match_list.c @@ -20,7 +20,8 @@ /* MATCH_LIST *list; /* DESCRIPTION /* This module implements a framework for tests for list membership. -/* The actual tests are done by user-supplied functions. +/* The actual tests are done by user-supplied functions. With +/* util_utf8_enable non-zero, string comparison supports UTF-8. /* /* Patterns are separated by whitespace and/or commas. A pattern /* is either a string, a file name (in which case the contents @@ -94,7 +95,8 @@ /* match_list_parse - parse buffer, destroy buffer */ -static ARGV *match_list_parse(ARGV *list, char *string, int init_match) +static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list, + char *string, int init_match) { const char *myname = "match_list_parse"; VSTRING *buf = vstring_alloc(10); @@ -105,15 +107,23 @@ static ARGV *match_list_parse(ARGV *list, char *string, int init_match) char *item; char *map_type_name_flags; int match; + const char *utf8_err; + /* + * No DICT_FLAG_FOLD_FIX here, because we casefold the search string at + * the beginning of a search. String constant patterns are casefolded + * during match_list initialization. + */ #define OPEN_FLAGS O_RDONLY -#define DICT_FLAGS (DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX \ - | DICT_FLAG_UTF8_REQUEST) +#define DICT_FLAGS (DICT_FLAG_LOCK | DICT_FLAG_UTF8_REQUEST) #define STR(x) vstring_str(x) /* * /filename contents are expanded in-line. To support !/filename we * prepend the negation operator to each item from the file. + * + * If there is an error, implement graceful degradation by inserting a + * pseudo table whose lookups fail with a warning message. */ while ((start = mystrtokq(&bp, delim, CHARS_BRACE)) != 0) { if (*start == '#') { @@ -128,17 +138,17 @@ static ARGV *match_list_parse(ARGV *list, char *string, int init_match) if (*item == '/') { /* /file/name */ if ((fp = vstream_fopen(item, O_RDONLY, 0)) == 0) { vstring_sprintf(buf, "%s:%s", DICT_TYPE_NOFILE, item); - /* XXX Should increment existing map refcount. */ if (dict_handle(STR(buf)) == 0) dict_register(STR(buf), dict_surrogate(DICT_TYPE_NOFILE, item, OPEN_FLAGS, DICT_FLAGS, "open file %s: %m", item)); - argv_add(list, STR(buf), (char *) 0); + argv_add(pat_list, STR(buf), (char *) 0); } else { while (vstring_fgets(buf, fp)) if (vstring_str(buf)[0] != '#') - list = match_list_parse(list, vstring_str(buf), match); + pat_list = match_list_parse(match_list, pat_list, + vstring_str(buf), match); if (vstream_fclose(fp)) msg_fatal("%s: read file %s: %m", myname, item); } @@ -146,18 +156,28 @@ static ARGV *match_list_parse(ARGV *list, char *string, int init_match) vstring_sprintf(buf, "%s%s(%o,%s)", match ? "" : "!", item, OPEN_FLAGS, dict_flags_str(DICT_FLAGS)); map_type_name_flags = STR(buf) + (match == 0); - /* XXX Should increment existing map refcount. */ if (dict_handle(map_type_name_flags) == 0) dict_register(map_type_name_flags, dict_open(item, OPEN_FLAGS, DICT_FLAGS)); - argv_add(list, STR(buf), (char *) 0); + argv_add(pat_list, STR(buf), (char *) 0); } else { /* other pattern */ - argv_add(list, match ? item : - STR(vstring_sprintf(buf, "!%s", item)), (char *) 0); + if (casefold(util_utf8_enable, match_list->fold_buf, match ? + item : STR(vstring_sprintf(buf, "!%s", item)), + &utf8_err) == 0) { + vstring_sprintf(match_list->fold_buf, "%s:%s", + DICT_TYPE_NOUTF8, item); + if (dict_handle(STR(match_list->fold_buf)) == 0) + dict_register(STR(match_list->fold_buf), + dict_surrogate(DICT_TYPE_NOFILE, item, + OPEN_FLAGS, DICT_FLAGS, + "casefold error: %s", + utf8_err)); + } + argv_add(pat_list, STR(match_list->fold_buf), (char *) 0); } } vstring_free(buf); - return (list); + return (pat_list); } /* match_list_init - initialize pattern list */ @@ -184,11 +204,13 @@ MATCH_LIST *match_list_init(int flags, const char *patterns, int match_count,... list->match_func[i] = va_arg(ap, MATCH_LIST_FN); va_end(ap); list->error = 0; + list->fold_buf = vstring_alloc(20); #define DO_MATCH 1 saved_patterns = mystrdup(patterns); - list->patterns = match_list_parse(argv_alloc(1), saved_patterns, DO_MATCH); + list->patterns = match_list_parse(list, argv_alloc(1), saved_patterns, + DO_MATCH); argv_terminate(list->patterns); myfree(saved_patterns); return (list); @@ -204,6 +226,7 @@ int match_list_match(MATCH_LIST *list,...) int match; int i; va_list ap; + const char *utf8_err; /* * Iterate over all patterns in the list, stop at the first match. @@ -217,11 +240,18 @@ int match_list_match(MATCH_LIST *list,...) for (cpp = list->patterns->argv; (pat = *cpp) != 0; cpp++) { for (match = 1; *pat == '!'; pat++) match = !match; - for (i = 0; i < list->match_count; i++) - if (list->match_func[i] (list, list->match_args[i], pat)) + for (i = 0; i < list->match_count; i++) { + if (casefold(util_utf8_enable, list->fold_buf, + list->match_args[i], &utf8_err) == 0) { + msg_warn("%s: casefold error for \"%s\": %s", + myname, list->match_args[i], utf8_err); + continue; + } + if (list->match_func[i] (list, STR(list->fold_buf), pat)) return (match); else if (list->error != 0) return (0); + } } if (msg_verbose) for (i = 0; i < list->match_count; i++) @@ -237,5 +267,6 @@ void match_list_free(MATCH_LIST *list) argv_free(list->patterns); myfree((void *) list->match_func); myfree((void *) list->match_args); + vstring_free(list->fold_buf); myfree((void *) list); } diff --git a/postfix/src/util/match_list.h b/postfix/src/util/match_list.h index d51b6e831..c08475cd3 100644 --- a/postfix/src/util/match_list.h +++ b/postfix/src/util/match_list.h @@ -15,6 +15,7 @@ * Utility library. */ #include +#include /* * External interface. @@ -29,6 +30,7 @@ struct MATCH_LIST { int match_count; /* match function/argument count */ MATCH_LIST_FN *match_func; /* match functions */ const char **match_args; /* match arguments */ + VSTRING *fold_buf; /* case-folded pattern string */ int error; /* last operation */ }; diff --git a/postfix/src/util/match_ops.c b/postfix/src/util/match_ops.c index f978d2629..f49b13865 100644 --- a/postfix/src/util/match_ops.c +++ b/postfix/src/util/match_ops.c @@ -132,9 +132,10 @@ int match_string(MATCH_LIST *list, const char *string, const char *pattern) } /* - * Try an exact string match. + * Try an exact string match. Note that the string and pattern are + * already casefolded. */ - if (strcasecmp(string, pattern) == 0) { + if (strcmp(string, pattern) == 0) { return (1); } @@ -189,23 +190,25 @@ int match_hostname(MATCH_LIST *list, const char *name, const char *pattern) } /* - * Try an exact match with the host name. + * Try an exact match with the host name. Note that the name and the + * pattern are already casefolded. */ - if (strcasecmp(name, pattern) == 0) { + if (strcmp(name, pattern) == 0) { return (1); } /* - * See if the pattern is a parent domain of the hostname. + * See if the pattern is a parent domain of the hostname. Note that the + * name and the pattern are already casefolded. */ else { if (list->flags & MATCH_FLAG_PARENT) { pd = name + strlen(name) - strlen(pattern); - if (pd > name && pd[-1] == '.' && strcasecmp(pd, pattern) == 0) + if (pd > name && pd[-1] == '.' && strcmp(pd, pattern) == 0) return (1); } else if (pattern[0] == '.') { pd = name + strlen(name) - strlen(pattern); - if (pd > name && strcasecmp(pd, pattern) == 0) + if (pd > name && strcmp(pd, pattern) == 0) return (1); } } @@ -247,15 +250,16 @@ int match_hostaddr(MATCH_LIST *list, const char *addr, const char *pattern) } /* - * Try an exact match with the host address. + * Try an exact match with the host address. Note that the address and + * pattern are already casefolded. */ if (pattern[0] != '[') { - if (strcasecmp(addr, pattern) == 0) + if (strcmp(addr, pattern) == 0) return (1); } else { size_t addr_len = strlen(addr); - if (strncasecmp(addr, pattern + 1, addr_len) == 0 + if (strncmp(addr, pattern + 1, addr_len) == 0 && strcmp(pattern + 1 + addr_len, "]") == 0) return (1); } @@ -271,7 +275,7 @@ int match_hostaddr(MATCH_LIST *list, const char *addr, const char *pattern) * - Don't bother unless the pattern is either an IPv6 address or net/mask. * * We can safely skip IPv4 address patterns because their form is - * unambiguous and they did not match in the strcasecmp() calls above. + * unambiguous and they did not match in the strcmp() calls above. * * XXX We MUST skip (parent) domain names, which may appear in NAMADR_LIST * input, to avoid triggering false cidr_match_parse() errors. diff --git a/postfix/src/util/stringops.h b/postfix/src/util/stringops.h index cac9eca55..52938ca30 100644 --- a/postfix/src/util/stringops.h +++ b/postfix/src/util/stringops.h @@ -23,7 +23,7 @@ extern int util_utf8_enable; extern char *printable(char *, int); extern char *neuter(char *, const char *, int); extern char *lowercase(char *); -extern char *casefold(VSTRING *, const char *, CONST_CHAR_STAR *); +extern char *casefold(int, VSTRING *, const char *, CONST_CHAR_STAR *); extern char *uppercase(char *); extern char *skipblanks(const char *); extern char *trimblanks(char *, ssize_t);