#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 (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 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(), changethread(), 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_bridge(), ast_do_masquerade(), ast_hangup(), ast_park_call(), ast_set_callerid(), ast_setstate(), conf_run(), fast_originate(), init_manager(), join_queue(), leave_queue(), load_module(), manager_log(), manager_state_cb(), notify_new_message(), park_exec(), pbx_extension_helper(), phase_e_handler(), post_manager_event(), process_sdp(), 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(), 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 | ( | 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 2482 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), result, s, and sessions.
02483 { 02484 int result = 0; 02485 struct mansession *s; 02486 02487 AST_LIST_LOCK(&sessions); 02488 AST_LIST_TRAVERSE(&sessions, s, list) { 02489 ast_mutex_lock(&s->__lock); 02490 if ((s->managerid == ident) && (s->readperm & perm)) { 02491 result = 1; 02492 ast_mutex_unlock(&s->__lock); 02493 break; 02494 } 02495 ast_mutex_unlock(&s->__lock); 02496 } 02497 AST_LIST_UNLOCK(&sessions); 02498 return result; 02499 }
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 2501 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), result, s, and sessions.
02502 { 02503 int result = 0; 02504 struct mansession *s; 02505 02506 AST_LIST_LOCK(&sessions); 02507 AST_LIST_TRAVERSE(&sessions, s, list) { 02508 ast_mutex_lock(&s->__lock); 02509 if ((s->managerid == ident) && (s->writeperm & perm)) { 02510 result = 1; 02511 ast_mutex_unlock(&s->__lock); 02512 break; 02513 } 02514 ast_mutex_unlock(&s->__lock); 02515 } 02516 AST_LIST_UNLOCK(&sessions); 02517 return result; 02518 }
void const char int init_manager | ( | void | ) |
Called by Asterisk initialization
Definition at line 2715 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, ast_manager_user::displayconnects, displayconnects, enabled, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, EVENT_FLAG_CONFIG, EVENT_FLAG_USER, ast_channel::flags, 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().
02716 { 02717 struct ast_config *cfg = NULL; 02718 const char *val; 02719 char *cat = NULL; 02720 int oldportno = portno; 02721 static struct sockaddr_in ba; 02722 int x = 1; 02723 int flags; 02724 int webenabled = 0; 02725 int newhttptimeout = 60; 02726 struct ast_manager_user *user = NULL; 02727 02728 if (!registered) { 02729 /* Register default actions */ 02730 ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping); 02731 ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events); 02732 ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff); 02733 ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup); 02734 ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" ); 02735 ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar ); 02736 ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar ); 02737 ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig); 02738 ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig); 02739 ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect ); 02740 ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate); 02741 ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command ); 02742 ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate ); 02743 ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout ); 02744 ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus ); 02745 ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount ); 02746 ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands); 02747 ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent); 02748 ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent); 02749 02750 ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry)); 02751 ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); 02752 registered = 1; 02753 /* Append placeholder event so master_eventq never runs dry */ 02754 append_event("Event: Placeholder\r\n\r\n", 0); 02755 } 02756 portno = DEFAULT_MANAGER_PORT; 02757 displayconnects = 1; 02758 cfg = ast_config_load("manager.conf"); 02759 if (!cfg) { 02760 ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n"); 02761 return 0; 02762 } 02763 val = ast_variable_retrieve(cfg, "general", "enabled"); 02764 if (val) 02765 enabled = ast_true(val); 02766 02767 val = ast_variable_retrieve(cfg, "general", "block-sockets"); 02768 if (val) 02769 block_sockets = ast_true(val); 02770 02771 val = ast_variable_retrieve(cfg, "general", "webenabled"); 02772 if (val) 02773 webenabled = ast_true(val); 02774 02775 if ((val = ast_variable_retrieve(cfg, "general", "port"))) { 02776 if (sscanf(val, "%d", &portno) != 1) { 02777 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val); 02778 portno = DEFAULT_MANAGER_PORT; 02779 } 02780 } 02781 02782 if ((val = ast_variable_retrieve(cfg, "general", "displayconnects"))) 02783 displayconnects = ast_true(val); 02784 02785 if ((val = ast_variable_retrieve(cfg, "general", "timestampevents"))) 02786 timestampevents = ast_true(val); 02787 02788 if ((val = ast_variable_retrieve(cfg, "general", "httptimeout"))) 02789 newhttptimeout = atoi(val); 02790 02791 memset(&ba, 0, sizeof(ba)); 02792 ba.sin_family = AF_INET; 02793 ba.sin_port = htons(portno); 02794 02795 if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) { 02796 if (!inet_aton(val, &ba.sin_addr)) { 02797 ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); 02798 memset(&ba.sin_addr, 0, sizeof(ba.sin_addr)); 02799 } 02800 } 02801 02802 02803 if ((asock > -1) && ((portno != oldportno) || !enabled)) { 02804 #if 0 02805 /* Can't be done yet */ 02806 close(asock); 02807 asock = -1; 02808 #else 02809 ast_log(LOG_WARNING, "Unable to change management port / enabled\n"); 02810 #endif 02811 } 02812 02813 AST_LIST_LOCK(&users); 02814 02815 while ((cat = ast_category_browse(cfg, cat))) { 02816 struct ast_variable *var = NULL; 02817 02818 if (!strcasecmp(cat, "general")) 02819 continue; 02820 02821 /* Look for an existing entry, if none found - create one and add it to the list */ 02822 if (!(user = ast_get_manager_by_name_locked(cat))) { 02823 if (!(user = ast_calloc(1, sizeof(*user)))) 02824 break; 02825 /* Copy name over */ 02826 ast_copy_string(user->username, cat, sizeof(user->username)); 02827 /* Insert into list */ 02828 AST_LIST_INSERT_TAIL(&users, user, list); 02829 } 02830 02831 /* Make sure we keep this user and don't destroy it during cleanup */ 02832 user->keep = 1; 02833 02834 var = ast_variable_browse(cfg, cat); 02835 while (var) { 02836 if (!strcasecmp(var->name, "secret")) { 02837 if (user->secret) 02838 free(user->secret); 02839 user->secret = ast_strdup(var->value); 02840 } else if (!strcasecmp(var->name, "deny") ) { 02841 if (user->deny) 02842 free(user->deny); 02843 user->deny = ast_strdup(var->value); 02844 } else if (!strcasecmp(var->name, "permit") ) { 02845 if (user->permit) 02846 free(user->permit); 02847 user->permit = ast_strdup(var->value); 02848 } else if (!strcasecmp(var->name, "read") ) { 02849 if (user->read) 02850 free(user->read); 02851 user->read = ast_strdup(var->value); 02852 } else if (!strcasecmp(var->name, "write") ) { 02853 if (user->write) 02854 free(user->write); 02855 user->write = ast_strdup(var->value); 02856 } else if (!strcasecmp(var->name, "displayconnects") ) 02857 user->displayconnects = ast_true(var->value); 02858 else 02859 ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name); 02860 var = var->next; 02861 } 02862 } 02863 02864 /* Perform cleanup - essentially prune out old users that no longer exist */ 02865 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) { 02866 if (user->keep) { 02867 user->keep = 0; 02868 continue; 02869 } 02870 /* We do not need to keep this user so take them out of the list */ 02871 AST_LIST_REMOVE_CURRENT(&users, list); 02872 /* Free their memory now */ 02873 if (user->secret) 02874 free(user->secret); 02875 if (user->deny) 02876 free(user->deny); 02877 if (user->permit) 02878 free(user->permit); 02879 if (user->read) 02880 free(user->read); 02881 if (user->write) 02882 free(user->write); 02883 free(user); 02884 } 02885 AST_LIST_TRAVERSE_SAFE_END 02886 02887 AST_LIST_UNLOCK(&users); 02888 02889 ast_config_destroy(cfg); 02890 02891 if (webenabled && enabled) { 02892 if (!webregged) { 02893 ast_http_uri_link(&rawmanuri); 02894 ast_http_uri_link(&manageruri); 02895 ast_http_uri_link(&managerxmluri); 02896 webregged = 1; 02897 } 02898 } else { 02899 if (webregged) { 02900 ast_http_uri_unlink(&rawmanuri); 02901 ast_http_uri_unlink(&manageruri); 02902 ast_http_uri_unlink(&managerxmluri); 02903 webregged = 0; 02904 } 02905 } 02906 02907 if (newhttptimeout > 0) 02908 httptimeout = newhttptimeout; 02909 02910 /* If not enabled, do nothing */ 02911 if (!enabled) 02912 return 0; 02913 02914 if (asock < 0) { 02915 asock = socket(AF_INET, SOCK_STREAM, 0); 02916 if (asock < 0) { 02917 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 02918 return -1; 02919 } 02920 setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 02921 if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) { 02922 ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno)); 02923 close(asock); 02924 asock = -1; 02925 return -1; 02926 } 02927 if (listen(asock, 2)) { 02928 ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno)); 02929 close(asock); 02930 asock = -1; 02931 return -1; 02932 } 02933 flags = fcntl(asock, F_GETFL); 02934 fcntl(asock, F_SETFL, flags | O_NONBLOCK); 02935 if (option_verbose) 02936 ast_verbose("Asterisk Management interface listening on port %d\n", portno); 02937 ast_pthread_create_background(&t, NULL, accept_thread, NULL); 02938 } 02939 return 0; 02940 }
int reload_manager | ( | void | ) |
Definition at line 2942 of file manager.c.
References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().
02943 { 02944 manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n"); 02945 return init_manager(); 02946 }
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(), monitor_main(), 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().