#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 2914 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().
02915 { 02916 struct ast_config *cfg = NULL; 02917 const char *val; 02918 char *cat = NULL; 02919 int oldportno = portno; 02920 static struct sockaddr_in ba; 02921 int x = 1; 02922 int flags; 02923 int webenabled = 0; 02924 int newhttptimeout = 60; 02925 struct ast_manager_user *user = NULL; 02926 02927 if (!registered) { 02928 /* Register default actions */ 02929 ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping); 02930 ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events); 02931 ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff); 02932 ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup); 02933 ast_manager_register2("Message", EVENT_FLAG_CALL, action_message, "Send Message", mandescr_message); 02934 ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" ); 02935 ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar ); 02936 ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar ); 02937 ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig); 02938 ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig); 02939 ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect ); 02940 ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate); 02941 ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command ); 02942 ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate ); 02943 ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout ); 02944 ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus ); 02945 ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount ); 02946 ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands); 02947 ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent); 02948 ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent); 02949 02950 ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry)); 02951 ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); 02952 registered = 1; 02953 /* Append placeholder event so master_eventq never runs dry */ 02954 append_event("Event: Placeholder\r\n\r\n", 0); 02955 } 02956 portno = DEFAULT_MANAGER_PORT; 02957 displayconnects = 1; 02958 cfg = ast_config_load("manager.conf"); 02959 if (!cfg) { 02960 ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n"); 02961 return 0; 02962 } 02963 val = ast_variable_retrieve(cfg, "general", "enabled"); 02964 if (val) 02965 enabled = ast_true(val); 02966 02967 val = ast_variable_retrieve(cfg, "general", "block-sockets"); 02968 if (val) 02969 block_sockets = ast_true(val); 02970 02971 val = ast_variable_retrieve(cfg, "general", "webenabled"); 02972 if (val) 02973 webenabled = ast_true(val); 02974 02975 if ((val = ast_variable_retrieve(cfg, "general", "port"))) { 02976 if (sscanf(val, "%d", &portno) != 1) { 02977 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val); 02978 portno = DEFAULT_MANAGER_PORT; 02979 } 02980 } 02981 02982 if ((val = ast_variable_retrieve(cfg, "general", "displayconnects"))) 02983 displayconnects = ast_true(val); 02984 02985 if ((val = ast_variable_retrieve(cfg, "general", "timestampevents"))) 02986 timestampevents = ast_true(val); 02987 02988 if ((val = ast_variable_retrieve(cfg, "general", "httptimeout"))) 02989 newhttptimeout = atoi(val); 02990 02991 memset(&ba, 0, sizeof(ba)); 02992 ba.sin_family = AF_INET; 02993 ba.sin_port = htons(portno); 02994 02995 if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) { 02996 if (!inet_aton(val, &ba.sin_addr)) { 02997 ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); 02998 memset(&ba.sin_addr, 0, sizeof(ba.sin_addr)); 02999 } 03000 } 03001 03002 03003 if ((asock > -1) && ((portno != oldportno) || !enabled)) { 03004 #if 0 03005 /* Can't be done yet */ 03006 close(asock); 03007 asock = -1; 03008 #else 03009 ast_log(LOG_WARNING, "Unable to change management port / enabled\n"); 03010 #endif 03011 } 03012 03013 AST_LIST_LOCK(&users); 03014 03015 while ((cat = ast_category_browse(cfg, cat))) { 03016 struct ast_variable *var = NULL; 03017 03018 if (!strcasecmp(cat, "general")) 03019 continue; 03020 03021 /* Look for an existing entry, if none found - create one and add it to the list */ 03022 if (!(user = ast_get_manager_by_name_locked(cat))) { 03023 if (!(user = ast_calloc(1, sizeof(*user)))) 03024 break; 03025 /* Copy name over */ 03026 ast_copy_string(user->username, cat, sizeof(user->username)); 03027 /* Insert into list */ 03028 AST_LIST_INSERT_TAIL(&users, user, list); 03029 } 03030 03031 /* Make sure we keep this user and don't destroy it during cleanup */ 03032 user->keep = 1; 03033 03034 var = ast_variable_browse(cfg, cat); 03035 while (var) { 03036 if (!strcasecmp(var->name, "secret")) { 03037 if (user->secret) 03038 free(user->secret); 03039 user->secret = ast_strdup(var->value); 03040 } else if (!strcasecmp(var->name, "deny") ) { 03041 if (user->deny) 03042 free(user->deny); 03043 user->deny = ast_strdup(var->value); 03044 } else if (!strcasecmp(var->name, "permit") ) { 03045 if (user->permit) 03046 free(user->permit); 03047 user->permit = ast_strdup(var->value); 03048 } else if (!strcasecmp(var->name, "read") ) { 03049 if (user->read) 03050 free(user->read); 03051 user->read = ast_strdup(var->value); 03052 } else if (!strcasecmp(var->name, "write") ) { 03053 if (user->write) 03054 free(user->write); 03055 user->write = ast_strdup(var->value); 03056 } else if (!strcasecmp(var->name, "displayconnects") ) 03057 user->displayconnects = ast_true(var->value); 03058 else 03059 ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name); 03060 var = var->next; 03061 } 03062 } 03063 03064 /* Perform cleanup - essentially prune out old users that no longer exist */ 03065 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) { 03066 if (user->keep) { 03067 user->keep = 0; 03068 continue; 03069 } 03070 /* We do not need to keep this user so take them out of the list */ 03071 AST_LIST_REMOVE_CURRENT(&users, list); 03072 /* Free their memory now */ 03073 if (user->secret) 03074 free(user->secret); 03075 if (user->deny) 03076 free(user->deny); 03077 if (user->permit) 03078 free(user->permit); 03079 if (user->read) 03080 free(user->read); 03081 if (user->write) 03082 free(user->write); 03083 free(user); 03084 } 03085 AST_LIST_TRAVERSE_SAFE_END 03086 03087 AST_LIST_UNLOCK(&users); 03088 03089 ast_config_destroy(cfg); 03090 03091 if (webenabled && enabled) { 03092 if (!webregged) { 03093 ast_http_uri_link(&rawmanuri); 03094 ast_http_uri_link(&manageruri); 03095 ast_http_uri_link(&managerxmluri); 03096 webregged = 1; 03097 } 03098 } else { 03099 if (webregged) { 03100 ast_http_uri_unlink(&rawmanuri); 03101 ast_http_uri_unlink(&manageruri); 03102 ast_http_uri_unlink(&managerxmluri); 03103 webregged = 0; 03104 } 03105 } 03106 03107 if (newhttptimeout > 0) 03108 httptimeout = newhttptimeout; 03109 03110 /* If not enabled, do nothing */ 03111 if (!enabled) 03112 return 0; 03113 03114 if (asock < 0) { 03115 asock = socket(AF_INET, SOCK_STREAM, 0); 03116 if (asock < 0) { 03117 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 03118 return -1; 03119 } 03120 setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 03121 if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) { 03122 ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno)); 03123 close(asock); 03124 asock = -1; 03125 return -1; 03126 } 03127 if (listen(asock, 2)) { 03128 ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno)); 03129 close(asock); 03130 asock = -1; 03131 return -1; 03132 } 03133 flags = fcntl(asock, F_GETFL); 03134 fcntl(asock, F_SETFL, flags | O_NONBLOCK); 03135 if (option_verbose) 03136 ast_verbose("Asterisk Management interface listening on port %d\n", portno); 03137 ast_pthread_create_background(&t, NULL, accept_thread, NULL); 03138 } 03139 return 0; 03140 }
int reload_manager | ( | void | ) |
Definition at line 3142 of file manager.c.
References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().
03143 { 03144 manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n"); 03145 return init_manager(); 03146 }
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().