Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
dovecot22.16060
0004-lib-master-Support-validating-config-filte...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0004-lib-master-Support-validating-config-filters-against.patch of Package dovecot22.16060
From 390592e6af07e02064ebdbb1bbcf06528887370f Mon Sep 17 00:00:00 2001 From: Aki Tuomi <aki.tuomi@dovecot.fi> Date: Thu, 30 Nov 2017 15:47:25 +0200 Subject: [PATCH 4/6] lib-master: Support validating config filters against requests Validation will sanitize the input request and drop any fields that have no filter in config. E.g. if you have a local block with name, and nothing else, then lip/rip will be dropped from the request. --- src/lib-master/Makefile.am | 2 + src/lib-master/master-service-settings-cache.c | 90 ++++++++++++++++++++++ src/lib-master/master-service-settings-cache.h | 2 +- src/lib-master/master-service-settings.c | 60 +++++++++++++++ src/lib-master/master-service-settings.h | 3 + .../test-master-service-settings-cache.c | 8 ++ 6 files changed, 164 insertions(+), 1 deletion(-) diff --git a/src/lib-master/Makefile.am b/src/lib-master/Makefile.am index 59f89a4..7d400cb 100644 --- a/src/lib-master/Makefile.am +++ b/src/lib-master/Makefile.am @@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libmaster.la AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-dns \ -I$(top_srcdir)/src/lib-test \ -I$(top_srcdir)/src/lib-settings \ -I$(top_srcdir)/src/lib-ssl-iostream \ @@ -58,6 +59,7 @@ noinst_PROGRAMS = $(test_programs) test_libs = \ ../lib-test/libtest.la \ + ../lib-dns/libdns.la \ ../lib/liblib.la test_deps = $(noinst_LTLIBRARIES) $(test_libs) diff --git a/src/lib-master/master-service-settings-cache.c b/src/lib-master/master-service-settings-cache.c index d6164ff..11e9204 100644 --- a/src/lib-master/master-service-settings-cache.c +++ b/src/lib-master/master-service-settings-cache.c @@ -1,9 +1,11 @@ /* Copyright (c) 2010-2017 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "wildcard-match.h" #include "hash.h" #include "llist.h" #include "settings-parser.h" +#include "dns-util.h" #include "master-service-private.h" #include "master-service-settings.h" #include "master-service-settings-cache.h" @@ -12,6 +14,14 @@ #define CACHE_INITIAL_ENTRY_POOL_SIZE (1024*16) #define CACHE_ADD_ENTRY_POOL_SIZE 1024 +struct config_filter { + struct config_filter *prev, *next; + + const char *local_name; + struct ip_addr local_ip, remote_ip; + unsigned int local_bits, remote_bits; +}; + struct settings_entry { struct settings_entry *prev, *next; @@ -41,6 +51,8 @@ struct master_service_settings_cache { HASH_TABLE(char *, struct settings_entry *) local_name_hash; HASH_TABLE(struct ip_addr *, struct settings_entry *) local_ip_hash; + struct config_filter *filters; + /* Initial size for new settings entry pools */ size_t approx_entry_pool_size; /* number of bytes malloced by cached settings entries @@ -70,6 +82,78 @@ master_service_settings_cache_init(struct master_service *service, return cache; } +int master_service_settings_cache_init_filter(struct master_service_settings_cache *cache) +{ + const char *const *filters; + const char *error; + + if (cache->filters != NULL) + return 0; + if (master_service_settings_get_filters(cache->service, &filters, &error) < 0) { + i_error("master-service: cannot get filters: %s", error); + return -1; + } + + /* parse filters */ + while(*filters != NULL) { + const char *const *keys = t_strsplit_spaces(*filters, " "); + struct config_filter *filter = + p_new(cache->pool, struct config_filter, 1); + while(*keys != NULL) { + if (strncmp(*keys, "local-net=", 10) == 0) { + (void)net_parse_range((*keys)+10, + &filter->local_ip, &filter->local_bits); + } else if (strncmp(*keys, "remote-net=", 11) == 0) { + (void)net_parse_range((*keys)+11, + &filter->remote_ip, &filter->remote_bits); + } else if (strncmp(*keys, "local-name=", 11) == 0) { + filter->local_name = p_strdup(cache->pool, (*keys)+11); + } + keys++; + } + DLLIST_PREPEND(&cache->filters, filter); + filters++; + } + return 0; +} + +/* Remove any elements which there is no filter for */ +static void +master_service_settings_cache_fix_input(struct master_service_settings_cache *cache, + const struct master_service_settings_input *input, + struct master_service_settings_input *new_input) +{ + bool found_lip, found_rip, found_local_name; + + found_lip = found_rip = found_local_name = FALSE; + + struct config_filter *filter = cache->filters; + while(filter != NULL) { + if (filter->local_bits > 0 && + net_is_in_network(&input->local_ip, &filter->local_ip, + filter->local_bits)) + found_lip = TRUE; + if (filter->remote_bits > 0 && + net_is_in_network(&input->remote_ip, &filter->remote_ip, + filter->remote_bits)) + found_rip = TRUE; + if (input->local_name != NULL && filter->local_name != NULL && + dns_match_wildcard(input->local_name, filter->local_name)) + found_local_name = TRUE; + filter = filter->next; + }; + + *new_input = *input; + + if (!found_lip) + i_zero(&new_input->local_ip); + if (!found_rip) + i_zero(&new_input->remote_ip); + if (!found_local_name) + new_input->local_name = NULL; +} + + void master_service_settings_cache_deinit(struct master_service_settings_cache **_cache) { struct master_service_settings_cache *cache = *_cache; @@ -273,6 +357,12 @@ int master_service_settings_cache_read(struct master_service_settings_cache *cac return 0; new_input = *input; + if (cache->filters != NULL) { + master_service_settings_cache_fix_input(cache, input, &new_input); + if (cache_find(cache, &new_input, parser_r)) + return 0; + } + if (dyn_parsers != NULL) { settings_parser_dyn_update(cache->pool, &new_input.roots, dyn_parsers); diff --git a/src/lib-master/master-service-settings-cache.h b/src/lib-master/master-service-settings-cache.h index de94042..157132e 100644 --- a/src/lib-master/master-service-settings-cache.h +++ b/src/lib-master/master-service-settings-cache.h @@ -6,7 +6,7 @@ master_service_settings_cache_init(struct master_service *service, const char *module, const char *service_name); void master_service_settings_cache_deinit(struct master_service_settings_cache **cache); - +int master_service_settings_cache_init_filter(struct master_service_settings_cache *cache); int master_service_settings_cache_read(struct master_service_settings_cache *cache, const struct master_service_settings_input *input, const struct dynamic_settings_parser *dyn_parsers, diff --git a/src/lib-master/master-service-settings.c b/src/lib-master/master-service-settings.c index 92d22e1..59d2165 100644 --- a/src/lib-master/master-service-settings.c +++ b/src/lib-master/master-service-settings.c @@ -304,6 +304,18 @@ config_send_request(struct master_service *service, } static int +config_send_filters_request(int fd, const char *path, const char **error_r) +{ + int ret; + ret = write_full(fd, CONFIG_HANDSHAKE"FILTERS\n", strlen(CONFIG_HANDSHAKE"FILTERS\n")); + if (ret < 0) { + *error_r = t_strdup_printf("write_full(%s) failed: %m", path); + return -1; + } + return 0; +} + +static int master_service_apply_config_overrides(struct master_service *service, struct setting_parser_context *parser, const char **error_r) @@ -399,6 +411,54 @@ void master_service_config_socket_try_open(struct master_service *service) service->config_fd = fd; } +int master_service_settings_get_filters(struct master_service *service, + const char *const **filters, + const char **error_r) +{ + struct master_service_settings_input input; + int fd; + bool retry = TRUE; + const char *path = NULL; + ARRAY_TYPE(const_string) filters_tmp; + t_array_init(&filters_tmp, 8); + i_zero(&input); + + if (getenv("DOVECONF_ENV") == NULL && + (service->flags & MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0) { + retry = service->config_fd != -1; + for (;;) { + fd = master_service_open_config(service, &input, &path, error_r); + if (fd == -1) { + return -1; + } + if (config_send_filters_request(fd, path, error_r) == 0) + break; + + i_close_fd(&fd); + if (!retry) + return -1; + retry = FALSE; + } + service->config_fd = fd; + struct istream *is = i_stream_create_fd(fd, (size_t)-1, FALSE); + const char *line; + /* try read response */ + while((line = i_stream_read_next_line(is)) != NULL) { + if (*line == '\0') + break; + if (strncmp(line, "FILTER\t", 7) == 0) { + line = t_strdup(line+7); + array_append(&filters_tmp, &line, 1); + } + } + i_stream_unref(&is); + } + + array_append_zero(&filters_tmp); + *filters = array_idx(&filters_tmp, 0); + return 0; +} + int master_service_settings_read(struct master_service *service, const struct master_service_settings_input *input, struct master_service_settings_output *output_r, diff --git a/src/lib-master/master-service-settings.h b/src/lib-master/master-service-settings.h index 43e4541..39ae8b4 100644 --- a/src/lib-master/master-service-settings.h +++ b/src/lib-master/master-service-settings.h @@ -67,6 +67,9 @@ extern const struct setting_parser_info master_service_setting_parser_info; /* Try to open the config socket if it's going to be needed later by master_service_settings_read*() */ void master_service_config_socket_try_open(struct master_service *service); +int master_service_settings_get_filters(struct master_service *service, + const char *const **filters, + const char **error_r); int master_service_settings_read(struct master_service *service, const struct master_service_settings_input *input, struct master_service_settings_output *output_r, diff --git a/src/lib-master/test-master-service-settings-cache.c b/src/lib-master/test-master-service-settings-cache.c index 506fe2b..fdc390d 100644 --- a/src/lib-master/test-master-service-settings-cache.c +++ b/src/lib-master/test-master-service-settings-cache.c @@ -53,6 +53,14 @@ int master_service_settings_read(struct master_service *service ATTR_UNUSED, return 0; } +int master_service_settings_get_filters(struct master_service *service ATTR_UNUSED, + const char *const **filters ATTR_UNUSED, + const char **error_r ATTR_UNUSED) +{ + return -1; +} + + const struct master_service_settings * master_service_settings_get(struct master_service *service ATTR_UNUSED) { -- 2.1.4 --- a/src/Makefile.in 2017-06-26 13:32:21.000000000 +0200 +++ b/src/Makefile.in 2018-08-21 13:33:56.840985600 +0200 @@ -154,8 +154,8 @@ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = lib-test lib lib-settings lib-auth lib-master \ - lib-charset lib-ssl-iostream lib-dcrypt lib-dns lib-dict \ +DIST_SUBDIRS = lib-test lib lib-settings lib-auth lib-dns lib-master \ + lib-charset lib-ssl-iostream lib-dcrypt lib-dict \ lib-sasl lib-stats lib-http lib-fs lib-mail lib-smtp lib-imap \ lib-imap-storage lib-program-client lib-oauth2 lib-dict-extra \ lib-dovecot lib-ldap lib-fts lib-imap-client lib-imap-urlauth \ @@ -389,11 +389,11 @@ lib \ lib-settings \ lib-auth \ + lib-dns \ lib-master \ lib-charset \ lib-ssl-iostream \ lib-dcrypt \ - lib-dns \ lib-dict \ lib-sasl \ lib-stats \ --- a/src/lib-master/Makefile.in 2017-06-26 13:32:22.000000000 +0200 +++ b/src/lib-master/Makefile.in 2018-08-21 13:29:11.173340936 +0200 @@ -414,6 +414,7 @@ noinst_LTLIBRARIES = libmaster.la AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-dns \ -I$(top_srcdir)/src/lib-test \ -I$(top_srcdir)/src/lib-settings \ -I$(top_srcdir)/src/lib-ssl-iostream \ @@ -465,6 +466,7 @@ test_libs = \ ../lib-test/libtest.la \ + ../lib-dns/libdns.la \ ../lib/liblib.la test_deps = $(noinst_LTLIBRARIES) $(test_libs)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor