This commit is contained in:
InterLinked1 2024-03-20 19:36:43 +00:00 committed by GitHub
commit 2b9e57b579
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 78 additions and 2 deletions

View File

@ -1728,6 +1728,7 @@ struct mansession_session {
time_t noncetime; /*!< Timer for nonce value expiration */
unsigned long oldnonce; /*!< Stale nonce value */
unsigned long nc; /*!< incremental nonce counter */
unsigned int kicked:1; /*!< Flag set if session is forcibly kicked */
ast_mutex_t notify_lock; /*!< Lock for notifying this session of events */
AST_LIST_HEAD_NOLOCK(mansession_datastores, ast_datastore) datastores; /*!< Data stores on the session */
AST_LIST_ENTRY(mansession_session) list;
@ -2772,6 +2773,76 @@ static char *handle_showmancmds(struct ast_cli_entry *e, int cmd, struct ast_cli
return CLI_SUCCESS;
}
/*! \brief CLI command manager kick session */
static char *handle_kickmanconn(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
struct ao2_container *sessions;
struct mansession_session *session;
struct ao2_iterator i;
int fd = -1;
int found = 0;
switch (cmd) {
case CLI_INIT:
e->command = "manager kick session";
e->usage =
"Usage: manager kick session <file descriptor>\n"
" Kick an active Asterisk Manager Interface session\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 4) {
return CLI_SHOWUSAGE;
}
fd = atoi(a->argv[3]);
if (fd <= 0) { /* STDOUT won't be a valid AMI fd either */
ast_cli(a->fd, "Invalid AMI file descriptor: %s\n", a->argv[3]);
return CLI_FAILURE;
}
sessions = ao2_global_obj_ref(mgr_sessions);
if (sessions) {
i = ao2_iterator_init(sessions, 0);
ao2_ref(sessions, -1);
while ((session = ao2_iterator_next(&i))) {
ao2_lock(session);
if (session->stream) {
if (ast_iostream_get_fd(session->stream) == fd) {
if (session->kicked) {
ast_cli(a->fd, "Manager session using file descriptor %d has already been kicked\n", fd);
ao2_unlock(session);
unref_mansession(session);
break;
}
fd = ast_iostream_get_fd(session->stream);
found = fd;
ast_cli(a->fd, "Kicking manager session connected using file descriptor %d\n", fd);
ast_mutex_lock(&session->notify_lock);
session->kicked = 1;
if (session->waiting_thread != AST_PTHREADT_NULL) {
pthread_kill(session->waiting_thread, SIGURG);
}
ast_mutex_unlock(&session->notify_lock);
ao2_unlock(session);
unref_mansession(session);
break;
}
}
ao2_unlock(session);
unref_mansession(session);
}
ao2_iterator_destroy(&i);
}
if (!found) {
ast_cli(a->fd, "No manager session found using file descriptor %d\n", fd);
}
return CLI_SUCCESS;
}
/*! \brief CLI command manager list connected */
static char *handle_showmanconn(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
@ -7465,6 +7536,10 @@ static int get_input(struct mansession *s, char *output)
ast_mutex_unlock(&s->session->notify_lock);
}
if (res < 0) {
if (s->session->kicked) {
ast_debug(1, "Manager session has been kicked\n");
return -1;
}
/* If we get a signal from some other thread (typically because
* there are new events queued), return 0 to notify the caller.
*/
@ -7664,7 +7739,7 @@ static void *session_do(void *data)
astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */
for (;;) {
if ((res = do_message(&s)) < 0 || s.write_error) {
if ((res = do_message(&s)) < 0 || s.write_error || session->kicked) {
break;
}
if (session->authenticated) {
@ -7674,7 +7749,7 @@ static void *session_do(void *data)
/* session is over, explain why and terminate */
if (session->authenticated) {
if (manager_displayconnects(session)) {
ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
ast_verb(2, "Manager '%s' %s from %s\n", session->username, session->kicked ? "kicked" : "logged off", ast_sockaddr_stringify_addr(&session->addr));
}
} else {
ast_atomic_fetchadd_int(&unauth_sessions, -1);
@ -9591,6 +9666,7 @@ static struct ast_cli_entry cli_manager[] = {
AST_CLI_DEFINE(handle_showmancmd, "Show a manager interface command"),
AST_CLI_DEFINE(handle_showmancmds, "List manager interface commands"),
AST_CLI_DEFINE(handle_showmanconn, "List connected manager interface users"),
AST_CLI_DEFINE(handle_kickmanconn, "Kick a connected manager interface connection"),
AST_CLI_DEFINE(handle_showmaneventq, "List manager interface queued events"),
AST_CLI_DEFINE(handle_showmanagers, "List configured manager users"),
AST_CLI_DEFINE(handle_showmanager, "Display information on a specific manager user"),