Asterisk - The Open Source Telephony Project GIT-master-25686a5
Data Structures | Macros | Enumerations | Functions | Variables
manager.c File Reference

The Asterisk Management Interface - AMI. More...

#include "asterisk.h"
#include "asterisk/paths.h"
#include <ctype.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <regex.h>
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/manager.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/callerid.h"
#include "asterisk/core_local.h"
#include "asterisk/lock.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/mwi.h"
#include "asterisk/pbx.h"
#include "asterisk/md5.h"
#include "asterisk/acl.h"
#include "asterisk/utils.h"
#include "asterisk/tcptls.h"
#include "asterisk/http.h"
#include "asterisk/ast_version.h"
#include "asterisk/threadstorage.h"
#include "asterisk/linkedlists.h"
#include "asterisk/term.h"
#include "asterisk/astobj2.h"
#include "asterisk/features.h"
#include "asterisk/security_events.h"
#include "asterisk/aoc.h"
#include "asterisk/strings.h"
#include "asterisk/stringfields.h"
#include "asterisk/presencestate.h"
#include "asterisk/stasis_message_router.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/test.h"
#include "asterisk/json.h"
#include "asterisk/bridge.h"
#include "asterisk/features_config.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/format_cache.h"
#include "asterisk/translate.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/message.h"
Include dependency graph for manager.c:

Go to the source code of this file.

Data Structures

struct  actions
 list of actions registered More...
 
struct  all_events
 
struct  ast_manager_user
 user descriptor, as read from the config file. More...
 
struct  eventqent
 
struct  fast_originate_helper
 helper function for originate More...
 
struct  manager_hooks
 list of hooks registered More...
 
struct  mansession
 In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data. More...
 
struct  mansession_session::mansession_datastores
 
struct  mansession_session
 
struct  permalias
 
struct  users
 list of users found in the config file More...
 
struct  variable_count
 

Macros

#define any_manager_listeners(sessions)    ((sessions && ao2_container_count(sessions)) || !AST_RWLIST_EMPTY(&manager_hooks))
 
#define ASTMAN_APPEND_BUF_INITSIZE   256
 initial allocated size for the astman_append_buf and astman_send_*_va More...
 
#define DEFAULT_REALM   "asterisk"
 
#define EVENT_FLAG_SHUTDOWN   -1
 Fake event class used to end sessions at shutdown. More...
 
#define FORMAT   " %-25.25s %-15.55s\n"
 
#define FORMAT2   " %-25.25s %-15d\n"
 
#define FORMAT3   " %-25.25s %s\n"
 
#define GET_HEADER_FIRST_MATCH   0
 
#define GET_HEADER_LAST_MATCH   1
 
#define GET_HEADER_SKIP_EMPTY   2
 
#define HSMC_FORMAT   " %-*.*s %-.*s\n"
 
#define HSMCONN_FORMAT1   " %-15.15s %-55.55s %-10.10s %-10.10s %-8.8s %-8.8s %-10.10s %-10.10s\n"
 
#define HSMCONN_FORMAT2   " %-15.15s %-55.55s %-10d %-10d %-8d %-8d %-10.10d %-10.10d\n"
 
#define MANAGER_EVENT_BUF_INITSIZE   256
 
#define manager_event_sessions(sessions, category, event, contents, ...)    __manager_event_sessions(sessions, category, event, 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__)
 
#define MAX_AUTH_PERM_STRING   150
 
#define MAX_BLACKLIST_CMD_LEN   2
 Descriptor for a manager session, either on the AMI socket or over HTTP. More...
 
#define MAX_VARS   128
 
#define MGR_SHOW_TERMINAL_WIDTH   80
 
#define MSG_MOREDATA   ((char *)astman_send_response)
 
#define ROW_FMT   "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\">%s</td></tr>\r\n"
 
#define TEST_STRING    "<form action=\"manager\" method=\"post\">\n\ Action: <select name=\"action\">\n\ <option value=\"\">-----&gt;</option>\n\ <option value=\"login\">login</option>\n\ <option value=\"command\">Command</option>\n\ <option value=\"waitevent\">waitevent</option>\n\ <option value=\"listcommands\">listcommands</option>\n\ </select>\n\ or <input name=\"action\"><br/>\n\ CLI Command <input name=\"command\"><br>\n\ user <input name=\"username\"> pass <input type=\"password\" name=\"secret\"><br>\n\ <input type=\"submit\">\n</form>\n"
 

Enumerations

enum  add_filter_result { FILTER_SUCCESS , FILTER_ALLOC_FAILED , FILTER_COMPILE_FAIL }
 
enum  error_type {
  UNKNOWN_ACTION = 1 , UNKNOWN_CATEGORY , UNSPECIFIED_CATEGORY , UNSPECIFIED_ARGUMENT ,
  FAILURE_ALLOCATION , FAILURE_NEWCAT , FAILURE_DELCAT , FAILURE_EMPTYCAT ,
  FAILURE_UPDATE , FAILURE_DELETE , FAILURE_APPEND , FAILURE_TEMPLATE
}
 
enum  mansession_message_parsing { MESSAGE_OKAY , MESSAGE_LINE_TOO_LONG }
 
enum  output_format { FORMAT_RAW , FORMAT_HTML , FORMAT_XML }
 

Functions

int __ast_manager_event_multichan (int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
 
static const char * __astman_get_header (const struct message *m, char *var, int mode)
 Return a matching header value. More...
 
static void __init_astman_append_buf (void)
 thread local buffer for astman_append More...
 
static int __init_manager (int reload, int by_external_config)
 
static void __init_manager_event_buf (void)
 
static void __init_userevent_buf (void)
 
static int __manager_event_sessions (struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
 
static int __manager_event_sessions_va (struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt, va_list ap)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void acl_change_stasis_subscribe (void)
 
static void acl_change_stasis_unsubscribe (void)
 
static struct ast_aoc_decodedaction_aoc_de_message (struct mansession *s, const struct message *m)
 
static struct ast_aoc_decodedaction_aoc_s_message (struct mansession *s, const struct message *m)
 
static int action_aoc_s_submessage (struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
 
static int action_aocmessage (struct mansession *s, const struct message *m)
 
static int action_atxfer (struct mansession *s, const struct message *m)
 
static int action_blind_transfer (struct mansession *s, const struct message *m)
 
static int action_cancel_atxfer (struct mansession *s, const struct message *m)
 
static int action_challenge (struct mansession *s, const struct message *m)
 
static int action_command (struct mansession *s, const struct message *m)
 Manager command "command" - execute CLI command. More...
 
static int action_coresettings (struct mansession *s, const struct message *m)
 Show PBX core settings information. More...
 
static int action_coreshowchannelmap (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannelMap" - Lists all channels connected to the specified channel. More...
 
static int action_coreshowchannels (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannels" - List currently defined channels and some information about them. More...
 
static int action_corestatus (struct mansession *s, const struct message *m)
 Show PBX core status information. More...
 
static int action_createconfig (struct mansession *s, const struct message *m)
 
static void action_destroy (void *obj)
 
static int action_events (struct mansession *s, const struct message *m)
 
static int action_extensionstate (struct mansession *s, const struct message *m)
 
static int action_filter (struct mansession *s, const struct message *m)
 Manager command to add an event filter to a manager session. More...
 
static struct manager_actionaction_find (const char *name)
 
static int action_getconfig (struct mansession *s, const struct message *m)
 
static int action_getconfigjson (struct mansession *s, const struct message *m)
 
static int action_getvar (struct mansession *s, const struct message *m)
 
static int action_hangup (struct mansession *s, const struct message *m)
 
static int action_listcategories (struct mansession *s, const struct message *m)
 
static int action_listcommands (struct mansession *s, const struct message *m)
 
static int action_loggerrotate (struct mansession *s, const struct message *m)
 Manager command "LoggerRotate" - reloads and rotates the logger in the same manner as the CLI command 'logger rotate'. More...
 
static int action_login (struct mansession *s, const struct message *m)
 
static int action_logoff (struct mansession *s, const struct message *m)
 
static int action_mailboxcount (struct mansession *s, const struct message *m)
 
static int action_mailboxstatus (struct mansession *s, const struct message *m)
 
static int action_originate (struct mansession *s, const struct message *m)
 
static int action_ping (struct mansession *s, const struct message *m)
 
static int action_presencestate (struct mansession *s, const struct message *m)
 
static int action_redirect (struct mansession *s, const struct message *m)
 action_redirect: The redirect manager command More...
 
static int action_reload (struct mansession *s, const struct message *m)
 Send a reload event. More...
 
static int action_sendtext (struct mansession *s, const struct message *m)
 
static int action_setvar (struct mansession *s, const struct message *m)
 
static int action_status (struct mansession *s, const struct message *m)
 Manager "status" command to show channels. More...
 
static int action_timeout (struct mansession *s, const struct message *m)
 
static int action_updateconfig (struct mansession *s, const struct message *m)
 
static int action_userevent (struct mansession *s, const struct message *m)
 
static int action_waitevent (struct mansession *s, const struct message *m)
 
static struct eventqentadvance_event (struct eventqent *e)
 
static AO2_GLOBAL_OBJ_STATIC (event_docs)
 A container of event documentation nodes. More...
 
static AO2_GLOBAL_OBJ_STATIC (mgr_sessions)
 
static int aocmessage_get_unit_entry (const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
 
static void append_channel_vars (struct ast_str **pbuf, struct ast_channel *chan)
 
static int append_event (const char *str, int category)
 events are appended to a queue from where they can be dispatched to clients. More...
 
int ast_hook_send_action (struct manager_custom_hook *hook, const char *msg)
 access for hooks to send action messages to ami More...
 
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
 
int ast_manager_check_enabled (void)
 Check if AMI is enabled. More...
 
struct ast_manager_event_blobast_manager_event_blob_create (int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
 Construct a ast_manager_event_blob. More...
 
struct stasis_message_routerast_manager_get_message_router (void)
 Get the stasis_message_router for AMI. More...
 
struct stasis_topicast_manager_get_topic (void)
 Get the Stasis Message Bus API topic for AMI. More...
 
int ast_manager_hangup_helper (struct mansession *s, const struct message *m, manager_hangup_handler_t hangup_handler, manager_hangup_cause_validator_t cause_validator)
 A manager helper function that hangs up a channel using a supplied channel type specific hangup function and cause code validator. More...
 
void ast_manager_publish_event (const char *type, int class_type, struct ast_json *obj)
 Publish an event to AMI. More...
 
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), struct ast_module *module, 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 More...
 
void ast_manager_register_hook (struct manager_custom_hook *hook)
 Add a custom hook to be called when an event is fired. More...
 
static int ast_manager_register_struct (struct manager_action *act)
 
struct ast_strast_manager_str_from_json_object (struct ast_json *blob, key_exclusion_cb exclusion_cb)
 Convert a JSON object into an AMI compatible string. More...
 
int ast_manager_unregister (const char *action)
 support functions to register/unregister AMI action handlers, More...
 
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
int ast_str_append_event_header (struct ast_str **fields_string, const char *header, const char *value)
 append an event header to an ast string More...
 
int ast_webmanager_check_enabled (void)
 Check if AMI/HTTP is enabled. More...
 
static int ast_xml_doc_item_cmp_fn (const void *a, const void *b)
 
void astman_append (struct mansession *s, const char *fmt,...)
 
static void astman_append_headers (struct message *m, const struct ast_variable *params)
 Append additional headers into the message structure from params. More...
 
static void astman_append_json (struct mansession *s, const char *str)
 
int astman_datastore_add (struct mansession *s, struct ast_datastore *datastore)
 Add a datastore to a session. More...
 
struct ast_datastoreastman_datastore_find (struct mansession *s, const struct ast_datastore_info *info, const char *uid)
 Find a datastore on a session. More...
 
int astman_datastore_remove (struct mansession *s, struct ast_datastore *datastore)
 Remove a datastore from a session. More...
 
static void astman_flush (struct mansession *s, struct ast_str *buf)
 
static void astman_free_headers (struct message *m)
 Free headers inside message structure, but not the message structure itself. More...
 
const char * astman_get_header (const struct message *m, char *var)
 Return the first matching variable from an array. More...
 
struct ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers. More...
 
struct ast_variableastman_get_variables_order (const struct message *m, enum variable_orders order)
 Get a linked list of the Variable: headers with order specified. More...
 
int astman_is_authed (uint32_t ident)
 Determine if a manager session ident is authenticated. More...
 
void astman_live_dangerously (int new_live_dangerously)
 Enable/disable the inclusion of 'dangerous' configurations outside of the ast_config_AST_CONFIG_DIR. More...
 
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction. More...
 
void astman_send_error (struct mansession *s, const struct message *m, char *error)
 Send error in manager transaction. More...
 
void astman_send_error_va (struct mansession *s, const struct message *m, const char *fmt,...)
 Send error in manager transaction (with va_args support) More...
 
static void astman_send_list_complete (struct mansession *s, const struct message *m, const char *event_name, int count)
 
void astman_send_list_complete_end (struct mansession *s)
 End the list complete event. More...
 
void astman_send_list_complete_start (struct mansession *s, const struct message *m, const char *event_name, int count)
 Start the list complete event. More...
 
static struct ast_strastman_send_list_complete_start_common (struct mansession *s, const struct message *m, const char *event_name, int count)
 
void astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager transaction to begin a list. More...
 
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction. More...
 
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. More...
 
static void astman_start_ack (struct mansession *s, const struct message *m)
 
int astman_verify_session_readpermissions (uint32_t ident, int perm)
 Verify a session's read permissions against a permission mask. More...
 
int astman_verify_session_writepermissions (uint32_t ident, int perm)
 Verify a session's write permissions against a permission mask. More...
 
static int auth_http_callback (struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, const struct ast_sockaddr *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
 
static int auth_manager_http_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
 
static int auth_mxml_http_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
 
static int auth_rawman_http_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
 
static int authenticate (struct mansession *s, const struct message *m)
 
static const char * authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned. More...
 
static int blackfilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
static struct mansession_sessionbuild_mansession (const struct ast_sockaddr *addr)
 Allocate manager session structure and add it to the list of sessions. More...
 
static int check_blacklist (const char *cmd)
 
static int check_manager_session_inuse (const char *name)
 
static void close_mansession_file (struct mansession *s)
 
static int coreshowchannelmap_add_connected_channels (struct ao2_container *channel_map, struct ast_channel_snapshot *channel_snapshot, struct ast_bridge_snapshot *bridge_snapshot)
 Recursive function to get all channels in a bridge. Follow local channels as well. More...
 
static int coreshowchannelmap_add_to_map (struct ao2_container *c, const char *s)
 Helper function to add a channel name to the vector. More...
 
static void destroy_fast_originate_helper (struct fast_originate_helper *doomed)
 
static int do_message (struct mansession *s)
 
static void event_filter_destructor (void *obj)
 
static void * fast_originate (void *data)
 
static struct mansession_sessionfind_session (uint32_t ident, int incinuse)
 
static struct mansession_sessionfind_session_by_nonce (const char *username, unsigned long nonce, int *stale)
 
static int function_amiclient (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${AMI_CLIENT()} Dialplan function - reads manager client data More...
 
static int function_capable_string_allowed_with_auths (const char *evaluating, int writepermlist)
 Checks to see if a string which can be used to evaluate functions should be rejected. More...
 
static void generate_status (struct mansession *s, struct ast_channel *chan, char **vars, int varc, int all_variables, char *id_text, int *count)
 
static int generic_http_callback (struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, const struct ast_sockaddr *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
 
static int get_input (struct mansession *s, char *output)
 
static struct ast_manager_userget_manager_by_name_locked (const char *name)
 
static int get_manager_sessions_cb (void *obj, void *arg, void *data, int flags)
 Get number of logged in sessions for a login name. More...
 
static int get_perm (const char *instr)
 
static struct eventqentgrab_last (void)
 
static char * handle_kickmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager kick session. More...
 
static char * handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager reload. More...
 
static char * handle_manager_show_event (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_manager_show_events (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_manager_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager show settings. More...
 
static char * handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void handle_parse_error (struct mansession *s, struct message *m, char *error)
 
static char * handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list commands. More...
 
static char * handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list connected. More...
 
static char * handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list eventq. More...
 
static enum error_type handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
 helper function for action_updateconfig More...
 
static void json_escape (char *out, const char *in)
 
static void load_channelvars (struct ast_variable *var)
 
static void load_disabledevents (struct ast_variable *var)
 
static int load_module (void)
 
static void log_action (const struct message *m, const char *action)
 
static struct ast_variableman_do_variable_value (struct ast_variable *head, const char *hdr_val)
 
static enum add_filter_result manager_add_filter (const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
 Add an event filter to a manager session. More...
 
static void manager_default_msg_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int manager_displayconnects (struct mansession_session *session)
 Get displayconnects config option. More...
 
static void manager_event_blob_dtor (void *obj)
 
static void manager_free_user (struct ast_manager_user *user)
 
static void manager_generic_msg_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int manager_http_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
 
static void manager_json_array_with_key (struct ast_json *obj, const char *key, size_t index, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_obj_with_key (struct ast_json *obj, const char *key, const char *parent_key, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_to_ast_str (struct ast_json *obj, const char *key, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_value_str_append (struct ast_json *value, const char *key, struct ast_str **res)
 
static int manager_modulecheck (struct mansession *s, const struct message *m)
 Manager function to check if module is loaded. More...
 
static int manager_moduleload (struct mansession *s, const struct message *m)
 
static void manager_set_defaults (void)
 
static void manager_shutdown (void)
 
static int manager_state_cb (const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
 
static int manager_subscriptions_init (void)
 Initialize all Stasis Message Bus API topics and routers used by the various sub-components of AMI. More...
 
static int mansession_cmp_fn (void *obj, void *arg, int flags)
 
static enum ast_transport mansession_get_transport (const struct mansession *s)
 
static void mansession_lock (struct mansession *s)
 Lock the 'mansession' structure. More...
 
static void mansession_unlock (struct mansession *s)
 Unlock the 'mansession' structure. More...
 
static int match_filter (struct mansession *s, char *eventdata)
 
static int mxml_http_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
 
static void print_event_instance (struct ast_cli_args *a, struct ast_xml_doc_item *instance)
 
static int process_events (struct mansession *s)
 
static int process_message (struct mansession *s, const struct message *m)
 Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the session to be destroyed. More...
 
static void process_output (struct mansession *s, struct ast_str **out, struct ast_variable *params, enum output_format format)
 
static void purge_events (void)
 
static void purge_old_stuff (void *data)
 cleanup code called at each iteration of server_root, guaranteed to happen every 5 seconds at most More...
 
static int purge_sessions (int n_max)
 remove at most n_max stale session from the list. More...
 
static int queue_read_action_payload (struct ast_channel *chan, const unsigned char *payload, size_t payload_size, enum ast_frame_read_action action)
 Queue a given read action containing a payload onto a channel. More...
 
static int queue_sendtext (struct ast_channel *chan, const char *body)
 Queue a read action to send a text message. More...
 
static int queue_sendtext_data (struct ast_channel *chan, const char *body, const char *content_type)
 Queue a read action to send a text data message. More...
 
static int rawman_http_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
 
static int reload_module (void)
 
static void report_auth_success (const struct mansession *s)
 
static void report_failed_acl (const struct mansession *s, const char *username)
 
static void report_failed_challenge_response (const struct mansession *s, const char *response, const char *expected_response)
 
static void report_inval_password (const struct mansession *s, const char *username)
 
static void report_invalid_user (const struct mansession *s, const char *username)
 
static void report_req_bad_format (const struct mansession *s, const char *action)
 
static void report_req_not_allowed (const struct mansession *s, const char *action)
 
static void report_session_limit (const struct mansession *s)
 
static int restrictedFile (const char *filename)
 Check if a file is restricted or not. More...
 
static int send_string (struct mansession *s, char *string)
 
static void session_destroy (struct mansession_session *s)
 
static void session_destructor (void *obj)
 
static void * session_do (void *data)
 The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ) More...
 
static int set_eventmask (struct mansession *s, const char *eventmask)
 Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. More...
 
static int strings_to_mask (const char *string)
 
static int subscribe_all (void)
 
static int unload_module (void)
 
static struct mansession_sessionunref_mansession (struct mansession_session *s)
 Unreference manager session object. If no more references, then go ahead and delete it. More...
 
static const char * user_authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options for a user. This will only display those authority codes that have an explicit match on authority. More...
 
static int variable_count_cmp_fn (void *obj, void *vstr, int flags)
 
static int variable_count_hash_fn (const void *vvc, const int flags)
 
static int whitefilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
static void xml_copy_escape (struct ast_str **out, const char *src, int mode)
 
static void xml_translate (struct ast_str **out, char *in, struct ast_variable *get_vars, enum output_format format)
 Convert the input into XML or HTML. The input is supposed to be a sequence of lines of the form Name: value optionally followed by a blob of unformatted text. A blank line is a section separator. Basically, this is a mixture of the format of Manager Interface and CLI commands. The unformatted text is considered as a single value of a field named 'Opaque-data'. More...
 
 STASIS_MESSAGE_TYPE_DEFN (ast_manager_get_generic_type)
 Define AMI message types. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Manager Interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig,acl,http", }
 
static struct stasis_subscriptionacl_change_sub
 
static struct actions actions = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct all_events all_events = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static int allowmultiplelogin = 1
 
static struct ast_http_uri amanageruri
 
static struct ast_http_uri amanagerxmluri
 
static struct ast_tcptls_session_args ami_desc
 
static struct ast_tls_config ami_tls_cfg
 
static struct ast_tcptls_session_args amis_desc
 
static struct ast_http_uri arawmanuri
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , }
 
static int authlimit
 
static int authtimeout
 
static int broken_events_action = 0
 
static struct ast_cli_entry cli_manager []
 
struct {
   const char *   words [AST_MAX_CMD_LEN]
 
command_blacklist []
 
static const char *const contenttype []
 
static int displayconnects = 1
 
static char global_realm [MAXHOSTNAMELEN]
 
static int httptimeout = 60
 
static int live_dangerously
 Set to true (non-zero) to globally allow all dangerous AMI actions to run. More...
 
static char * manager_channelvars
 
static int manager_debug = 0
 
static char * manager_disabledevents
 
static int manager_enabled = 0
 
static struct ast_threadstorage manager_event_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_buf , .custom_init = NULL , }
 
static struct manager_hooks manager_hooks = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct stasis_topicmanager_topic
 A stasis_topic that all topics AMI cares about will be forwarded to. More...
 
static struct ast_custom_function managerclient_function
 description of AMI_CLIENT dialplan function More...
 
static struct ast_http_uri manageruri
 
static struct ast_http_uri managerxmluri
 
static const struct permalias perms []
 
static struct ast_http_uri rawmanuri
 
static struct stasis_forwardrtp_topic_forwarder
 The stasis_subscription for forwarding the RTP topic to the AMI topic. More...
 
static struct stasis_forwardsecurity_topic_forwarder
 The stasis_subscription for forwarding the Security topic to the AMI topic. More...
 
static struct stasis_message_routerstasis_router
 The stasis_message_router for all Stasis Message Bus API messages. More...
 
static int subscribed = 0
 
static int timestampevents
 
static int unauth_sessions = 0
 
static struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , }
 
static struct users users = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static int webmanager_enabled = 0
 
static int webregged = 0
 

Detailed Description

The Asterisk Management Interface - AMI.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

OpenSSL http://www.openssl.org - for AMI/SSL

At the moment this file contains a number of functions, namely:

manager.conf

Definition in file manager.c.

Macro Definition Documentation

◆ FORMAT

#define FORMAT   " %-25.25s %-15.55s\n"

◆ FORMAT2

#define FORMAT2   " %-25.25s %-15d\n"

◆ FORMAT3

#define FORMAT3   " %-25.25s %s\n"

◆ HSMC_FORMAT

#define HSMC_FORMAT   " %-*.*s %-.*s\n"

◆ HSMCONN_FORMAT1

#define HSMCONN_FORMAT1   " %-15.15s %-55.55s %-10.10s %-10.10s %-8.8s %-8.8s %-10.10s %-10.10s\n"

◆ HSMCONN_FORMAT2

#define HSMCONN_FORMAT2   " %-15.15s %-55.55s %-10d %-10d %-8d %-8d %-10.10d %-10.10d\n"

◆ ROW_FMT

#define ROW_FMT   "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\">%s</td></tr>\r\n"

◆ TEST_STRING

#define TEST_STRING    "<form action=\"manager\" method=\"post\">\n\ Action: <select name=\"action\">\n\ <option value=\"\">-----&gt;</option>\n\ <option value=\"login\">login</option>\n\ <option value=\"command\">Command</option>\n\ <option value=\"waitevent\">waitevent</option>\n\ <option value=\"listcommands\">listcommands</option>\n\ </select>\n\ or <input name=\"action\"><br/>\n\ CLI Command <input name=\"command\"><br>\n\ user <input name=\"username\"> pass <input type=\"password\" name=\"secret\"><br>\n\ <input type=\"submit\">\n</form>\n"

Enumeration Type Documentation

◆ output_format

Enumerator
FORMAT_RAW 
FORMAT_HTML 
FORMAT_XML 

Definition at line 8260 of file manager.c.

8260 {
8261 FORMAT_RAW,
8263 FORMAT_XML,
8264};
@ FORMAT_RAW
Definition: manager.c:8261
@ FORMAT_HTML
Definition: manager.c:8262
@ FORMAT_XML
Definition: manager.c:8263

Function Documentation

◆ __init_manager()

static int __init_manager ( int  reload,
int  by_external_config 
)
static

Definition at line 9978 of file manager.c.

9979{
9980 struct ast_config *ucfg = NULL, *cfg = NULL;
9981 const char *val;
9982 char *cat = NULL;
9983 int newhttptimeout = 60;
9984 struct ast_manager_user *user = NULL;
9985 struct ast_variable *var;
9986 struct ast_flags config_flags = { (reload && !by_external_config) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
9987 char a1[256];
9988 char a1_hash[256];
9989 struct ast_sockaddr ami_desc_local_address_tmp;
9990 struct ast_sockaddr amis_desc_local_address_tmp;
9991 int tls_was_enabled = 0;
9992 int acl_subscription_flag = 0;
9993
9994 if (!reload) {
9995 struct ao2_container *sessions;
9996#ifdef AST_XML_DOCS
9997 struct ao2_container *temp_event_docs;
9998#endif
9999 int res;
10000
10002 if (res != 0) {
10003 return -1;
10004 }
10005 manager_topic = stasis_topic_create("manager:core");
10006 if (!manager_topic) {
10007 return -1;
10008 }
10009
10010 /* Register default actions */
10050
10051#ifdef TEST_FRAMEWORK
10052 test_suite_forwarder = stasis_forward_all(ast_test_suite_topic(), manager_topic);
10053#endif
10054
10058
10059 /* Append placeholder event so master_eventq never runs dry */
10060 if (append_event("Event: Placeholder\r\n\r\n", 0)) {
10061 return -1;
10062 }
10063
10064#ifdef AST_XML_DOCS
10065 temp_event_docs = ast_xmldoc_build_documentation("managerEvent");
10066 if (temp_event_docs) {
10067 ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs");
10068 ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now");
10069 }
10070#endif
10071
10072 /* If you have a NULL hash fn, you only need a single bucket */
10074 if (!sessions) {
10075 return -1;
10076 }
10078 ao2_ref(sessions, -1);
10079
10080 /* Initialize all settings before first configuration load. */
10082 }
10083
10084 cfg = ast_config_load2("manager.conf", "manager", config_flags);
10085 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
10086 return 0;
10087 } else if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
10088 ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid.\n");
10089 return 0;
10090 }
10091
10092 /* If this wasn't performed due to a forced reload (because those can be created by ACL change events, we need to unsubscribe to ACL change events. */
10093 if (!by_external_config) {
10095 }
10096
10097 if (reload) {
10098 /* Reset all settings before reloading configuration */
10099 tls_was_enabled = ami_tls_cfg.enabled;
10101 }
10102
10103 ast_sockaddr_parse(&ami_desc_local_address_tmp, "[::]", 0);
10104 ast_sockaddr_set_port(&ami_desc_local_address_tmp, DEFAULT_MANAGER_PORT);
10105
10106 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
10107 val = var->value;
10108
10109 /* read tls config options while preventing unsupported options from being set */
10110 if (strcasecmp(var->name, "tlscafile")
10111 && strcasecmp(var->name, "tlscapath")
10112 && strcasecmp(var->name, "tlscadir")
10113 && strcasecmp(var->name, "tlsverifyclient")
10114 && strcasecmp(var->name, "tlsdontverifyserver")
10115 && strcasecmp(var->name, "tlsclientmethod")
10116 && strcasecmp(var->name, "sslclientmethod")
10117 && !ast_tls_read_conf(&ami_tls_cfg, &amis_desc, var->name, val)) {
10118 continue;
10119 }
10120
10121 if (!strcasecmp(var->name, "enabled")) {
10123 } else if (!strcasecmp(var->name, "webenabled")) {
10125 } else if (!strcasecmp(var->name, "port")) {
10126 int bindport;
10127 if (ast_parse_arg(val, PARSE_UINT32|PARSE_IN_RANGE, &bindport, 1024, 65535)) {
10128 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
10129 }
10130 ast_sockaddr_set_port(&ami_desc_local_address_tmp, bindport);
10131 } else if (!strcasecmp(var->name, "bindaddr")) {
10132 /* remember port if it has already been set */
10133 int setport = ast_sockaddr_port(&ami_desc_local_address_tmp);
10134
10136 ast_log(LOG_WARNING, "Invalid address '%s' specified, default '%s' will be used\n", val,
10137 ast_sockaddr_stringify_addr(&ami_desc_local_address_tmp));
10138 } else {
10139 ast_sockaddr_parse(&ami_desc_local_address_tmp, val, PARSE_PORT_IGNORE);
10140 }
10141
10142 if (setport) {
10143 ast_sockaddr_set_port(&ami_desc_local_address_tmp, setport);
10144 }
10145
10146 } else if (!strcasecmp(var->name, "brokeneventsaction")) {
10148 } else if (!strcasecmp(var->name, "allowmultiplelogin")) {
10150 } else if (!strcasecmp(var->name, "displayconnects")) {
10152 } else if (!strcasecmp(var->name, "timestampevents")) {
10154 } else if (!strcasecmp(var->name, "debug")) {
10156 } else if (!strcasecmp(var->name, "httptimeout")) {
10157 newhttptimeout = atoi(val);
10158 } else if (!strcasecmp(var->name, "authtimeout")) {
10159 int timeout = atoi(var->value);
10160
10161 if (timeout < 1) {
10162 ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", var->value);
10163 } else {
10164 authtimeout = timeout;
10165 }
10166 } else if (!strcasecmp(var->name, "authlimit")) {
10167 int limit = atoi(var->value);
10168
10169 if (limit < 1) {
10170 ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", var->value);
10171 } else {
10172 authlimit = limit;
10173 }
10174 } else if (!strcasecmp(var->name, "channelvars")) {
10176 } else if (!strcasecmp(var->name, "disabledevents")) {
10178 } else {
10179 ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
10180 var->name, val);
10181 }
10182 }
10183
10184 if (manager_enabled && !subscribed) {
10185 if (subscribe_all() != 0) {
10186 ast_log(LOG_ERROR, "Manager subscription error\n");
10187 return -1;
10188 }
10189 }
10190
10191 ast_sockaddr_copy(&amis_desc_local_address_tmp, &amis_desc.local_address);
10192
10193 /* if the amis address has not been set, default is the same as non secure ami */
10194 if (ast_sockaddr_isnull(&amis_desc_local_address_tmp)) {
10195 ast_sockaddr_copy(&amis_desc_local_address_tmp, &ami_desc_local_address_tmp);
10196 }
10197
10198 /* if the amis address was not set, it will have non-secure ami port set; if
10199 amis address was set, we need to check that a port was set or not, if not
10200 use the default tls port */
10201 if (ast_sockaddr_port(&amis_desc_local_address_tmp) == 0 ||
10202 (ast_sockaddr_port(&ami_desc_local_address_tmp) == ast_sockaddr_port(&amis_desc_local_address_tmp))) {
10203
10204 ast_sockaddr_set_port(&amis_desc_local_address_tmp, DEFAULT_MANAGER_TLS_PORT);
10205 }
10206
10207 if (manager_enabled) {
10208 ast_sockaddr_copy(&ami_desc.local_address, &ami_desc_local_address_tmp);
10209 ast_sockaddr_copy(&amis_desc.local_address, &amis_desc_local_address_tmp);
10210 }
10211
10213
10214 /* First, get users from users.conf */
10215 ucfg = ast_config_load2("users.conf", "manager", config_flags);
10216 if (ucfg && (ucfg != CONFIG_STATUS_FILEUNCHANGED) && ucfg != CONFIG_STATUS_FILEINVALID) {
10217 const char *hasmanager;
10218 int genhasmanager = ast_true(ast_variable_retrieve(ucfg, "general", "hasmanager"));
10219
10220 while ((cat = ast_category_browse(ucfg, cat))) {
10221 if (!strcasecmp(cat, "general")) {
10222 continue;
10223 }
10224
10225 hasmanager = ast_variable_retrieve(ucfg, cat, "hasmanager");
10226 if ((!hasmanager && genhasmanager) || ast_true(hasmanager)) {
10227 const char *user_secret = ast_variable_retrieve(ucfg, cat, "secret");
10228 const char *user_read = ast_variable_retrieve(ucfg, cat, "read");
10229 const char *user_write = ast_variable_retrieve(ucfg, cat, "write");
10230 const char *user_displayconnects = ast_variable_retrieve(ucfg, cat, "displayconnects");
10231 const char *user_allowmultiplelogin = ast_variable_retrieve(ucfg, cat, "allowmultiplelogin");
10232 const char *user_writetimeout = ast_variable_retrieve(ucfg, cat, "writetimeout");
10233
10234 /* Look for an existing entry,
10235 * if none found - create one and add it to the list
10236 */
10237 if (!(user = get_manager_by_name_locked(cat))) {
10238 if (!(user = ast_calloc(1, sizeof(*user)))) {
10239 break;
10240 }
10241
10242 /* Copy name over */
10243 ast_copy_string(user->username, cat, sizeof(user->username));
10244 /* Insert into list */
10246 user->acl = NULL;
10247 user->keep = 1;
10248 user->readperm = -1;
10249 user->writeperm = -1;
10250 /* Default displayconnect from [general] */
10251 user->displayconnects = displayconnects;
10252 /* Default allowmultiplelogin from [general] */
10253 user->allowmultiplelogin = allowmultiplelogin;
10254 user->writetimeout = 100;
10255 }
10256
10257 if (!user_secret) {
10258 user_secret = ast_variable_retrieve(ucfg, "general", "secret");
10259 }
10260 if (!user_read) {
10261 user_read = ast_variable_retrieve(ucfg, "general", "read");
10262 }
10263 if (!user_write) {
10264 user_write = ast_variable_retrieve(ucfg, "general", "write");
10265 }
10266 if (!user_displayconnects) {
10267 user_displayconnects = ast_variable_retrieve(ucfg, "general", "displayconnects");
10268 }
10269 if (!user_allowmultiplelogin) {
10270 user_allowmultiplelogin = ast_variable_retrieve(ucfg, "general", "allowmultiplelogin");
10271 }
10272 if (!user_writetimeout) {
10273 user_writetimeout = ast_variable_retrieve(ucfg, "general", "writetimeout");
10274 }
10275
10276 if (!ast_strlen_zero(user_secret)) {
10277 ast_free(user->secret);
10278 user->secret = ast_strdup(user_secret);
10279 }
10280
10281 if (user_read) {
10282 user->readperm = get_perm(user_read);
10283 }
10284 if (user_write) {
10285 user->writeperm = get_perm(user_write);
10286 }
10287 if (user_displayconnects) {
10288 user->displayconnects = ast_true(user_displayconnects);
10289 }
10290 if (user_allowmultiplelogin) {
10291 user->allowmultiplelogin = ast_true(user_allowmultiplelogin);
10292 }
10293 if (user_writetimeout) {
10294 int value = atoi(user_writetimeout);
10295 if (value < 100) {
10296 ast_log(LOG_WARNING, "Invalid writetimeout value '%d' in users.conf\n", value);
10297 } else {
10298 user->writetimeout = value;
10299 }
10300 }
10301 }
10302 }
10303 ast_config_destroy(ucfg);
10304 }
10305
10306 /* cat is NULL here in any case */
10307
10308 while ((cat = ast_category_browse(cfg, cat))) {
10309 struct ast_acl_list *oldacl;
10310
10311 if (!strcasecmp(cat, "general")) {
10312 continue;
10313 }
10314
10315 /* Look for an existing entry, if none found - create one and add it to the list */
10316 if (!(user = get_manager_by_name_locked(cat))) {
10317 if (!(user = ast_calloc(1, sizeof(*user)))) {
10318 break;
10319 }
10320 /* Copy name over */
10321 ast_copy_string(user->username, cat, sizeof(user->username));
10322
10323 user->acl = NULL;
10324 user->readperm = 0;
10325 user->writeperm = 0;
10326 /* Default displayconnect from [general] */
10327 user->displayconnects = displayconnects;
10328 /* Default allowmultiplelogin from [general] */
10329 user->allowmultiplelogin = allowmultiplelogin;
10330 user->writetimeout = 100;
10333 if (!user->whitefilters || !user->blackfilters) {
10335 break;
10336 }
10337
10338 /* Insert into list */
10340 } else {
10341 ao2_t_callback(user->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters");
10342 ao2_t_callback(user->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters");
10343 }
10344
10345 /* Make sure we keep this user and don't destroy it during cleanup */
10346 user->keep = 1;
10347 oldacl = user->acl;
10348 user->acl = NULL;
10349 ast_variables_destroy(user->chanvars);
10350
10351 var = ast_variable_browse(cfg, cat);
10352 for (; var; var = var->next) {
10353 if (!strcasecmp(var->name, "secret")) {
10354 ast_free(user->secret);
10355 user->secret = ast_strdup(var->value);
10356 } else if (!strcasecmp(var->name, "deny") ||
10357 !strcasecmp(var->name, "permit") ||
10358 !strcasecmp(var->name, "acl")) {
10359 int acl_error = 0;
10360
10361 ast_append_acl(var->name, var->value, &user->acl, &acl_error, &acl_subscription_flag);
10362 if (acl_error) {
10363 ast_log(LOG_ERROR, "Invalid ACL '%s' for manager user '%s' on line %d. Deleting user\n",
10364 var->value, user->username, var->lineno);
10365 user->keep = 0;
10366 }
10367 } else if (!strcasecmp(var->name, "read") ) {
10368 user->readperm = get_perm(var->value);
10369 } else if (!strcasecmp(var->name, "write") ) {
10370 user->writeperm = get_perm(var->value);
10371 } else if (!strcasecmp(var->name, "displayconnects") ) {
10372 user->displayconnects = ast_true(var->value);
10373 } else if (!strcasecmp(var->name, "allowmultiplelogin") ) {
10374 user->allowmultiplelogin = ast_true(var->value);
10375 } else if (!strcasecmp(var->name, "writetimeout")) {
10376 int value = atoi(var->value);
10377 if (value < 100) {
10378 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", var->value, var->lineno);
10379 } else {
10380 user->writetimeout = value;
10381 }
10382 } else if (!strcasecmp(var->name, "setvar")) {
10383 struct ast_variable *tmpvar;
10384 char varbuf[256];
10385 char *varval;
10386 char *varname;
10387
10388 ast_copy_string(varbuf, var->value, sizeof(varbuf));
10389 varname = varbuf;
10390
10391 if ((varval = strchr(varname,'='))) {
10392 *varval++ = '\0';
10393 if ((tmpvar = ast_variable_new(varname, varval, ""))) {
10394 tmpvar->next = user->chanvars;
10395 user->chanvars = tmpvar;
10396 }
10397 }
10398 } else if (!strcasecmp(var->name, "eventfilter")) {
10399 const char *value = var->value;
10400 manager_add_filter(value, user->whitefilters, user->blackfilters);
10401 } else {
10402 ast_debug(1, "%s is an unknown option.\n", var->name);
10403 }
10404 }
10405
10406 oldacl = ast_free_acl_list(oldacl);
10407 }
10408 ast_config_destroy(cfg);
10409
10410 /* Check the flag for named ACL event subscription and if we need to, register a subscription. */
10411 if (acl_subscription_flag && !by_external_config) {
10413 }
10414
10415 /* Perform cleanup - essentially prune out old users that no longer exist */
10417 if (user->keep) { /* valid record. clear flag for the next round */
10418 user->keep = 0;
10419
10420 /* Calculate A1 for Digest auth */
10421 snprintf(a1, sizeof(a1), "%s:%s:%s", user->username, global_realm, user->secret);
10422 ast_md5_hash(a1_hash,a1);
10423 ast_free(user->a1_hash);
10424 user->a1_hash = ast_strdup(a1_hash);
10425 continue;
10426 }
10427 /* We do not need to keep this user so take them out of the list */
10429 ast_debug(4, "Pruning user '%s'\n", user->username);
10431 }
10433
10435
10437 if (!webregged) {
10441
10445 webregged = 1;
10446 }
10447 } else {
10448 if (webregged) {
10452
10456 webregged = 0;
10457 }
10458 }
10459
10460 if (newhttptimeout > 0) {
10461 httptimeout = newhttptimeout;
10462 }
10463
10465 if (tls_was_enabled && !ami_tls_cfg.enabled) {
10467 } else if (ast_ssl_setup(amis_desc.tls_cfg)) {
10469 }
10470
10471 return 0;
10472}
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
Definition: acl.c:429
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
#define var
Definition: ast_expr2f.c:605
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
#define ao2_t_ref(o, delta, tag)
Definition: astobj2.h:460
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
#define ao2_t_global_obj_replace_unref(holder, obj, tag)
Definition: astobj2.h:904
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
Definition: astobj2.h:1696
static struct unistimsession * sessions
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static int action_setvar(struct mansession *s, const struct message *m)
Definition: manager.c:4889
static int action_createconfig(struct mansession *s, const struct message *m)
Definition: manager.c:4490
static int manager_state_cb(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
Definition: manager.c:8087
static int action_loggerrotate(struct mansession *s, const struct message *m)
Manager command "LoggerRotate" - reloads and rotates the logger in the same manner as the CLI command...
Definition: manager.c:7240
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:2465
static void acl_change_stasis_subscribe(void)
Definition: manager.c:1693
static int manager_enabled
Definition: manager.c:1628
static int action_sendtext(struct mansession *s, const struct message *m)
Definition: manager.c:5245
static int action_mailboxcount(struct mansession *s, const struct message *m)
Definition: manager.c:6558
static int action_getconfigjson(struct mansession *s, const struct message *m)
Definition: manager.c:4042
static int action_listcategories(struct mansession *s, const struct message *m)
Definition: manager.c:3976
static int action_hangup(struct mansession *s, const struct message *m)
Definition: manager.c:4883
static int action_listcommands(struct mansession *s, const struct message *m)
Definition: manager.c:4626
static int action_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:5479
static int action_timeout(struct mansession *s, const struct message *m)
Definition: manager.c:6649
static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
Add an event filter to a manager session.
Definition: manager.c:6768
static int action_coresettings(struct mansession *s, const struct message *m)
Show PBX core settings information.
Definition: manager.c:6882
static int mansession_cmp_fn(void *obj, void *arg, int flags)
Definition: manager.c:2422
static int displayconnects
Definition: manager.c:1623
static int action_filter(struct mansession *s, const struct message *m)
Manager command to add an event filter to a manager session.
Definition: manager.c:6716
static int manager_debug
Definition: manager.c:1631
static int action_mailboxstatus(struct mansession *s, const struct message *m)
Definition: manager.c:6541
static int action_login(struct mansession *s, const struct message *m)
Definition: manager.c:4695
static int action_getvar(struct mansession *s, const struct message *m)
Definition: manager.c:4922
static int action_blind_transfer(struct mansession *s, const struct message *m)
Definition: manager.c:5433
static int action_extensionstate(struct mansession *s, const struct message *m)
Definition: manager.c:6579
static int action_getconfig(struct mansession *s, const struct message *m)
Definition: manager.c:3904
static int action_logoff(struct mansession *s, const struct message *m)
Definition: manager.c:4689
static int action_updateconfig(struct mansession *s, const struct message *m)
Definition: manager.c:4399
static int manager_moduleload(struct mansession *s, const struct message *m)
Definition: manager.c:7281
static void acl_change_stasis_unsubscribe(void)
Definition: manager.c:1703
static int action_reload(struct mansession *s, const struct message *m)
Send a reload event.
Definition: manager.c:6966
static int authlimit
Definition: manager.c:1633
static int action_aocmessage(struct mansession *s, const struct message *m)
Definition: manager.c:6269
static int action_events(struct mansession *s, const struct message *m)
Definition: manager.c:4645
static int action_redirect(struct mansession *s, const struct message *m)
action_redirect: The redirect manager command
Definition: manager.c:5288
static int action_presencestate(struct mansession *s, const struct message *m)
Definition: manager.c:6609
static int allowmultiplelogin
Definition: manager.c:1624
static int action_cancel_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:5533
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:1638
static int action_originate(struct mansession *s, const struct message *m)
Definition: manager.c:6328
static int action_userevent(struct mansession *s, const struct message *m)
Definition: manager.c:6861
static int action_command(struct mansession *s, const struct message *m)
Manager command "command" - execute CLI command.
Definition: manager.c:5610
static int broken_events_action
Definition: manager.c:1627
static int timestampevents
Definition: manager.c:1625
static int subscribed
Definition: manager.c:1629
static int authtimeout
Definition: manager.c:1632
static int manager_modulecheck(struct mansession *s, const struct message *m)
Manager function to check if module is loaded.
Definition: manager.c:7252
static int webmanager_enabled
Definition: manager.c:1630
static int action_status(struct mansession *s, const struct message *m)
Manager "status" command to show channels.
Definition: manager.c:5089
static int get_perm(const char *instr)
Definition: manager.c:2291
static int action_coreshowchannels(struct mansession *s, const struct message *m)
Manager command "CoreShowChannels" - List currently defined channels and some information about them.
Definition: manager.c:6998
static int action_corestatus(struct mansession *s, const struct message *m)
Show PBX core status information.
Definition: manager.c:6926
static int action_challenge(struct mansession *s, const struct message *m)
Definition: manager.c:4744
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1644
static int action_waitevent(struct mansession *s, const struct message *m)
Definition: manager.c:4508
static int append_event(const char *str, int category)
events are appended to a queue from where they can be dispatched to clients.
Definition: manager.c:7859
static int action_coreshowchannelmap(struct mansession *s, const struct message *m)
Manager command "CoreShowChannelMap" - Lists all channels connected to the specified channel.
Definition: manager.c:7166
static int action_ping(struct mansession *s, const struct message *m)
Definition: manager.c:3832
static int httptimeout
Definition: manager.c:1626
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:708
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:676
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
#define ast_variable_new(name, value, filename)
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
Definition: main/config.c:3827
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
@ CONFIG_FLAG_FILEUNCHANGED
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_NOTICE
#define LOG_WARNING
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:9459
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:9460
static struct ast_http_uri managerxmluri
Definition: manager.c:9299
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:9471
static struct ast_custom_function managerclient_function
description of AMI_CLIENT dialplan function
Definition: manager.c:9432
static void load_channelvars(struct ast_variable *var)
Definition: manager.c:9736
static struct ast_http_uri manageruri
Definition: manager.c:9291
static void manager_set_defaults(void)
Definition: manager.c:9950
static struct ast_http_uri arawmanuri
Definition: manager.c:9342
static struct ast_http_uri rawmanuri
Definition: manager.c:9283
static struct ast_cli_entry cli_manager[]
Definition: manager.c:9713
static void manager_free_user(struct ast_manager_user *user)
Definition: manager.c:9769
static struct ast_http_uri amanageruri
Definition: manager.c:9351
static int webregged
Definition: manager.c:9438
static int subscribe_all(void)
Definition: manager.c:9920
static struct ast_http_uri amanagerxmluri
Definition: manager.c:9360
static void load_disabledevents(struct ast_variable *var)
Definition: manager.c:9759
#define EVENT_FLAG_REPORTING
Definition: manager.h:84
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:202
#define EVENT_FLAG_CONFIG
Definition: manager.h:82
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
#define DEFAULT_MANAGER_PORT
Definition: manager.h:58
#define DEFAULT_MANAGER_TLS_PORT
Definition: manager.h:59
#define EVENT_FLAG_CALL
Definition: manager.h:76
#define EVENT_FLAG_COMMAND
Definition: manager.h:79
#define EVENT_FLAG_USER
Definition: manager.h:81
#define EVENT_FLAG_AOC
Definition: manager.h:91
#define EVENT_FLAG_ORIGINATE
Definition: manager.h:87
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
int ast_extension_state_add(const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
Add watcher for extension states.
Definition: pbx.c:3823
static int reload(void)
#define NULL
Definition: resample.c:96
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:617
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1578
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Generic container type.
Wrapper for an ast_acl linked list.
Definition: acl.h:76
Structure used to handle boolean flags.
Definition: utils.h:199
user descriptor, as read from the config file.
Definition: manager.c:1804
Socket address structure.
Definition: netsock2.h:97
struct ast_sockaddr local_address
Definition: tcptls.h:131
struct ast_tls_config * tls_cfg
Definition: tcptls.h:135
int enabled
Definition: tcptls.h:89
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
structure to hold users read from users.conf
list of users found in the config file
Definition: ast_expr2.c:325
int value
Definition: syslog.c:37
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition: tcptls.c:925
int ast_ssl_setup(struct ast_tls_config *cfg)
Set up an SSL server.
Definition: tcptls.c:570
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a ...
Definition: tcptls.c:760
int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
Used to parse conf files containing tls/ssl options.
Definition: tcptls.c:951
#define ARRAY_LEN(a)
Definition: utils.h:666
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: utils.c:250
struct ao2_container * ast_xmldoc_build_documentation(const char *type)
Build the documentation for a particular source type.
Definition: xmldoc.c:2684

References __ast_custom_function_register(), acl_change_stasis_subscribe(), acl_change_stasis_unsubscribe(), action_aocmessage(), action_atxfer(), action_blind_transfer(), action_cancel_atxfer(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannelmap(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_events(), action_extensionstate(), action_filter(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_listcommands(), action_loggerrotate(), action_login(), action_logoff(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_ping(), action_presencestate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_updateconfig(), action_userevent(), action_waitevent(), allowmultiplelogin, amanageruri, amanagerxmluri, ami_desc, ami_tls_cfg, amis_desc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ao2_global_obj_replace_unref, ao2_ref, ao2_t_callback, ao2_t_global_obj_replace_unref, ao2_t_ref, append_event(), arawmanuri, ARRAY_LEN, ast_append_acl(), ast_calloc, ast_category_browse(), ast_cli_register_multiple, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_debug, ast_extension_state_add(), ast_free, ast_free_acl_list(), ast_http_uri_link(), ast_http_uri_unlink(), AST_LIST_INSERT_TAIL, ast_log, ast_manager_get_generic_type(), ast_manager_register_xml_core, ast_md5_hash(), ast_parse_arg(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify_addr(), ast_ssl_setup(), ast_strdup, ast_strlen_zero(), ast_tcptls_server_start(), ast_tcptls_server_stop(), ast_tls_read_conf(), ast_true(), ast_variable_browse(), ast_variable_new, ast_variable_retrieve(), ast_variables_destroy(), ast_xmldoc_build_documentation(), authlimit, authtimeout, broken_events_action, cli_manager, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MANAGER_PORT, DEFAULT_MANAGER_TLS_PORT, displayconnects, ast_tls_config::enabled, EVENT_FLAG_AOC, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, EVENT_FLAG_CONFIG, EVENT_FLAG_ORIGINATE, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, EVENT_FLAG_USER, get_manager_by_name_locked(), get_perm(), global_realm, httptimeout, load_channelvars(), load_disabledevents(), ast_tcptls_session_args::local_address, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_add_filter(), manager_debug, manager_enabled, manager_free_user(), manager_modulecheck(), manager_moduleload(), manager_set_defaults(), manager_state_cb(), manager_topic, managerclient_function, manageruri, managerxmluri, mansession_cmp_fn(), ast_variable::next, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, PARSE_ADDR, PARSE_IN_RANGE, PARSE_PORT_IGNORE, PARSE_UINT32, rawmanuri, reload(), sessions, stasis_forward_all(), STASIS_MESSAGE_TYPE_INIT, stasis_topic_create(), subscribe_all(), subscribed, timestampevents, ast_tcptls_session_args::tls_cfg, value, var, webmanager_enabled, and webregged.

Referenced by acl_change_stasis_cb(), load_module(), and reload_module().

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 10603 of file manager.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 10603 of file manager.c.

◆ ast_manager_event_blob_create()

struct ast_manager_event_blob * ast_manager_event_blob_create ( int  event_flags,
const char *  manager_event,
const char *  extra_fields_fmt,
  ... 
)

Construct a ast_manager_event_blob.

Since
12

The returned object is AO2 managed, so clean up with ao2_cleanup().

Parameters
event_flagsFlags the event should be raised with.
manager_eventThe event to be raised, should be a string literal.
extra_fields_fmtFormat string for extra fields to include. Or NO_EXTRA_FIELDS for no extra fields.
Returns
New ast_manager_event_blob object.
Return values
NULLon error.

Definition at line 10564 of file manager.c.

10569{
10570 struct ast_manager_event_blob *ev;
10571 va_list argp;
10572
10573 ast_assert(extra_fields_fmt != NULL);
10575
10577 if (!ev) {
10578 return NULL;
10579 }
10580
10581 if (ast_string_field_init(ev, 20)) {
10582 ao2_ref(ev, -1);
10583 return NULL;
10584 }
10585
10588
10589 va_start(argp, extra_fields_fmt);
10590 ast_string_field_ptr_build_va(ev, &ev->extra_fields, extra_fields_fmt, argp);
10591 va_end(argp);
10592
10593 return ev;
10594}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void manager_event_blob_dtor(void *obj)
Definition: manager.c:10555
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
#define ast_string_field_ptr_build_va(x, ptr, fmt, args)
Set a field to a complex (built) value with prebuilt va_lists.
Definition: stringfields.h:573
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Struct containing info for an AMI event to send out.
Definition: manager.h:502
const ast_string_field extra_fields
Definition: manager.h:507
const char * manager_event
Definition: manager.h:504
#define ast_assert(a)
Definition: utils.h:739

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_assert, ast_string_field_init, ast_string_field_ptr_build_va, ast_manager_event_blob::event_flags, ast_manager_event_blob::extra_fields, manager_event, ast_manager_event_blob::manager_event, manager_event_blob_dtor(), and NULL.

Referenced by agent_login_to_ami(), agent_logoff_to_ami(), agi_channel_to_ami(), aoc_to_ami(), attended_transfer_to_ami(), blind_transfer_to_ami(), bridge_create(), bridge_destroy(), bridge_video_update(), call_pickup_to_ami(), cc_available_to_ami(), cc_callerrecalling_to_ami(), cc_callerstartmonitoring_to_ami(), cc_callerstopmonitoring_to_ami(), cc_failure_to_ami(), cc_monitorfailed_to_ami(), cc_offertimerstart_to_ami(), cc_recallcomplete_to_ami(), cc_requestacknowledged_to_ami(), cc_requested_to_ami(), channel_new_accountcode(), channel_new_callerid(), channel_new_connected_line(), channel_newexten(), channel_state_change(), contactstatus_to_ami(), dahdichannel_to_ami(), devstate_to_ami(), fake_ami(), local_message_to_ami(), multi_user_event_to_ami(), peerstatus_to_ami(), presence_state_to_ami(), queue_channel_to_ami(), queue_member_to_ami(), queue_multi_channel_to_ami(), rtcp_report_to_ami(), security_event_to_ami_blob(), system_registry_to_ami(), talking_start_to_ami(), talking_stop_to_ami(), and varset_to_ami().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 10603 of file manager.c.

◆ ast_str_append_event_header()

int ast_str_append_event_header ( struct ast_str **  fields_string,
const char *  header,
const char *  value 
)

append an event header to an ast string

Since
12
Parameters
fields_stringpointer to an ast_string pointer. It may be a pointer to a NULL ast_str pointer, in which case the ast_str will be initialized.
headerThe header being applied
valuethe value of the header
Return values
0if successful
non-zeroon failure

Definition at line 10542 of file manager.c.

10544{
10545 if (!*fields_string) {
10546 *fields_string = ast_str_create(128);
10547 if (!*fields_string) {
10548 return -1;
10549 }
10550 }
10551
10552 return (ast_str_append(fields_string, 0, "%s: %s\r\n", header, value) < 0) ? -1 : 0;
10553}
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659

References ast_str_append(), ast_str_create, and value.

Referenced by confbridge_talking_cb(), get_bool_header(), and meetme_stasis_cb().

◆ ast_xml_doc_item_cmp_fn()

static int ast_xml_doc_item_cmp_fn ( const void *  a,
const void *  b 
)
static

Definition at line 9526 of file manager.c.

9527{
9528 struct ast_xml_doc_item **item_a = (struct ast_xml_doc_item **)a;
9529 struct ast_xml_doc_item **item_b = (struct ast_xml_doc_item **)b;
9530 return strcmp((*item_a)->name, (*item_b)->name);
9531}
Struct that contains the XML documentation for a particular item. Note that this is an ao2 ref counte...
Definition: xmldoc.h:56
static struct test_val b
static struct test_val a

References a, and b.

Referenced by handle_manager_show_events().

◆ astman_datastore_add()

int astman_datastore_add ( struct mansession s,
struct ast_datastore datastore 
)

Add a datastore to a session.

Return values
0success
non-zerofailure
Since
1.6.1

Definition at line 10503 of file manager.c.

10504{
10505 AST_LIST_INSERT_HEAD(&s->session->datastores, datastore, entry);
10506
10507 return 0;
10508}
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
Definition: search.h:40
struct mansession_session::mansession_datastores datastores
struct mansession_session * session
Definition: manager.c:1786

References AST_LIST_INSERT_HEAD, mansession_session::datastores, and mansession::session.

◆ astman_datastore_find()

struct ast_datastore * astman_datastore_find ( struct mansession s,
const struct ast_datastore_info info,
const char *  uid 
)

Find a datastore on a session.

Returns
pointer to the datastore if found
Return values
NULLif not found
Since
1.6.1

Definition at line 10515 of file manager.c.

10516{
10517 struct ast_datastore *datastore = NULL;
10518
10519 if (info == NULL)
10520 return NULL;
10521
10523 if (datastore->info != info) {
10524 continue;
10525 }
10526
10527 if (uid == NULL) {
10528 /* matched by type only */
10529 break;
10530 }
10531
10532 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
10533 /* Matched by type AND uid */
10534 break;
10535 }
10536 }
10538
10539 return datastore;
10540}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
def info(msg)
Structure for a data store object.
Definition: datastore.h:64
const struct ast_datastore_info * info
Definition: datastore.h:67
const char * uid
Definition: datastore.h:65

References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, mansession_session::datastores, sip_to_pjsip::info(), ast_datastore::info, NULL, mansession::session, and ast_datastore::uid.

◆ astman_datastore_remove()

int astman_datastore_remove ( struct mansession s,
struct ast_datastore datastore 
)

Remove a datastore from a session.

Return values
0success
non-zerofailure
Since
1.6.1

Definition at line 10510 of file manager.c.

10511{
10512 return AST_LIST_REMOVE(&s->session->datastores, datastore, entry) ? 0 : -1;
10513}
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:856

References AST_LIST_REMOVE, mansession_session::datastores, and mansession::session.

◆ astman_is_authed()

int astman_is_authed ( uint32_t  ident)

Determine if a manager session ident is authenticated.

Definition at line 8349 of file manager.c.

8350{
8351 int authed;
8353
8354 if (!(session = find_session(ident, 0)))
8355 return 0;
8356
8357 authed = (session->authenticated != 0);
8358
8361
8362 return authed;
8363}
static struct ast_mansession session
#define ao2_unlock(a)
Definition: astobj2.h:729
static struct mansession_session * unref_mansession(struct mansession_session *s)
Unreference manager session object. If no more references, then go ahead and delete it.
Definition: manager.c:2343
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:8277

References ao2_unlock, find_session(), session, and unref_mansession().

Referenced by http_post_callback(), and static_callback().

◆ astman_verify_session_readpermissions()

int astman_verify_session_readpermissions ( uint32_t  ident,
int  perm 
)

Verify a session's read permissions against a permission mask.

Parameters
identsession identity
permpermission mask to verify
Return values
1if the session has the permission mask capabilities
0otherwise

Definition at line 8365 of file manager.c.

8366{
8367 int result = 0;
8369 struct ao2_container *sessions;
8370 struct ao2_iterator i;
8371
8372 if (ident == 0) {
8373 return 0;
8374 }
8375
8376 sessions = ao2_global_obj_ref(mgr_sessions);
8377 if (!sessions) {
8378 return 0;
8379 }
8381 ao2_ref(sessions, -1);
8382 while ((session = ao2_iterator_next(&i))) {
8384 if ((session->managerid == ident) && (session->readperm & perm)) {
8385 result = 1;
8388 break;
8389 }
8392 }
8394
8395 return result;
8396}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_lock(a)
Definition: astobj2.h:717
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static PGresult * result
Definition: cel_pgsql.c:84
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821

References ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, result, session, sessions, and unref_mansession().

◆ astman_verify_session_writepermissions()

int astman_verify_session_writepermissions ( uint32_t  ident,
int  perm 
)

Verify a session's write permissions against a permission mask.

Parameters
identsession identity
permpermission mask to verify
Return values
1if the session has the permission mask capabilities, otherwise 0
0otherwise

Definition at line 8398 of file manager.c.

8399{
8400 int result = 0;
8402 struct ao2_container *sessions;
8403 struct ao2_iterator i;
8404
8405 if (ident == 0) {
8406 return 0;
8407 }
8408
8409 sessions = ao2_global_obj_ref(mgr_sessions);
8410 if (!sessions) {
8411 return 0;
8412 }
8414 ao2_ref(sessions, -1);
8415 while ((session = ao2_iterator_next(&i))) {
8417 if ((session->managerid == ident) && (session->writeperm & perm)) {
8418 result = 1;
8421 break;
8422 }
8425 }
8427
8428 return result;
8429}

References ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, result, session, sessions, and unref_mansession().

Referenced by http_post_callback().

◆ auth_http_callback()

static int auth_http_callback ( struct ast_tcptls_session_instance ser,
enum ast_http_method  method,
enum output_format  format,
const struct ast_sockaddr remote_address,
const char *  uri,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 8927 of file manager.c.

8933{
8935 struct mansession s = { .session = NULL, .tcptls_session = ser };
8936 struct ast_variable *v, *params = get_params;
8937 char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
8938 struct ast_str *http_header = NULL, *out = NULL;
8939 size_t result_size;
8940 struct message m = { 0 };
8941 int fd;
8942
8943 time_t time_now = time(NULL);
8944 unsigned long nonce = 0, nc;
8945 struct ast_http_digest d = { NULL, };
8946 struct ast_manager_user *user = NULL;
8947 int stale = 0;
8948 char resp_hash[256]="";
8949 /* Cache for user data */
8950 char u_username[80];
8951 int u_readperm;
8952 int u_writeperm;
8953 int u_writetimeout;
8954 int u_displayconnects;
8955
8957 ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
8958 return 0;
8959 }
8960
8961 /* Find "Authorization: " header */
8962 for (v = headers; v; v = v->next) {
8963 if (!strcasecmp(v->name, "Authorization")) {
8964 break;
8965 }
8966 }
8967
8968 if (!v || ast_strlen_zero(v->value)) {
8969 goto out_401; /* Authorization Header not present - send auth request */
8970 }
8971
8972 /* Digest found - parse */
8973 if (ast_string_field_init(&d, 128)) {
8975 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8976 return 0;
8977 }
8978
8979 if (ast_parse_digest(v->value, &d, 0, 1)) {
8980 /* Error in Digest - send new one */
8981 nonce = 0;
8982 goto out_401;
8983 }
8984 if (sscanf(d.nonce, "%30lx", &nonce) != 1) {
8985 ast_log(LOG_WARNING, "Received incorrect nonce in Digest <%s>\n", d.nonce);
8986 nonce = 0;
8987 goto out_401;
8988 }
8989
8991 user = get_manager_by_name_locked(d.username);
8992 if(!user) {
8994 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8995 nonce = 0;
8996 goto out_401;
8997 }
8998
8999 /* --- We have User for this auth, now check ACL */
9000 if (user->acl && !ast_apply_acl(user->acl, remote_address, "Manager User ACL:")) {
9002 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
9004 ast_http_error(ser, 403, "Permission denied", "Permission denied");
9005 return 0;
9006 }
9007
9008 /* --- We have auth, so check it */
9009
9010 /* compute the expected response to compare with what we received */
9011 {
9012 char *a2;
9013 /* ast_md5_hash outputs 32 characters plus NULL terminator. */
9014 char a2_hash[33];
9015 char resp[256];
9016
9017 /* XXX Now request method are hardcoded in A2 */
9018 if (ast_asprintf(&a2, "%s:%s", ast_get_http_method(method), d.uri) < 0) {
9021 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
9022 return 0;
9023 }
9024
9025 ast_md5_hash(a2_hash, a2);
9026 ast_free(a2);
9027
9028 if (d.qop) {
9029 /* RFC 2617 */
9030 snprintf(resp, sizeof(resp), "%s:%08lx:%s:%s:auth:%s", user->a1_hash, nonce, d.nc, d.cnonce, a2_hash);
9031 } else {
9032 /* RFC 2069 */
9033 snprintf(resp, sizeof(resp), "%s:%08lx:%s", user->a1_hash, nonce, a2_hash);
9034 }
9035 ast_md5_hash(resp_hash, resp);
9036 }
9037
9038 if (strncasecmp(d.response, resp_hash, strlen(resp_hash))) {
9039 /* Something was wrong, so give the client to try with a new challenge */
9041 nonce = 0;
9042 goto out_401;
9043 }
9044
9045 /*
9046 * User are pass Digest authentication.
9047 * Now, cache the user data and unlock user list.
9048 */
9049 ast_copy_string(u_username, user->username, sizeof(u_username));
9050 u_readperm = user->readperm;
9051 u_writeperm = user->writeperm;
9052 u_displayconnects = user->displayconnects;
9053 u_writetimeout = user->writetimeout;
9055
9056 if (!(session = find_session_by_nonce(d.username, nonce, &stale))) {
9057 /*
9058 * Create new session.
9059 * While it is not in the list we don't need any locking
9060 */
9061 if (!(session = build_mansession(remote_address))) {
9063 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
9064 return 0;
9065 }
9067
9068 ast_copy_string(session->username, u_username, sizeof(session->username));
9069 session->managerid = nonce;
9070 session->last_ev = grab_last();
9071 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
9072
9073 session->readperm = u_readperm;
9074 session->writeperm = u_writeperm;
9075 session->writetimeout = u_writetimeout;
9076
9077 if (u_displayconnects) {
9078 ast_verb(2, "HTTP Manager '%s' logged in from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
9079 }
9080 session->noncetime = session->sessionstart = time_now;
9081 session->authenticated = 1;
9082 } else if (stale) {
9083 /*
9084 * Session found, but nonce is stale.
9085 *
9086 * This could be because an old request (w/old nonce) arrived.
9087 *
9088 * This may be as the result of http proxy usage (separate delay or
9089 * multipath) or in a situation where a page was refreshed too quickly
9090 * (seen in Firefox).
9091 *
9092 * In this situation, we repeat the 401 auth with the current nonce
9093 * value.
9094 */
9095 nonce = session->managerid;
9097 stale = 1;
9098 goto out_401;
9099 } else {
9100 sscanf(d.nc, "%30lx", &nc);
9101 if (session->nc >= nc || ((time_now - session->noncetime) > 62) ) {
9102 /*
9103 * Nonce time expired (> 2 minutes) or something wrong with nonce
9104 * counter.
9105 *
9106 * Create new nonce key and resend Digest auth request. Old nonce
9107 * is saved for stale checking...
9108 */
9109 session->nc = 0; /* Reset nonce counter */
9110 session->oldnonce = session->managerid;
9111 nonce = session->managerid = ast_random();
9112 session->noncetime = time_now;
9114 stale = 1;
9115 goto out_401;
9116 } else {
9117 session->nc = nc; /* All OK, save nonce counter */
9118 }
9119 }
9120
9121
9122 /* Reset session timeout. */
9123 session->sessiontimeout = time(NULL) + (httptimeout > 5 ? httptimeout : 5);
9125
9126 ast_mutex_init(&s.lock);
9127 s.session = session;
9128 fd = mkstemp(template); /* create a temporary file for command output */
9129 unlink(template);
9130 if (fd <= -1) {
9131 ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
9132 goto auth_callback_out;
9133 }
9135 if (!s.stream) {
9136 ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
9137 ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
9138 close(fd);
9139 goto auth_callback_out;
9140 }
9141
9142 if (method == AST_HTTP_POST) {
9143 params = ast_http_get_post_vars(ser, headers);
9144 if (!params) {
9145 switch (errno) {
9146 case EFBIG:
9147 ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
9149 goto auth_callback_out;
9150 case ENOMEM:
9152 ast_http_error(ser, 500, "Server Error", "Out of memory");
9154 goto auth_callback_out;
9155 case EIO:
9156 ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
9158 goto auth_callback_out;
9159 }
9160 }
9161 }
9162
9163 astman_append_headers(&m, params);
9164
9165 if (process_message(&s, &m)) {
9166 if (u_displayconnects) {
9167 ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
9168 }
9169
9170 session->needdestroy = 1;
9171 }
9172
9174
9175 result_size = lseek(ast_iostream_get_fd(s.stream), 0, SEEK_CUR); /* Calculate approx. size of result */
9176
9177 http_header = ast_str_create(80);
9178 out = ast_str_create(result_size * 2 + 512);
9179 if (http_header == NULL || out == NULL) {
9181 ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
9183 goto auth_callback_out;
9184 }
9185
9186 ast_str_append(&http_header, 0, "Content-type: text/%s\r\n", contenttype[format]);
9187
9188 if (format == FORMAT_XML) {
9189 ast_str_append(&out, 0, "<ajax-response>\n");
9190 } else if (format == FORMAT_HTML) {
9191 ast_str_append(&out, 0,
9192 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
9193 "<html><head>\r\n"
9194 "<title>Asterisk&trade; Manager Interface</title>\r\n"
9195 "</head><body style=\"background-color: #ffffff;\">\r\n"
9196 "<form method=\"POST\">\r\n"
9197 "<table align=\"center\" style=\"background-color: #f1f1f1;\" width=\"500\">\r\n"
9198 "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\"><h1>Manager Tester</h1></th></tr>\r\n"
9199 "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\">Action: <input name=\"action\" /> Cmd: <input name=\"command\" /><br>"
9200 "<input type=\"submit\" value=\"Send request\" /></th></tr>\r\n");
9201 }
9202
9203 process_output(&s, &out, params, format);
9204
9205 if (format == FORMAT_XML) {
9206 ast_str_append(&out, 0, "</ajax-response>\n");
9207 } else if (format == FORMAT_HTML) {
9208 ast_str_append(&out, 0, "</table></form></body></html>\r\n");
9209 }
9210
9211 ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
9212 http_header = NULL;
9213 out = NULL;
9214
9215auth_callback_out:
9217
9218 /* Clear resources and unlock manager session */
9219 if (method == AST_HTTP_POST && params) {
9220 ast_variables_destroy(params);
9221 }
9222
9223 ast_free(http_header);
9224 ast_free(out);
9225
9227 if (session->stream) {
9228 ast_iostream_close(session->stream);
9229 session->stream = NULL;
9230 }
9232
9233 if (session->needdestroy) {
9234 ast_debug(1, "Need destroy, doing it now!\n");
9236 }
9238 return 0;
9239
9240out_401:
9241 if (!nonce) {
9242 nonce = ast_random();
9243 }
9244
9245 ast_http_auth(ser, global_realm, nonce, nonce, stale, NULL);
9247 return 0;
9248}
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:799
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
static int process_message(struct mansession *s, const struct message *m)
Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the ...
Definition: manager.c:7391
static struct mansession_session * build_mansession(const struct ast_sockaddr *addr)
Allocate manager session structure and add it to the list of sessions.
Definition: manager.c:2389
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:3074
static void session_destroy(struct mansession_session *s)
Definition: manager.c:2429
static void astman_append_headers(struct message *m, const struct ast_variable *params)
Append additional headers into the message structure from params.
Definition: manager.c:3060
static struct eventqent * grab_last(void)
Definition: manager.c:2123
void ast_http_send(struct ast_tcptls_session_instance *ser, enum ast_http_method method, int status_code, const char *status_title, struct ast_str *http_header, struct ast_str *out, int fd, unsigned int static_content)
Generic function for sending HTTP/1.1 response.
Definition: http.c:459
struct ast_variable * ast_http_get_post_vars(struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
Get post variables from client Request Entity-Body, if content type is application/x-www-form-urlenco...
Definition: http.c:1356
@ AST_HTTP_POST
Definition: http.h:61
@ AST_HTTP_GET
Definition: http.h:60
@ AST_HTTP_HEAD
Definition: http.h:62
const char * ast_get_http_method(enum ast_http_method method) attribute_pure
Return http method name string.
Definition: http.c:193
void ast_http_auth(struct ast_tcptls_session_instance *ser, const char *realm, const unsigned long nonce, const unsigned long opaque, int stale, const char *text)
Send http "401 Unauthorized" response and close socket.
Definition: http.c:625
void ast_http_request_close_on_completion(struct ast_tcptls_session_instance *ser)
Request the HTTP connection be closed after this HTTP request.
Definition: http.c:840
void ast_http_error(struct ast_tcptls_session_instance *ser, int status, const char *title, const char *text)
Send HTTP error message and close socket.
Definition: http.c:651
#define ast_verb(level,...)
struct ast_iostream * ast_iostream_from_fd(int *fd)
Create an iostream from a file descriptor.
Definition: iostream.c:611
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition: iostream.c:85
int ast_iostream_close(struct ast_iostream *stream)
Close an iostream.
Definition: iostream.c:539
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_mutex_destroy(a)
Definition: lock.h:188
int errno
static void close_mansession_file(struct mansession *s)
Definition: manager.c:8672
static struct mansession_session * find_session_by_nonce(const char *username, unsigned long nonce, int *stale)
Definition: manager.c:8316
static void process_output(struct mansession *s, struct ast_str **out, struct ast_variable *params, enum output_format format)
Definition: manager.c:8682
static const char *const contenttype[]
Definition: manager.c:8266
const char * method
Definition: res_pjsip.c:1279
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
Support for dynamic strings.
Definition: strings.h:623
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:1785
struct ast_iostream * stream
Definition: manager.c:1787
ast_mutex_t lock
Definition: manager.c:1792
static struct test_val d
FILE * out
Definition: utils/frame.c:33
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic)
Parse digest authorization header.
Definition: utils.c:2638
long int ast_random(void)
Definition: utils.c:2312

References ao2_lock, ao2_unlock, ast_apply_acl(), ast_asprintf, ast_copy_string(), ast_debug, ast_free, ast_get_http_method(), ast_http_auth(), ast_http_error(), AST_HTTP_GET, ast_http_get_post_vars(), AST_HTTP_HEAD, AST_HTTP_POST, ast_http_request_close_on_completion(), ast_http_send(), ast_iostream_close(), ast_iostream_from_fd(), ast_iostream_get_fd(), AST_LIST_HEAD_INIT_NOLOCK, ast_log, ast_md5_hash(), ast_mutex_destroy, ast_mutex_init, ast_parse_digest(), ast_random(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sockaddr_stringify_addr(), ast_str_append(), ast_str_create, ast_string_field_free_memory, ast_string_field_init, ast_strlen_zero(), ast_variables_destroy(), ast_verb, astman_append_headers(), astman_free_headers(), build_mansession(), close_mansession_file(), contenttype, d, errno, find_session_by_nonce(), FORMAT_HTML, FORMAT_XML, get_manager_by_name_locked(), global_realm, grab_last(), httptimeout, mansession::lock, LOG_NOTICE, LOG_WARNING, method, ast_variable::name, ast_variable::next, NULL, out, process_message(), process_output(), mansession::session, session, session_destroy(), mansession::stream, and ast_variable::value.

Referenced by auth_manager_http_callback(), auth_mxml_http_callback(), and auth_rawman_http_callback().

◆ auth_manager_http_callback()

static int auth_manager_http_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 9309 of file manager.c.

9310{
9311 int retval;
9312 struct ast_sockaddr ser_remote_address_tmp;
9313
9314 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9315 retval = auth_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
9316 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9317 return retval;
9318}
static ENTRY retval
Definition: hsearch.c:50
static int auth_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, const struct ast_sockaddr *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:8927
struct ast_sockaddr remote_address
Definition: tcptls.h:152

References ast_sockaddr_copy(), auth_http_callback(), FORMAT_HTML, method, ast_tcptls_session_instance::remote_address, and retval.

◆ auth_mxml_http_callback()

static int auth_mxml_http_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 9320 of file manager.c.

9321{
9322 int retval;
9323 struct ast_sockaddr ser_remote_address_tmp;
9324
9325 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9326 retval = auth_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
9327 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9328 return retval;
9329}

References ast_sockaddr_copy(), auth_http_callback(), FORMAT_XML, method, ast_tcptls_session_instance::remote_address, and retval.

◆ auth_rawman_http_callback()

static int auth_rawman_http_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 9331 of file manager.c.

9332{
9333 int retval;
9334 struct ast_sockaddr ser_remote_address_tmp;
9335
9336 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9337 retval = auth_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
9338 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9339 return retval;
9340}

References ast_sockaddr_copy(), auth_http_callback(), FORMAT_RAW, method, ast_tcptls_session_instance::remote_address, and retval.

◆ close_mansession_file()

static void close_mansession_file ( struct mansession s)
static

Definition at line 8672 of file manager.c.

8673{
8674 if (s->stream) {
8676 s->stream = NULL;
8677 } else {
8678 ast_log(LOG_ERROR, "Attempted to close file/file descriptor on mansession without a valid file or file descriptor.\n");
8679 }
8680}

References ast_iostream_close(), ast_log, LOG_ERROR, NULL, and mansession::stream.

Referenced by auth_http_callback(), generic_http_callback(), and process_output().

◆ find_session()

static struct mansession_session * find_session ( uint32_t  ident,
int  incinuse 
)
static

locate an http session in the list. The search key (ident) is the value of the mansession_id cookie (0 is not valid and means a session on the AMI socket).

Definition at line 8277 of file manager.c.

8278{
8279 struct ao2_container *sessions;
8281 struct ao2_iterator i;
8282
8283 if (ident == 0) {
8284 return NULL;
8285 }
8286
8287 sessions = ao2_global_obj_ref(mgr_sessions);
8288 if (!sessions) {
8289 return NULL;
8290 }
8292 ao2_ref(sessions, -1);
8293 while ((session = ao2_iterator_next(&i))) {
8295 if (session->managerid == ident && !session->needdestroy) {
8296 ast_atomic_fetchadd_int(&session->inuse, incinuse ? 1 : 0);
8297 break;
8298 }
8301 }
8303
8304 return session;
8305}
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757

References ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_atomic_fetchadd_int(), NULL, session, sessions, and unref_mansession().

Referenced by astman_is_authed(), generic_http_callback(), and manager_fax_session().

◆ find_session_by_nonce()

static struct mansession_session * find_session_by_nonce ( const char *  username,
unsigned long  nonce,
int *  stale 
)
static

locate an http session in the list. The search keys (nonce) and (username) is value from received "Authorization" http header. As well as in find_session() function, the value of the nonce can't be zero. (0 meansi, that the session used for AMI socket connection). Flag (stale) is set, if client used valid, but old, nonce value.

Definition at line 8316 of file manager.c.

8317{
8319 struct ao2_container *sessions;
8320 struct ao2_iterator i;
8321
8322 if (nonce == 0 || username == NULL || stale == NULL) {
8323 return NULL;
8324 }
8325
8326 sessions = ao2_global_obj_ref(mgr_sessions);
8327 if (!sessions) {
8328 return NULL;
8329 }
8331 ao2_ref(sessions, -1);
8332 while ((session = ao2_iterator_next(&i))) {
8334 if (!strcasecmp(session->username, username) && session->managerid == nonce) {
8335 *stale = 0;
8336 break;
8337 } else if (!strcasecmp(session->username, username) && session->oldnonce == nonce) {
8338 *stale = 1;
8339 break;
8340 }
8343 }
8345
8346 return session;
8347}

References ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, NULL, session, sessions, and unref_mansession().

Referenced by auth_http_callback().

◆ function_amiclient()

static int function_amiclient ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

${AMI_CLIENT()} Dialplan function - reads manager client data

Definition at line 9385 of file manager.c.

9386{
9387 struct ast_manager_user *user = NULL;
9388
9391 AST_APP_ARG(param);
9392 );
9393
9394
9395 if (ast_strlen_zero(data) ) {
9396 ast_log(LOG_WARNING, "AMI_CLIENT() requires two arguments: AMI_CLIENT(<name>[,<arg>])\n");
9397 return -1;
9398 }
9400 args.name = ast_strip(args.name);
9401 args.param = ast_strip(args.param);
9402
9404 if (!(user = get_manager_by_name_locked(args.name))) {
9406 ast_log(LOG_ERROR, "There's no manager user called : \"%s\"\n", args.name);
9407 return -1;
9408 }
9410
9411 if (!strcasecmp(args.param, "sessions")) {
9412 int no_sessions = 0;
9413 struct ao2_container *sessions;
9414
9415 sessions = ao2_global_obj_ref(mgr_sessions);
9416 if (sessions) {
9417 ao2_callback_data(sessions, 0, get_manager_sessions_cb, /*login name*/ data, &no_sessions);
9418 ao2_ref(sessions, -1);
9419 }
9420 snprintf(buf, len, "%d", no_sessions);
9421 } else {
9422 ast_log(LOG_ERROR, "Invalid arguments provided to function AMI_CLIENT: %s\n", args.param);
9423 return -1;
9424
9425 }
9426
9427 return 0;
9428}
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1723
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static const char name[]
Definition: format_mp3.c:68
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
static int get_manager_sessions_cb(void *obj, void *arg, void *data, int flags)
Get number of logged in sessions for a login name.
Definition: manager.c:9370
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
const char * args

References ao2_callback_data, ao2_global_obj_ref, ao2_ref, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, AST_STANDARD_APP_ARGS, ast_strip(), ast_strlen_zero(), buf, get_manager_by_name_locked(), get_manager_sessions_cb(), len(), LOG_ERROR, LOG_WARNING, name, NULL, and sessions.

◆ generic_http_callback()

static int generic_http_callback ( struct ast_tcptls_session_instance ser,
enum ast_http_method  method,
enum output_format  format,
const struct ast_sockaddr remote_address,
const char *  uri,
struct ast_variable get_params,
struct ast_variable headers 
)
static
Note
There is approximately a 1 in 1.8E19 chance that the following calculation will produce 0, which is an invalid ID, but due to the properties of the rand() function (and the constancy of s), that won't happen twice in a row.

Definition at line 8715 of file manager.c.

8721{
8722 struct mansession s = { .session = NULL, .tcptls_session = ser };
8724 uint32_t ident;
8725 int fd;
8726 int blastaway = 0;
8727 struct ast_variable *params = get_params;
8728 char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
8729 struct ast_str *http_header = NULL, *out = NULL;
8730 struct message m = { 0 };
8731
8733 ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
8734 return 0;
8735 }
8736
8737 ident = ast_http_manid_from_vars(headers);
8738
8739 if (!(session = find_session(ident, 1))) {
8740
8741 /**/
8742 /* Create new session.
8743 * While it is not in the list we don't need any locking
8744 */
8745 if (!(session = build_mansession(remote_address))) {
8747 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8748 return 0;
8749 }
8751 session->send_events = 0;
8752 session->inuse = 1;
8753 /*!
8754 * \note There is approximately a 1 in 1.8E19 chance that the following
8755 * calculation will produce 0, which is an invalid ID, but due to the
8756 * properties of the rand() function (and the constancy of s), that
8757 * won't happen twice in a row.
8758 */
8759 while ((session->managerid = ast_random() ^ (unsigned long) session) == 0) {
8760 }
8761 session->last_ev = grab_last();
8762 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
8763 }
8765
8766 http_header = ast_str_create(128);
8767 out = ast_str_create(2048);
8768
8769 ast_mutex_init(&s.lock);
8770
8771 if (http_header == NULL || out == NULL) {
8773 ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
8774 goto generic_callback_out;
8775 }
8776
8777 s.session = session;
8778 fd = mkstemp(template); /* create a temporary file for command output */
8779 unlink(template);
8780 if (fd <= -1) {
8781 ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
8782 goto generic_callback_out;
8783 }
8785 if (!s.stream) {
8786 ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
8787 ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
8788 close(fd);
8789 goto generic_callback_out;
8790 }
8791
8792 if (method == AST_HTTP_POST) {
8793 params = ast_http_get_post_vars(ser, headers);
8794 if (!params) {
8795 switch (errno) {
8796 case EFBIG:
8797 ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
8799 goto generic_callback_out;
8800 case ENOMEM:
8802 ast_http_error(ser, 500, "Server Error", "Out of memory");
8804 goto generic_callback_out;
8805 case EIO:
8806 ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8808 goto generic_callback_out;
8809 }
8810 }
8811 }
8812
8813 astman_append_headers(&m, params);
8814
8815 if (process_message(&s, &m)) {
8816 if (session->authenticated) {
8818 ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8819 }
8820 } else {
8821 if (displayconnects) {
8822 ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
8823 }
8824 }
8825 session->needdestroy = 1;
8826 }
8827
8829
8830 ast_str_append(&http_header, 0,
8831 "Content-type: text/%s\r\n"
8832 "Set-Cookie: mansession_id=\"%08x\"; Version=1; Max-Age=%d\r\n"
8833 "Pragma: SuppressEvents\r\n",
8834 contenttype[format],
8835 session->managerid, httptimeout);
8836
8837 if (format == FORMAT_XML) {
8838 ast_str_append(&out, 0, "<ajax-response>\n");
8839 } else if (format == FORMAT_HTML) {
8840 /*
8841 * When handling AMI-over-HTTP in HTML format, we provide a simple form for
8842 * debugging purposes. This HTML code should not be here, we
8843 * should read from some config file...
8844 */
8845
8846#define ROW_FMT "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\">%s</td></tr>\r\n"
8847#define TEST_STRING \
8848 "<form action=\"manager\" method=\"post\">\n\
8849 Action: <select name=\"action\">\n\
8850 <option value=\"\">-----&gt;</option>\n\
8851 <option value=\"login\">login</option>\n\
8852 <option value=\"command\">Command</option>\n\
8853 <option value=\"waitevent\">waitevent</option>\n\
8854 <option value=\"listcommands\">listcommands</option>\n\
8855 </select>\n\
8856 or <input name=\"action\"><br/>\n\
8857 CLI Command <input name=\"command\"><br>\n\
8858 user <input name=\"username\"> pass <input type=\"password\" name=\"secret\"><br>\n\
8859 <input type=\"submit\">\n</form>\n"
8860
8861 ast_str_append(&out, 0, "<title>Asterisk&trade; Manager Interface</title>");
8862 ast_str_append(&out, 0, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n");
8863 ast_str_append(&out, 0, ROW_FMT, "<h1>Manager Tester</h1>");
8865 }
8866
8867 process_output(&s, &out, params, format);
8868
8869 if (format == FORMAT_XML) {
8870 ast_str_append(&out, 0, "</ajax-response>\n");
8871 } else if (format == FORMAT_HTML) {
8872 ast_str_append(&out, 0, "</table></body>\r\n");
8873 }
8874
8876 /* Reset HTTP timeout. If we're not authenticated, keep it extremely short */
8877 session->sessiontimeout = time(NULL) + ((session->authenticated || httptimeout < 5) ? httptimeout : 5);
8878
8879 if (session->needdestroy) {
8880 if (session->inuse == 1) {
8881 ast_debug(1, "Need destroy, doing it now!\n");
8882 blastaway = 1;
8883 } else {
8884 ast_debug(1, "Need destroy, but can't do it yet!\n");
8885 ast_mutex_lock(&session->notify_lock);
8886 if (session->waiting_thread != AST_PTHREADT_NULL) {
8887 pthread_kill(session->waiting_thread, SIGURG);
8888 }
8889 ast_mutex_unlock(&session->notify_lock);
8890 session->inuse--;
8891 }
8892 } else {
8893 session->inuse--;
8894 }
8896
8897 ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
8898 http_header = NULL;
8899 out = NULL;
8900
8901generic_callback_out:
8903
8904 /* Clear resource */
8905
8906 if (method == AST_HTTP_POST && params) {
8907 ast_variables_destroy(params);
8908 }
8909 ast_free(http_header);
8910 ast_free(out);
8911
8912 if (session) {
8913 if (blastaway) {
8915 } else {
8916 if (session->stream) {
8917 ast_iostream_close(session->stream);
8918 session->stream = NULL;
8919 }
8921 }
8922 }
8923
8924 return 0;
8925}
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:2482
uint32_t ast_http_manid_from_vars(struct ast_variable *headers) attribute_pure
Return manager id, if exist, from request headers.
Definition: http.c:220
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
#define ROW_FMT
#define TEST_STRING

References ao2_lock, ao2_unlock, ast_debug, ast_free, ast_http_error(), AST_HTTP_GET, ast_http_get_post_vars(), AST_HTTP_HEAD, ast_http_manid_from_vars(), AST_HTTP_POST, ast_http_request_close_on_completion(), ast_http_send(), ast_iostream_close(), ast_iostream_from_fd(), AST_LIST_HEAD_INIT_NOLOCK, ast_log, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, ast_random(), ast_sockaddr_stringify_addr(), ast_str_append(), ast_str_create, ast_variables_destroy(), ast_verb, astman_append_headers(), astman_free_headers(), build_mansession(), close_mansession_file(), contenttype, displayconnects, errno, find_session(), FORMAT_HTML, FORMAT_XML, grab_last(), httptimeout, mansession::lock, LOG_WARNING, manager_displayconnects(), method, NULL, out, process_message(), process_output(), ROW_FMT, mansession::session, session, session_destroy(), mansession::stream, TEST_STRING, and unref_mansession().

Referenced by manager_http_callback(), mxml_http_callback(), and rawman_http_callback().

◆ get_manager_sessions_cb()

static int get_manager_sessions_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Get number of logged in sessions for a login name.

Definition at line 9370 of file manager.c.

9371{
9372 struct mansession_session *session = obj;
9373 const char *login = (char *)arg;
9374 int *no_sessions = data;
9375
9376 if (strcasecmp(session->username, login) == 0) {
9377 (*no_sessions)++;
9378 }
9379
9380 return 0;
9381}

References session.

Referenced by function_amiclient().

◆ handle_manager_show_event()

static char * handle_manager_show_event ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 9651 of file manager.c.

9652{
9654 struct ao2_iterator it_events;
9655 struct ast_xml_doc_item *item, *temp;
9656 int length;
9657
9658 if (cmd == CLI_INIT) {
9659 e->command = "manager show event";
9660 e->usage =
9661 "Usage: manager show event <eventname>\n"
9662 " Provides a detailed description a Manager interface event.\n";
9663 return NULL;
9664 }
9665
9666 events = ao2_global_obj_ref(event_docs);
9667 if (!events) {
9668 ast_cli(a->fd, "No manager event documentation loaded\n");
9669 return CLI_SUCCESS;
9670 }
9671
9672 if (cmd == CLI_GENERATE) {
9673 if (a->pos != 3) {
9674 return NULL;
9675 }
9676
9677 length = strlen(a->word);
9678 it_events = ao2_iterator_init(events, 0);
9679 while ((item = ao2_iterator_next(&it_events))) {
9680 if (!strncasecmp(a->word, item->name, length)) {
9682 ao2_ref(item, -1);
9683 break;
9684 }
9685 }
9686 ao2_ref(item, -1);
9687 }
9688 ao2_iterator_destroy(&it_events);
9689
9690 return NULL;
9691 }
9692
9693 if (a->argc != 4) {
9694 return CLI_SHOWUSAGE;
9695 }
9696
9697 if (!(item = ao2_find(events, a->argv[3], OBJ_KEY))) {
9698 ast_cli(a->fd, "Could not find event '%s'\n", a->argv[3]);
9699 return CLI_SUCCESS;
9700 }
9701
9702 ast_cli(a->fd, "Event: %s\n", a->argv[3]);
9703 for (temp = item; temp; temp = AST_LIST_NEXT(temp, next)) {
9704 print_event_instance(a, temp);
9705 }
9706
9707 ao2_ref(item, -1);
9708 return CLI_SUCCESS;
9709}
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
#define OBJ_KEY
Definition: astobj2.h:1151
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2761
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance)
Definition: manager.c:9614
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
const char * name
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
struct ast_xml_doc_item * next
Definition: xmldoc.h:80
static struct aco_type item
Definition: test_config.c:1463
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References a, ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), ast_cli_completion_add(), AST_LIST_NEXT, ast_strdup, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, events, item, aco_type::name, ast_xml_doc_item::next, NULL, OBJ_KEY, print_event_instance(), RAII_VAR, and ast_cli_entry::usage.

◆ handle_manager_show_events()

static char * handle_manager_show_events ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 9533 of file manager.c.

9534{
9535 struct ao2_container *events;
9536 struct ao2_iterator *it_events;
9537 struct ast_xml_doc_item *item;
9538 struct ast_xml_doc_item **items;
9539 struct ast_str *buffer;
9540 int i = 0, totalitems = 0;
9541
9542 switch (cmd) {
9543 case CLI_INIT:
9544 e->command = "manager show events";
9545 e->usage =
9546 "Usage: manager show events\n"
9547 " Prints a listing of the available Asterisk manager interface events.\n";
9548 return NULL;
9549 case CLI_GENERATE:
9550 return NULL;
9551 }
9552 if (a->argc != 3) {
9553 return CLI_SHOWUSAGE;
9554 }
9555
9556 buffer = ast_str_create(128);
9557 if (!buffer) {
9558 return CLI_SUCCESS;
9559 }
9560
9561 events = ao2_global_obj_ref(event_docs);
9562 if (!events) {
9563 ast_cli(a->fd, "No manager event documentation loaded\n");
9564 ast_free(buffer);
9565 return CLI_SUCCESS;
9566 }
9567
9569 if (!(it_events = ao2_callback(events, OBJ_MULTIPLE | OBJ_NOLOCK, NULL, NULL))) {
9571 ast_log(AST_LOG_ERROR, "Unable to create iterator for events container\n");
9572 ast_free(buffer);
9573 ao2_ref(events, -1);
9574 return CLI_SUCCESS;
9575 }
9576 if (!(items = ast_calloc(sizeof(struct ast_xml_doc_item *), ao2_container_count(events)))) {
9578 ast_log(AST_LOG_ERROR, "Unable to create temporary sorting array for events\n");
9579 ao2_iterator_destroy(it_events);
9580 ast_free(buffer);
9581 ao2_ref(events, -1);
9582 return CLI_SUCCESS;
9583 }
9585
9586 while ((item = ao2_iterator_next(it_events))) {
9587 items[totalitems++] = item;
9588 ao2_ref(item, -1);
9589 }
9590
9591 qsort(items, totalitems, sizeof(struct ast_xml_doc_item *), ast_xml_doc_item_cmp_fn);
9592
9593 ast_cli(a->fd, "Events:\n");
9594 ast_cli(a->fd, " -------------------- -------------------- -------------------- \n");
9595 for (i = 0; i < totalitems; i++) {
9596 ast_str_append(&buffer, 0, " %-20.20s", items[i]->name);
9597 if ((i + 1) % 3 == 0) {
9598 ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
9599 ast_str_set(&buffer, 0, "%s", "");
9600 }
9601 }
9602 if ((i + 1) % 3 != 0) {
9603 ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
9604 }
9605
9606 ao2_iterator_destroy(it_events);
9607 ast_free(items);
9608 ao2_ref(events, -1);
9609 ast_free(buffer);
9610
9611 return CLI_SUCCESS;
9612}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
#define AST_LOG_ERROR
static int ast_xml_doc_item_cmp_fn(const void *a, const void *b)
Definition: manager.c:9526
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113

References a, ao2_callback, ao2_container_count(), ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_calloc, ast_cli(), ast_free, ast_log, AST_LOG_ERROR, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_xml_doc_item_cmp_fn(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, events, item, name, NULL, OBJ_MULTIPLE, OBJ_NOLOCK, and ast_cli_entry::usage.

◆ handle_manager_show_settings()

static char * handle_manager_show_settings ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

CLI command manager show settings.

Definition at line 9482 of file manager.c.

9483{
9484 switch (cmd) {
9485 case CLI_INIT:
9486 e->command = "manager show settings";
9487 e->usage =
9488 "Usage: manager show settings\n"
9489 " Provides detailed list of the configuration of the Manager.\n";
9490 return NULL;
9491 case CLI_GENERATE:
9492 return NULL;
9493 }
9494#define FORMAT " %-25.25s %-15.55s\n"
9495#define FORMAT2 " %-25.25s %-15d\n"
9496#define FORMAT3 " %-25.25s %s\n"
9497 if (a->argc != 3) {
9498 return CLI_SHOWUSAGE;
9499 }
9500 ast_cli(a->fd, "\nGlobal Settings:\n");
9501 ast_cli(a->fd, "----------------\n");
9502 ast_cli(a->fd, FORMAT, "Manager (AMI):", AST_CLI_YESNO(manager_enabled));
9503 ast_cli(a->fd, FORMAT, "Web Manager (AMI/HTTP):", AST_CLI_YESNO(webmanager_enabled));
9504 ast_cli(a->fd, FORMAT, "TCP Bindaddress:", manager_enabled != 0 ? ast_sockaddr_stringify(&ami_desc.local_address) : "Disabled");
9505 ast_cli(a->fd, FORMAT2, "HTTP Timeout (seconds):", httptimeout);
9506 ast_cli(a->fd, FORMAT, "TLS Enable:", AST_CLI_YESNO(ami_tls_cfg.enabled));
9507 ast_cli(a->fd, FORMAT, "TLS Bindaddress:", ami_tls_cfg.enabled != 0 ? ast_sockaddr_stringify(&amis_desc.local_address) : "Disabled");
9508 ast_cli(a->fd, FORMAT, "TLS Certfile:", ami_tls_cfg.certfile);
9509 ast_cli(a->fd, FORMAT, "TLS Privatekey:", ami_tls_cfg.pvtfile);
9510 ast_cli(a->fd, FORMAT, "TLS Cipher:", ami_tls_cfg.cipher);
9511 ast_cli(a->fd, FORMAT, "Allow multiple login:", AST_CLI_YESNO(allowmultiplelogin));
9512 ast_cli(a->fd, FORMAT, "Display connects:", AST_CLI_YESNO(displayconnects));
9513 ast_cli(a->fd, FORMAT, "Timestamp events:", AST_CLI_YESNO(timestampevents));
9514 ast_cli(a->fd, FORMAT3, "Channel vars:", S_OR(manager_channelvars, ""));
9515 ast_cli(a->fd, FORMAT3, "Disabled events:", S_OR(manager_disabledevents, ""));
9516 ast_cli(a->fd, FORMAT, "Debug:", AST_CLI_YESNO(manager_debug));
9517#undef FORMAT
9518#undef FORMAT2
9519#undef FORMAT3
9520
9521 return CLI_SUCCESS;
9522}
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
static char * manager_channelvars
Definition: manager.c:1634
static char * manager_disabledevents
Definition: manager.c:1635
#define FORMAT3
#define FORMAT
#define FORMAT2
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
char * certfile
Definition: tcptls.h:90
char * cipher
Definition: tcptls.h:92
char * pvtfile
Definition: tcptls.h:91

References a, allowmultiplelogin, ami_desc, ami_tls_cfg, amis_desc, ast_cli(), AST_CLI_YESNO, ast_sockaddr_stringify(), ast_tls_config::certfile, ast_tls_config::cipher, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, displayconnects, ast_tls_config::enabled, FORMAT, FORMAT2, FORMAT3, httptimeout, ast_tcptls_session_args::local_address, manager_channelvars, manager_debug, manager_disabledevents, manager_enabled, NULL, ast_tls_config::pvtfile, S_OR, timestampevents, ast_cli_entry::usage, and webmanager_enabled.

◆ load_channelvars()

static void load_channelvars ( struct ast_variable var)
static

Definition at line 9736 of file manager.c.

9737{
9738 char *parse = NULL;
9740 AST_APP_ARG(vars)[MAX_VARS];
9741 );
9742
9745
9746 /* parse the setting */
9749
9751}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
void ast_channel_set_manager_vars(size_t varc, char **vars)
Sets the variables to be stored in the manager_vars field of all snapshots.
Definition: channel.c:7887
#define MAX_VARS
Definition: manager.c:1667

References args, AST_APP_ARG, ast_channel_set_manager_vars(), AST_DECLARE_APP_ARGS, ast_free, AST_STANDARD_APP_ARGS, ast_strdup, ast_strdupa, manager_channelvars, MAX_VARS, NULL, and var.

Referenced by __init_manager().

◆ load_disabledevents()

static void load_disabledevents ( struct ast_variable var)
static

Definition at line 9759 of file manager.c.

References ast_free, ast_strdup, manager_disabledevents, and var.

Referenced by __init_manager().

◆ load_module()

static int load_module ( void  )
static

Definition at line 10491 of file manager.c.

10492{
10494
10496}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static int __init_manager(int reload, int by_external_config)
Definition: manager.c:9978
static void manager_shutdown(void)
Definition: manager.c:9788
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

References __init_manager(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_cleanup(), and manager_shutdown().

◆ manager_event_blob_dtor()

static void manager_event_blob_dtor ( void *  obj)
static

Definition at line 10555 of file manager.c.

10556{
10557 struct ast_manager_event_blob *ev = obj;
10558
10560}

References ast_string_field_free_memory.

Referenced by ast_manager_event_blob_create().

◆ manager_free_user()

static void manager_free_user ( struct ast_manager_user user)
static

Definition at line 9769 of file manager.c.

9770{
9771 ast_free(user->a1_hash);
9772 ast_free(user->secret);
9773 if (user->whitefilters) {
9774 ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one");
9775 }
9776 if (user->blackfilters) {
9777 ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one");
9778 }
9779 user->acl = ast_free_acl_list(user->acl);
9780 ast_variables_destroy(user->chanvars);
9781 ast_free(user);
9782}

References ao2_t_ref, ast_free, ast_free_acl_list(), and ast_variables_destroy().

Referenced by __init_manager(), and manager_shutdown().

◆ manager_http_callback()

static int manager_http_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 9250 of file manager.c.

9251{
9252 int retval;
9253 struct ast_sockaddr ser_remote_address_tmp;
9254
9255 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9256 retval = generic_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
9257 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9258 return retval;
9259}
static int generic_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, const struct ast_sockaddr *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:8715

References ast_sockaddr_copy(), FORMAT_HTML, generic_http_callback(), method, ast_tcptls_session_instance::remote_address, and retval.

◆ manager_set_defaults()

static void manager_set_defaults ( void  )
static

Definition at line 9950 of file manager.c.

9951{
9952 manager_enabled = 0;
9953 displayconnects = 1;
9955 authtimeout = 30;
9956 authlimit = 50;
9957 manager_debug = 0; /* Debug disabled by default */
9958
9959 /* default values */
9961 sizeof(global_realm));
9964
9965 ami_tls_cfg.enabled = 0;
9976}
#define DEFAULT_REALM
Definition: manager.c:1637
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
char * capath
Definition: tcptls.h:94
char * cafile
Definition: tcptls.h:93
#define AST_CERTFILE
Definition: tcptls.h:63

References ami_desc, ami_tls_cfg, amis_desc, AST_CERTFILE, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_free, ast_sockaddr_setnull(), ast_strdup, authlimit, authtimeout, broken_events_action, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, DEFAULT_REALM, displayconnects, ast_tls_config::enabled, global_realm, ast_tcptls_session_args::local_address, manager_debug, manager_enabled, ast_tls_config::pvtfile, and S_OR.

Referenced by __init_manager().

◆ manager_shutdown()

static void manager_shutdown ( void  )
static

Definition at line 9788 of file manager.c.

9789{
9790 struct ast_manager_user *user;
9791
9792 /* This event is not actually transmitted, but causes all TCP sessions to be closed */
9793 manager_event(EVENT_FLAG_SHUTDOWN, "CloseSession", "CloseSession: true\r\n");
9794
9795 ast_manager_unregister("Ping");
9796 ast_manager_unregister("Events");
9797 ast_manager_unregister("Logoff");
9798 ast_manager_unregister("Login");
9799 ast_manager_unregister("Challenge");
9800 ast_manager_unregister("Hangup");
9801 ast_manager_unregister("Status");
9802 ast_manager_unregister("Setvar");
9803 ast_manager_unregister("Getvar");
9804 ast_manager_unregister("GetConfig");
9805 ast_manager_unregister("GetConfigJSON");
9806 ast_manager_unregister("UpdateConfig");
9807 ast_manager_unregister("CreateConfig");
9808 ast_manager_unregister("ListCategories");
9809 ast_manager_unregister("Redirect");
9810 ast_manager_unregister("Atxfer");
9811 ast_manager_unregister("CancelAtxfer");
9812 ast_manager_unregister("Originate");
9813 ast_manager_unregister("Command");
9814 ast_manager_unregister("ExtensionState");
9815 ast_manager_unregister("PresenceState");
9816 ast_manager_unregister("AbsoluteTimeout");
9817 ast_manager_unregister("MailboxStatus");
9818 ast_manager_unregister("MailboxCount");
9819 ast_manager_unregister("ListCommands");
9820 ast_manager_unregister("SendText");
9821 ast_manager_unregister("UserEvent");
9822 ast_manager_unregister("WaitEvent");
9823 ast_manager_unregister("CoreSettings");
9824 ast_manager_unregister("CoreStatus");
9825 ast_manager_unregister("Reload");
9826 ast_manager_unregister("LoggerRotate");
9827 ast_manager_unregister("CoreShowChannels");
9828 ast_manager_unregister("CoreShowChannelMap");
9829 ast_manager_unregister("ModuleLoad");
9830 ast_manager_unregister("ModuleCheck");
9831 ast_manager_unregister("AOCMessage");
9832 ast_manager_unregister("Filter");
9833 ast_manager_unregister("BlindTransfer");
9836
9837#ifdef AST_XML_DOCS
9838 ao2_t_global_obj_release(event_docs, "Dispose of event_docs");
9839#endif
9840
9841#ifdef TEST_FRAMEWORK
9842 stasis_forward_cancel(test_suite_forwarder);
9843 test_suite_forwarder = NULL;
9844#endif
9845
9846 if (stasis_router) {
9849 }
9857
9860
9871
9872 ao2_global_obj_release(mgr_sessions);
9873
9874 while ((user = AST_LIST_REMOVE_HEAD(&users, list))) {
9876 }
9878
9881}
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
#define ao2_t_global_obj_release(holder, tag)
Definition: astobj2.h:861
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct stasis_message_router * stasis_router
The stasis_message_router for all Stasis Message Bus API messages.
Definition: manager.c:1647
static struct stasis_forward * rtp_topic_forwarder
The stasis_subscription for forwarding the RTP topic to the AMI topic.
Definition: manager.c:1650
static struct stasis_forward * security_topic_forwarder
The stasis_subscription for forwarding the Security topic to the AMI topic.
Definition: manager.c:1653
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:1670
int ast_manager_unregister(const char *action)
support functions to register/unregister AMI action handlers,
Definition: manager.c:8057
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static char user[512]
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548
void stasis_message_router_unsubscribe_and_join(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic, blocking until the final message has been processed.

References acl_change_stasis_unsubscribe(), ami_desc, ami_tls_cfg, amis_desc, ao2_cleanup, ao2_global_obj_release, ao2_t_global_obj_release, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free, AST_LIST_REMOVE_HEAD, ast_manager_get_generic_type(), ast_manager_unregister(), ast_tcptls_server_stop(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, cli_manager, EVENT_FLAG_SHUTDOWN, manager_channelvars, manager_disabledevents, manager_event, manager_free_user(), manager_topic, managerclient_function, NULL, ast_tls_config::pvtfile, rtp_topic_forwarder, security_topic_forwarder, stasis_forward_cancel(), stasis_message_router_unsubscribe_and_join(), STASIS_MESSAGE_TYPE_CLEANUP, stasis_router, and user.

Referenced by load_module().

◆ manager_subscriptions_init()

static int manager_subscriptions_init ( void  )
static

Initialize all Stasis Message Bus API topics and routers used by the various sub-components of AMI.

Definition at line 9887 of file manager.c.

9888{
9889 int res = 0;
9890
9892 if (!rtp_topic_forwarder) {
9893 return -1;
9894 }
9895
9898 return -1;
9899 }
9900
9902 if (!stasis_router) {
9903 return -1;
9904 }
9907
9910
9913
9914 if (res != 0) {
9915 return -1;
9916 }
9917 return 0;
9918}
static void manager_default_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:1998
static void manager_generic_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:2029
struct stasis_topic * ast_rtp_topic(void)
Stasis Message Bus API topic for RTP and RTCP related messages
Definition: rtp_engine.c:3675
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
@ STASIS_SUBSCRIPTION_FORMATTER_AMI
Definition: stasis.h:311
int stasis_message_router_set_congestion_limits(struct stasis_message_router *router, long low_water, long high_water)
Set the high and low alert water marks of the stasis message router.
#define stasis_message_router_create(topic)
Create a new message router object.
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
void stasis_message_router_set_formatters_default(struct stasis_message_router *router, stasis_subscription_cb callback, void *data, enum stasis_subscription_message_formatters formatters)
Sets the default route of a router with formatters.
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
Definition: taskprocessor.h:64

References ast_manager_get_generic_type(), ast_rtp_topic(), ast_security_topic(), AST_TASKPROCESSOR_HIGH_WATER_LEVEL, manager_default_msg_cb(), manager_generic_msg_cb(), manager_topic, NULL, rtp_topic_forwarder, security_topic_forwarder, stasis_forward_all(), stasis_message_router_add(), stasis_message_router_create, stasis_message_router_set_congestion_limits(), stasis_message_router_set_formatters_default(), stasis_router, and STASIS_SUBSCRIPTION_FORMATTER_AMI.

Referenced by subscribe_all().

◆ mxml_http_callback()

static int mxml_http_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 9261 of file manager.c.

9262{
9263 int retval;
9264 struct ast_sockaddr ser_remote_address_tmp;
9265
9266 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9267 retval = generic_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
9268 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9269 return retval;
9270}

References ast_sockaddr_copy(), FORMAT_XML, generic_http_callback(), method, ast_tcptls_session_instance::remote_address, and retval.

◆ process_output()

static void process_output ( struct mansession s,
struct ast_str **  out,
struct ast_variable params,
enum output_format  format 
)
static

Definition at line 8682 of file manager.c.

8683{
8684 char *buf;
8685 off_t l;
8686 int fd;
8687
8688 if (!s->stream)
8689 return;
8690
8691 /* Ensure buffer is NULL-terminated */
8692 ast_iostream_write(s->stream, "", 1);
8693
8694 fd = ast_iostream_get_fd(s->stream);
8695
8696 l = lseek(fd, 0, SEEK_CUR);
8697 if (l > 0) {
8698 if (MAP_FAILED == (buf = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))) {
8699 ast_log(LOG_WARNING, "mmap failed. Manager output was not processed\n");
8700 } else {
8701 if (format == FORMAT_XML || format == FORMAT_HTML) {
8702 xml_translate(out, buf, params, format);
8703 } else {
8704 ast_str_append(out, 0, "%s", buf);
8705 }
8706 munmap(buf, l);
8707 }
8708 } else if (format == FORMAT_XML || format == FORMAT_HTML) {
8709 xml_translate(out, "", params, format);
8710 }
8711
8713}
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t count)
Write data to an iostream.
Definition: iostream.c:385
static void xml_translate(struct ast_str **out, char *in, struct ast_variable *get_vars, enum output_format format)
Convert the input into XML or HTML. The input is supposed to be a sequence of lines of the form Name:...
Definition: manager.c:8554

References ast_iostream_get_fd(), ast_iostream_write(), ast_log, ast_str_append(), buf, close_mansession_file(), FORMAT_HTML, FORMAT_XML, LOG_WARNING, NULL, out, mansession::stream, and xml_translate().

Referenced by auth_http_callback(), and generic_http_callback().

◆ purge_old_stuff()

static void purge_old_stuff ( void *  data)
static

cleanup code called at each iteration of server_root, guaranteed to happen every 5 seconds at most

Definition at line 9443 of file manager.c.

9444{
9445 struct ast_tcptls_session_args *ser = data;
9446 /* purge_sessions will return the number of sessions actually purged,
9447 * up to a maximum of it's arguments, purge one at a time, keeping a
9448 * purge interval of 1ms as long as we purged a session, otherwise
9449 * revert to a purge check every 5s
9450 */
9451 if (purge_sessions(1) == 1) {
9452 ser->poll_timeout = 1;
9453 } else {
9454 ser->poll_timeout = 5000;
9455 }
9456 purge_events();
9457}
static void purge_events(void)
Definition: manager.c:2143
static int purge_sessions(int n_max)
remove at most n_max stale session from the list.
Definition: manager.c:7819
arguments for the accepting thread
Definition: tcptls.h:130

References ast_tcptls_session_args::poll_timeout, purge_events(), and purge_sessions().

◆ rawman_http_callback()

static int rawman_http_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 9272 of file manager.c.

9273{
9274 int retval;
9275 struct ast_sockaddr ser_remote_address_tmp;
9276
9277 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9278 retval = generic_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
9279 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9280 return retval;
9281}

References ast_sockaddr_copy(), FORMAT_RAW, generic_http_callback(), method, ast_tcptls_session_instance::remote_address, and retval.

◆ subscribe_all()

static int subscribe_all ( void  )
static

Definition at line 9920 of file manager.c.

9921{
9923 ast_log(AST_LOG_ERROR, "Failed to initialize manager subscriptions\n");
9924 return -1;
9925 }
9926 if (manager_system_init()) {
9927 ast_log(AST_LOG_ERROR, "Failed to initialize manager system handling\n");
9928 return -1;
9929 }
9930 if (manager_channels_init()) {
9931 ast_log(AST_LOG_ERROR, "Failed to initialize manager channel handling\n");
9932 return -1;
9933 }
9934 if (manager_mwi_init()) {
9935 ast_log(AST_LOG_ERROR, "Failed to initialize manager MWI handling\n");
9936 return -1;
9937 }
9938 if (manager_bridging_init()) {
9939 return -1;
9940 }
9941 if (manager_endpoints_init()) {
9942 ast_log(AST_LOG_ERROR, "Failed to initialize manager endpoints handling\n");
9943 return -1;
9944 }
9945
9946 subscribed = 1;
9947 return 0;
9948}
static int manager_subscriptions_init(void)
Initialize all Stasis Message Bus API topics and routers used by the various sub-components of AMI.
Definition: manager.c:9887
int manager_mwi_init(void)
Initialize support for AMI MWI events.
Definition: manager_mwi.c:155
int manager_bridging_init(void)
Initialize support for AMI channel events.
int manager_endpoints_init(void)
Initialize support for AMI endpoint events.
int manager_system_init(void)
Initialize support for AMI system events.
int manager_channels_init(void)
Initialize support for AMI channel events.

References ast_log, AST_LOG_ERROR, manager_bridging_init(), manager_channels_init(), manager_endpoints_init(), manager_mwi_init(), manager_subscriptions_init(), manager_system_init(), and subscribed.

Referenced by __init_manager().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 10486 of file manager.c.

10487{
10488 return 0;
10489}

◆ variable_count_cmp_fn()

static int variable_count_cmp_fn ( void *  obj,
void *  vstr,
int  flags 
)
static

Definition at line 8515 of file manager.c.

8516{
8517 /* Due to the simplicity of struct variable_count, it makes no difference
8518 * if you pass in objects or strings, the same operation applies. This is
8519 * due to the fact that the hash occurs on the first element, which means
8520 * the address of both the struct and the string are exactly the same. */
8521 struct variable_count *vc = obj;
8522 char *str = vstr;
8523 return !strcmp(vc->varname, str) ? CMP_MATCH | CMP_STOP : 0;
8524}
const char * str
Definition: app_jack.c:147
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
char * varname
Definition: manager.c:8504

References CMP_MATCH, CMP_STOP, str, and variable_count::varname.

Referenced by xml_translate().

◆ variable_count_hash_fn()

static int variable_count_hash_fn ( const void *  vvc,
const int  flags 
)
static

Definition at line 8508 of file manager.c.

8509{
8510 const struct variable_count *vc = vvc;
8511
8512 return ast_str_hash(vc->varname);
8513}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

References ast_str_hash(), and variable_count::varname.

Referenced by xml_translate().

◆ xml_copy_escape()

static void xml_copy_escape ( struct ast_str **  out,
const char *  src,
int  mode 
)
static

Definition at line 8436 of file manager.c.

8437{
8438 /* store in a local buffer to avoid calling ast_str_append too often */
8439 char buf[256];
8440 char *dst = buf;
8441 const char *save = src;
8442 int space = sizeof(buf);
8443 /* repeat until done and nothing to flush */
8444 for ( ; *src || dst != buf ; src++) {
8445 if (*src == '\0' || space < 10) { /* flush */
8446 *dst++ = '\0';
8447 ast_str_append(out, 0, "%s", buf);
8448 dst = buf;
8449 space = sizeof(buf);
8450 if (*src == '\0') {
8451 break;
8452 }
8453 }
8454
8455 if (mode & 2) {
8456 if (save == src && isdigit(*src)) {
8457 /* The first character of an XML attribute cannot be a digit */
8458 *dst++ = '_';
8459 *dst++ = *src;
8460 space -= 2;
8461 continue;
8462 } else if (!isalnum(*src)) {
8463 /* Replace non-alphanumeric with an underscore */
8464 *dst++ = '_';
8465 space--;
8466 continue;
8467 }
8468 }
8469 switch (*src) {
8470 case '<':
8471 strcpy(dst, "&lt;");
8472 dst += 4;
8473 space -= 4;
8474 break;
8475 case '>':
8476 strcpy(dst, "&gt;");
8477 dst += 4;
8478 space -= 4;
8479 break;
8480 case '\"':
8481 strcpy(dst, "&quot;");
8482 dst += 6;
8483 space -= 6;
8484 break;
8485 case '\'':
8486 strcpy(dst, "&apos;");
8487 dst += 6;
8488 space -= 6;
8489 break;
8490 case '&':
8491 strcpy(dst, "&amp;");
8492 dst += 5;
8493 space -= 5;
8494 break;
8495
8496 default:
8497 *dst++ = mode ? tolower(*src) : *src;
8498 space--;
8499 }
8500 }
8501}

References ast_str_append(), buf, and out.

Referenced by xml_translate().

◆ xml_translate()

static void xml_translate ( struct ast_str **  out,
char *  in,
struct ast_variable get_vars,
enum output_format  format 
)
static

Convert the input into XML or HTML. The input is supposed to be a sequence of lines of the form Name: value optionally followed by a blob of unformatted text. A blank line is a section separator. Basically, this is a mixture of the format of Manager Interface and CLI commands. The unformatted text is considered as a single value of a field named 'Opaque-data'.

At the moment the output format is the following (but it may change depending on future requirements so don't count too much on it when writing applications):

General: the unformatted text is used as a value of XML output: to be completed

*   Each section is within <response type="object" id="xxx">
*   where xxx is taken from ajaxdest variable or defaults to unknown
*   Each row is reported as an attribute Name="value" of an XML
*   entity named from the variable ajaxobjtype, default to "generic"
* 

HTML output: each Name-value pair is output as a single row of a two-column table. Sections (blank lines in the input) are separated by a


Definition at line 8554 of file manager.c.

8555{
8556 struct ast_variable *v;
8557 const char *dest = NULL;
8558 char *var, *val;
8559 const char *objtype = NULL;
8560 int in_data = 0; /* parsing data */
8561 int inobj = 0;
8562 int xml = (format == FORMAT_XML);
8563 struct variable_count *vc = NULL;
8564 struct ao2_container *vco = NULL;
8565
8566 if (xml) {
8567 /* dest and objtype need only for XML format */
8568 for (v = get_vars; v; v = v->next) {
8569 if (!strcasecmp(v->name, "ajaxdest")) {
8570 dest = v->value;
8571 } else if (!strcasecmp(v->name, "ajaxobjtype")) {
8572 objtype = v->value;
8573 }
8574 }
8575 if (ast_strlen_zero(dest)) {
8576 dest = "unknown";
8577 }
8578 if (ast_strlen_zero(objtype)) {
8579 objtype = "generic";
8580 }
8581 }
8582
8583 /* we want to stop when we find an empty line */
8584 while (in && *in) {
8585 val = strsep(&in, "\r\n"); /* mark start and end of line */
8586 if (in && *in == '\n') { /* remove trailing \n if any */
8587 in++;
8588 }
8590 ast_debug(5, "inobj %d in_data %d line <%s>\n", inobj, in_data, val);
8591 if (ast_strlen_zero(val)) {
8592 /* empty line */
8593 if (in_data) {
8594 /* close data in Opaque mode */
8595 ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
8596 in_data = 0;
8597 }
8598
8599 if (inobj) {
8600 /* close block */
8601 ast_str_append(out, 0, xml ? " /></response>\n" :
8602 "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
8603 inobj = 0;
8604 ao2_ref(vco, -1);
8605 vco = NULL;
8606 }
8607 continue;
8608 }
8609
8610 if (!inobj) {
8611 /* start new block */
8612 if (xml) {
8613 ast_str_append(out, 0, "<response type='object' id='%s'><%s", dest, objtype);
8614 }
8617 inobj = 1;
8618 }
8619
8620 if (in_data) {
8621 /* Process data field in Opaque mode. This is a
8622 * followup, so we re-add line feeds. */
8623 ast_str_append(out, 0, xml ? "\n" : "<br>\n");
8624 xml_copy_escape(out, val, 0); /* data field */
8625 continue;
8626 }
8627
8628 /* We expect "Name: value" line here */
8629 var = strsep(&val, ":");
8630 if (val) {
8631 /* found the field name */
8634 } else {
8635 /* field name not found, switch to opaque mode */
8636 val = var;
8637 var = "Opaque-data";
8638 in_data = 1;
8639 }
8640
8641
8642 ast_str_append(out, 0, xml ? " " : "<tr><td>");
8643 if ((vc = ao2_find(vco, var, 0))) {
8644 vc->count++;
8645 } else {
8646 /* Create a new entry for this one */
8647 vc = ao2_alloc(sizeof(*vc), NULL);
8648 vc->varname = var;
8649 vc->count = 1;
8650 ao2_link(vco, vc);
8651 }
8652
8653 xml_copy_escape(out, var, xml ? 1 | 2 : 0); /* data name */
8654 if (vc->count > 1) {
8655 ast_str_append(out, 0, "-%d", vc->count);
8656 }
8657 ao2_ref(vc, -1);
8658 ast_str_append(out, 0, xml ? "='" : "</td><td>");
8659 xml_copy_escape(out, val, 0); /* data field */
8660 if (!in_data || !*in) {
8661 ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
8662 }
8663 }
8664
8665 if (inobj) {
8666 ast_str_append(out, 0, xml ? " /></response>\n" :
8667 "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
8668 ao2_ref(vco, -1);
8669 }
8670}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
char * strsep(char **str, const char *delims)
static void xml_copy_escape(struct ast_str **out, const char *src, int mode)
Definition: manager.c:8436
static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
Definition: manager.c:8515
static int variable_count_hash_fn(const void *vvc, const int flags)
Definition: manager.c:8508
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:186
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
FILE * in
Definition: utils/frame.c:33

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_find, ao2_link, ao2_ref, ast_debug, ast_skip_blanks(), ast_str_append(), ast_strlen_zero(), ast_trim_blanks(), variable_count::count, FORMAT_XML, in, ast_variable::name, ast_variable::next, NULL, out, strsep(), ast_variable::value, var, variable_count_cmp_fn(), variable_count_hash_fn(), variable_count::varname, and xml_copy_escape().

Referenced by process_output().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Manager Interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig,acl,http", }
static

Definition at line 10603 of file manager.c.

◆ amanageruri

struct ast_http_uri amanageruri
static

Definition at line 9351 of file manager.c.

Referenced by __init_manager().

◆ amanagerxmluri

struct ast_http_uri amanagerxmluri
static

Definition at line 9360 of file manager.c.

Referenced by __init_manager().

◆ ami_desc

struct ast_tcptls_session_args ami_desc
static

◆ ami_tls_cfg

struct ast_tls_config ami_tls_cfg
static

◆ amis_desc

struct ast_tcptls_session_args amis_desc
static

◆ arawmanuri

struct ast_http_uri arawmanuri
static

Definition at line 9342 of file manager.c.

Referenced by __init_manager().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 10603 of file manager.c.

◆ cli_manager

struct ast_cli_entry cli_manager[]
static

Definition at line 9713 of file manager.c.

Referenced by __init_manager(), and manager_shutdown().

◆ contenttype

const char* const contenttype[]
static
Initial value:
= {
[FORMAT_RAW] = "plain",
[FORMAT_HTML] = "html",
[FORMAT_XML] = "xml",
}

Definition at line 8266 of file manager.c.

Referenced by auth_http_callback(), and generic_http_callback().

◆ managerclient_function

struct ast_custom_function managerclient_function
static
Initial value:
= {
.name = "AMI_CLIENT",
.read_max = 12,
}
static int function_amiclient(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
${AMI_CLIENT()} Dialplan function - reads manager client data
Definition: manager.c:9385

description of AMI_CLIENT dialplan function

Definition at line 9432 of file manager.c.

Referenced by __init_manager(), and manager_shutdown().

◆ manageruri

struct ast_http_uri manageruri
static

Definition at line 9291 of file manager.c.

Referenced by __init_manager().

◆ managerxmluri

struct ast_http_uri managerxmluri
static

Definition at line 9299 of file manager.c.

Referenced by __init_manager().

◆ rawmanuri

struct ast_http_uri rawmanuri
static

Definition at line 9283 of file manager.c.

Referenced by __init_manager().

◆ webregged

int webregged = 0
static

Definition at line 9438 of file manager.c.

Referenced by __init_manager().

◆ words

const char* words[AST_MAX_CMD_LEN]

Definition at line 1684 of file manager.c.

Referenced by check_blacklist().