1
0
Эх сурвалжийг харах

Allow authenticating with a username to redis (#1488)

Add ability to authenticate to redis with a password (and optionally username for redis 6.0)

Tested by building and using with redis on old and new versionss
maddy 11 сар өмнө
parent
commit
c4a954a7fc

+ 22 - 12
src/apps/relay/dbdrivers/dbd_redis.c

@@ -49,6 +49,7 @@ static void turnFreeRedisReply(void *reply) {
 struct _Ryconninfo {
   char *host;
   char *dbname;
+  char *user;
   char *password;
   unsigned int connect_timeout;
   unsigned int port;
@@ -64,6 +65,9 @@ static void RyconninfoFree(Ryconninfo *co) {
     if (co->dbname) {
       free(co->dbname);
     }
+    if (co->user) {
+      free(co->user);
+    }
     if (co->password) {
       free(co->password);
     }
@@ -117,13 +121,13 @@ static Ryconninfo *RyconninfoParse(const char *userdb, char **errmsg) {
       } else if (!strcmp(s, "database")) {
         co->dbname = strdup(seq + 1);
       } else if (!strcmp(s, "user")) {
-        ;
+        co->user = strdup(seq + 1);
       } else if (!strcmp(s, "uname")) {
-        ;
+        co->user = strdup(seq + 1);
       } else if (!strcmp(s, "name")) {
-        ;
+        co->user = strdup(seq + 1);
       } else if (!strcmp(s, "username")) {
-        ;
+        co->user = strdup(seq + 1);
       } else if (!strcmp(s, "password")) {
         co->password = strdup(seq + 1);
       } else if (!strcmp(s, "pwd")) {
@@ -162,9 +166,6 @@ static Ryconninfo *RyconninfoParse(const char *userdb, char **errmsg) {
     if (!(co->host)) {
       co->host = strdup("127.0.0.1");
     }
-    if (!(co->password)) {
-      co->password = strdup("");
-    }
   }
 
   return co;
@@ -224,8 +225,12 @@ redis_context_handle get_redis_async_connection(struct event_base *base, redis_s
         if (!rc) {
           TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB async connection\n");
         } else {
-          if (co->password) {
-            turnFreeRedisReply(redisCommand(rc, "AUTH %s", co->password));
+          if (co->password && strlen(co->password)) {
+            if (co->user && strlen(co->user)) {
+              turnFreeRedisReply(redisCommand(rc, "AUTH %s %s", co->user, co->password));
+            } else {
+              turnFreeRedisReply(redisCommand(rc, "AUTH %s", co->password));
+            }
           }
           if (co->dbname) {
             turnFreeRedisReply(redisCommand(rc, "select %s", co->dbname));
@@ -267,7 +272,7 @@ redis_context_handle get_redis_async_connection(struct event_base *base, redis_s
         }
       }
 
-      ret = redisLibeventAttach(base, co->host, co->port, co->password, atoi(co->dbname));
+      ret = redisLibeventAttach(base, co->host, co->port, co->user, co->password, atoi(co->dbname));
 
       if (!ret) {
         TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n");
@@ -347,8 +352,13 @@ static redisContext *get_redis_connection(void) {
           }
           redisFree(redisconnection);
           redisconnection = NULL;
-        } else if (co->password) {
-          void *reply = redisCommand(redisconnection, "AUTH %s", co->password);
+        } else if (co->password && strlen(co->password)) {
+          void *reply;
+          if (co->user && strlen(co->user)) {
+            reply = redisCommand(redisconnection, "AUTH %s %s", co->user, co->password);
+          } else {
+            reply = redisCommand(redisconnection, "AUTH %s", co->password);
+          }
           if (!reply) {
             if (redisconnection->err && redisconnection->errstr[0]) {
               TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis: %s\n", redisconnection->errstr);

+ 23 - 7
src/apps/relay/hiredis_libevent2.c

@@ -50,6 +50,7 @@ struct redisLibeventEvents {
   int rev_set, wev_set;
   char *ip;
   int port;
+  char *user;
   char *pwd;
   int db;
 };
@@ -212,7 +213,7 @@ void send_message_to_redis(redis_context_handle rch, const char *command, const
 
 ///////////////////////// Attach /////////////////////////////////
 
-redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *pwd, int db) {
+redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *user, char *pwd, int db) {
 
   char ip[256];
   if (ip0 && ip0[0]) {
@@ -246,6 +247,9 @@ redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int
   e->base = base;
   e->ip = strdup(ip);
   e->port = port;
+  if (user) {
+    e->user = strdup(user);
+  }
   if (pwd) {
     e->pwd = strdup(pwd);
   }
@@ -274,9 +278,15 @@ redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int
   e->wev_set = 1;
 
   // Authentication
-  if (redis_le_valid(e) && pwd) {
-    if (redisAsyncCommand(ac, NULL, e, "AUTH %s", pwd) != REDIS_OK) {
-      e->invalid = 1;
+  if (redis_le_valid(e) && pwd && strlen(pwd)) {
+    if (user && strlen(user)) {
+      if (redisAsyncCommand(ac, NULL, e, "AUTH %s %s", e->user, e->pwd) != REDIS_OK) {
+        e->invalid = 1;
+      }
+    } else {
+      if (redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd) != REDIS_OK) {
+        e->invalid = 1;
+      }
     }
   }
 
@@ -349,9 +359,15 @@ static void redis_reconnect(struct redisLibeventEvents *e) {
   e->invalid = 0;
 
   // Authentication
-  if (redis_le_valid(e) && e->pwd) {
-    if (redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd) != REDIS_OK) {
-      e->invalid = 1;
+  if (redis_le_valid(e) && e->pwd && strlen(e->pwd)) {
+    if (e->user && strlen(e->user)) {
+      if (redisAsyncCommand(ac, NULL, e, "AUTH %s %s", e->user, e->pwd) != REDIS_OK) {
+        e->invalid = 1;
+      }
+    } else {
+      if (redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd) != REDIS_OK) {
+        e->invalid = 1;
+      }
     }
   }
 

+ 1 - 1
src/apps/relay/hiredis_libevent2.h

@@ -48,7 +48,7 @@ typedef void *redis_context_handle;
 
 #if !defined(TURN_NO_HIREDIS)
 
-redis_context_handle redisLibeventAttach(struct event_base *base, char *ip, int port, char *pwd, int db);
+redis_context_handle redisLibeventAttach(struct event_base *base, char *ip, int port, char *user, char *pwd, int db);
 
 void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format, ...);
 

+ 1 - 1
src/apps/relay/mainrelay.c

@@ -3034,7 +3034,7 @@ int main(int argc, char **argv) {
     return adminmain(argc, argv);
   }
 
-  memset(&turn_params.default_users_db, 0, sizeof(default_users_db_t));
+  memset(&turn_params.default_users_db.ram_db, 0, sizeof(ram_users_db_t));
   turn_params.default_users_db.ram_db.static_accounts = ur_string_map_create(free);
 
   // Zero pass apply the log options.