#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_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 85 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_change_name(), ast_channel_alloc(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_set_callerid(), ast_setstate(), change_hold_state(), conf_run(), fast_originate(), init_manager(), join_queue(), leave_queue(), load_module(), manager_log(), manager_state_cb(), 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_SYSTEM (1 << 0) |
Definition at line 50 of file manager.h.
Referenced by __expire_registry(), __iax2_poke_noanswer(), ast_log(), astdb_init(), dahdi_handle_event(), expire_register(), handle_alarms(), 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(), and update_registry().
| #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 2656 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), s, and sessions.
02657 { 02658 int result = 0; 02659 struct mansession *s; 02660 02661 AST_LIST_LOCK(&sessions); 02662 AST_LIST_TRAVERSE(&sessions, s, list) { 02663 ast_mutex_lock(&s->__lock); 02664 if ((s->managerid == ident) && (s->readperm & perm)) { 02665 result = 1; 02666 ast_mutex_unlock(&s->__lock); 02667 break; 02668 } 02669 ast_mutex_unlock(&s->__lock); 02670 } 02671 AST_LIST_UNLOCK(&sessions); 02672 return result; 02673 }
| 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 2675 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), s, and sessions.
02676 { 02677 int result = 0; 02678 struct mansession *s; 02679 02680 AST_LIST_LOCK(&sessions); 02681 AST_LIST_TRAVERSE(&sessions, s, list) { 02682 ast_mutex_lock(&s->__lock); 02683 if ((s->managerid == ident) && (s->writeperm & perm)) { 02684 result = 1; 02685 ast_mutex_unlock(&s->__lock); 02686 break; 02687 } 02688 ast_mutex_unlock(&s->__lock); 02689 } 02690 AST_LIST_UNLOCK(&sessions); 02691 return result; 02692 }
| void const char int init_manager | ( | void | ) |
Called by Asterisk initialization
Definition at line 2894 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_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().
02895 { 02896 struct ast_config *cfg = NULL, *ucfg = NULL; 02897 const char *val; 02898 char *cat = NULL; 02899 int oldportno = portno; 02900 static struct sockaddr_in ba; 02901 int x = 1; 02902 int flags; 02903 int webenabled = 0; 02904 int newhttptimeout = 60; 02905 struct ast_manager_user *user = NULL; 02906 02907 if (!registered) { 02908 /* Register default actions */ 02909 ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping); 02910 ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events); 02911 ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff); 02912 ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup); 02913 ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" ); 02914 ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar ); 02915 ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar ); 02916 ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig); 02917 ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig); 02918 ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect ); 02919 ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate); 02920 ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command ); 02921 ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate ); 02922 ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout ); 02923 ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus ); 02924 ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount ); 02925 ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands); 02926 ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent); 02927 ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent); 02928 02929 ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry)); 02930 ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); 02931 registered = 1; 02932 /* Append placeholder event so master_eventq never runs dry */ 02933 append_event("Event: Placeholder\r\n\r\n", 0); 02934 } 02935 portno = DEFAULT_MANAGER_PORT; 02936 displayconnects = 1; 02937 cfg = ast_config_load("manager.conf"); 02938 if (!cfg) { 02939 ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n"); 02940 return 0; 02941 } 02942 val = ast_variable_retrieve(cfg, "general", "enabled"); 02943 if (val) 02944 enabled = ast_true(val); 02945 02946 val = ast_variable_retrieve(cfg, "general", "block-sockets"); 02947 if (val) 02948 block_sockets = ast_true(val); 02949 02950 val = ast_variable_retrieve(cfg, "general", "webenabled"); 02951 if (val) 02952 webenabled = ast_true(val); 02953 02954 if ((val = ast_variable_retrieve(cfg, "general", "port"))) { 02955 if (sscanf(val, "%d", &portno) != 1) { 02956 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val); 02957 portno = DEFAULT_MANAGER_PORT; 02958 } 02959 } 02960 02961 if ((val = ast_variable_retrieve(cfg, "general", "displayconnects"))) 02962 displayconnects = ast_true(val); 02963 02964 if ((val = ast_variable_retrieve(cfg, "general", "timestampevents"))) 02965 timestampevents = ast_true(val); 02966 02967 if ((val = ast_variable_retrieve(cfg, "general", "httptimeout"))) 02968 newhttptimeout = atoi(val); 02969 02970 memset(&ba, 0, sizeof(ba)); 02971 ba.sin_family = AF_INET; 02972 ba.sin_port = htons(portno); 02973 02974 if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) { 02975 if (!inet_aton(val, &ba.sin_addr)) { 02976 ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); 02977 memset(&ba.sin_addr, 0, sizeof(ba.sin_addr)); 02978 } 02979 } 02980 02981 02982 if ((asock > -1) && ((portno != oldportno) || !enabled)) { 02983 #if 0 02984 /* Can't be done yet */ 02985 close(asock); 02986 asock = -1; 02987 #else 02988 ast_log(LOG_WARNING, "Unable to change management port / enabled\n"); 02989 #endif 02990 } 02991 02992 AST_LIST_LOCK(&users); 02993 02994 if ((ucfg = ast_config_load("users.conf"))) { 02995 while ((cat = ast_category_browse(ucfg, cat))) { 02996 int hasmanager = 0; 02997 struct ast_variable *var = NULL; 02998 02999 if (!strcasecmp(cat, "general")) { 03000 continue; 03001 } 03002 03003 if (!(hasmanager = ast_true(ast_variable_retrieve(ucfg, cat, "hasmanager")))) { 03004 continue; 03005 } 03006 03007 /* Look for an existing entry, if none found - create one and add it to the list */ 03008 if (!(user = ast_get_manager_by_name_locked(cat))) { 03009 if (!(user = ast_calloc(1, sizeof(*user)))) { 03010 break; 03011 } 03012 /* Copy name over */ 03013 ast_copy_string(user->username, cat, sizeof(user->username)); 03014 /* Insert into list */ 03015 AST_LIST_INSERT_TAIL(&users, user, list); 03016 } 03017 03018 /* Make sure we keep this user and don't destroy it during cleanup */ 03019 user->keep = 1; 03020 03021 for (var = ast_variable_browse(ucfg, cat); var; var = var->next) { 03022 if (!strcasecmp(var->name, "secret")) { 03023 if (user->secret) { 03024 free(user->secret); 03025 } 03026 user->secret = ast_strdup(var->value); 03027 } else if (!strcasecmp(var->name, "deny") ) { 03028 if (user->deny) { 03029 free(user->deny); 03030 } 03031 user->deny = ast_strdup(var->value); 03032 } else if (!strcasecmp(var->name, "permit") ) { 03033 if (user->permit) { 03034 free(user->permit); 03035 } 03036 user->permit = ast_strdup(var->value); 03037 } else if (!strcasecmp(var->name, "read") ) { 03038 if (user->read) { 03039 free(user->read); 03040 } 03041 user->read = ast_strdup(var->value); 03042 } else if (!strcasecmp(var->name, "write") ) { 03043 if (user->write) { 03044 free(user->write); 03045 } 03046 user->write = ast_strdup(var->value); 03047 } else if (!strcasecmp(var->name, "displayconnects") ) { 03048 user->displayconnects = ast_true(var->value); 03049 } else if (!strcasecmp(var->name, "hasmanager")) { 03050 /* already handled */ 03051 } else { 03052 ast_log(LOG_DEBUG, "%s is an unknown option (to the manager module).\n", var->name); 03053 } 03054 } 03055 } 03056 ast_config_destroy(ucfg); 03057 } 03058 03059 while ((cat = ast_category_browse(cfg, cat))) { 03060 struct ast_variable *var = NULL; 03061 03062 if (!strcasecmp(cat, "general")) 03063 continue; 03064 03065 /* Look for an existing entry, if none found - create one and add it to the list */ 03066 if (!(user = ast_get_manager_by_name_locked(cat))) { 03067 if (!(user = ast_calloc(1, sizeof(*user)))) 03068 break; 03069 /* Copy name over */ 03070 ast_copy_string(user->username, cat, sizeof(user->username)); 03071 /* Insert into list */ 03072 AST_LIST_INSERT_TAIL(&users, user, list); 03073 } 03074 03075 /* Make sure we keep this user and don't destroy it during cleanup */ 03076 user->keep = 1; 03077 03078 var = ast_variable_browse(cfg, cat); 03079 while (var) { 03080 if (!strcasecmp(var->name, "secret")) { 03081 if (user->secret) 03082 free(user->secret); 03083 user->secret = ast_strdup(var->value); 03084 } else if (!strcasecmp(var->name, "deny") ) { 03085 if (user->deny) 03086 free(user->deny); 03087 user->deny = ast_strdup(var->value); 03088 } else if (!strcasecmp(var->name, "permit") ) { 03089 if (user->permit) 03090 free(user->permit); 03091 user->permit = ast_strdup(var->value); 03092 } else if (!strcasecmp(var->name, "read") ) { 03093 if (user->read) 03094 free(user->read); 03095 user->read = ast_strdup(var->value); 03096 } else if (!strcasecmp(var->name, "write") ) { 03097 if (user->write) 03098 free(user->write); 03099 user->write = ast_strdup(var->value); 03100 } else if (!strcasecmp(var->name, "displayconnects") ) 03101 user->displayconnects = ast_true(var->value); 03102 else 03103 ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name); 03104 var = var->next; 03105 } 03106 } 03107 03108 /* Perform cleanup - essentially prune out old users that no longer exist */ 03109 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) { 03110 if (user->keep) { 03111 user->keep = 0; 03112 continue; 03113 } 03114 /* We do not need to keep this user so take them out of the list */ 03115 AST_LIST_REMOVE_CURRENT(&users, list); 03116 /* Free their memory now */ 03117 if (user->secret) 03118 free(user->secret); 03119 if (user->deny) 03120 free(user->deny); 03121 if (user->permit) 03122 free(user->permit); 03123 if (user->read) 03124 free(user->read); 03125 if (user->write) 03126 free(user->write); 03127 free(user); 03128 } 03129 AST_LIST_TRAVERSE_SAFE_END 03130 03131 AST_LIST_UNLOCK(&users); 03132 03133 ast_config_destroy(cfg); 03134 03135 if (webenabled && enabled) { 03136 if (!webregged) { 03137 ast_http_uri_link(&rawmanuri); 03138 ast_http_uri_link(&manageruri); 03139 ast_http_uri_link(&managerxmluri); 03140 webregged = 1; 03141 } 03142 } else { 03143 if (webregged) { 03144 ast_http_uri_unlink(&rawmanuri); 03145 ast_http_uri_unlink(&manageruri); 03146 ast_http_uri_unlink(&managerxmluri); 03147 webregged = 0; 03148 } 03149 } 03150 03151 if (newhttptimeout > 0) 03152 httptimeout = newhttptimeout; 03153 03154 /* If not enabled, do nothing */ 03155 if (!enabled) 03156 return 0; 03157 03158 if (asock < 0) { 03159 asock = socket(AF_INET, SOCK_STREAM, 0); 03160 if (asock < 0) { 03161 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 03162 return -1; 03163 } 03164 setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 03165 if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) { 03166 ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno)); 03167 close(asock); 03168 asock = -1; 03169 return -1; 03170 } 03171 if (listen(asock, 2)) { 03172 ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno)); 03173 close(asock); 03174 asock = -1; 03175 return -1; 03176 } 03177 flags = fcntl(asock, F_GETFL); 03178 fcntl(asock, F_SETFL, flags | O_NONBLOCK); 03179 if (option_verbose) 03180 ast_verbose("Asterisk Management interface listening on port %d\n", portno); 03181 ast_pthread_create_background(&t, NULL, accept_thread, NULL); 03182 } 03183 return 0; 03184 }
| int reload_manager | ( | void | ) |
Definition at line 3186 of file manager.c.
References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().
03187 { 03188 manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n"); 03189 return init_manager(); 03190 }
| int const char* event |
Definition at line 129 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 142 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(), 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().
1.5.1