#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/manager.h"
#include "asterisk/config.h"
#include "asterisk/callerid.h"
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/md5.h"
#include "asterisk/acl.h"
#include "asterisk/utils.h"
#include "asterisk/http.h"
#include "asterisk/threadstorage.h"
#include "asterisk/linkedlists.h"
Include dependency graph for manager.c:

Go to the source code of this file.
Data Structures | |
| struct | ast_manager_user |
| struct | eventqent |
| struct | fast_originate_helper |
| struct | mansession |
| struct | permalias |
Defines | |
| #define | ASTMAN_APPEND_BUF_INITSIZE 256 |
| #define | MANAGER_EVENT_BUF_INITSIZE 256 |
Enumerations | |
| enum | { FORMAT_RAW, FORMAT_HTML, FORMAT_XML } |
Functions | |
| static void * | accept_thread (void *ignore) |
| static int | action_command (struct mansession *s, const struct message *m) |
| action_command: Manager command "command" - execute CLI command | |
| static int | action_events (struct mansession *s, const struct message *m) |
| static int | action_extensionstate (struct mansession *s, const struct message *m) |
| static int | action_getconfig (struct mansession *s, const struct message *m) |
| static int | action_getvar (struct mansession *s, const struct message *m) |
| static int | action_hangup (struct mansession *s, const struct message *m) |
| static int | action_listcommands (struct mansession *s, const struct message *m) |
| static int | action_logoff (struct mansession *s, const struct message *m) |
| static int | action_mailboxcount (struct mansession *s, const struct message *m) |
| static int | action_mailboxstatus (struct mansession *s, const struct message *m) |
| static int | action_originate (struct mansession *s, const struct message *m) |
| static int | action_ping (struct mansession *s, const struct message *m) |
| static int | action_redirect (struct mansession *s, const struct message *m) |
| action_redirect: The redirect manager command | |
| static int | action_setvar (struct mansession *s, const struct message *m) |
| static int | action_status (struct mansession *s, const struct message *m) |
| Manager "status" command to show channels. | |
| static int | action_timeout (struct mansession *s, const struct message *m) |
| static int | action_updateconfig (struct mansession *s, const struct message *m) |
| static int | action_userevent (struct mansession *s, const struct message *m) |
| static int | action_waitevent (struct mansession *s, const struct message *m) |
| static int | append_event (const char *str, int category) |
| static struct ast_manager_user * | ast_get_manager_by_name_locked (const char *name) |
| static int | ast_instring (const char *bigstr, const char *smallstr, char delim) |
| static int | ast_is_number (char *string) |
| static | AST_LIST_HEAD_STATIC (users, ast_manager_user) |
| static | AST_LIST_HEAD_STATIC (sessions, mansession) |
| int | ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description) |
| register a new command with manager, including online help. This is the preferred way to register a manager command | |
| static int | ast_manager_register_struct (struct manager_action *act) |
| int | ast_manager_unregister (char *action) |
| AST_RWLOCK_DEFINE_STATIC (actionlock) | |
| AST_THREADSTORAGE (astman_append_buf, astman_append_buf_init) | |
| AST_THREADSTORAGE (manager_event_buf, manager_event_buf_init) | |
| void | astman_append (struct mansession *s, const char *fmt,...) |
| const char * | astman_get_header (const struct message *m, char *var) |
| ast_variable * | astman_get_variables (const struct message *m) |
| void | astman_send_ack (struct mansession *s, const struct message *m, char *msg) |
| void | astman_send_error (struct mansession *s, const struct message *m, char *error) |
| void | astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg) |
| int | astman_verify_session_readpermissions (unsigned long ident, int perm) |
| Verify a session's read permissions against a permission mask. | |
| int | astman_verify_session_writepermissions (unsigned long ident, int perm) |
| Verify a session's write permissions against a permission mask. | |
| static int | authenticate (struct mansession *s, const struct message *m) |
| static char * | authority_to_str (int authority, char *res, int reslen) |
| Convert authority code to string with serveral options. | |
| static char * | complete_show_mancmd (const char *line, const char *word, int pos, int state) |
| static void | destroy_session (struct mansession *s) |
| static int | do_message (struct mansession *s) |
| static void * | fast_originate (void *data) |
| static struct mansession * | find_session (unsigned long ident) |
| static void | free_session (struct mansession *s) |
| static char * | generic_http_callback (int format, struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength) |
| static int | get_input (struct mansession *s, char *output) |
| static int | get_perm (const char *instr) |
| static int | handle_showmanager (int fd, int argc, char *argv[]) |
| static int | handle_showmanagers (int fd, int argc, char *argv[]) |
| static int | handle_showmancmd (int fd, int argc, char *argv[]) |
| static int | handle_showmancmds (int fd, int argc, char *argv[]) |
| CLI command Should change to "manager show commands". | |
| static int | handle_showmanconn (int fd, int argc, char *argv[]) |
| CLI command show manager connected. | |
| static int | handle_showmaneventq (int fd, int argc, char *argv[]) |
| CLI command show manager connected. | |
| static void | handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg) |
| static char * | html_translate (char *in) |
| int | init_manager (void) |
| int | manager_event (int category, const char *event, const char *fmt,...) |
| manager_event: Send AMI event to client | |
| static char * | manager_http_callback (struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength) |
| static int | manager_state_cb (char *context, char *exten, int state, void *data) |
| static char * | mxml_http_callback (struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength) |
| static int | process_events (struct mansession *s) |
| static int | process_message (struct mansession *s, const struct message *m) |
| static char * | rawman_http_callback (struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength) |
| int | reload_manager (void) |
| static void * | session_do (void *data) |
| static int | set_eventmask (struct mansession *s, const char *eventmask) |
| Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. | |
| static int | strings_to_mask (const char *string) |
| static void | unuse_eventqent (struct eventqent *e) |
| static void | xml_copy_escape (char **dst, size_t *maxlen, const char *src, int lower) |
| static char * | xml_translate (char *in, struct ast_variable *vars) |
Variables | |
| static int | asock = -1 |
| static int | block_sockets |
| static struct ast_cli_entry | cli_manager [] |
| static struct ast_cli_entry | cli_show_manager_command_deprecated |
| static struct ast_cli_entry | cli_show_manager_commands_deprecated |
| static struct ast_cli_entry | cli_show_manager_connected_deprecated |
| static struct ast_cli_entry | cli_show_manager_eventq_deprecated |
| static char * | contenttype [] = { "plain", "html", "xml" } |
| static int | displayconnects = 1 |
| static int | enabled |
| static struct manager_action * | first_action |
| static int | httptimeout = 60 |
| ast_http_uri | manageruri |
| ast_http_uri | managerxmluri |
| static char | mandescr_command [] |
| static char | mandescr_events [] |
| static char | mandescr_extensionstate [] |
| static char | mandescr_getconfig [] |
| static char | mandescr_getvar [] |
| static char | mandescr_hangup [] |
| static char | mandescr_listcommands [] |
| static char | mandescr_logoff [] |
| static char | mandescr_mailboxcount [] |
| static char | mandescr_mailboxstatus [] |
| Help text for manager command mailboxstatus. | |
| static char | mandescr_originate [] |
| static char | mandescr_ping [] |
| Manager PING. | |
| static char | mandescr_redirect [] |
| static char | mandescr_setvar [] |
| static char | mandescr_timeout [] |
| static char | mandescr_updateconfig [] |
| static char | mandescr_userevent [] |
| static char | mandescr_waitevent [] |
| Manager WAITEVENT. | |
| eventqent * | master_eventq = NULL |
| static int | num_sessions |
| static struct permalias | perms [] |
| static int | portno = DEFAULT_MANAGER_PORT |
| ast_http_uri | rawmanuri |
| static int | registered = 0 |
| static char | showmanager_help [] |
| static char | showmanagers_help [] |
| static char | showmancmd_help [] |
| static char | showmancmds_help [] |
| static char | showmanconn_help [] |
| static char | showmaneventq_help [] |
| static pthread_t | t |
| static int | timestampevents |
| static int | webregged = 0 |
Channel Management and more
Definition in file manager.c.
| anonymous enum |
Definition at line 2498 of file manager.c.
02498 { 02499 FORMAT_RAW, 02500 FORMAT_HTML, 02501 FORMAT_XML, 02502 };
| int astman_verify_session_readpermissions | ( | unsigned long | ident, | |
| int | perm | |||
| ) |
Verify a session's read permissions against a permission mask.
| ident | session identity | |
| perm | permission mask to verify |
Definition at line 2460 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), result, s, and sessions.
02461 { 02462 int result = 0; 02463 struct mansession *s; 02464 02465 AST_LIST_LOCK(&sessions); 02466 AST_LIST_TRAVERSE(&sessions, s, list) { 02467 ast_mutex_lock(&s->__lock); 02468 if ((s->managerid == ident) && (s->readperm & perm)) { 02469 result = 1; 02470 ast_mutex_unlock(&s->__lock); 02471 break; 02472 } 02473 ast_mutex_unlock(&s->__lock); 02474 } 02475 AST_LIST_UNLOCK(&sessions); 02476 return result; 02477 }
| int astman_verify_session_writepermissions | ( | unsigned long | ident, | |
| int | perm | |||
| ) |
Verify a session's write permissions against a permission mask.
| ident | session identity | |
| perm | permission mask to verify |
Definition at line 2479 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), result, s, and sessions.
02480 { 02481 int result = 0; 02482 struct mansession *s; 02483 02484 AST_LIST_LOCK(&sessions); 02485 AST_LIST_TRAVERSE(&sessions, s, list) { 02486 ast_mutex_lock(&s->__lock); 02487 if ((s->managerid == ident) && (s->writeperm & perm)) { 02488 result = 1; 02489 ast_mutex_unlock(&s->__lock); 02490 break; 02491 } 02492 ast_mutex_unlock(&s->__lock); 02493 } 02494 AST_LIST_UNLOCK(&sessions); 02495 return result; 02496 }
| static struct mansession* find_session | ( | unsigned long | ident | ) | [static] |
END Doxygen group
Definition at line 2442 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), s, and sessions.
02443 { 02444 struct mansession *s; 02445 02446 AST_LIST_LOCK(&sessions); 02447 AST_LIST_TRAVERSE(&sessions, s, list) { 02448 ast_mutex_lock(&s->__lock); 02449 if (s->sessiontimeout && (s->managerid == ident) && !s->needdestroy) { 02450 s->inuse++; 02451 break; 02452 } 02453 ast_mutex_unlock(&s->__lock); 02454 } 02455 AST_LIST_UNLOCK(&sessions); 02456 02457 return s; 02458 }
| static char* generic_http_callback | ( | int | format, | |
| struct sockaddr_in * | requestor, | |||
| const char * | uri, | |||
| struct ast_variable * | params, | |||
| int * | status, | |||
| char ** | title, | |||
| int * | contentlength | |||
| ) | [static] |
Definition at line 2505 of file manager.c.
References len, ast_variable::name, ast_variable::next, s, and ast_variable::value.
Referenced by manager_http_callback(), mxml_http_callback(), and rawman_http_callback().
02506 { 02507 struct mansession *s = NULL; 02508 unsigned long ident = 0; 02509 char workspace[512]; 02510 char cookie[128]; 02511 size_t len = sizeof(workspace); 02512 int blastaway = 0; 02513 char *c = workspace; 02514 char *retval = NULL; 02515 struct ast_variable *v; 02516 02517 for (v = params; v; v = v->next) { 02518 if (!strcasecmp(v->name, "mansession_id")) { 02519 sscanf(v->value, "%lx", &ident); 02520 break; 02521 } 02522 } 02523 02524 if (!(s = find_session(ident))) { 02525 /* Create new session */ 02526 if (!(s = ast_calloc(1, sizeof(*s)))) { 02527 *status = 500; 02528 goto generic_callback_out; 02529 } 02530 memcpy(&s->sin, requestor, sizeof(s->sin)); 02531 s->fd = -1; 02532 s->waiting_thread = AST_PTHREADT_NULL; 02533 s->send_events = 0; 02534 ast_mutex_init(&s->__lock); 02535 ast_mutex_lock(&s->__lock); 02536 s->inuse = 1; 02537 s->managerid = rand() | (unsigned long)s; 02538 AST_LIST_LOCK(&sessions); 02539 AST_LIST_INSERT_HEAD(&sessions, s, list); 02540 /* Hook into the last spot in the event queue */ 02541 s->eventq = master_eventq; 02542 while (s->eventq->next) 02543 s->eventq = s->eventq->next; 02544 AST_LIST_UNLOCK(&sessions); 02545 ast_atomic_fetchadd_int(&s->eventq->usecount, 1); 02546 ast_atomic_fetchadd_int(&num_sessions, 1); 02547 } 02548 02549 /* Reset HTTP timeout. If we're not yet authenticated, keep it extremely short */ 02550 time(&s->sessiontimeout); 02551 if (!s->authenticated && (httptimeout > 5)) 02552 s->sessiontimeout += 5; 02553 else 02554 s->sessiontimeout += httptimeout; 02555 ast_mutex_unlock(&s->__lock); 02556 02557 if (s) { 02558 struct message m = { 0 }; 02559 char tmp[80]; 02560 unsigned int x; 02561 size_t hdrlen; 02562 02563 for (x = 0, v = params; v && (x < AST_MAX_MANHEADERS); x++, v = v->next) { 02564 hdrlen = strlen(v->name) + strlen(v->value) + 3; 02565 m.headers[m.hdrcount] = alloca(hdrlen); 02566 snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", v->name, v->value); 02567 m.hdrcount = x + 1; 02568 } 02569 02570 if (process_message(s, &m)) { 02571 if (s->authenticated) { 02572 if (option_verbose > 1) { 02573 if (displayconnects) 02574 ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02575 } 02576 ast_log(LOG_EVENT, "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02577 } else { 02578 if (option_verbose > 1) { 02579 if (displayconnects) 02580 ast_verbose(VERBOSE_PREFIX_2 "HTTP Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); 02581 } 02582 ast_log(LOG_EVENT, "HTTP Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 02583 } 02584 s->needdestroy = 1; 02585 } 02586 ast_build_string(&c, &len, "Content-type: text/%s\r\n", contenttype[format]); 02587 sprintf(tmp, "%08lx", s->managerid); 02588 ast_build_string(&c, &len, "%s\r\n", ast_http_setcookie("mansession_id", tmp, httptimeout, cookie, sizeof(cookie))); 02589 if (format == FORMAT_HTML) 02590 ast_build_string(&c, &len, "<title>Asterisk™ Manager Interface</title>"); 02591 if (format == FORMAT_XML) { 02592 ast_build_string(&c, &len, "<ajax-response>\n"); 02593 } else if (format == FORMAT_HTML) { 02594 ast_build_string(&c, &len, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n"); 02595 ast_build_string(&c, &len, "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\"><h1> Manager Tester</h1></td></tr>\r\n"); 02596 } 02597 ast_mutex_lock(&s->__lock); 02598 if (s->outputstr) { 02599 char *tmp; 02600 if (format == FORMAT_XML) 02601 tmp = xml_translate(s->outputstr->str, params); 02602 else if (format == FORMAT_HTML) 02603 tmp = html_translate(s->outputstr->str); 02604 else 02605 tmp = s->outputstr->str; 02606 if (tmp) { 02607 retval = malloc(strlen(workspace) + strlen(tmp) + 128); 02608 if (retval) { 02609 strcpy(retval, workspace); 02610 strcpy(retval + strlen(retval), tmp); 02611 c = retval + strlen(retval); 02612 len = 120; 02613 } 02614 } 02615 if (tmp != s->outputstr->str) 02616 free(tmp); 02617 free(s->outputstr); 02618 s->outputstr = NULL; 02619 } 02620 ast_mutex_unlock(&s->__lock); 02621 /* Still okay because c would safely be pointing to workspace even 02622 if retval failed to allocate above */ 02623 if (format == FORMAT_XML) { 02624 ast_build_string(&c, &len, "</ajax-response>\n"); 02625 } else if (format == FORMAT_HTML) 02626 ast_build_string(&c, &len, "</table></body>\r\n"); 02627 } else { 02628 *status = 500; 02629 *title = strdup("Server Error"); 02630 } 02631 ast_mutex_lock(&s->__lock); 02632 if (s->needdestroy) { 02633 if (s->inuse == 1) { 02634 ast_log(LOG_DEBUG, "Need destroy, doing it now!\n"); 02635 blastaway = 1; 02636 } else { 02637 ast_log(LOG_DEBUG, "Need destroy, but can't do it yet!\n"); 02638 if (s->waiting_thread != AST_PTHREADT_NULL) 02639 pthread_kill(s->waiting_thread, SIGURG); 02640 s->inuse--; 02641 } 02642 } else 02643 s->inuse--; 02644 ast_mutex_unlock(&s->__lock); 02645 02646 if (blastaway) 02647 destroy_session(s); 02648 generic_callback_out: 02649 if (*status != 200) 02650 return ast_http_error(500, "Server Error", NULL, "Internal Server Error (out of memory)\n"); 02651 return retval; 02652 }
| int init_manager | ( | void | ) |
Called by Asterisk initialization
Definition at line 2693 of file manager.c.
References accept_thread(), action_command(), action_events(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_listcommands(), action_logoff(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_ping(), action_redirect(), action_setvar(), action_status(), action_timeout(), action_updateconfig(), action_userevent(), action_waitevent(), append_event(), asock, ast_calloc, ast_category_browse(), ast_cli_register_multiple(), ast_config_destroy(), ast_config_load(), ast_extension_state_add(), ast_get_manager_by_name_locked(), ast_http_uri_link(), ast_http_uri_unlink(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_manager_register, ast_manager_register2(), ast_pthread_create_background, ast_strdup, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), block_sockets, cli_manager, DEFAULT_MANAGER_PORT, ast_manager_user::deny, displayconnects, ast_manager_user::displayconnects, enabled, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, EVENT_FLAG_CONFIG, EVENT_FLAG_USER, free, httptimeout, ast_manager_user::keep, LOG_DEBUG, LOG_WARNING, manager_state_cb(), manageruri, managerxmluri, option_verbose, ast_manager_user::permit, portno, rawmanuri, ast_manager_user::read, ast_manager_user::secret, t, timestampevents, var, and ast_manager_user::write.
Referenced by main(), and reload_manager().
02694 { 02695 struct ast_config *cfg = NULL; 02696 const char *val; 02697 char *cat = NULL; 02698 int oldportno = portno; 02699 static struct sockaddr_in ba; 02700 int x = 1; 02701 int flags; 02702 int webenabled = 0; 02703 int newhttptimeout = 60; 02704 struct ast_manager_user *user = NULL; 02705 02706 if (!registered) { 02707 /* Register default actions */ 02708 ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping); 02709 ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events); 02710 ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff); 02711 ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup); 02712 ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" ); 02713 ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar ); 02714 ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar ); 02715 ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig); 02716 ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig); 02717 ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect ); 02718 ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate); 02719 ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command ); 02720 ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate ); 02721 ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout ); 02722 ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus ); 02723 ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount ); 02724 ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands); 02725 ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent); 02726 ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent); 02727 02728 ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry)); 02729 ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); 02730 registered = 1; 02731 /* Append placeholder event so master_eventq never runs dry */ 02732 append_event("Event: Placeholder\r\n\r\n", 0); 02733 } 02734 portno = DEFAULT_MANAGER_PORT; 02735 displayconnects = 1; 02736 cfg = ast_config_load("manager.conf"); 02737 if (!cfg) { 02738 ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n"); 02739 return 0; 02740 } 02741 val = ast_variable_retrieve(cfg, "general", "enabled"); 02742 if (val) 02743 enabled = ast_true(val); 02744 02745 val = ast_variable_retrieve(cfg, "general", "block-sockets"); 02746 if (val) 02747 block_sockets = ast_true(val); 02748 02749 val = ast_variable_retrieve(cfg, "general", "webenabled"); 02750 if (val) 02751 webenabled = ast_true(val); 02752 02753 if ((val = ast_variable_retrieve(cfg, "general", "port"))) { 02754 if (sscanf(val, "%d", &portno) != 1) { 02755 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val); 02756 portno = DEFAULT_MANAGER_PORT; 02757 } 02758 } 02759 02760 if ((val = ast_variable_retrieve(cfg, "general", "displayconnects"))) 02761 displayconnects = ast_true(val); 02762 02763 if ((val = ast_variable_retrieve(cfg, "general", "timestampevents"))) 02764 timestampevents = ast_true(val); 02765 02766 if ((val = ast_variable_retrieve(cfg, "general", "httptimeout"))) 02767 newhttptimeout = atoi(val); 02768 02769 memset(&ba, 0, sizeof(ba)); 02770 ba.sin_family = AF_INET; 02771 ba.sin_port = htons(portno); 02772 02773 if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) { 02774 if (!inet_aton(val, &ba.sin_addr)) { 02775 ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); 02776 memset(&ba.sin_addr, 0, sizeof(ba.sin_addr)); 02777 } 02778 } 02779 02780 02781 if ((asock > -1) && ((portno != oldportno) || !enabled)) { 02782 #if 0 02783 /* Can't be done yet */ 02784 close(asock); 02785 asock = -1; 02786 #else 02787 ast_log(LOG_WARNING, "Unable to change management port / enabled\n"); 02788 #endif 02789 } 02790 02791 AST_LIST_LOCK(&users); 02792 02793 while ((cat = ast_category_browse(cfg, cat))) { 02794 struct ast_variable *var = NULL; 02795 02796 if (!strcasecmp(cat, "general")) 02797 continue; 02798 02799 /* Look for an existing entry, if none found - create one and add it to the list */ 02800 if (!(user = ast_get_manager_by_name_locked(cat))) { 02801 if (!(user = ast_calloc(1, sizeof(*user)))) 02802 break; 02803 /* Copy name over */ 02804 ast_copy_string(user->username, cat, sizeof(user->username)); 02805 /* Insert into list */ 02806 AST_LIST_INSERT_TAIL(&users, user, list); 02807 } 02808 02809 /* Make sure we keep this user and don't destroy it during cleanup */ 02810 user->keep = 1; 02811 02812 var = ast_variable_browse(cfg, cat); 02813 while (var) { 02814 if (!strcasecmp(var->name, "secret")) { 02815 if (user->secret) 02816 free(user->secret); 02817 user->secret = ast_strdup(var->value); 02818 } else if (!strcasecmp(var->name, "deny") ) { 02819 if (user->deny) 02820 free(user->deny); 02821 user->deny = ast_strdup(var->value); 02822 } else if (!strcasecmp(var->name, "permit") ) { 02823 if (user->permit) 02824 free(user->permit); 02825 user->permit = ast_strdup(var->value); 02826 } else if (!strcasecmp(var->name, "read") ) { 02827 if (user->read) 02828 free(user->read); 02829 user->read = ast_strdup(var->value); 02830 } else if (!strcasecmp(var->name, "write") ) { 02831 if (user->write) 02832 free(user->write); 02833 user->write = ast_strdup(var->value); 02834 } else if (!strcasecmp(var->name, "displayconnects") ) 02835 user->displayconnects = ast_true(var->value); 02836 else 02837 ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name); 02838 var = var->next; 02839 } 02840 } 02841 02842 /* Perform cleanup - essentially prune out old users that no longer exist */ 02843 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) { 02844 if (user->keep) { 02845 user->keep = 0; 02846 continue; 02847 } 02848 /* We do not need to keep this user so take them out of the list */ 02849 AST_LIST_REMOVE_CURRENT(&users, list); 02850 /* Free their memory now */ 02851 if (user->secret) 02852 free(user->secret); 02853 if (user->deny) 02854 free(user->deny); 02855 if (user->permit) 02856 free(user->permit); 02857 if (user->read) 02858 free(user->read); 02859 if (user->write) 02860 free(user->write); 02861 free(user); 02862 } 02863 AST_LIST_TRAVERSE_SAFE_END 02864 02865 AST_LIST_UNLOCK(&users); 02866 02867 ast_config_destroy(cfg); 02868 02869 if (webenabled && enabled) { 02870 if (!webregged) { 02871 ast_http_uri_link(&rawmanuri); 02872 ast_http_uri_link(&manageruri); 02873 ast_http_uri_link(&managerxmluri); 02874 webregged = 1; 02875 } 02876 } else { 02877 if (webregged) { 02878 ast_http_uri_unlink(&rawmanuri); 02879 ast_http_uri_unlink(&manageruri); 02880 ast_http_uri_unlink(&managerxmluri); 02881 webregged = 0; 02882 } 02883 } 02884 02885 if (newhttptimeout > 0) 02886 httptimeout = newhttptimeout; 02887 02888 /* If not enabled, do nothing */ 02889 if (!enabled) 02890 return 0; 02891 02892 if (asock < 0) { 02893 asock = socket(AF_INET, SOCK_STREAM, 0); 02894 if (asock < 0) { 02895 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 02896 return -1; 02897 } 02898 setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 02899 if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) { 02900 ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno)); 02901 close(asock); 02902 asock = -1; 02903 return -1; 02904 } 02905 if (listen(asock, 2)) { 02906 ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno)); 02907 close(asock); 02908 asock = -1; 02909 return -1; 02910 } 02911 flags = fcntl(asock, F_GETFL); 02912 fcntl(asock, F_SETFL, flags | O_NONBLOCK); 02913 if (option_verbose) 02914 ast_verbose("Asterisk Management interface listening on port %d\n", portno); 02915 ast_pthread_create_background(&t, NULL, accept_thread, NULL); 02916 } 02917 return 0; 02918 }
| static char* manager_http_callback | ( | struct sockaddr_in * | requestor, | |
| const char * | uri, | |||
| struct ast_variable * | params, | |||
| int * | status, | |||
| char ** | title, | |||
| int * | contentlength | |||
| ) | [static] |
Definition at line 2654 of file manager.c.
References FORMAT_HTML, and generic_http_callback().
02655 { 02656 return generic_http_callback(FORMAT_HTML, requestor, uri, params, status, title, contentlength); 02657 }
| static char* mxml_http_callback | ( | struct sockaddr_in * | requestor, | |
| const char * | uri, | |||
| struct ast_variable * | params, | |||
| int * | status, | |||
| char ** | title, | |||
| int * | contentlength | |||
| ) | [static] |
Definition at line 2659 of file manager.c.
References FORMAT_XML, and generic_http_callback().
02660 { 02661 return generic_http_callback(FORMAT_XML, requestor, uri, params, status, title, contentlength); 02662 }
| static char* rawman_http_callback | ( | struct sockaddr_in * | requestor, | |
| const char * | uri, | |||
| struct ast_variable * | params, | |||
| int * | status, | |||
| char ** | title, | |||
| int * | contentlength | |||
| ) | [static] |
Definition at line 2664 of file manager.c.
References FORMAT_RAW, and generic_http_callback().
02665 { 02666 return generic_http_callback(FORMAT_RAW, requestor, uri, params, status, title, contentlength); 02667 }
| int reload_manager | ( | void | ) |
Definition at line 2920 of file manager.c.
References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().
02921 { 02922 manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n"); 02923 return init_manager(); 02924 }
char* contenttype[] = { "plain", "html", "xml" } [static] |
| struct ast_http_uri manageruri |
| struct ast_http_uri managerxmluri |
| struct ast_http_uri rawmanuri |
int registered = 0 [static] |
1.5.1