|
|
|
@ -1773,11 +1773,11 @@ static void session_destructor(void *obj)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (session->whitefilters) {
|
|
|
|
|
ao2_t_ref(session->whitefilters, -1 , "decrement ref for white container, should be last one");
|
|
|
|
|
ao2_t_ref(session->whitefilters, -1, "decrement ref for white container, should be last one");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (session->blackfilters) {
|
|
|
|
|
ao2_t_ref(session->blackfilters, -1 , "decrement ref for black container, should be last one");
|
|
|
|
|
ao2_t_ref(session->blackfilters, -1, "decrement ref for black container, should be last one");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -6936,12 +6936,8 @@ generic_callback_out:
|
|
|
|
|
if (method == AST_HTTP_POST && params) {
|
|
|
|
|
ast_variables_destroy(params);
|
|
|
|
|
}
|
|
|
|
|
if (http_header) {
|
|
|
|
|
ast_free(http_header);
|
|
|
|
|
}
|
|
|
|
|
if (out) {
|
|
|
|
|
ast_free(out);
|
|
|
|
|
}
|
|
|
|
|
ast_free(http_header);
|
|
|
|
|
ast_free(out);
|
|
|
|
|
|
|
|
|
|
if (session && blastaway) {
|
|
|
|
|
session_destroy(session);
|
|
|
|
@ -7452,7 +7448,6 @@ static struct ast_custom_function managerclient_function = {
|
|
|
|
|
.read_max = 12,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int registered = 0;
|
|
|
|
|
static int webregged = 0;
|
|
|
|
|
|
|
|
|
|
/*! \brief cleanup code called at each iteration of server_root,
|
|
|
|
@ -7797,16 +7792,14 @@ static void test_suite_event_cb(void *data, struct stasis_subscription *sub,
|
|
|
|
|
*/
|
|
|
|
|
static void manager_free_user(struct ast_manager_user *user)
|
|
|
|
|
{
|
|
|
|
|
if (user->a1_hash) {
|
|
|
|
|
ast_free(user->a1_hash);
|
|
|
|
|
ast_free(user->a1_hash);
|
|
|
|
|
ast_free(user->secret);
|
|
|
|
|
if (user->whitefilters) {
|
|
|
|
|
ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one");
|
|
|
|
|
}
|
|
|
|
|
if (user->secret) {
|
|
|
|
|
ast_free(user->secret);
|
|
|
|
|
if (user->blackfilters) {
|
|
|
|
|
ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one");
|
|
|
|
|
}
|
|
|
|
|
ao2_t_callback(user->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters");
|
|
|
|
|
ao2_t_callback(user->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters");
|
|
|
|
|
ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one");
|
|
|
|
|
ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one");
|
|
|
|
|
user->acl = ast_free_acl_list(user->acl);
|
|
|
|
|
ast_variables_destroy(user->chanvars);
|
|
|
|
|
ast_free(user);
|
|
|
|
@ -7820,46 +7813,44 @@ static void manager_shutdown(void)
|
|
|
|
|
{
|
|
|
|
|
struct ast_manager_user *user;
|
|
|
|
|
|
|
|
|
|
if (registered) {
|
|
|
|
|
ast_manager_unregister("Ping");
|
|
|
|
|
ast_manager_unregister("Events");
|
|
|
|
|
ast_manager_unregister("Logoff");
|
|
|
|
|
ast_manager_unregister("Login");
|
|
|
|
|
ast_manager_unregister("Challenge");
|
|
|
|
|
ast_manager_unregister("Hangup");
|
|
|
|
|
ast_manager_unregister("Status");
|
|
|
|
|
ast_manager_unregister("Setvar");
|
|
|
|
|
ast_manager_unregister("Getvar");
|
|
|
|
|
ast_manager_unregister("GetConfig");
|
|
|
|
|
ast_manager_unregister("GetConfigJSON");
|
|
|
|
|
ast_manager_unregister("UpdateConfig");
|
|
|
|
|
ast_manager_unregister("CreateConfig");
|
|
|
|
|
ast_manager_unregister("ListCategories");
|
|
|
|
|
ast_manager_unregister("Redirect");
|
|
|
|
|
ast_manager_unregister("Atxfer");
|
|
|
|
|
ast_manager_unregister("Originate");
|
|
|
|
|
ast_manager_unregister("Command");
|
|
|
|
|
ast_manager_unregister("ExtensionState");
|
|
|
|
|
ast_manager_unregister("PresenceState");
|
|
|
|
|
ast_manager_unregister("AbsoluteTimeout");
|
|
|
|
|
ast_manager_unregister("MailboxStatus");
|
|
|
|
|
ast_manager_unregister("MailboxCount");
|
|
|
|
|
ast_manager_unregister("ListCommands");
|
|
|
|
|
ast_manager_unregister("SendText");
|
|
|
|
|
ast_manager_unregister("UserEvent");
|
|
|
|
|
ast_manager_unregister("WaitEvent");
|
|
|
|
|
ast_manager_unregister("CoreSettings");
|
|
|
|
|
ast_manager_unregister("CoreStatus");
|
|
|
|
|
ast_manager_unregister("Reload");
|
|
|
|
|
ast_manager_unregister("CoreShowChannels");
|
|
|
|
|
ast_manager_unregister("ModuleLoad");
|
|
|
|
|
ast_manager_unregister("ModuleCheck");
|
|
|
|
|
ast_manager_unregister("AOCMessage");
|
|
|
|
|
ast_manager_unregister("Filter");
|
|
|
|
|
ast_manager_unregister("BlindTransfer");
|
|
|
|
|
ast_custom_function_unregister(&managerclient_function);
|
|
|
|
|
ast_cli_unregister_multiple(cli_manager, ARRAY_LEN(cli_manager));
|
|
|
|
|
}
|
|
|
|
|
ast_manager_unregister("Ping");
|
|
|
|
|
ast_manager_unregister("Events");
|
|
|
|
|
ast_manager_unregister("Logoff");
|
|
|
|
|
ast_manager_unregister("Login");
|
|
|
|
|
ast_manager_unregister("Challenge");
|
|
|
|
|
ast_manager_unregister("Hangup");
|
|
|
|
|
ast_manager_unregister("Status");
|
|
|
|
|
ast_manager_unregister("Setvar");
|
|
|
|
|
ast_manager_unregister("Getvar");
|
|
|
|
|
ast_manager_unregister("GetConfig");
|
|
|
|
|
ast_manager_unregister("GetConfigJSON");
|
|
|
|
|
ast_manager_unregister("UpdateConfig");
|
|
|
|
|
ast_manager_unregister("CreateConfig");
|
|
|
|
|
ast_manager_unregister("ListCategories");
|
|
|
|
|
ast_manager_unregister("Redirect");
|
|
|
|
|
ast_manager_unregister("Atxfer");
|
|
|
|
|
ast_manager_unregister("Originate");
|
|
|
|
|
ast_manager_unregister("Command");
|
|
|
|
|
ast_manager_unregister("ExtensionState");
|
|
|
|
|
ast_manager_unregister("PresenceState");
|
|
|
|
|
ast_manager_unregister("AbsoluteTimeout");
|
|
|
|
|
ast_manager_unregister("MailboxStatus");
|
|
|
|
|
ast_manager_unregister("MailboxCount");
|
|
|
|
|
ast_manager_unregister("ListCommands");
|
|
|
|
|
ast_manager_unregister("SendText");
|
|
|
|
|
ast_manager_unregister("UserEvent");
|
|
|
|
|
ast_manager_unregister("WaitEvent");
|
|
|
|
|
ast_manager_unregister("CoreSettings");
|
|
|
|
|
ast_manager_unregister("CoreStatus");
|
|
|
|
|
ast_manager_unregister("Reload");
|
|
|
|
|
ast_manager_unregister("CoreShowChannels");
|
|
|
|
|
ast_manager_unregister("ModuleLoad");
|
|
|
|
|
ast_manager_unregister("ModuleCheck");
|
|
|
|
|
ast_manager_unregister("AOCMessage");
|
|
|
|
|
ast_manager_unregister("Filter");
|
|
|
|
|
ast_manager_unregister("BlindTransfer");
|
|
|
|
|
ast_custom_function_unregister(&managerclient_function);
|
|
|
|
|
ast_cli_unregister_multiple(cli_manager, ARRAY_LEN(cli_manager));
|
|
|
|
|
|
|
|
|
|
#ifdef AST_XML_DOCS
|
|
|
|
|
ao2_t_global_obj_release(event_docs, "Dispose of event_docs");
|
|
|
|
@ -7880,18 +7871,12 @@ static void manager_shutdown(void)
|
|
|
|
|
ast_tcptls_server_stop(&ami_desc);
|
|
|
|
|
ast_tcptls_server_stop(&amis_desc);
|
|
|
|
|
|
|
|
|
|
if (ami_tls_cfg.certfile) {
|
|
|
|
|
ast_free(ami_tls_cfg.certfile);
|
|
|
|
|
ami_tls_cfg.certfile = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (ami_tls_cfg.pvtfile) {
|
|
|
|
|
ast_free(ami_tls_cfg.pvtfile);
|
|
|
|
|
ami_tls_cfg.pvtfile = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (ami_tls_cfg.cipher) {
|
|
|
|
|
ast_free(ami_tls_cfg.cipher);
|
|
|
|
|
ami_tls_cfg.cipher = NULL;
|
|
|
|
|
}
|
|
|
|
|
ast_free(ami_tls_cfg.certfile);
|
|
|
|
|
ami_tls_cfg.certfile = NULL;
|
|
|
|
|
ast_free(ami_tls_cfg.pvtfile);
|
|
|
|
|
ami_tls_cfg.pvtfile = NULL;
|
|
|
|
|
ast_free(ami_tls_cfg.cipher);
|
|
|
|
|
ami_tls_cfg.cipher = NULL;
|
|
|
|
|
|
|
|
|
|
ao2_global_obj_release(mgr_sessions);
|
|
|
|
|
|
|
|
|
@ -7965,12 +7950,33 @@ static int subscribe_all(void)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void manager_set_defaults(void)
|
|
|
|
|
{
|
|
|
|
|
manager_enabled = 0;
|
|
|
|
|
displayconnects = 1;
|
|
|
|
|
broken_events_action = 0;
|
|
|
|
|
authtimeout = 30;
|
|
|
|
|
authlimit = 50;
|
|
|
|
|
manager_debug = 0; /* Debug disabled by default */
|
|
|
|
|
|
|
|
|
|
/* default values */
|
|
|
|
|
ast_copy_string(global_realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM),
|
|
|
|
|
sizeof(global_realm));
|
|
|
|
|
ast_sockaddr_setnull(&ami_desc.local_address);
|
|
|
|
|
ast_sockaddr_setnull(&amis_desc.local_address);
|
|
|
|
|
|
|
|
|
|
ami_tls_cfg.enabled = 0;
|
|
|
|
|
ast_free(ami_tls_cfg.certfile);
|
|
|
|
|
ami_tls_cfg.certfile = ast_strdup(AST_CERTFILE);
|
|
|
|
|
ast_free(ami_tls_cfg.pvtfile);
|
|
|
|
|
ami_tls_cfg.pvtfile = ast_strdup("");
|
|
|
|
|
ast_free(ami_tls_cfg.cipher);
|
|
|
|
|
ami_tls_cfg.cipher = ast_strdup("");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
{
|
|
|
|
|
struct ast_config *ucfg = NULL, *cfg = NULL;
|
|
|
|
|
#ifdef AST_XML_DOCS
|
|
|
|
|
struct ao2_container *temp_event_docs;
|
|
|
|
|
#endif
|
|
|
|
|
const char *val;
|
|
|
|
|
char *cat = NULL;
|
|
|
|
|
int newhttptimeout = 60;
|
|
|
|
@ -7984,10 +7990,16 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
int tls_was_enabled = 0;
|
|
|
|
|
int acl_subscription_flag = 0;
|
|
|
|
|
|
|
|
|
|
manager_enabled = 0;
|
|
|
|
|
|
|
|
|
|
if (!reload) {
|
|
|
|
|
int res = STASIS_MESSAGE_TYPE_INIT(ast_manager_get_generic_type);
|
|
|
|
|
struct ao2_container *sessions;
|
|
|
|
|
#ifdef AST_XML_DOCS
|
|
|
|
|
struct ao2_container *temp_event_docs;
|
|
|
|
|
#endif
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
ast_register_atexit(manager_shutdown);
|
|
|
|
|
|
|
|
|
|
res = STASIS_MESSAGE_TYPE_INIT(ast_manager_get_generic_type);
|
|
|
|
|
if (res != 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
@ -7995,9 +8007,7 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
if (!manager_topic) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!registered) {
|
|
|
|
|
/* Register default actions */
|
|
|
|
|
ast_manager_register_xml_core("Ping", 0, action_ping);
|
|
|
|
|
ast_manager_register_xml_core("Events", 0, action_events);
|
|
|
|
@ -8043,33 +8053,37 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
ast_cli_register_multiple(cli_manager, ARRAY_LEN(cli_manager));
|
|
|
|
|
__ast_custom_function_register(&managerclient_function, NULL);
|
|
|
|
|
ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
|
|
|
|
|
registered = 1;
|
|
|
|
|
|
|
|
|
|
/* Append placeholder event so master_eventq never runs dry */
|
|
|
|
|
append_event("Event: Placeholder\r\n\r\n", 0);
|
|
|
|
|
}
|
|
|
|
|
if (append_event("Event: Placeholder\r\n\r\n", 0)) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef AST_XML_DOCS
|
|
|
|
|
temp_event_docs = ast_xmldoc_build_documentation("managerEvent");
|
|
|
|
|
if (temp_event_docs) {
|
|
|
|
|
ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs");
|
|
|
|
|
ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now");
|
|
|
|
|
}
|
|
|
|
|
temp_event_docs = ast_xmldoc_build_documentation("managerEvent");
|
|
|
|
|
if (temp_event_docs) {
|
|
|
|
|
ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs");
|
|
|
|
|
ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ast_register_atexit(manager_shutdown);
|
|
|
|
|
/* If you have a NULL hash fn, you only need a single bucket */
|
|
|
|
|
sessions = ao2_container_alloc(1, NULL, mansession_cmp_fn);
|
|
|
|
|
if (!sessions) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ao2_global_obj_replace_unref(mgr_sessions, sessions);
|
|
|
|
|
ao2_ref(sessions, -1);
|
|
|
|
|
|
|
|
|
|
if ((cfg = ast_config_load2("manager.conf", "manager", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
|
|
|
|
|
return 0;
|
|
|
|
|
/* Initialize all settings before first configuration load. */
|
|
|
|
|
manager_set_defaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
displayconnects = 1;
|
|
|
|
|
broken_events_action = 0;
|
|
|
|
|
authtimeout = 30;
|
|
|
|
|
authlimit = 50;
|
|
|
|
|
manager_debug = 0; /* Debug disabled by default */
|
|
|
|
|
|
|
|
|
|
if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
|
|
|
|
|
ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid. Asterisk management interface (AMI) disabled.\n");
|
|
|
|
|
cfg = ast_config_load2("manager.conf", "manager", config_flags);
|
|
|
|
|
if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
|
|
|
|
|
return 0;
|
|
|
|
|
} else if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
|
|
|
|
|
ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid.\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -8078,30 +8092,15 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
acl_change_stasis_unsubscribe();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* default values */
|
|
|
|
|
ast_copy_string(global_realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(global_realm));
|
|
|
|
|
ast_sockaddr_setnull(&ami_desc.local_address);
|
|
|
|
|
ast_sockaddr_setnull(&amis_desc.local_address);
|
|
|
|
|
if (reload) {
|
|
|
|
|
/* Reset all settings before reloading configuration */
|
|
|
|
|
tls_was_enabled = ami_tls_cfg.enabled;
|
|
|
|
|
manager_set_defaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_sockaddr_parse(&ami_desc_local_address_tmp, "[::]", 0);
|
|
|
|
|
ast_sockaddr_set_port(&ami_desc_local_address_tmp, DEFAULT_MANAGER_PORT);
|
|
|
|
|
|
|
|
|
|
tls_was_enabled = (reload && ami_tls_cfg.enabled);
|
|
|
|
|
|
|
|
|
|
ami_tls_cfg.enabled = 0;
|
|
|
|
|
if (ami_tls_cfg.certfile) {
|
|
|
|
|
ast_free(ami_tls_cfg.certfile);
|
|
|
|
|
}
|
|
|
|
|
ami_tls_cfg.certfile = ast_strdup(AST_CERTFILE);
|
|
|
|
|
if (ami_tls_cfg.pvtfile) {
|
|
|
|
|
ast_free(ami_tls_cfg.pvtfile);
|
|
|
|
|
}
|
|
|
|
|
ami_tls_cfg.pvtfile = ast_strdup("");
|
|
|
|
|
if (ami_tls_cfg.cipher) {
|
|
|
|
|
ast_free(ami_tls_cfg.cipher);
|
|
|
|
|
}
|
|
|
|
|
ami_tls_cfg.cipher = ast_strdup("");
|
|
|
|
|
|
|
|
|
|
for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
|
|
|
|
|
val = var->value;
|
|
|
|
|
|
|
|
|
@ -8273,9 +8272,7 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ast_strlen_zero(user_secret)) {
|
|
|
|
|
if (user->secret) {
|
|
|
|
|
ast_free(user->secret);
|
|
|
|
|
}
|
|
|
|
|
ast_free(user->secret);
|
|
|
|
|
user->secret = ast_strdup(user_secret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -8331,6 +8328,10 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
user->writetimeout = 100;
|
|
|
|
|
user->whitefilters = ao2_container_alloc(1, NULL, NULL);
|
|
|
|
|
user->blackfilters = ao2_container_alloc(1, NULL, NULL);
|
|
|
|
|
if (!user->whitefilters || !user->blackfilters) {
|
|
|
|
|
manager_free_user(user);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Insert into list */
|
|
|
|
|
AST_RWLIST_INSERT_TAIL(&users, user, list);
|
|
|
|
@ -8348,9 +8349,7 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
var = ast_variable_browse(cfg, cat);
|
|
|
|
|
for (; var; var = var->next) {
|
|
|
|
|
if (!strcasecmp(var->name, "secret")) {
|
|
|
|
|
if (user->secret) {
|
|
|
|
|
ast_free(user->secret);
|
|
|
|
|
}
|
|
|
|
|
ast_free(user->secret);
|
|
|
|
|
user->secret = ast_strdup(var->value);
|
|
|
|
|
} else if (!strcasecmp(var->name, "deny") ||
|
|
|
|
|
!strcasecmp(var->name, "permit") ||
|
|
|
|
@ -8412,9 +8411,7 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
/* Calculate A1 for Digest auth */
|
|
|
|
|
snprintf(a1, sizeof(a1), "%s:%s:%s", user->username, global_realm, user->secret);
|
|
|
|
|
ast_md5_hash(a1_hash,a1);
|
|
|
|
|
if (user->a1_hash) {
|
|
|
|
|
ast_free(user->a1_hash);
|
|
|
|
|
}
|
|
|
|
|
ast_free(user->a1_hash);
|
|
|
|
|
user->a1_hash = ast_strdup(a1_hash);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -8427,20 +8424,8 @@ static int __init_manager(int reload, int by_external_config)
|
|
|
|
|
|
|
|
|
|
AST_RWLIST_UNLOCK(&users);
|
|
|
|
|
|
|
|
|
|
if (!reload) {
|
|
|
|
|
struct ao2_container *sessions;
|
|
|
|
|
|
|
|
|
|
/* If you have a NULL hash fn, you only need a single bucket */
|
|
|
|
|
sessions = ao2_container_alloc(1, NULL, mansession_cmp_fn);
|
|
|
|
|
if (sessions) {
|
|
|
|
|
ao2_global_obj_replace_unref(mgr_sessions, sessions);
|
|
|
|
|
ao2_ref(sessions, -1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (webmanager_enabled && manager_enabled) {
|
|
|
|
|
if (!webregged) {
|
|
|
|
|
|
|
|
|
|
ast_http_uri_link(&rawmanuri);
|
|
|
|
|
ast_http_uri_link(&manageruri);
|
|
|
|
|
ast_http_uri_link(&managerxmluri);
|
|
|
|
|