]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dict-redis: Added support for authentication.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 24 Jun 2016 09:09:31 +0000 (12:09 +0300)
committerAki Tuomi <aki.tuomi@dovecot.fi>
Thu, 2 Nov 2017 10:31:12 +0000 (12:31 +0200)
Patch by David Zambonini

src/lib-dict/dict-redis.c

index 322666441ac9646a6fce0a1d2a69fddbc9dded4e..e437d5f4ae34b637870da0be5358b64101ef00fd 100644 (file)
@@ -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 / $<size> followed by GET reply */
@@ -45,7 +47,7 @@ struct redis_dict_reply {
 
 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;
@@ -233,6 +235,7 @@ redis_conn_input_more(struct redis_connection *conn, const char **error_r)
        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:
@@ -367,6 +370,7 @@ redis_dict_init(struct dict *driver, const char *uri,
                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++) {
@@ -409,6 +413,9 @@ redis_dict_init(struct dict *driver, const char *uri,
                                        "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);
@@ -416,6 +423,7 @@ redis_dict_init(struct dict *driver, const char *uri,
                }
        }
        if (ret < 0) {
+               i_free(dict->password);
                i_free(dict->key_prefix);
                i_free(dict);
                return -1;
@@ -458,6 +466,7 @@ static void redis_dict_deinit(struct dict *_dict)
        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);
 
@@ -490,6 +499,19 @@ redis_dict_get_full_key(struct redis_dict *dict, const char *key)
        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;
@@ -535,6 +557,8 @@ static int redis_dict_lookup(struct dict *_dict, pool_t pool, const char *key,
                if (!dict->connected) {
                        /* wait for connection */
                        io_loop_run(dict->ioloop);
+                       if (dict->connected)
+                               redis_dict_auth(dict);
                }
 
                if (dict->connected) {
@@ -591,6 +615,8 @@ redis_transaction_init(struct dict *_dict)
        } 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);