[packages/dovecot] - rel 2; add support for wildcard local_name matching
arekm
arekm at pld-linux.org
Fri Nov 11 16:34:03 CET 2016
commit 1c1943204af3db4567dd829c98e26dadff90639a
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Fri Nov 11 16:33:56 2016 +0100
- rel 2; add support for wildcard local_name matching
dovecot-local_name-wildcard.patch | 392 ++++++++++++++++++++++++++++++++++++++
dovecot.spec | 6 +-
2 files changed, 395 insertions(+), 3 deletions(-)
---
diff --git a/dovecot.spec b/dovecot.spec
index c3c67fb..eeb3c3f 100644
--- a/dovecot.spec
+++ b/dovecot.spec
@@ -12,7 +12,7 @@ Summary: IMAP and POP3 server written with security primarily in mind
Summary(pl.UTF-8): Serwer IMAP i POP3 pisany głównie z myślą o bezpieczeństwie
Name: dovecot
Version: 2.2.26.0
-Release: 1
+Release: 2
Epoch: 1
License: MIT (libraries), LGPL v2.1 (the rest)
Group: Networking/Daemons
@@ -24,7 +24,7 @@ Source3: %{name}.sysconfig
Source4: %{name}.tmpfiles
Patch0: %{name}-config.patch
Patch1: %{name}-rpath.patch
-
+Patch2: dovecot-local_name-wildcard.patch
Patch3: %{name}-disableSSLv3.patch
URL: http://dovecot.org/
BuildRequires: autoconf
@@ -158,7 +158,7 @@ Współdzielone biblioteki Dovecota.
%setup -q
%patch0 -p1
%patch1 -p1
-
+%patch2 -p1
%patch3 -p2
%{__sed} -i 's,/usr/lib/dovecot,%{_libdir}/dovecot,g' doc/example-config/*.conf doc/example-config/conf.d/*.conf
diff --git a/dovecot-local_name-wildcard.patch b/dovecot-local_name-wildcard.patch
new file mode 100644
index 0000000..26cd008
--- /dev/null
+++ b/dovecot-local_name-wildcard.patch
@@ -0,0 +1,392 @@
+From 1016a956f6fb8a14e5d24372dc8ed3615b2ecc10 Mon Sep 17 00:00:00 2001
+From: Aki Tuomi <aki.tuomi at dovecot.fi>
+Date: Fri, 11 Nov 2016 13:13:29 +0200
+Subject: [PATCH 1/3] lib-dns: Add DNS specific matching algorithms
+
+RFC4343 and RFCRFC4592 compare and match algorithms
+---
+ src/lib-dns/Makefile.am | 6 ++--
+ src/lib-dns/dns-util.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/lib-dns/dns-util.h | 36 +++++++++++++++++++++
+ 3 files changed, 125 insertions(+), 2 deletions(-)
+ create mode 100644 src/lib-dns/dns-util.c
+ create mode 100644 src/lib-dns/dns-util.h
+
+diff --git a/src/lib-dns/Makefile.am b/src/lib-dns/Makefile.am
+index 751860a..4a0e8bc 100644
+--- a/src/lib-dns/Makefile.am
++++ b/src/lib-dns/Makefile.am
+@@ -4,10 +4,12 @@ AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/lib
+
+ libdns_la_SOURCES = \
+- dns-lookup.c
++ dns-lookup.c \
++ dns-util.c
+
+ headers = \
+- dns-lookup.h
++ dns-lookup.h \
++ dns-util.h
+
+ pkginc_libdir=$(pkgincludedir)
+ pkginc_lib_HEADERS = $(headers)
+diff --git a/src/lib-dns/dns-util.c b/src/lib-dns/dns-util.c
+new file mode 100644
+index 0000000..3ed7244
+--- /dev/null
++++ b/src/lib-dns/dns-util.c
+@@ -0,0 +1,85 @@
++/* Copyright (c) 2010-2016 Dovecot authors, see the included COPYING file */
++#include "lib.h"
++#include "dns-util.h"
++
++/**
++ return first position from b->a of c or a if not found
++ */
++static inline
++const char *strchr_ba(const char *a, const char *b, char c)
++{
++ for(;b>a && *b != c; b--);
++ return b;
++}
++
++int dns_ncompare(const char *a, const char *b, size_t n)
++{
++ if (a == NULL && b == NULL) return 0;
++ if (a == NULL && b != NULL) return 1;
++ if (a != NULL && b == NULL) return -1;
++
++ for(size_t i = 0; i < n &&
++ *a != '\0' &&
++ *b != '\0' &&
++ dns_tolower(*a) == dns_tolower(*b);
++ i++, a++, b++);
++
++ return dns_tolower(*a) - dns_tolower(*b);
++}
++
++int dns_compare(const char *a, const char *b)
++{
++ return dns_ncompare(a, b, (size_t)-1);
++}
++
++int dns_compare_labels(const char *a, const char *b)
++{
++ if (a == NULL && b == NULL) return 0;
++ if (a == NULL && b != NULL) return 1;
++ if (a != NULL && b == NULL) return -1;
++
++ const char *ptr_a = a + strlen(a);
++ const char *ptr_b = b + strlen(b);
++ const char *label_a = ptr_a, *label_b = ptr_b;
++ int comp = 0;
++
++ while(comp == 0 && ptr_a > a && ptr_b > b) {
++ /* look for start of label, including dot */
++ label_a = strchr_ba(a, ptr_a, '.');
++ label_b = strchr_ba(b, ptr_b, '.');
++ if (ptr_a - label_a != ptr_b - label_b)
++ /* compare labels up to minimum length
++ but include \0 to make sure that we
++ don't consider alpha and alphabet
++ equal */
++ return dns_ncompare(label_a, label_b,
++ I_MIN(ptr_a - label_a,
++ ptr_b - label_b)+1);
++ comp = dns_ncompare(label_a, label_b, ptr_a -label_a);
++ ptr_a = label_a - 1;
++ ptr_b = label_b - 1;
++ }
++
++ return dns_tolower(*label_a) - dns_tolower(*label_b);
++}
++
++int dns_match_wildcard(const char *name, const char *mask)
++{
++ i_assert(name != NULL && mask != NULL);
++
++ for(;*name != '\0' && *mask != '\0'; name++, mask++) {
++ switch(*mask) {
++ case '*':
++ for(; *name != '\0' && *name != '.'; name++);
++ if (*name == '.') mask++;
++ if (dns_tolower(*name) != dns_tolower(*mask)) return -1;
++ break;
++ case '?':
++ break;
++ default:
++ if (dns_tolower(*name) != dns_tolower(*mask)) return -1;
++ }
++ }
++ if (*mask == '*') mask++;
++ return dns_tolower(*name) == dns_tolower(*mask) ? 0 : -1;
++}
+diff --git a/src/lib-dns/dns-util.h b/src/lib-dns/dns-util.h
+new file mode 100644
+index 0000000..cff52ff
+--- /dev/null
++++ b/src/lib-dns/dns-util.h
+@@ -0,0 +1,36 @@
++#ifndef DNS_UTIL_H
++#define DNS_UTIL_H 1
++
++static inline char
++dns_tolower(char c)
++{
++ if (c >= 'A' && c <= 'Z')
++ c+='a'-'A';
++ return c;
++}
++
++/**
++ * Will compare names in accordance with RFC4343
++ */
++int dns_compare(const char *a, const char *b) ATTR_PURE;
++int dns_ncompare(const char *a, const char *b, size_t n) ATTR_PURE;
++
++/**
++ * Same as above but done by labels from right to left
++ *
++ * www.example.org and www.example.net would be compared as
++ * org = net (return first difference)
++ * example = example
++ * www = www
++ */
++int dns_compare_labels(const char *a, const char *b) ATTR_PURE;
++
++/**
++ * Will match names in RFC4592 style
++ *
++ * this means *.foo.bar will match name.foo.bar
++ * but *DOES NOT* match something.name.foo.bar
++ */
++int dns_match_wildcard(const char *name, const char *mask) ATTR_PURE;
++
++#endif
+--
+2.1.4
+
+From da2908b37fc00d23018a2a455bad805bfd5ba006 Mon Sep 17 00:00:00 2001
+From: Aki Tuomi <aki.tuomi at dovecot.fi>
+Date: Fri, 11 Nov 2016 13:36:23 +0200
+Subject: [PATCH 2/3] lib-dns: Add tests for dns-util
+
+---
+ src/lib-dns/Makefile.am | 26 ++++++++++
+ src/lib-dns/test-dns-util.c | 120 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 146 insertions(+)
+ create mode 100644 src/lib-dns/test-dns-util.c
+
+diff --git a/src/lib-dns/Makefile.am b/src/lib-dns/Makefile.am
+index 4a0e8bc..302e37c 100644
+--- a/src/lib-dns/Makefile.am
++++ b/src/lib-dns/Makefile.am
+@@ -11,5 +11,31 @@ headers = \
+ dns-lookup.h \
+ dns-util.h
+
++test_programs = \
++ test-dns-util
++
++noinst_PROGRAMS = $(test_programs)
++
++test_libs = \
++ libdns.la \
++ ../lib-test/libtest.la \
++ ../lib/liblib.la
++
++test_dns_util_SOURCE = test-dns-util.c
++test_dns_util_LDADD = $(test_libs)
++test_dns_util_CFLAGS = $(AM_CPPFLAGS) \
++ -I$(top_srcdir)/src/lib-test
++
++check: check-am check-test
++check-test: all-am
++ for bin in $(test_programs); do \
++ if test "$$bin" = "test-program-client-local"; then \
++ if ! env NOVALGRIND=yes $(RUN_TEST) ./$$bin; then exit 1; fi; \
++ else \
++ if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \
++ fi \
++ done
++
++
+ pkginc_libdir=$(pkgincludedir)
+ pkginc_lib_HEADERS = $(headers)
+diff --git a/src/lib-dns/test-dns-util.c b/src/lib-dns/test-dns-util.c
+new file mode 100644
+index 0000000..96c1be7
+--- /dev/null
++++ b/src/lib-dns/test-dns-util.c
+@@ -0,0 +1,120 @@
++#include "lib.h"
++#include "test-lib.h"
++#include "dns-util.h"
++#include "array.h"
++
++static void test_dns_compare(void)
++{
++ struct {
++ const char *a;
++ const char *b;
++ int res;
++ } tests[] =
++ {
++ { NULL, NULL, 0 },
++ { NULL, "", 1 },
++ { "", NULL, -1 },
++ { "", "", 0 },
++ { "a", "a", 0 },
++ { "a", "b", -1 },
++ { "b", "a", 1 },
++ { "A", "A", 0 },
++ { "A", "B", -1 },
++ { "B", "A", 1 },
++ { "A", "a", 0 },
++ { "a", "B", -1 },
++ { "B", "a", 1 },
++ { "test.invalid", "TeSt.InVaLid", 0 },
++ { "alphabet.com", "alpha.com", 52 },
++ { "com.alphabet", "com.alpha", 98 },
++ { "com.com", "com.comcom", -99 },
++ };
++
++ test_begin("test_dns_compare");
++
++ for(size_t i = 0; i < N_ELEMENTS(tests); i++) {
++ test_assert_idx(dns_compare(tests[i].a, tests[i].b) == tests[i].res, i);
++ test_assert_idx(dns_compare_labels(tests[i].a, tests[i].b) == tests[i].res, i);
++ }
++
++ test_end();
++}
++
++static void test_dns_match(void)
++{
++ struct {
++ const char *name;
++ const char *mask;
++ int res;
++ } tests[] =
++ {
++ { "", "", 0 },
++ { "", "*", 0 },
++ { "*", "", -1 },
++ { "TeSt.InVaLid", "test.invalid", 0 },
++ { "contoso.com", "test.invalid", -1 },
++ { "test.invalid", "test.unvalid", -1 },
++ { "name.test.invalid", "*.test.invalid", 0 },
++ { "real.name.test.invalid", "*.test.invalid", -1 },
++ { "real.name.test.invalid", "*.*.test.invalid", 0 },
++ { "name.test.invalid", "*name*.test.invalid", -1 },
++ };
++
++ test_begin("test_dns_match");
++
++ for(size_t i = 0; i < N_ELEMENTS(tests); i++) {
++ test_assert_idx(dns_match_wildcard(tests[i].name, tests[i].mask) == tests[i].res, i);
++ }
++
++ test_end();
++}
++
++static int
++arr_dns_compare(const char *const *a, const char *const *b)
++{
++ return dns_compare_labels(*a,*b);
++}
++
++static void test_dns_sort(void)
++{
++ const char *input[] = {
++ "test.invalid",
++ "test.com",
++ "test.contoso.com",
++ "test.alphabet.com",
++ "test.xxx",
++ };
++
++ const char *output[] = {
++ "test.alphabet.com",
++ "test.contoso.com",
++ "test.com",
++ "test.invalid",
++ "test.xxx",
++ };
++
++ test_begin("test_dns_sort");
++
++ ARRAY_TYPE(const_string) arr;
++ t_array_init(&arr, 8);
++
++ array_append(&arr, input, N_ELEMENTS(input));
++
++ array_sort(&arr, arr_dns_compare);
++
++ for(size_t i = 0; i < N_ELEMENTS(output); i++) {
++ test_assert_idx(dns_compare(*array_idx(&arr, i), output[i]) == 0, i);
++ }
++
++ test_end();
++}
++
++int main(void) {
++ void (*test_functions[])(void) = {
++ test_dns_compare,
++ test_dns_match,
++ test_dns_sort,
++ NULL
++ };
++ return test_run(test_functions);
++}
+--
+2.1.4
+
+From b2cd5c1cbfa91e7288a6ff41d51ced05c1c25f57 Mon Sep 17 00:00:00 2001
+From: Aki Tuomi <aki.tuomi at dovecot.fi>
+Date: Fri, 11 Nov 2016 13:40:55 +0200
+Subject: [PATCH 3/3] config: Match local_name using dns-util
+
+This way it correctly handles wildcards.
+---
+ src/config/Makefile.am | 1 +
+ src/config/config-filter.c | 3 ++-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/config/Makefile.am b/src/config/Makefile.am
+index 245ee56..a8cafa1 100644
+--- a/src/config/Makefile.am
++++ b/src/config/Makefile.am
+@@ -7,6 +7,7 @@ pkglibexec_PROGRAMS = config
+
+ AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/lib \
++ -I$(top_srcdir)/src/lib-dns \
+ -I$(top_srcdir)/src/lib-settings \
+ -I$(top_srcdir)/src/lib-master \
+ -DPKG_RUNDIR=\""$(rundir)"\" \
+diff --git a/src/config/config-filter.c b/src/config/config-filter.c
+index 87a24da..426a326 100644
+--- a/src/config/config-filter.c
++++ b/src/config/config-filter.c
+@@ -6,6 +6,7 @@
+ #include "master-service-settings.h"
+ #include "config-parser.h"
+ #include "config-filter.h"
++#include "dns-util.h"
+
+ struct config_filter_context {
+ pool_t pool;
+@@ -36,7 +37,7 @@ static bool config_filter_match_rest(const struct config_filter *mask,
+ if (mask->local_name != NULL) {
+ if (filter->local_name == NULL)
+ return FALSE;
+- if (strcasecmp(filter->local_name, mask->local_name) != 0)
++ if (dns_match_wildcard(filter->local_name, mask->local_name) != 0)
+ return FALSE;
+ }
+ /* FIXME: it's not comparing full masks */
+--
+2.1.4
+
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/dovecot.git/commitdiff/1c1943204af3db4567dd829c98e26dadff90639a
More information about the pld-cvs-commit
mailing list