dovecot-2.2: auth: Fixed auth cache key generation to support %{...
dovecot at dovecot.org
dovecot at dovecot.org
Sun May 20 03:26:27 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/a090cbbe3008
changeset: 14340:a090cbbe3008
user: Timo Sirainen <tss at iki.fi>
date: Wed Mar 14 14:55:25 2012 +0200
description:
auth: Fixed auth cache key generation to support %{long} variables
diffstat:
src/auth/Makefile.am | 20 +++++++++++++
src/auth/auth-cache.c | 70 ++++++++++++++++++++++++++++++++++++++-------
src/auth/auth-request.c | 48 ++++++++++++++++---------------
src/auth/auth-request.h | 2 +
src/auth/test-auth-cache.c | 57 +++++++++++++++++++++++++++++++++++++
5 files changed, 162 insertions(+), 35 deletions(-)
diffs (272 lines):
diff -r 13d4c4f91622 -r a090cbbe3008 src/auth/Makefile.am
--- a/src/auth/Makefile.am Wed Mar 14 13:42:08 2012 +0200
+++ b/src/auth/Makefile.am Wed Mar 14 14:55:25 2012 +0200
@@ -24,6 +24,7 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib-auth \
+ -I$(top_srcdir)/src/lib-test \
-I$(top_srcdir)/src/lib-dns \
-I$(top_srcdir)/src/lib-sql \
-I$(top_srcdir)/src/lib-settings \
@@ -182,3 +183,22 @@
checkpassword_reply_sources = \
checkpassword-reply.c
+
+test_programs = \
+ test-auth-cache
+
+noinst_PROGRAMS = $(test_programs)
+
+test_libs = \
+ ../lib-test/libtest.la \
+ ../lib/liblib.la
+
+test_auth_cache_SOURCES = test-auth-cache.c
+test_auth_cache_LDADD = auth-cache.o $(test_libs)
+test_auth_cache_DEPENDENCIES = auth-cache.o $(test_libs)
+
+check: check-am check-test
+check-test: all-am
+ for bin in $(test_programs); do \
+ if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \
+ done
diff -r 13d4c4f91622 -r a090cbbe3008 src/auth/auth-cache.c
--- a/src/auth/auth-cache.c Wed Mar 14 13:42:08 2012 +0200
+++ b/src/auth/auth-cache.c Wed Mar 14 14:55:25 2012 +0200
@@ -23,29 +23,75 @@
unsigned long long pos_size, neg_size;
};
+static const struct var_expand_table *
+auth_request_var_expand_tab_find(const char *key, unsigned int size)
+{
+ const struct var_expand_table *tab = auth_request_var_expand_static_tab;
+ unsigned int i;
+
+ for (i = 0; tab[i].key != '\0' || tab[i].long_key != NULL; i++) {
+ if (size == 1) {
+ if (key[0] == tab[i].key)
+ return &tab[i];
+ } else if (tab[i].long_key != NULL) {
+ if (strncmp(key, tab[i].long_key, size) == 0 &&
+ tab[i].long_key[size] == '\0')
+ return &tab[i];
+ }
+ }
+ return NULL;
+}
+
char *auth_cache_parse_key(pool_t pool, const char *query)
{
+ const struct var_expand_table *tab;
string_t *str;
- char key_seen[256];
- uint8_t key;
+ bool key_seen[100];
+ unsigned int idx, size, tab_idx;
+ bool add_key;
memset(key_seen, 0, sizeof(key_seen));
str = str_new(pool, 32);
- for (; *query != '\0'; query++) {
- if (*query == '%' && query[1] != '\0') {
+ for (; *query != '\0'; ) {
+ if (*query != '%') {
query++;
- key = var_get_key(query);
- if (key != '\0' && key != '%' && !key_seen[key]) {
- if (str_len(str) != 0)
- str_append_c(str, '\t');
- str_append_c(str, '%');
- str_append_c(str, key);
+ continue;
+ }
- /* @UNSAFE */
- key_seen[key] = 1;
+ var_get_key_range(++query, &idx, &size);
+ if (size == 0) {
+ /* broken %variable ending too early */
+ break;
+ }
+ query += idx;
+
+ tab = auth_request_var_expand_tab_find(query, size);
+ if (tab == NULL) {
+ /* just add the key. it would be nice to prevent
+ duplicates here as well, but that's just too
+ much trouble and probably very rare. */
+ add_key = TRUE;
+ } else {
+ tab_idx = tab - auth_request_var_expand_static_tab;
+ i_assert(tab_idx < N_ELEMENTS(key_seen));
+ /* @UNSAFE */
+ add_key = !key_seen[tab_idx];
+ key_seen[tab_idx] = TRUE;
+ }
+ if (add_key) {
+ if (str_len(str) != 0)
+ str_append_c(str, '\t');
+ str_append_c(str, '%');
+ if (size == 1)
+ str_append_c(str, query[0]);
+ else {
+ str_append_c(str, '{');
+ str_append_n(str, query, size);
+ str_append_c(str, '}');
}
}
+ query += size;
}
return str_free_without_data(&str);
}
diff -r 13d4c4f91622 -r a090cbbe3008 src/auth/auth-request.c
--- a/src/auth/auth-request.c Wed Mar 14 13:42:08 2012 +0200
+++ b/src/auth/auth-request.c Wed Mar 14 14:55:25 2012 +0200
@@ -1741,38 +1741,40 @@
return str_escape(string);
}
+const struct var_expand_table auth_request_var_expand_static_tab[] = {
+ { 'u', NULL, "user" },
+ { 'n', NULL, "username" },
+ { 'd', NULL, "domain" },
+ { 's', NULL, "service" },
+ { 'h', NULL, "home" },
+ { 'l', NULL, "lip" },
+ { 'r', NULL, "rip" },
+ { 'p', NULL, "pid" },
+ { 'w', NULL, "password" },
+ { '!', NULL, NULL },
+ { 'm', NULL, "mech" },
+ { 'c', NULL, "secured" },
+ { 'a', NULL, "lport" },
+ { 'b', NULL, "rport" },
+ { 'k', NULL, "cert" },
+ { '\0', NULL, "login_user" },
+ { '\0', NULL, "login_username" },
+ { '\0', NULL, "login_domain" },
+ { '\0', NULL, NULL }
+};
+
const struct var_expand_table *
auth_request_get_var_expand_table(const struct auth_request *auth_request,
auth_request_escape_func_t *escape_func)
{
- static struct var_expand_table static_tab[] = {
- { 'u', NULL, "user" },
- { 'n', NULL, "username" },
- { 'd', NULL, "domain" },
- { 's', NULL, "service" },
- { 'h', NULL, "home" },
- { 'l', NULL, "lip" },
- { 'r', NULL, "rip" },
- { 'p', NULL, "pid" },
- { 'w', NULL, "password" },
- { '!', NULL, NULL },
- { 'm', NULL, "mech" },
- { 'c', NULL, "secured" },
- { 'a', NULL, "lport" },
- { 'b', NULL, "rport" },
- { 'k', NULL, "cert" },
- { '\0', NULL, "login_user" },
- { '\0', NULL, "login_username" },
- { '\0', NULL, "login_domain" },
- { '\0', NULL, NULL }
- };
struct var_expand_table *tab;
if (escape_func == NULL)
escape_func = escape_none;
- tab = t_malloc(sizeof(static_tab));
- memcpy(tab, static_tab, sizeof(static_tab));
+ tab = t_malloc(sizeof(auth_request_var_expand_static_tab));
+ memcpy(tab, auth_request_var_expand_static_tab,
+ sizeof(auth_request_var_expand_static_tab));
tab[0].value = escape_func(auth_request->user, auth_request);
tab[1].value = escape_func(t_strcut(auth_request->user, '@'),
diff -r 13d4c4f91622 -r a090cbbe3008 src/auth/auth-request.h
--- a/src/auth/auth-request.h Wed Mar 14 13:42:08 2012 +0200
+++ b/src/auth/auth-request.h Wed Mar 14 14:55:25 2012 +0200
@@ -2,6 +2,7 @@
#define AUTH_REQUEST_H
#include "network.h"
+#include "var-expand.h"
#include "mech.h"
#include "userdb.h"
#include "passdb.h"
@@ -122,6 +123,7 @@
typedef void auth_request_proxy_cb_t(bool success, struct auth_request *);
extern unsigned int auth_request_state_count[AUTH_REQUEST_STATE_MAX];
+extern const struct var_expand_table auth_request_var_expand_static_tab[];
struct auth_request *
auth_request_new(const struct mech_module *mech);
diff -r 13d4c4f91622 -r a090cbbe3008 src/auth/test-auth-cache.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/auth/test-auth-cache.c Wed Mar 14 14:55:25 2012 +0200
@@ -0,0 +1,57 @@
+/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "auth-request.h"
+#include "auth-cache.h"
+#include "test-common.h"
+
+const struct var_expand_table auth_request_var_expand_static_tab[] = {
+ { 'a', NULL, NULL },
+ { '\0', NULL, "longb" },
+ { 'c', NULL, "longc" },
+ { '\0', NULL, NULL }
+};
+
+const struct var_expand_table *
+auth_request_get_var_expand_table(const struct auth_request *auth_request ATTR_UNUSED,
+ auth_request_escape_func_t *escape_func ATTR_UNUSED)
+{
+ return auth_request_var_expand_static_tab;
+}
+
+static void test_auth_cache_parse_key(void)
+{
+ struct {
+ const char *in, *out;
+ } tests[] = {
+ { "foo%5.5Mabar", "%a" },
+ { "foo%5.5M{longb}bar", "%{longb}" },
+ { "foo%5.5Mcbar", "%c" },
+ { "foo%5.5M{longc}bar", "%{longc}" },
+ { "%a%b", "%a\t%b" },
+ { "%a%{longb}%a", "%a\t%{longb}" },
+ { "%{longc}%c", "%{longc}" },
+ { "%c%a%{longc}%c", "%c\t%a" },
+ { "%a%{env:foo}%{env:foo}%a", "%a\t%{env:foo}\t%{env:foo}" }
+ };
+ const char *cache_key;
+ unsigned int i;
+
+ test_begin("auth cache parse key");
+
+ for (i = 0; i < N_ELEMENTS(tests); i++) {
+ cache_key = auth_cache_parse_key(pool_datastack_create(),
+ tests[i].in);
+ test_assert(strcmp(cache_key, tests[i].out) == 0);
+ }
+ test_end();
+}
+
+int main(void)
+{
+ static void (*test_functions[])(void) = {
+ test_auth_cache_parse_key,
+ NULL
+ };
+ return test_run(test_functions);
+}
More information about the dovecot-cvs
mailing list