#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/lock.h"
Include dependency graph for manager.h:
This graph shows which files directly or indirectly include this file:
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) |
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 (uint32_t ident, int perm) |
Verify a session's read permissions against a permission mask. | |
int | astman_verify_session_writepermissions (uint32_t 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(), 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_hold_call(), ast_monitor_stop(), autoanswer_exec(), bridge_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_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)) | ) |
category | Event category, matches manager authorization | |
event | Event name | |
contents | Contents of event |
int astman_verify_session_readpermissions | ( | uint32_t | ident, | |
int | perm | |||
) |
Verify a session's read permissions against a permission mask.
ident | session identity | |
perm | permission mask to verify |
Definition at line 2739 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), s, and sessions.
02740 { 02741 int result = 0; 02742 struct mansession *s; 02743 02744 AST_LIST_LOCK(&sessions); 02745 AST_LIST_TRAVERSE(&sessions, s, list) { 02746 ast_mutex_lock(&s->__lock); 02747 if ((s->managerid == ident) && (s->readperm & perm)) { 02748 result = 1; 02749 ast_mutex_unlock(&s->__lock); 02750 break; 02751 } 02752 ast_mutex_unlock(&s->__lock); 02753 } 02754 AST_LIST_UNLOCK(&sessions); 02755 return result; 02756 }
int astman_verify_session_writepermissions | ( | uint32_t | ident, | |
int | perm | |||
) |
Verify a session's write permissions against a permission mask.
ident | session identity | |
perm | permission mask to verify |
Definition at line 2758 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), s, and sessions.
02759 { 02760 int result = 0; 02761 struct mansession *s; 02762 02763 AST_LIST_LOCK(&sessions); 02764 AST_LIST_TRAVERSE(&sessions, s, list) { 02765 ast_mutex_lock(&s->__lock); 02766 if ((s->managerid == ident) && (s->writeperm & perm)) { 02767 result = 1; 02768 ast_mutex_unlock(&s->__lock); 02769 break; 02770 } 02771 ast_mutex_unlock(&s->__lock); 02772 } 02773 AST_LIST_UNLOCK(&sessions); 02774 return result; 02775 }
void const char int init_manager | ( | void | ) |
Called by Asterisk initialization
Definition at line 2977 of file manager.c.
References 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(), asock, ast_calloc, ast_category_browse(), ast_cli_register_multiple(), ast_config_load(), ast_extension_state_add(), ast_get_manager_by_name_locked(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, ast_log(), ast_manager_register, ast_manager_register2(), ast_strdup, ast_true(), ast_variable_browse(), ast_variable_retrieve(), block_sockets, cli_manager, DEFAULT_MANAGER_PORT, ast_manager_user::deny, ast_manager_user::displayconnects, displayconnects, enabled, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, EVENT_FLAG_CONFIG, EVENT_FLAG_USER, ast_channel::flags, free, ast_manager_user::keep, LOG_DEBUG, LOG_WARNING, manager_state_cb(), ast_manager_user::permit, portno, ast_manager_user::read, ast_manager_user::secret, timestampevents, users, var, and ast_manager_user::write.
Referenced by main(), and reload_manager().
02978 { 02979 struct ast_config *cfg = NULL, *ucfg = NULL; 02980 const char *val; 02981 char *cat = NULL; 02982 int oldportno = portno; 02983 static struct sockaddr_in ba; 02984 int x = 1; 02985 int flags; 02986 int webenabled = 0; 02987 int newhttptimeout = 60; 02988 struct ast_manager_user *user = NULL; 02989 02990 if (!registered) { 02991 /* Register default actions */ 02992 ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping); 02993 ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events); 02994 ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff); 02995 ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup); 02996 ast_manager_register2("Message", EVENT_FLAG_CALL, action_message, "Send Message", mandescr_message); 02997 ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" ); 02998 ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar ); 02999 ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar ); 03000 ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig); 03001 ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig); 03002 ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect ); 03003 ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate); 03004 ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command ); 03005 ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate ); 03006 ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout ); 03007 ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus ); 03008 ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount ); 03009 ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands); 03010 ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent); 03011 ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent); 03012 03013 ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry)); 03014 ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); 03015 registered = 1; 03016 /* Append placeholder event so master_eventq never runs dry */ 03017 append_event("Event: Placeholder\r\n\r\n", 0); 03018 } 03019 portno = DEFAULT_MANAGER_PORT; 03020 displayconnects = 1; 03021 cfg = ast_config_load("manager.conf"); 03022 if (!cfg) { 03023 ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n"); 03024 return 0; 03025 } 03026 val = ast_variable_retrieve(cfg, "general", "enabled"); 03027 if (val) 03028 enabled = ast_true(val); 03029 03030 val = ast_variable_retrieve(cfg, "general", "block-sockets"); 03031 if (val) 03032 block_sockets = ast_true(val); 03033 03034 val = ast_variable_retrieve(cfg, "general", "webenabled"); 03035 if (val) 03036 webenabled = ast_true(val); 03037 03038 if ((val = ast_variable_retrieve(cfg, "general", "port"))) { 03039 if (sscanf(val, "%d", &portno) != 1) { 03040 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val); 03041 portno = DEFAULT_MANAGER_PORT; 03042 } 03043 } 03044 03045 if ((val = ast_variable_retrieve(cfg, "general", "displayconnects"))) 03046 displayconnects = ast_true(val); 03047 03048 if ((val = ast_variable_retrieve(cfg, "general", "timestampevents"))) 03049 timestampevents = ast_true(val); 03050 03051 if ((val = ast_variable_retrieve(cfg, "general", "httptimeout"))) 03052 newhttptimeout = atoi(val); 03053 03054 memset(&ba, 0, sizeof(ba)); 03055 ba.sin_family = AF_INET; 03056 ba.sin_port = htons(portno); 03057 03058 if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) { 03059 if (!inet_aton(val, &ba.sin_addr)) { 03060 ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); 03061 memset(&ba.sin_addr, 0, sizeof(ba.sin_addr)); 03062 } 03063 } 03064 03065 03066 if ((asock > -1) && ((portno != oldportno) || !enabled)) { 03067 #if 0 03068 /* Can't be done yet */ 03069 close(asock); 03070 asock = -1; 03071 #else 03072 ast_log(LOG_WARNING, "Unable to change management port / enabled\n"); 03073 #endif 03074 } 03075 03076 AST_LIST_LOCK(&users); 03077 03078 if ((ucfg = ast_config_load("users.conf"))) { 03079 while ((cat = ast_category_browse(ucfg, cat))) { 03080 int hasmanager = 0; 03081 struct ast_variable *var = NULL; 03082 03083 if (!strcasecmp(cat, "general")) { 03084 continue; 03085 } 03086 03087 if (!(hasmanager = ast_true(ast_variable_retrieve(ucfg, cat, "hasmanager")))) { 03088 continue; 03089 } 03090 03091 /* Look for an existing entry, if none found - create one and add it to the list */ 03092 if (!(user = ast_get_manager_by_name_locked(cat))) { 03093 if (!(user = ast_calloc(1, sizeof(*user)))) { 03094 break; 03095 } 03096 /* Copy name over */ 03097 ast_copy_string(user->username, cat, sizeof(user->username)); 03098 /* Insert into list */ 03099 AST_LIST_INSERT_TAIL(&users, user, list); 03100 } 03101 03102 /* Make sure we keep this user and don't destroy it during cleanup */ 03103 user->keep = 1; 03104 03105 for (var = ast_variable_browse(ucfg, cat); var; var = var->next) { 03106 if (!strcasecmp(var->name, "secret")) { 03107 if (user->secret) { 03108 free(user->secret); 03109 } 03110 user->secret = ast_strdup(var->value); 03111 } else if (!strcasecmp(var->name, "deny") ) { 03112 if (user->deny) { 03113 free(user->deny); 03114 } 03115 user->deny = ast_strdup(var->value); 03116 } else if (!strcasecmp(var->name, "permit") ) { 03117 if (user->permit) { 03118 free(user->permit); 03119 } 03120 user->permit = ast_strdup(var->value); 03121 } else if (!strcasecmp(var->name, "read") ) { 03122 if (user->read) { 03123 free(user->read); 03124 } 03125 user->read = ast_strdup(var->value); 03126 } else if (!strcasecmp(var->name, "write") ) { 03127 if (user->write) { 03128 free(user->write); 03129 } 03130 user->write = ast_strdup(var->value); 03131 } else if (!strcasecmp(var->name, "displayconnects") ) { 03132 user->displayconnects = ast_true(var->value); 03133 } else if (!strcasecmp(var->name, "hasmanager")) { 03134 /* already handled */ 03135 } else { 03136 ast_log(LOG_DEBUG, "%s is an unknown option (to the manager module).\n", var->name); 03137 } 03138 } 03139 } 03140 ast_config_destroy(ucfg); 03141 } 03142 03143 while ((cat = ast_category_browse(cfg, cat))) { 03144 struct ast_variable *var = NULL; 03145 03146 if (!strcasecmp(cat, "general")) 03147 continue; 03148 03149 /* Look for an existing entry, if none found - create one and add it to the list */ 03150 if (!(user = ast_get_manager_by_name_locked(cat))) { 03151 if (!(user = ast_calloc(1, sizeof(*user)))) 03152 break; 03153 /* Copy name over */ 03154 ast_copy_string(user->username, cat, sizeof(user->username)); 03155 /* Insert into list */ 03156 AST_LIST_INSERT_TAIL(&users, user, list); 03157 } 03158 03159 /* Make sure we keep this user and don't destroy it during cleanup */ 03160 user->keep = 1; 03161 03162 var = ast_variable_browse(cfg, cat); 03163 while (var) { 03164 if (!strcasecmp(var->name, "secret")) { 03165 if (user->secret) 03166 free(user->secret); 03167 user->secret = ast_strdup(var->value); 03168 } else if (!strcasecmp(var->name, "deny") ) { 03169 if (user->deny) 03170 free(user->deny); 03171 user->deny = ast_strdup(var->value); 03172 } else if (!strcasecmp(var->name, "permit") ) { 03173 if (user->permit) 03174 free(user->permit); 03175 user->permit = ast_strdup(var->value); 03176 } else if (!strcasecmp(var->name, "read") ) { 03177 if (user->read) 03178 free(user->read); 03179 user->read = ast_strdup(var->value); 03180 } else if (!strcasecmp(var->name, "write") ) { 03181 if (user->write) 03182 free(user->write); 03183 user->write = ast_strdup(var->value); 03184 } else if (!strcasecmp(var->name, "displayconnects") ) 03185 user->displayconnects = ast_true(var->value); 03186 else 03187 ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name); 03188 var = var->next; 03189 } 03190 } 03191 03192 /* Perform cleanup - essentially prune out old users that no longer exist */ 03193 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) { 03194 if (user->keep) { 03195 user->keep = 0; 03196 continue; 03197 } 03198 /* We do not need to keep this user so take them out of the list */ 03199 AST_LIST_REMOVE_CURRENT(&users, list); 03200 /* Free their memory now */ 03201 if (user->secret) 03202 free(user->secret); 03203 if (user->deny) 03204 free(user->deny); 03205 if (user->permit) 03206 free(user->permit); 03207 if (user->read) 03208 free(user->read); 03209 if (user->write) 03210 free(user->write); 03211 free(user); 03212 } 03213 AST_LIST_TRAVERSE_SAFE_END 03214 03215 AST_LIST_UNLOCK(&users); 03216 03217 ast_config_destroy(cfg); 03218 03219 if (webenabled && enabled) { 03220 if (!webregged) { 03221 ast_http_uri_link(&rawmanuri); 03222 ast_http_uri_link(&manageruri); 03223 ast_http_uri_link(&managerxmluri); 03224 webregged = 1; 03225 } 03226 } else { 03227 if (webregged) { 03228 ast_http_uri_unlink(&rawmanuri); 03229 ast_http_uri_unlink(&manageruri); 03230 ast_http_uri_unlink(&managerxmluri); 03231 webregged = 0; 03232 } 03233 } 03234 03235 if (newhttptimeout > 0) 03236 httptimeout = newhttptimeout; 03237 03238 /* If not enabled, do nothing */ 03239 if (!enabled) 03240 return 0; 03241 03242 if (asock < 0) { 03243 asock = socket(AF_INET, SOCK_STREAM, 0); 03244 if (asock < 0) { 03245 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 03246 return -1; 03247 } 03248 setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 03249 if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) { 03250 ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno)); 03251 close(asock); 03252 asock = -1; 03253 return -1; 03254 } 03255 if (listen(asock, 2)) { 03256 ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno)); 03257 close(asock); 03258 asock = -1; 03259 return -1; 03260 } 03261 flags = fcntl(asock, F_GETFL); 03262 fcntl(asock, F_SETFL, flags | O_NONBLOCK); 03263 if (option_verbose) 03264 ast_verbose("Asterisk Management interface listening on port %d\n", portno); 03265 ast_pthread_create_background(&t, NULL, accept_thread, NULL); 03266 } 03267 return 0; 03268 }
int reload_manager | ( | void | ) |
Definition at line 3270 of file manager.c.
References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().
03271 { 03272 manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n"); 03273 return init_manager(); 03274 }
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(), log_events(), onevent(), process_cisco_dtmf(), process_rfc2833(), ql_exec(), receive_ademco_contact_id(), sla_handle_hold_event(), sla_queue_event_full(), sla_thread(), and write_event().
void const char* fmt |
Definition at line 143 of file manager.h.
Referenced by __oh323_new(), add_codec_to_sdp(), ast_cdr_getvar(), ast_cli_netstats(), ast_codec_pref_getsize(), ast_openvstream(), ast_request_with_uniqueid(), ast_rtp_write(), ast_streamfile(), check_header(), get_filestream(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), local_new(), mgcp_new(), setformat(), sip_new(), skinny_new(), transmit_connect(), try_suggested_sip_codec(), and write_header().