#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/lock.h"
Go to the source code of this file.
Data Structures | |
struct | manager_action |
struct | message |
Defines | |
#define | ast_manager_register(a, b, c, d) ast_manager_register2(a, b, c, d, NULL) |
#define | AST_MAX_MANHEADERS 128 |
#define | DEFAULT_MANAGER_PORT 5038 |
#define | EVENT_FLAG_AGENT (1 << 5) |
#define | EVENT_FLAG_CALL (1 << 1) |
#define | EVENT_FLAG_COMMAND (1 << 4) |
#define | EVENT_FLAG_CONFIG (1 << 7) |
#define | EVENT_FLAG_EXTENSIONSTATUS (1 << 8) |
#define | EVENT_FLAG_LOG (1 << 2) |
#define | EVENT_FLAG_SYSTEM (1 << 0) |
#define | EVENT_FLAG_USER (1 << 6) |
#define | EVENT_FLAG_VERBOSE (1 << 3) |
Functions | |
void | __attribute__ ((format(printf, 2, 3))) astman_append(struct mansession *s |
int | __attribute__ ((format(printf, 3, 4))) manager_event(int category |
int | ast_manager_register2 (const char *action, int authority, 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 | |
int | ast_manager_unregister (char *action) |
int const char const char const char * | astman_get_header (const struct message *m, char *var) |
struct 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. | |
void const char int | init_manager (void) |
int | reload_manager (void) |
Variables | |
int const char const char * | contents |
int const char * | event |
void const char * | fmt |
Manager protocol packages are text fields of the form a: b. There is always exactly one space after the colon.
The first header type is the "Event" header. Other headers vary from event to event. Headers end with standard
termination. The last line of the manager response or event is an empty line. (
)
Please try to re-use existing headers to simplify manager message parsing in clients. Don't re-use an existing header with a new meaning, please. You can find a reference of standard headers in doc/manager.txt
Definition in file manager.h.
#define ast_manager_register | ( | a, | |||
b, | |||||
c, | |||||
d | ) | ast_manager_register2(a, b, c, d, NULL) |
Definition at line 86 of file manager.h.
Referenced by astdb_init(), init_manager(), and load_module().
#define AST_MAX_MANHEADERS 128 |
#define DEFAULT_MANAGER_PORT 5038 |
#define EVENT_FLAG_AGENT (1 << 5) |
Definition at line 55 of file manager.h.
Referenced by __login_exec(), action_agent_callback_login(), add_to_queue(), agent_logoff_maintenance(), handle_statechange(), load_module(), record_abandoned(), remove_from_queue(), ring_entry(), set_member_paused(), try_calling(), and update_status().
#define EVENT_FLAG_CALL (1 << 1) |
Definition at line 51 of file manager.h.
Referenced by ast_autoanswer_login(), ast_change_name(), ast_channel_alloc(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_hold_call(), ast_monitor_stop(), ast_set_callerid(), ast_setstate_and_cid(), autoanswer_exec(), change_hold_state(), conf_run(), do_autoanswer_thread(), fast_originate(), init_manager(), join_queue(), leave_queue(), load_module(), manager_log(), notify_new_message(), park_call_full(), park_exec(), pbx_extension_helper(), post_manager_event(), realtime_exec(), senddialevent(), socket_process(), and vm_execmain().
#define EVENT_FLAG_COMMAND (1 << 4) |
#define EVENT_FLAG_CONFIG (1 << 7) |
#define EVENT_FLAG_EXTENSIONSTATUS (1 << 8) |
#define EVENT_FLAG_SYSTEM (1 << 0) |
Definition at line 50 of file manager.h.
Referenced by __expire_registry(), __iax2_poke_noanswer(), ast_log(), astdb_init(), expire_register(), handle_init_event(), handle_response_peerpoke(), handle_response_register(), iax2_ack_registry(), load_module(), parse_register_contact(), quit_handler(), register_verify(), reload_config(), reload_logger(), reload_manager(), sip_poke_noanswer(), sip_reg_timeout(), socket_process(), ss_thread(), update_registry(), and zt_handle_event().
#define EVENT_FLAG_USER (1 << 6) |
Definition at line 56 of file manager.h.
Referenced by action_userevent(), aji_log_hook(), init_manager(), and userevent_exec().
void __attribute__ | ( | (format(printf, 2, 3)) | ) |
int __attribute__ | ( | (format(printf, 3, 4)) | ) |
External routines may send asterisk manager events this way
category | Event category, matches manager authorization | |
event | Event name | |
contents | Contents of event |
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 2676 of file manager.c.
References mansession::__lock, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), mansession::managerid, mansession::readperm, and s.
02677 { 02678 int result = 0; 02679 struct mansession *s; 02680 02681 AST_LIST_LOCK(&sessions); 02682 AST_LIST_TRAVERSE(&sessions, s, list) { 02683 ast_mutex_lock(&s->__lock); 02684 if ((s->managerid == ident) && (s->readperm & perm)) { 02685 result = 1; 02686 ast_mutex_unlock(&s->__lock); 02687 break; 02688 } 02689 ast_mutex_unlock(&s->__lock); 02690 } 02691 AST_LIST_UNLOCK(&sessions); 02692 return result; 02693 }
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 2695 of file manager.c.
References mansession::__lock, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), mansession::managerid, s, and mansession::writeperm.
02696 { 02697 int result = 0; 02698 struct mansession *s; 02699 02700 AST_LIST_LOCK(&sessions); 02701 AST_LIST_TRAVERSE(&sessions, s, list) { 02702 ast_mutex_lock(&s->__lock); 02703 if ((s->managerid == ident) && (s->writeperm & perm)) { 02704 result = 1; 02705 ast_mutex_unlock(&s->__lock); 02706 break; 02707 } 02708 ast_mutex_unlock(&s->__lock); 02709 } 02710 AST_LIST_UNLOCK(&sessions); 02711 return result; 02712 }
void const char int init_manager | ( | void | ) |
Called by Asterisk initialization
Definition at line 2909 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_message(), action_originate(), action_ping(), action_redirect(), action_setvar(), action_status(), action_timeout(), action_updateconfig(), action_userevent(), action_waitevent(), append_event(), 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(), DEFAULT_MANAGER_PORT, ast_manager_user::deny, ast_manager_user::displayconnects, errno, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, EVENT_FLAG_CONFIG, EVENT_FLAG_USER, ast_channel::flags, free, ast_manager_user::keep, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_state_cb(), ast_variable::name, ast_variable::next, option_verbose, ast_manager_user::permit, ast_manager_user::read, ast_manager_user::secret, ast_manager_user::username, users, ast_variable::value, var, and ast_manager_user::write.
Referenced by main(), and reload_manager().
02910 { 02911 struct ast_config *cfg = NULL; 02912 const char *val; 02913 char *cat = NULL; 02914 int oldportno = portno; 02915 static struct sockaddr_in ba; 02916 int x = 1; 02917 int flags; 02918 int webenabled = 0; 02919 int newhttptimeout = 60; 02920 struct ast_manager_user *user = NULL; 02921 02922 if (!registered) { 02923 /* Register default actions */ 02924 ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping); 02925 ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events); 02926 ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff); 02927 ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup); 02928 ast_manager_register2("Message", EVENT_FLAG_CALL, action_message, "Send Message", mandescr_message); 02929 ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" ); 02930 ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar ); 02931 ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar ); 02932 ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig); 02933 ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig); 02934 ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect ); 02935 ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate); 02936 ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command ); 02937 ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate ); 02938 ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout ); 02939 ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus ); 02940 ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount ); 02941 ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands); 02942 ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent); 02943 ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent); 02944 02945 ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry)); 02946 ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); 02947 registered = 1; 02948 /* Append placeholder event so master_eventq never runs dry */ 02949 append_event("Event: Placeholder\r\n\r\n", 0); 02950 } 02951 portno = DEFAULT_MANAGER_PORT; 02952 displayconnects = 1; 02953 cfg = ast_config_load("manager.conf"); 02954 if (!cfg) { 02955 ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n"); 02956 return 0; 02957 } 02958 val = ast_variable_retrieve(cfg, "general", "enabled"); 02959 if (val) 02960 enabled = ast_true(val); 02961 02962 val = ast_variable_retrieve(cfg, "general", "block-sockets"); 02963 if (val) 02964 block_sockets = ast_true(val); 02965 02966 val = ast_variable_retrieve(cfg, "general", "webenabled"); 02967 if (val) 02968 webenabled = ast_true(val); 02969 02970 if ((val = ast_variable_retrieve(cfg, "general", "port"))) { 02971 if (sscanf(val, "%d", &portno) != 1) { 02972 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val); 02973 portno = DEFAULT_MANAGER_PORT; 02974 } 02975 } 02976 02977 if ((val = ast_variable_retrieve(cfg, "general", "displayconnects"))) 02978 displayconnects = ast_true(val); 02979 02980 if ((val = ast_variable_retrieve(cfg, "general", "timestampevents"))) 02981 timestampevents = ast_true(val); 02982 02983 if ((val = ast_variable_retrieve(cfg, "general", "httptimeout"))) 02984 newhttptimeout = atoi(val); 02985 02986 memset(&ba, 0, sizeof(ba)); 02987 ba.sin_family = AF_INET; 02988 ba.sin_port = htons(portno); 02989 02990 if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) { 02991 if (!inet_aton(val, &ba.sin_addr)) { 02992 ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); 02993 memset(&ba.sin_addr, 0, sizeof(ba.sin_addr)); 02994 } 02995 } 02996 02997 02998 if ((asock > -1) && ((portno != oldportno) || !enabled)) { 02999 #if 0 03000 /* Can't be done yet */ 03001 close(asock); 03002 asock = -1; 03003 #else 03004 ast_log(LOG_WARNING, "Unable to change management port / enabled\n"); 03005 #endif 03006 } 03007 03008 AST_LIST_LOCK(&users); 03009 03010 while ((cat = ast_category_browse(cfg, cat))) { 03011 struct ast_variable *var = NULL; 03012 03013 if (!strcasecmp(cat, "general")) 03014 continue; 03015 03016 /* Look for an existing entry, if none found - create one and add it to the list */ 03017 if (!(user = ast_get_manager_by_name_locked(cat))) { 03018 if (!(user = ast_calloc(1, sizeof(*user)))) 03019 break; 03020 /* Copy name over */ 03021 ast_copy_string(user->username, cat, sizeof(user->username)); 03022 /* Insert into list */ 03023 AST_LIST_INSERT_TAIL(&users, user, list); 03024 } 03025 03026 /* Make sure we keep this user and don't destroy it during cleanup */ 03027 user->keep = 1; 03028 03029 var = ast_variable_browse(cfg, cat); 03030 while (var) { 03031 if (!strcasecmp(var->name, "secret")) { 03032 if (user->secret) 03033 free(user->secret); 03034 user->secret = ast_strdup(var->value); 03035 } else if (!strcasecmp(var->name, "deny") ) { 03036 if (user->deny) 03037 free(user->deny); 03038 user->deny = ast_strdup(var->value); 03039 } else if (!strcasecmp(var->name, "permit") ) { 03040 if (user->permit) 03041 free(user->permit); 03042 user->permit = ast_strdup(var->value); 03043 } else if (!strcasecmp(var->name, "read") ) { 03044 if (user->read) 03045 free(user->read); 03046 user->read = ast_strdup(var->value); 03047 } else if (!strcasecmp(var->name, "write") ) { 03048 if (user->write) 03049 free(user->write); 03050 user->write = ast_strdup(var->value); 03051 } else if (!strcasecmp(var->name, "displayconnects") ) 03052 user->displayconnects = ast_true(var->value); 03053 else 03054 ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name); 03055 var = var->next; 03056 } 03057 } 03058 03059 /* Perform cleanup - essentially prune out old users that no longer exist */ 03060 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) { 03061 if (user->keep) { 03062 user->keep = 0; 03063 continue; 03064 } 03065 /* We do not need to keep this user so take them out of the list */ 03066 AST_LIST_REMOVE_CURRENT(&users, list); 03067 /* Free their memory now */ 03068 if (user->secret) 03069 free(user->secret); 03070 if (user->deny) 03071 free(user->deny); 03072 if (user->permit) 03073 free(user->permit); 03074 if (user->read) 03075 free(user->read); 03076 if (user->write) 03077 free(user->write); 03078 free(user); 03079 } 03080 AST_LIST_TRAVERSE_SAFE_END 03081 03082 AST_LIST_UNLOCK(&users); 03083 03084 ast_config_destroy(cfg); 03085 03086 if (webenabled && enabled) { 03087 if (!webregged) { 03088 ast_http_uri_link(&rawmanuri); 03089 ast_http_uri_link(&manageruri); 03090 ast_http_uri_link(&managerxmluri); 03091 webregged = 1; 03092 } 03093 } else { 03094 if (webregged) { 03095 ast_http_uri_unlink(&rawmanuri); 03096 ast_http_uri_unlink(&manageruri); 03097 ast_http_uri_unlink(&managerxmluri); 03098 webregged = 0; 03099 } 03100 } 03101 03102 if (newhttptimeout > 0) 03103 httptimeout = newhttptimeout; 03104 03105 /* If not enabled, do nothing */ 03106 if (!enabled) 03107 return 0; 03108 03109 if (asock < 0) { 03110 asock = socket(AF_INET, SOCK_STREAM, 0); 03111 if (asock < 0) { 03112 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 03113 return -1; 03114 } 03115 setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 03116 if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) { 03117 ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno)); 03118 close(asock); 03119 asock = -1; 03120 return -1; 03121 } 03122 if (listen(asock, 2)) { 03123 ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno)); 03124 close(asock); 03125 asock = -1; 03126 return -1; 03127 } 03128 flags = fcntl(asock, F_GETFL); 03129 fcntl(asock, F_SETFL, flags | O_NONBLOCK); 03130 if (option_verbose) 03131 ast_verbose("Asterisk Management interface listening on port %d\n", portno); 03132 ast_pthread_create_background(&t, NULL, accept_thread, NULL); 03133 } 03134 return 0; 03135 }
int reload_manager | ( | void | ) |
Definition at line 3137 of file manager.c.
References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().
03138 { 03139 manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n"); 03140 return init_manager(); 03141 }
int const char* event |
Definition at line 130 of file manager.h.
Referenced by action_userevent(), adsi_process(), ast_rtp_read(), handle_event_nt(), handle_frm(), handle_request_info(), handle_request_notify(), handle_request_subscribe(), handle_soft_key_event_message(), handle_stimulus_message(), onevent(), process_cisco_dtmf(), process_rfc2833(), ql_exec(), receive_ademco_contact_id(), sla_queue_event_full(), and sla_thread().
void const char* fmt |
Definition at line 143 of file manager.h.
Referenced by __oh323_new(), ast_cdr_getvar(), ast_cli_netstats(), ast_openvstream(), ast_request_with_uniqueid(), ast_streamfile(), check_header(), do_say(), gtalk_new(), iax2_request(), local_new(), mgcp_new(), setformat(), sip_new(), skinny_new(), try_suggested_sip_codec(), and write_header().