|
@@ -21,9 +21,11 @@
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
#include "../../dprint.h"
|
|
#include "../../dprint.h"
|
|
|
|
+#include "../../locking.h"
|
|
#include "../../mod_fix.h"
|
|
#include "../../mod_fix.h"
|
|
#include "../../sr_module.h"
|
|
#include "../../sr_module.h"
|
|
#include "../../str.h"
|
|
#include "../../str.h"
|
|
|
|
+#include "../../lib/kmi/mi.h"
|
|
#include "../../modules/auth/api.h"
|
|
#include "../../modules/auth/api.h"
|
|
|
|
|
|
#include "autheph_mod.h"
|
|
#include "autheph_mod.h"
|
|
@@ -37,6 +39,10 @@ static void destroy(void);
|
|
|
|
|
|
static int secret_param(modparam_t _type, void *_val);
|
|
static int secret_param(modparam_t _type, void *_val);
|
|
struct secret *secret_list = NULL;
|
|
struct secret *secret_list = NULL;
|
|
|
|
+static struct mi_root *mi_dump_secrets(struct mi_root *cmd, void *param);
|
|
|
|
+static struct mi_root *mi_add_secret(struct mi_root *cmd, void *param);
|
|
|
|
+static struct mi_root *mi_rm_secret(struct mi_root *cmd, void *param);
|
|
|
|
+gen_lock_t *autheph_secret_lock = NULL;
|
|
|
|
|
|
autheph_username_format_t autheph_username_format = AUTHEPH_USERNAME_IETF;
|
|
autheph_username_format_t autheph_username_format = AUTHEPH_USERNAME_IETF;
|
|
|
|
|
|
@@ -86,6 +92,15 @@ static param_export_t params[]=
|
|
{0, 0, 0}
|
|
{0, 0, 0}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static mi_export_t mi_cmds[] =
|
|
|
|
+{
|
|
|
|
+ { "autheph.add_secret", mi_add_secret, 0, 0, 0 },
|
|
|
|
+ { "autheph.dump_secrets", mi_dump_secrets,0, 0, 0 },
|
|
|
|
+ { "autheph.rm_secret", mi_rm_secret, 0, 0, 0 },
|
|
|
|
+
|
|
|
|
+ { 0, 0, 0, 0, 0 }
|
|
|
|
+};
|
|
|
|
+
|
|
struct module_exports exports=
|
|
struct module_exports exports=
|
|
{
|
|
{
|
|
"auth_ephemeral",
|
|
"auth_ephemeral",
|
|
@@ -93,7 +108,7 @@ struct module_exports exports=
|
|
cmds, /* Exported functions */
|
|
cmds, /* Exported functions */
|
|
params, /* Exported parameters */
|
|
params, /* Exported parameters */
|
|
0, /* exported statistics */
|
|
0, /* exported statistics */
|
|
- 0, /* exported MI functions */
|
|
|
|
|
|
+ mi_cmds, /* exported MI functions */
|
|
0, /* exported pseudo-variables */
|
|
0, /* exported pseudo-variables */
|
|
0, /* extra processes */
|
|
0, /* extra processes */
|
|
mod_init, /* module initialization function */
|
|
mod_init, /* module initialization function */
|
|
@@ -106,6 +121,12 @@ static int mod_init(void)
|
|
{
|
|
{
|
|
bind_auth_s_t bind_auth;
|
|
bind_auth_s_t bind_auth;
|
|
|
|
|
|
|
|
+ if (register_mi_mod(exports.name, mi_cmds) != 0)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("registering MI commands\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (secret_list == NULL)
|
|
if (secret_list == NULL)
|
|
{
|
|
{
|
|
LM_ERR("secret modparam not set\n");
|
|
LM_ERR("secret modparam not set\n");
|
|
@@ -153,16 +174,28 @@ static void destroy(void)
|
|
{
|
|
{
|
|
struct secret *secret_struct;
|
|
struct secret *secret_struct;
|
|
|
|
|
|
- while (secret_list != NULL)
|
|
|
|
|
|
+ if (secret_list != NULL)
|
|
{
|
|
{
|
|
- secret_struct = secret_list;
|
|
|
|
- secret_list = secret_struct->next;
|
|
|
|
-
|
|
|
|
- if (secret_struct->secret_key.s != NULL)
|
|
|
|
|
|
+ SECRET_UNLOCK;
|
|
|
|
+ SECRET_LOCK;
|
|
|
|
+ while (secret_list != NULL)
|
|
{
|
|
{
|
|
- shm_free(secret_struct->secret_key.s);
|
|
|
|
|
|
+ secret_struct = secret_list;
|
|
|
|
+ secret_list = secret_struct->next;
|
|
|
|
+
|
|
|
|
+ if (secret_struct->secret_key.s != NULL)
|
|
|
|
+ {
|
|
|
|
+ shm_free(secret_struct->secret_key.s);
|
|
|
|
+ }
|
|
|
|
+ shm_free(secret_struct);
|
|
}
|
|
}
|
|
- shm_free(secret_struct);
|
|
|
|
|
|
+ SECRET_UNLOCK;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (autheph_secret_lock != NULL)
|
|
|
|
+ {
|
|
|
|
+ lock_destroy(autheph_secret_lock);
|
|
|
|
+ lock_dealloc((void *) autheph_secret_lock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -170,6 +203,21 @@ static inline int add_secret(str _secret_key)
|
|
{
|
|
{
|
|
struct secret *secret_struct;
|
|
struct secret *secret_struct;
|
|
|
|
|
|
|
|
+ if (autheph_secret_lock == NULL)
|
|
|
|
+ {
|
|
|
|
+ autheph_secret_lock = lock_alloc();
|
|
|
|
+ if (autheph_secret_lock == NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("allocating lock\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (lock_init(autheph_secret_lock) == 0)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("initialising lock\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
secret_struct = (struct secret *) shm_malloc(sizeof(struct secret));
|
|
secret_struct = (struct secret *) shm_malloc(sizeof(struct secret));
|
|
if (secret_struct == NULL)
|
|
if (secret_struct == NULL)
|
|
{
|
|
{
|
|
@@ -178,13 +226,64 @@ static inline int add_secret(str _secret_key)
|
|
}
|
|
}
|
|
|
|
|
|
memset(secret_struct, 0, sizeof (struct secret));
|
|
memset(secret_struct, 0, sizeof (struct secret));
|
|
|
|
+ secret_struct->secret_key = _secret_key;
|
|
|
|
+ SECRET_LOCK;
|
|
|
|
+ if (secret_list != NULL)
|
|
|
|
+ {
|
|
|
|
+ secret_list->prev = secret_struct;
|
|
|
|
+ }
|
|
secret_struct->next = secret_list;
|
|
secret_struct->next = secret_list;
|
|
secret_list = secret_struct;
|
|
secret_list = secret_struct;
|
|
- secret_struct->secret_key = _secret_key;
|
|
|
|
|
|
+ SECRET_UNLOCK;
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline int rm_secret(int _id)
|
|
|
|
+{
|
|
|
|
+ int pos = 0;
|
|
|
|
+ struct secret *secret_struct;
|
|
|
|
+
|
|
|
|
+ if (secret_list == NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("secret list empty\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ SECRET_LOCK;
|
|
|
|
+ secret_struct = secret_list;
|
|
|
|
+ while (pos <= _id && secret_struct != NULL)
|
|
|
|
+ {
|
|
|
|
+ if (pos == _id)
|
|
|
|
+ {
|
|
|
|
+ if (secret_struct->prev != NULL)
|
|
|
|
+ {
|
|
|
|
+ secret_struct->prev->next = secret_struct->next;
|
|
|
|
+ }
|
|
|
|
+ if (secret_struct->next != NULL)
|
|
|
|
+ {
|
|
|
|
+ secret_struct->next->prev = secret_struct->prev;
|
|
|
|
+ }
|
|
|
|
+ if (pos == 0)
|
|
|
|
+ {
|
|
|
|
+ secret_list = secret_struct->next;
|
|
|
|
+ }
|
|
|
|
+ SECRET_UNLOCK;
|
|
|
|
+ shm_free(secret_struct->secret_key.s);
|
|
|
|
+ shm_free(secret_struct);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pos++;
|
|
|
|
+ secret_struct = secret_struct->next;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ SECRET_UNLOCK;
|
|
|
|
+
|
|
|
|
+ LM_ERR("ID %d not found\n", _id);
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
static int secret_param(modparam_t _type, void *_val)
|
|
static int secret_param(modparam_t _type, void *_val)
|
|
{
|
|
{
|
|
str sval;
|
|
str sval;
|
|
@@ -208,3 +307,143 @@ static int secret_param(modparam_t _type, void *_val)
|
|
|
|
|
|
return add_secret(sval);
|
|
return add_secret(sval);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+static str str_status_too_many_params = str_init("Too many parameters");
|
|
|
|
+static str str_status_empty_param = str_init("Not enough parameters");
|
|
|
|
+static str str_status_no_memory = str_init("Unable to allocate shared memory");
|
|
|
|
+static str str_status_string_error = str_init("Error converting string to int");
|
|
|
|
+static str str_status_adding_secret = str_init("Error adding secret");
|
|
|
|
+static str str_status_removing_secret = str_init("Error removing secret");
|
|
|
|
+
|
|
|
|
+static struct mi_root *mi_dump_secrets(struct mi_root *cmd, void *param)
|
|
|
|
+{
|
|
|
|
+ int pos = 0;
|
|
|
|
+ struct secret *secret_struct = secret_list;
|
|
|
|
+ struct mi_root *rpl_tree;
|
|
|
|
+
|
|
|
|
+ if (cmd->node.kids != NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_WARN("too many parameters\n");
|
|
|
|
+ return init_mi_tree(400, str_status_too_many_params.s,
|
|
|
|
+ str_status_too_many_params.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
|
|
|
|
+ if (rpl_tree == NULL)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ SECRET_LOCK;
|
|
|
|
+ while (secret_struct != NULL)
|
|
|
|
+ {
|
|
|
|
+ if (addf_mi_node_child(&rpl_tree->node, 0, 0, 0,
|
|
|
|
+ "ID %d: %.*s", pos++,
|
|
|
|
+ secret_struct->secret_key.len,
|
|
|
|
+ secret_struct->secret_key.s) == 0)
|
|
|
|
+ {
|
|
|
|
+ free_mi_tree(rpl_tree);
|
|
|
|
+ SECRET_UNLOCK;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ secret_struct = secret_struct->next;
|
|
|
|
+ }
|
|
|
|
+ SECRET_UNLOCK;
|
|
|
|
+
|
|
|
|
+ return rpl_tree;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static struct mi_root *mi_add_secret(struct mi_root *cmd, void *param)
|
|
|
|
+{
|
|
|
|
+ str sval;
|
|
|
|
+ struct mi_node *node = NULL;
|
|
|
|
+
|
|
|
|
+ node = cmd->node.kids;
|
|
|
|
+ if (node == NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_WARN("no secret parameter\n");
|
|
|
|
+ return init_mi_tree(400, str_status_empty_param.s,
|
|
|
|
+ str_status_empty_param.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (node->value.s == NULL || node->value.len == 0)
|
|
|
|
+ {
|
|
|
|
+ LM_WARN("empty secret parameter\n");
|
|
|
|
+ return init_mi_tree(400, str_status_empty_param.s,
|
|
|
|
+ str_status_empty_param.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (node->next != NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_WARN("too many parameters\n");
|
|
|
|
+ return init_mi_tree(400, str_status_too_many_params.s,
|
|
|
|
+ str_status_too_many_params.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sval.len = node->value.len;
|
|
|
|
+ sval.s = shm_malloc(sizeof(char) * sval.len);
|
|
|
|
+ if (sval.s == NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("Unable to allocate shared memory\n");
|
|
|
|
+ return init_mi_tree(400, str_status_no_memory.s,
|
|
|
|
+ str_status_no_memory.len);
|
|
|
|
+ }
|
|
|
|
+ memcpy(sval.s, node->value.s, sval.len);
|
|
|
|
+
|
|
|
|
+ if (add_secret(sval) == 0)
|
|
|
|
+ {
|
|
|
|
+ return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("Adding secret\n");
|
|
|
|
+ return init_mi_tree(400, str_status_adding_secret.s,
|
|
|
|
+ str_status_adding_secret.len);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static struct mi_root *mi_rm_secret(struct mi_root *cmd, void *param)
|
|
|
|
+{
|
|
|
|
+ unsigned int id;
|
|
|
|
+ struct mi_node *node = NULL;
|
|
|
|
+
|
|
|
|
+ node = cmd->node.kids;
|
|
|
|
+ if (node == NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_WARN("no id parameter\n");
|
|
|
|
+ return init_mi_tree(400, str_status_empty_param.s,
|
|
|
|
+ str_status_empty_param.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (node->value.s == NULL || node->value.len == 0)
|
|
|
|
+ {
|
|
|
|
+ LM_WARN("empty id parameter\n");
|
|
|
|
+ return init_mi_tree(400, str_status_empty_param.s,
|
|
|
|
+ str_status_empty_param.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (str2int(&node->value, &id) < 0)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("converting string to int\n");
|
|
|
|
+ return init_mi_tree(400, str_status_string_error.s,
|
|
|
|
+ str_status_string_error.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (node->next != NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_WARN("too many parameters\n");
|
|
|
|
+ return init_mi_tree(400, str_status_too_many_params.s,
|
|
|
|
+ str_status_too_many_params.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (rm_secret(id) == 0)
|
|
|
|
+ {
|
|
|
|
+ return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("Removing secret\n");
|
|
|
|
+ return init_mi_tree(400, str_status_removing_secret.s,
|
|
|
|
+ str_status_removing_secret.len);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
|
|
|
|
+}
|