Pārlūkot izejas kodu

auth_ephemeral: fix authentication with secrets added at runtime (#3390)

* auth_ephemeral: fix authentication with secrets added at runtime

- proper way to work with shm pointer to secret list

* fix: free secret_struct shm

Free shm secret_struct in case the allocation error of secret_list pointer.
Dennis 2 gadi atpakaļ
vecāks
revīzija
6fa5a8fa8d

+ 35 - 14
src/modules/auth_ephemeral/auth_ephemeral_mod.c

@@ -46,7 +46,7 @@ static int mod_init(void);
 static void destroy(void);
 
 static int secret_param(modparam_t _type, void *_val);
-struct secret *secret_list = NULL;
+struct secret **secret_list = NULL;
 gen_lock_t *autheph_secret_lock = NULL;
 
 autheph_username_format_t autheph_username_format = AUTHEPH_USERNAME_IETF;
@@ -125,7 +125,7 @@ static int mod_init(void)
 		return -1;
 	}
 
-	if (secret_list == NULL)
+	if (secret_list == NULL || *secret_list == NULL)
 	{
 		LM_ERR("secret modparam not set\n");
 		return -1;
@@ -172,14 +172,14 @@ static void destroy(void)
 {
 	struct secret *secret_struct;
 
-	if (secret_list != NULL)
+	if (secret_list != NULL && *secret_list != NULL)
 	{
 		SECRET_UNLOCK;
 		SECRET_LOCK;
-		while (secret_list != NULL)
+		while (*secret_list != NULL)
 		{
-			secret_struct = secret_list;
-			secret_list = secret_struct->next;
+			secret_struct = *secret_list;
+			*secret_list = secret_struct->next;
 
 			if (secret_struct->secret_key.s != NULL)
 			{
@@ -190,6 +190,10 @@ static void destroy(void)
 		SECRET_UNLOCK;
 	}
 
+	if (secret_list != NULL) {
+		shm_free(secret_list);
+	}
+
 	if (autheph_secret_lock != NULL)
 	{
 		lock_destroy(autheph_secret_lock);
@@ -226,12 +230,23 @@ static inline int add_secret(str _secret_key)
 	memset(secret_struct, 0, sizeof (struct secret));
 	secret_struct->secret_key = _secret_key;
 	SECRET_LOCK;
-	if (secret_list != NULL)
+	if (secret_list == NULL)
 	{
-		secret_list->prev = secret_struct;
+		secret_list = (struct secret **) shm_malloc(sizeof(struct secret *));
+		if (secret_list == NULL)
+		{
+			LM_ERR("unable to allocate shared memory\n");
+			shm_free(secret_struct);
+			return -1;
+		}
+		*secret_list = NULL;
 	}
-	secret_struct->next = secret_list;
-	secret_list = secret_struct;
+	if (*secret_list != NULL)
+	{
+		(*secret_list)->prev = secret_struct;
+	}
+	secret_struct->next = *secret_list;
+	*secret_list = secret_struct;
 	SECRET_UNLOCK;
 
 	return 0;
@@ -242,14 +257,14 @@ static inline int rm_secret(int _id)
 	int pos = 0;
 	struct secret *secret_struct;
 
-	if (secret_list == NULL)
+	if (secret_list == NULL || *secret_list == NULL)
 	{
 		LM_ERR("secret list empty\n");
 		return -1;
 	}
 
 	SECRET_LOCK;
-	secret_struct = secret_list;
+	secret_struct = *secret_list;
 	while (pos <= _id && secret_struct != NULL)
 	{
 		if (pos == _id)
@@ -264,7 +279,7 @@ static inline int rm_secret(int _id)
 			}
 			if (pos == 0)
 			{
-				secret_list = secret_struct->next;
+				*secret_list = secret_struct->next;
 			}
 			SECRET_UNLOCK;
 			shm_free(secret_struct->secret_key.s);
@@ -309,7 +324,13 @@ static int secret_param(modparam_t _type, void *_val)
 void autheph_rpc_dump_secrets(rpc_t* rpc, void* ctx)
 {
 	int pos = 0;
-	struct secret *secret_struct = secret_list;
+	struct secret *secret_struct;
+	if (secret_list == NULL)
+	{
+		return;
+	}
+
+	secret_struct = *secret_list;
 
 	SECRET_LOCK;
 	while (secret_struct != NULL)

+ 0 - 1
src/modules/auth_ephemeral/auth_ephemeral_mod.h

@@ -39,7 +39,6 @@ struct secret
 	struct secret *prev;
 	struct secret *next;
 };
-extern struct secret *secret_list;
 
 typedef enum {
 	AUTHEPH_USERNAME_NON_IETF	= 0,

+ 14 - 2
src/modules/auth_ephemeral/authorize.c

@@ -40,6 +40,8 @@
 #include "auth_ephemeral_mod.h"
 #include "authorize.h"
 
+extern struct secret **secret_list;
+
 static inline int get_pass(str *_username, str *_secret, str *_password)
 {
 	unsigned int hmac_len = SHA_DIGEST_LENGTH;
@@ -266,8 +268,13 @@ static inline int digest_authenticate(struct sip_msg *_m, str *_realm,
 		}
 	}
 
+	if (secret_list == NULL)
+	{
+		LM_DBG("empty secret list\n");
+		return ret;
+	}
 	SECRET_LOCK;
-	secret_struct = secret_list;
+	secret_struct = *secret_list;
 	while (secret_struct != NULL)
 	{
 		ret = do_auth(_m, h, _realm, _method,
@@ -529,8 +536,13 @@ int ki_autheph_authenticate(sip_msg_t *_m, str *susername, str *spassword)
 	LM_DBG("password: %.*s\n", spassword->len, spassword->s);
 
 	sgenerated_password.s = generated_password;
+	if (secret_list == NULL)
+	{
+		LM_DBG("empty secret list\n");
+		return AUTH_ERROR;
+	}
 	SECRET_LOCK;
-	secret_struct = secret_list;
+	secret_struct = *secret_list;
 	while (secret_struct != NULL)
 	{
 		LM_DBG("trying secret: %.*s (%i)\n",