diff -aurN dovecot-2.2.24.orig/src/lib-dict/dict-redis.c dovecot-2.2.24/src/lib-dict/dict-redis.c --- dovecot-2.2.24.orig/src/lib-dict/dict-redis.c 2016-04-26 14:01:20.000000000 +0100 +++ dovecot-2.2.24/src/lib-dict/dict-redis.c 2016-06-22 17:18:45.082453708 +0100 @@ -13,6 +13,8 @@ #define DICT_USERNAME_SEPARATOR '/' enum redis_input_state { + /* expecting +OK reply for AUTH */ + REDIS_INPUT_STATE_AUTH, /* expecting +OK reply for SELECT */ REDIS_INPUT_STATE_SELECT, /* expecting $-1 / $ followed by GET reply */ @@ -45,7 +47,7 @@ struct redis_dict { struct dict dict; - char *username, *key_prefix, *expire_value; + char *username, *password, *key_prefix, *expire_value; unsigned int timeout_msecs, db_id; struct ioloop *ioloop, *prev_ioloop; @@ -219,6 +221,7 @@ switch (state) { case REDIS_INPUT_STATE_GET: i_unreached(); + case REDIS_INPUT_STATE_AUTH: case REDIS_INPUT_STATE_SELECT: case REDIS_INPUT_STATE_MULTI: case REDIS_INPUT_STATE_DISCARD: @@ -348,6 +351,7 @@ i_unreached(); dict->timeout_msecs = REDIS_DEFAULT_LOOKUP_TIMEOUT_MSECS; dict->key_prefix = i_strdup(""); + dict->password = i_strdup(""); args = t_strsplit(uri, ":"); for (; *args != NULL; args++) { @@ -390,6 +394,9 @@ "Invalid timeout_msecs: %s", *args+14); ret = -1; } + } else if (strncmp(*args, "password=", 9) == 0) { + i_free(dict->password); + dict->password = i_strdup(*args + 9); } else { *error_r = t_strdup_printf("Unknown parameter: %s", *args); @@ -397,6 +404,7 @@ } } if (ret < 0) { + i_free(dict->password); i_free(dict->key_prefix); i_free(dict); return -1; @@ -439,6 +447,7 @@ array_free(&dict->input_states); i_free(dict->expire_value); i_free(dict->key_prefix); + i_free(dict->password); i_free(dict->username); i_free(dict); @@ -470,6 +479,19 @@ return key; } +static void redis_dict_auth(struct redis_dict *dict) +{ + const char *cmd; + + if (*dict->password == '\0') + return; + + cmd = t_strdup_printf("*2\r\n$4\r\nAUTH\r\n$%d\r\n%s\r\n", + (int)strlen(dict->password), dict->password); + o_stream_nsend_str(dict->conn.conn.output, cmd); + redis_input_state_add(dict, REDIS_INPUT_STATE_AUTH); +} + static void redis_dict_select_db(struct redis_dict *dict) { const char *cmd, *db_str; @@ -515,6 +537,8 @@ if (!dict->connected) { /* wait for connection */ io_loop_run(dict->ioloop); + if (dict->connected) + redis_dict_auth(dict); } if (dict->connected) { @@ -586,6 +610,8 @@ } else if (!dict->connected) { /* wait for connection */ redis_wait(dict); + if (dict->connected) + redis_dict_auth(dict); } if (dict->connected) redis_dict_select_db(dict);