[patch] Support redis AUTH

Dave dovecot-e51 at deemzed.uk
Thu Jun 30 10:45:51 UTC 2016


	A very minor patch to support redis AUTH (for all that's worth) using 
an extra password= field. I'm not sure if this will be of any value to 
anyone here. We're testing it in development and "it works for us" but 
it's yet to be used in anger.

	Sorry if I'm going about this the wrong way, I tried emailing this 
directly but heard nothing back; so I'm reposting to the list as I'm 
honestly not sure what established protocol is regarding code contribution.

-- 
Dave
-------------- next part --------------
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 / $<size> 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);


More information about the dovecot mailing list