Asterisk - The Open Source Telephony Project GIT-master-5963e62
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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/bridge_after.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  event_filter_entry
 
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  originate_permissions_entry
 
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 = 0 , FILTER_ALLOC_FAILED , FILTER_COMPILE_FAIL , FILTER_FORMAT_ERROR }
 
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  event_filter_match_type {
  FILTER_MATCH_REGEX = 0 , FILTER_MATCH_EXACT , FILTER_MATCH_STARTS_WITH , FILTER_MATCH_ENDS_WITH ,
  FILTER_MATCH_CONTAINS , FILTER_MATCH_NONE
}
 
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 int app_match (const char *app, const char *data, const char *search)
 
static int appdata_match (const char *app, const char *data, const char *search)
 
static void append_channel_vars (struct ast_str **pbuf, struct ast_channel *chan)
 
static int append_event (const char *str, int event_name_hash, 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 async_goto_with_discard_bridge_after (struct ast_channel *chan, const char *context, const char *exten, int priority)
 
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 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 int file_in_modules_dir (const char *filename)
 Check if the given file path is in the modules dir or not. More...
 
static int filter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
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 int is_originate_app_permitted (const char *app, const char *data, int permission)
 
static int is_restricted_file (const char *filename)
 Check if a file is restricted or not. 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 *criteria, const char *filter_pattern, struct ao2_container *includefilters, struct ao2_container *excludefilters)
 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_eventdata (struct event_filter_entry *entry, const char *eventdata)
 Test eventdata against a filter entry. More...
 
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_match (const char *app, const char *data, const char *search)
 
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 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 should_send_event (struct ao2_container *includefilters, struct ao2_container *excludefilters, struct eventqent *eqe)
 
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 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 char * match_type_names []
 
static struct originate_permissions_entry originate_app_permissions []
 
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 7911 of file manager.c.

7911 {
7912 FORMAT_RAW,
7914 FORMAT_XML,
7915};
@ FORMAT_RAW
Definition: manager.c:7912
@ FORMAT_HTML
Definition: manager.c:7913
@ FORMAT_XML
Definition: manager.c:7914

Function Documentation

◆ __init_manager()

static int __init_manager ( int  reload,
int  by_external_config 
)
static

Definition at line 9646 of file manager.c.

9647{
9648 struct ast_config *ucfg = NULL, *cfg = NULL;
9649 const char *val;
9650 char *cat = NULL;
9651 int newhttptimeout = 60;
9652 struct ast_manager_user *user = NULL;
9653 struct ast_variable *var;
9654 struct ast_flags config_flags = { (reload && !by_external_config) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
9655 char a1[337];
9656 char a1_hash[256];
9657 struct ast_sockaddr ami_desc_local_address_tmp;
9658 struct ast_sockaddr amis_desc_local_address_tmp;
9659 int tls_was_enabled = 0;
9660 int acl_subscription_flag = 0;
9661
9662 if (!reload) {
9663 struct ao2_container *sessions;
9664#ifdef AST_XML_DOCS
9665 struct ao2_container *temp_event_docs;
9666#endif
9667 int res;
9668
9670 if (res != 0) {
9671 return -1;
9672 }
9673 manager_topic = stasis_topic_create("manager:core");
9674 if (!manager_topic) {
9675 return -1;
9676 }
9677
9678 /* Register default actions */
9718
9719#ifdef TEST_FRAMEWORK
9720 test_suite_forwarder = stasis_forward_all(ast_test_suite_topic(), manager_topic);
9721#endif
9722
9726
9727 /* Append placeholder event so master_eventq never runs dry */
9728 if (append_event("Event: Placeholder\r\n\r\n",
9729 ast_str_hash("Placeholder"), 0)) {
9730 return -1;
9731 }
9732
9733#ifdef AST_XML_DOCS
9734 temp_event_docs = ast_xmldoc_build_documentation("managerEvent");
9735 if (temp_event_docs) {
9736 ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs");
9737 ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now");
9738 }
9739#endif
9740
9741 /* If you have a NULL hash fn, you only need a single bucket */
9743 if (!sessions) {
9744 return -1;
9745 }
9747 ao2_ref(sessions, -1);
9748
9749 /* Initialize all settings before first configuration load. */
9751 }
9752
9753 cfg = ast_config_load2("manager.conf", "manager", config_flags);
9754 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
9755 return 0;
9756 } else if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
9757 ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid.\n");
9758 return 0;
9759 }
9760
9761 /* 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. */
9762 if (!by_external_config) {
9764 }
9765
9766 if (reload) {
9767 /* Reset all settings before reloading configuration */
9768 tls_was_enabled = ami_tls_cfg.enabled;
9770 }
9771
9772 ast_sockaddr_parse(&ami_desc_local_address_tmp, "[::]", 0);
9773 ast_sockaddr_set_port(&ami_desc_local_address_tmp, DEFAULT_MANAGER_PORT);
9774
9775 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
9776 val = var->value;
9777
9778 /* read tls config options while preventing unsupported options from being set */
9779 if (strcasecmp(var->name, "tlscafile")
9780 && strcasecmp(var->name, "tlscapath")
9781 && strcasecmp(var->name, "tlscadir")
9782 && strcasecmp(var->name, "tlsverifyclient")
9783 && strcasecmp(var->name, "tlsdontverifyserver")
9784 && strcasecmp(var->name, "tlsclientmethod")
9785 && strcasecmp(var->name, "sslclientmethod")
9786 && !ast_tls_read_conf(&ami_tls_cfg, &amis_desc, var->name, val)) {
9787 continue;
9788 }
9789
9790 if (!strcasecmp(var->name, "enabled")) {
9792 } else if (!strcasecmp(var->name, "webenabled")) {
9794 } else if (!strcasecmp(var->name, "port")) {
9795 int bindport;
9796 if (ast_parse_arg(val, PARSE_UINT32|PARSE_IN_RANGE, &bindport, 1024, 65535)) {
9797 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
9798 }
9799 ast_sockaddr_set_port(&ami_desc_local_address_tmp, bindport);
9800 } else if (!strcasecmp(var->name, "bindaddr")) {
9801 /* remember port if it has already been set */
9802 int setport = ast_sockaddr_port(&ami_desc_local_address_tmp);
9803
9805 ast_log(LOG_WARNING, "Invalid address '%s' specified, default '%s' will be used\n", val,
9806 ast_sockaddr_stringify_addr(&ami_desc_local_address_tmp));
9807 } else {
9808 ast_sockaddr_parse(&ami_desc_local_address_tmp, val, PARSE_PORT_IGNORE);
9809 }
9810
9811 if (setport) {
9812 ast_sockaddr_set_port(&ami_desc_local_address_tmp, setport);
9813 }
9814
9815 } else if (!strcasecmp(var->name, "brokeneventsaction")) {
9817 } else if (!strcasecmp(var->name, "allowmultiplelogin")) {
9819 } else if (!strcasecmp(var->name, "displayconnects")) {
9821 } else if (!strcasecmp(var->name, "timestampevents")) {
9823 } else if (!strcasecmp(var->name, "debug")) {
9825 } else if (!strcasecmp(var->name, "httptimeout")) {
9826 newhttptimeout = atoi(val);
9827 } else if (!strcasecmp(var->name, "authtimeout")) {
9828 int timeout = atoi(var->value);
9829
9830 if (timeout < 1) {
9831 ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", var->value);
9832 } else {
9833 authtimeout = timeout;
9834 }
9835 } else if (!strcasecmp(var->name, "authlimit")) {
9836 int limit = atoi(var->value);
9837
9838 if (limit < 1) {
9839 ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", var->value);
9840 } else {
9841 authlimit = limit;
9842 }
9843 } else if (!strcasecmp(var->name, "channelvars")) {
9845 } else if (!strcasecmp(var->name, "disabledevents")) {
9847 } else {
9848 ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
9849 var->name, val);
9850 }
9851 }
9852
9853 if (manager_enabled && !subscribed) {
9854 if (subscribe_all() != 0) {
9855 ast_log(LOG_ERROR, "Manager subscription error\n");
9856 return -1;
9857 }
9858 }
9859
9860 ast_sockaddr_copy(&amis_desc_local_address_tmp, &amis_desc.local_address);
9861
9862 /* if the amis address has not been set, default is the same as non secure ami */
9863 if (ast_sockaddr_isnull(&amis_desc_local_address_tmp)) {
9864 ast_sockaddr_copy(&amis_desc_local_address_tmp, &ami_desc_local_address_tmp);
9865 }
9866
9867 /* if the amis address was not set, it will have non-secure ami port set; if
9868 amis address was set, we need to check that a port was set or not, if not
9869 use the default tls port */
9870 if (ast_sockaddr_port(&amis_desc_local_address_tmp) == 0 ||
9871 (ast_sockaddr_port(&ami_desc_local_address_tmp) == ast_sockaddr_port(&amis_desc_local_address_tmp))) {
9872
9873 ast_sockaddr_set_port(&amis_desc_local_address_tmp, DEFAULT_MANAGER_TLS_PORT);
9874 }
9875
9876 if (manager_enabled) {
9877 ast_sockaddr_copy(&ami_desc.local_address, &ami_desc_local_address_tmp);
9878 ast_sockaddr_copy(&amis_desc.local_address, &amis_desc_local_address_tmp);
9879 }
9880
9882
9883 /* First, get users from users.conf */
9884 ucfg = ast_config_load2("users.conf", "manager", config_flags);
9885 if (ucfg && (ucfg != CONFIG_STATUS_FILEUNCHANGED) && ucfg != CONFIG_STATUS_FILEINVALID) {
9886 const char *hasmanager;
9887 int genhasmanager = ast_true(ast_variable_retrieve(ucfg, "general", "hasmanager"));
9888
9889 while ((cat = ast_category_browse(ucfg, cat))) {
9890 if (!strcasecmp(cat, "general")) {
9891 continue;
9892 }
9893
9894 hasmanager = ast_variable_retrieve(ucfg, cat, "hasmanager");
9895 if ((!hasmanager && genhasmanager) || ast_true(hasmanager)) {
9896 const char *user_secret = ast_variable_retrieve(ucfg, cat, "secret");
9897 const char *user_read = ast_variable_retrieve(ucfg, cat, "read");
9898 const char *user_write = ast_variable_retrieve(ucfg, cat, "write");
9899 const char *user_displayconnects = ast_variable_retrieve(ucfg, cat, "displayconnects");
9900 const char *user_allowmultiplelogin = ast_variable_retrieve(ucfg, cat, "allowmultiplelogin");
9901 const char *user_writetimeout = ast_variable_retrieve(ucfg, cat, "writetimeout");
9902
9903 /* Look for an existing entry,
9904 * if none found - create one and add it to the list
9905 */
9906 if (!(user = get_manager_by_name_locked(cat))) {
9907 if (!(user = ast_calloc(1, sizeof(*user)))) {
9908 break;
9909 }
9910
9911 /* Copy name over */
9912 ast_copy_string(user->username, cat, sizeof(user->username));
9913 /* Insert into list */
9915 user->acl = NULL;
9916 user->keep = 1;
9917 user->readperm = -1;
9918 user->writeperm = -1;
9919 /* Default displayconnect from [general] */
9920 user->displayconnects = displayconnects;
9921 /* Default allowmultiplelogin from [general] */
9922 user->allowmultiplelogin = allowmultiplelogin;
9923 user->writetimeout = 100;
9924 }
9925
9926 if (!user_secret) {
9927 user_secret = ast_variable_retrieve(ucfg, "general", "secret");
9928 }
9929 if (!user_read) {
9930 user_read = ast_variable_retrieve(ucfg, "general", "read");
9931 }
9932 if (!user_write) {
9933 user_write = ast_variable_retrieve(ucfg, "general", "write");
9934 }
9935 if (!user_displayconnects) {
9936 user_displayconnects = ast_variable_retrieve(ucfg, "general", "displayconnects");
9937 }
9938 if (!user_allowmultiplelogin) {
9939 user_allowmultiplelogin = ast_variable_retrieve(ucfg, "general", "allowmultiplelogin");
9940 }
9941 if (!user_writetimeout) {
9942 user_writetimeout = ast_variable_retrieve(ucfg, "general", "writetimeout");
9943 }
9944
9945 if (!ast_strlen_zero(user_secret)) {
9946 ast_free(user->secret);
9947 user->secret = ast_strdup(user_secret);
9948 }
9949
9950 if (user_read) {
9951 user->readperm = get_perm(user_read);
9952 }
9953 if (user_write) {
9954 user->writeperm = get_perm(user_write);
9955 }
9956 if (user_displayconnects) {
9957 user->displayconnects = ast_true(user_displayconnects);
9958 }
9959 if (user_allowmultiplelogin) {
9960 user->allowmultiplelogin = ast_true(user_allowmultiplelogin);
9961 }
9962 if (user_writetimeout) {
9963 int value = atoi(user_writetimeout);
9964 if (value < 100) {
9965 ast_log(LOG_WARNING, "Invalid writetimeout value '%d' in users.conf\n", value);
9966 } else {
9967 user->writetimeout = value;
9968 }
9969 }
9970 }
9971 }
9972 ast_config_destroy(ucfg);
9973 }
9974
9975 /* cat is NULL here in any case */
9976
9977 while ((cat = ast_category_browse(cfg, cat))) {
9978 struct ast_acl_list *oldacl;
9979
9980 if (!strcasecmp(cat, "general")) {
9981 continue;
9982 }
9983
9984 /* Look for an existing entry, if none found - create one and add it to the list */
9985 if (!(user = get_manager_by_name_locked(cat))) {
9986 if (!(user = ast_calloc(1, sizeof(*user)))) {
9987 break;
9988 }
9989 /* Copy name over */
9990 ast_copy_string(user->username, cat, sizeof(user->username));
9991
9992 user->acl = NULL;
9993 user->readperm = 0;
9994 user->writeperm = 0;
9995 /* Default displayconnect from [general] */
9996 user->displayconnects = displayconnects;
9997 /* Default allowmultiplelogin from [general] */
9998 user->allowmultiplelogin = allowmultiplelogin;
9999 user->writetimeout = 100;
10002 if (!user->includefilters || !user->excludefilters) {
10004 break;
10005 }
10006
10007 /* Insert into list */
10009 } else {
10010 ao2_t_callback(user->includefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all include filters");
10011 ao2_t_callback(user->excludefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all exclude filters");
10012 }
10013
10014 /* Make sure we keep this user and don't destroy it during cleanup */
10015 user->keep = 1;
10016 oldacl = user->acl;
10017 user->acl = NULL;
10018 ast_variables_destroy(user->chanvars);
10019
10020 var = ast_variable_browse(cfg, cat);
10021 for (; var; var = var->next) {
10022 if (!strcasecmp(var->name, "secret")) {
10023 ast_free(user->secret);
10024 user->secret = ast_strdup(var->value);
10025 } else if (!strcasecmp(var->name, "deny") ||
10026 !strcasecmp(var->name, "permit") ||
10027 !strcasecmp(var->name, "acl")) {
10028 int acl_error = 0;
10029
10030 ast_append_acl(var->name, var->value, &user->acl, &acl_error, &acl_subscription_flag);
10031 if (acl_error) {
10032 ast_log(LOG_ERROR, "Invalid ACL '%s' for manager user '%s' on line %d. Deleting user\n",
10033 var->value, user->username, var->lineno);
10034 user->keep = 0;
10035 }
10036 } else if (!strcasecmp(var->name, "read") ) {
10037 user->readperm = get_perm(var->value);
10038 } else if (!strcasecmp(var->name, "write") ) {
10039 user->writeperm = get_perm(var->value);
10040 } else if (!strcasecmp(var->name, "displayconnects") ) {
10041 user->displayconnects = ast_true(var->value);
10042 } else if (!strcasecmp(var->name, "allowmultiplelogin") ) {
10043 user->allowmultiplelogin = ast_true(var->value);
10044 } else if (!strcasecmp(var->name, "writetimeout")) {
10045 int value = atoi(var->value);
10046 if (value < 100) {
10047 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", var->value, var->lineno);
10048 } else {
10049 user->writetimeout = value;
10050 }
10051 } else if (!strcasecmp(var->name, "setvar")) {
10052 struct ast_variable *tmpvar;
10053 char varbuf[256];
10054 char *varval;
10055 char *varname;
10056
10057 ast_copy_string(varbuf, var->value, sizeof(varbuf));
10058 varname = varbuf;
10059
10060 if ((varval = strchr(varname,'='))) {
10061 *varval++ = '\0';
10062 if ((tmpvar = ast_variable_new(varname, varval, ""))) {
10063 tmpvar->next = user->chanvars;
10064 user->chanvars = tmpvar;
10065 }
10066 }
10067 } else if (ast_begins_with(var->name, "eventfilter")) {
10068 const char *value = var->value;
10069 manager_add_filter(var->name, value, user->includefilters, user->excludefilters);
10070 } else {
10071 ast_debug(1, "%s is an unknown option.\n", var->name);
10072 }
10073 }
10074
10075 oldacl = ast_free_acl_list(oldacl);
10076 }
10077 ast_config_destroy(cfg);
10078
10079 /* Check the flag for named ACL event subscription and if we need to, register a subscription. */
10080 if (acl_subscription_flag && !by_external_config) {
10082 }
10083
10084 /* Perform cleanup - essentially prune out old users that no longer exist */
10086 if (user->keep) { /* valid record. clear flag for the next round */
10087 user->keep = 0;
10088
10089 /* Calculate A1 for Digest auth */
10090 snprintf(a1, sizeof(a1), "%s:%s:%s", user->username, global_realm, user->secret);
10091 ast_md5_hash(a1_hash,a1);
10092 ast_free(user->a1_hash);
10093 user->a1_hash = ast_strdup(a1_hash);
10094 continue;
10095 }
10096 /* We do not need to keep this user so take them out of the list */
10098 ast_debug(4, "Pruning user '%s'\n", user->username);
10100 }
10102
10104
10106 if (!webregged) {
10110
10114 webregged = 1;
10115 }
10116 } else {
10117 if (webregged) {
10121
10125 webregged = 0;
10126 }
10127 }
10128
10129 if (newhttptimeout > 0) {
10130 httptimeout = newhttptimeout;
10131 }
10132
10134 if (tls_was_enabled && !ami_tls_cfg.enabled) {
10136 } else if (ast_ssl_setup(amis_desc.tls_cfg)) {
10138 }
10139
10140 return 0;
10141}
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:3552
static int action_createconfig(struct mansession *s, const struct message *m)
Definition: manager.c:3097
static int manager_state_cb(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
Definition: manager.c:7729
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:6830
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:1046
static void acl_change_stasis_subscribe(void)
Definition: manager.c:235
static int append_event(const char *str, int event_name_hash, int category)
events are appended to a queue from where they can be dispatched to clients.
Definition: manager.c:7497
static int manager_enabled
Definition: manager.c:170
static int action_sendtext(struct mansession *s, const struct message *m)
Definition: manager.c:3908
static int action_mailboxcount(struct mansession *s, const struct message *m)
Definition: manager.c:5443
static int action_getconfigjson(struct mansession *s, const struct message *m)
Definition: manager.c:2649
static int action_listcategories(struct mansession *s, const struct message *m)
Definition: manager.c:2573
static int action_hangup(struct mansession *s, const struct message *m)
Definition: manager.c:3546
static int action_listcommands(struct mansession *s, const struct message *m)
Definition: manager.c:3289
static int action_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:4148
static int action_timeout(struct mansession *s, const struct message *m)
Definition: manager.c:5534
static int action_coresettings(struct mansession *s, const struct message *m)
Show PBX core settings information.
Definition: manager.c:6463
static int mansession_cmp_fn(void *obj, void *arg, int flags)
Definition: manager.c:1003
static int displayconnects
Definition: manager.c:165
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:5686
static int manager_debug
Definition: manager.c:173
static int action_mailboxstatus(struct mansession *s, const struct message *m)
Definition: manager.c:5426
static int action_login(struct mansession *s, const struct message *m)
Definition: manager.c:3358
static int action_getvar(struct mansession *s, const struct message *m)
Definition: manager.c:3585
static int action_blind_transfer(struct mansession *s, const struct message *m)
Definition: manager.c:4102
static int action_extensionstate(struct mansession *s, const struct message *m)
Definition: manager.c:5464
static int action_getconfig(struct mansession *s, const struct message *m)
Definition: manager.c:2501
static enum add_filter_result manager_add_filter(const char *criteria, const char *filter_pattern, struct ao2_container *includefilters, struct ao2_container *excludefilters)
Add an event filter to a manager session.
Definition: manager.c:5753
static int action_logoff(struct mansession *s, const struct message *m)
Definition: manager.c:3352
static int action_updateconfig(struct mansession *s, const struct message *m)
Definition: manager.c:3006
static int manager_moduleload(struct mansession *s, const struct message *m)
Definition: manager.c:6907
static void acl_change_stasis_unsubscribe(void)
Definition: manager.c:245
static int action_reload(struct mansession *s, const struct message *m)
Send a reload event.
Definition: manager.c:6549
static int authlimit
Definition: manager.c:175
static int action_aocmessage(struct mansession *s, const struct message *m)
Definition: manager.c:4938
static int action_events(struct mansession *s, const struct message *m)
Definition: manager.c:3308
static int action_redirect(struct mansession *s, const struct message *m)
action_redirect: The redirect manager command
Definition: manager.c:3957
static int action_presencestate(struct mansession *s, const struct message *m)
Definition: manager.c:5494
static int allowmultiplelogin
Definition: manager.c:166
static int action_cancel_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:4202
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:180
static int action_originate(struct mansession *s, const struct message *m)
Definition: manager.c:5231
static int action_userevent(struct mansession *s, const struct message *m)
Definition: manager.c:6442
static int action_command(struct mansession *s, const struct message *m)
Manager command "command" - execute CLI command.
Definition: manager.c:4279
static int broken_events_action
Definition: manager.c:169
static int timestampevents
Definition: manager.c:167
static int subscribed
Definition: manager.c:171
static int authtimeout
Definition: manager.c:174
static int manager_modulecheck(struct mansession *s, const struct message *m)
Manager function to check if module is loaded.
Definition: manager.c:6842
static int webmanager_enabled
Definition: manager.c:172
static int action_status(struct mansession *s, const struct message *m)
Manager "status" command to show channels.
Definition: manager.c:3752
static int get_perm(const char *instr)
Definition: manager.c:866
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:6581
static int action_corestatus(struct mansession *s, const struct message *m)
Show PBX core status information.
Definition: manager.c:6507
static int action_challenge(struct mansession *s, const struct message *m)
Definition: manager.c:3407
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:186
static int action_waitevent(struct mansession *s, const struct message *m)
Definition: manager.c:3171
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:6749
static int action_ping(struct mansession *s, const struct message *m)
Definition: manager.c:2429
static int httptimeout
Definition: manager.c:168
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:721
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:689
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:3541
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:4047
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:869
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
@ CONFIG_FLAG_FILEUNCHANGED
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
#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:9110
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:9111
static struct ast_http_uri managerxmluri
Definition: manager.c:8950
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:9122
static struct ast_custom_function managerclient_function
description of AMI_CLIENT dialplan function
Definition: manager.c:9083
static void load_channelvars(struct ast_variable *var)
Definition: manager.c:9398
static struct ast_http_uri manageruri
Definition: manager.c:8942
static void manager_set_defaults(void)
Definition: manager.c:9618
static struct ast_http_uri arawmanuri
Definition: manager.c:8993
static struct ast_http_uri rawmanuri
Definition: manager.c:8934
static struct ast_cli_entry cli_manager[]
Definition: manager.c:9375
static void manager_free_user(struct ast_manager_user *user)
Definition: manager.c:9431
static struct ast_http_uri amanageruri
Definition: manager.c:9002
static int webregged
Definition: manager.c:9089
static int subscribe_all(void)
Definition: manager.c:9588
static struct ast_http_uri amanagerxmluri
Definition: manager.c:9011
static void load_disabledevents(struct ast_variable *var)
Definition: manager.c:9421
#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:203
#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:3838
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:644
#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:1605
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259
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
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
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:346
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:933
int ast_ssl_setup(struct ast_tls_config *cfg)
Set up an SSL server.
Definition: tcptls.c:577
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:768
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:959
#define ARRAY_LEN(a)
Definition: utils.h:672
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:2778

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_begins_with(), 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_str_hash(), 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 10278 of file manager.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 10278 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 10239 of file manager.c.

10244{
10245 struct ast_manager_event_blob *ev;
10246 va_list argp;
10247
10248 ast_assert(extra_fields_fmt != NULL);
10250
10252 if (!ev) {
10253 return NULL;
10254 }
10255
10256 if (ast_string_field_init(ev, 20)) {
10257 ao2_ref(ev, -1);
10258 return NULL;
10259 }
10260
10263
10264 va_start(argp, extra_fields_fmt);
10265 ast_string_field_ptr_build_va(ev, &ev->extra_fields, extra_fields_fmt, argp);
10266 va_end(argp);
10267
10268 return ev;
10269}
@ 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:10230
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:254
#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:503
const ast_string_field extra_fields
Definition: manager.h:508
const char * manager_event
Definition: manager.h:505
#define ast_assert(a)
Definition: utils.h:745

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 10278 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 10217 of file manager.c.

10219{
10220 if (!*fields_string) {
10221 *fields_string = ast_str_create(128);
10222 if (!*fields_string) {
10223 return -1;
10224 }
10225 }
10226
10227 return (ast_str_append(fields_string, 0, "%s: %s\r\n", header, value) < 0) ? -1 : 0;
10228}
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 9177 of file manager.c.

9178{
9179 struct ast_xml_doc_item **item_a = (struct ast_xml_doc_item **)a;
9180 struct ast_xml_doc_item **item_b = (struct ast_xml_doc_item **)b;
9181 return strcmp((*item_a)->name, (*item_b)->name);
9182}
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 10178 of file manager.c.

10179{
10180 AST_LIST_INSERT_HEAD(&s->session->datastores, datastore, entry);
10181
10182 return 0;
10183}
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
struct mansession_session::mansession_datastores datastores
struct mansession_session * session
Definition: manager.c:328

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 10190 of file manager.c.

10191{
10192 struct ast_datastore *datastore = NULL;
10193
10194 if (info == NULL)
10195 return NULL;
10196
10198 if (datastore->info != info) {
10199 continue;
10200 }
10201
10202 if (uid == NULL) {
10203 /* matched by type only */
10204 break;
10205 }
10206
10207 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
10208 /* Matched by type AND uid */
10209 break;
10210 }
10211 }
10213
10214 return datastore;
10215}
#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
struct ast_datastore::@219 entry
const char * uid
Definition: datastore.h:65

References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, mansession_session::datastores, ast_datastore::entry, 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 10185 of file manager.c.

10186{
10187 return AST_LIST_REMOVE(&s->session->datastores, datastore, entry) ? 0 : -1;
10188}
#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 8000 of file manager.c.

8001{
8002 int authed;
8004
8005 if (!(session = find_session(ident, 0)))
8006 return 0;
8007
8008 authed = (session->authenticated != 0);
8009
8012
8013 return authed;
8014}
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:918
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:7928

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 8016 of file manager.c.

8017{
8018 int result = 0;
8020 struct ao2_container *sessions;
8021 struct ao2_iterator i;
8022
8023 if (ident == 0) {
8024 return 0;
8025 }
8026
8027 sessions = ao2_global_obj_ref(mgr_sessions);
8028 if (!sessions) {
8029 return 0;
8030 }
8032 ao2_ref(sessions, -1);
8033 while ((session = ao2_iterator_next(&i))) {
8035 if ((session->managerid == ident) && (session->readperm & perm)) {
8036 result = 1;
8039 break;
8040 }
8043 }
8045
8046 return result;
8047}
#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 8049 of file manager.c.

8050{
8051 int result = 0;
8053 struct ao2_container *sessions;
8054 struct ao2_iterator i;
8055
8056 if (ident == 0) {
8057 return 0;
8058 }
8059
8060 sessions = ao2_global_obj_ref(mgr_sessions);
8061 if (!sessions) {
8062 return 0;
8063 }
8065 ao2_ref(sessions, -1);
8066 while ((session = ao2_iterator_next(&i))) {
8068 if ((session->managerid == ident) && (session->writeperm & perm)) {
8069 result = 1;
8072 break;
8073 }
8076 }
8078
8079 return result;
8080}

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 8578 of file manager.c.

8584{
8586 struct mansession s = { .session = NULL, .tcptls_session = ser };
8587 struct ast_variable *v, *params = get_params;
8588 char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
8589 struct ast_str *http_header = NULL, *out = NULL;
8590 size_t result_size;
8591 struct message m = { 0 };
8592 int fd;
8593
8594 time_t time_now = time(NULL);
8595 unsigned long nonce = 0, nc;
8596 struct ast_http_digest d = { NULL, };
8597 struct ast_manager_user *user = NULL;
8598 int stale = 0;
8599 char resp_hash[256]="";
8600 /* Cache for user data */
8601 char u_username[80];
8602 int u_readperm;
8603 int u_writeperm;
8604 int u_writetimeout;
8605 int u_displayconnects;
8606
8608 ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
8609 return 0;
8610 }
8611
8612 /* Find "Authorization: " header */
8613 for (v = headers; v; v = v->next) {
8614 if (!strcasecmp(v->name, "Authorization")) {
8615 break;
8616 }
8617 }
8618
8619 if (!v || ast_strlen_zero(v->value)) {
8620 goto out_401; /* Authorization Header not present - send auth request */
8621 }
8622
8623 /* Digest found - parse */
8624 if (ast_string_field_init(&d, 128)) {
8626 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8627 return 0;
8628 }
8629
8630 if (ast_parse_digest(v->value, &d, 0, 1)) {
8631 /* Error in Digest - send new one */
8632 nonce = 0;
8633 goto out_401;
8634 }
8635 if (sscanf(d.nonce, "%30lx", &nonce) != 1) {
8636 ast_log(LOG_WARNING, "Received incorrect nonce in Digest <%s>\n", d.nonce);
8637 nonce = 0;
8638 goto out_401;
8639 }
8640
8642 user = get_manager_by_name_locked(d.username);
8643 if(!user) {
8645 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8646 nonce = 0;
8647 goto out_401;
8648 }
8649
8650 /* --- We have User for this auth, now check ACL */
8651 if (user->acl && !ast_apply_acl(user->acl, remote_address, "Manager User ACL:")) {
8653 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8655 ast_http_error(ser, 403, "Permission denied", "Permission denied");
8656 return 0;
8657 }
8658
8659 /* --- We have auth, so check it */
8660
8661 /* compute the expected response to compare with what we received */
8662 {
8663 char *a2;
8664 /* ast_md5_hash outputs 32 characters plus NULL terminator. */
8665 char a2_hash[33];
8666 char resp[256];
8667
8668 /* XXX Now request method are hardcoded in A2 */
8669 if (ast_asprintf(&a2, "%s:%s", ast_get_http_method(method), d.uri) < 0) {
8672 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8673 return 0;
8674 }
8675
8676 ast_md5_hash(a2_hash, a2);
8677 ast_free(a2);
8678
8679 if (d.qop) {
8680 /* RFC 2617 */
8681 snprintf(resp, sizeof(resp), "%s:%08lx:%s:%s:auth:%s", user->a1_hash, nonce, d.nc, d.cnonce, a2_hash);
8682 } else {
8683 /* RFC 2069 */
8684 snprintf(resp, sizeof(resp), "%s:%08lx:%s", user->a1_hash, nonce, a2_hash);
8685 }
8686 ast_md5_hash(resp_hash, resp);
8687 }
8688
8689 if (strncasecmp(d.response, resp_hash, strlen(resp_hash))) {
8690 /* Something was wrong, so give the client to try with a new challenge */
8692 nonce = 0;
8693 goto out_401;
8694 }
8695
8696 /*
8697 * User are pass Digest authentication.
8698 * Now, cache the user data and unlock user list.
8699 */
8700 ast_copy_string(u_username, user->username, sizeof(u_username));
8701 u_readperm = user->readperm;
8702 u_writeperm = user->writeperm;
8703 u_displayconnects = user->displayconnects;
8704 u_writetimeout = user->writetimeout;
8706
8707 if (!(session = find_session_by_nonce(d.username, nonce, &stale))) {
8708 /*
8709 * Create new session.
8710 * While it is not in the list we don't need any locking
8711 */
8712 if (!(session = build_mansession(remote_address))) {
8714 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8715 return 0;
8716 }
8718
8719 ast_copy_string(session->username, u_username, sizeof(session->username));
8720 session->managerid = nonce;
8721 session->last_ev = grab_last();
8722 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
8723
8724 session->readperm = u_readperm;
8725 session->writeperm = u_writeperm;
8726 session->writetimeout = u_writetimeout;
8727
8728 if (u_displayconnects) {
8729 ast_verb(2, "HTTP Manager '%s' logged in from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8730 }
8731 session->noncetime = session->sessionstart = time_now;
8732 session->authenticated = 1;
8733 } else if (stale) {
8734 /*
8735 * Session found, but nonce is stale.
8736 *
8737 * This could be because an old request (w/old nonce) arrived.
8738 *
8739 * This may be as the result of http proxy usage (separate delay or
8740 * multipath) or in a situation where a page was refreshed too quickly
8741 * (seen in Firefox).
8742 *
8743 * In this situation, we repeat the 401 auth with the current nonce
8744 * value.
8745 */
8746 nonce = session->managerid;
8748 stale = 1;
8749 goto out_401;
8750 } else {
8751 sscanf(d.nc, "%30lx", &nc);
8752 if (session->nc >= nc || ((time_now - session->noncetime) > 62) ) {
8753 /*
8754 * Nonce time expired (> 2 minutes) or something wrong with nonce
8755 * counter.
8756 *
8757 * Create new nonce key and resend Digest auth request. Old nonce
8758 * is saved for stale checking...
8759 */
8760 session->nc = 0; /* Reset nonce counter */
8761 session->oldnonce = session->managerid;
8762 nonce = session->managerid = ast_random();
8763 session->noncetime = time_now;
8765 stale = 1;
8766 goto out_401;
8767 } else {
8768 session->nc = nc; /* All OK, save nonce counter */
8769 }
8770 }
8771
8772
8773 /* Reset session timeout. */
8774 session->sessiontimeout = time(NULL) + (httptimeout > 5 ? httptimeout : 5);
8776
8777 ast_mutex_init(&s.lock);
8778 s.session = session;
8779 fd = mkstemp(template); /* create a temporary file for command output */
8780 unlink(template);
8781 if (fd <= -1) {
8782 ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
8783 goto auth_callback_out;
8784 }
8786 if (!s.stream) {
8787 ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
8788 ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
8789 close(fd);
8790 goto auth_callback_out;
8791 }
8792
8793 if (method == AST_HTTP_POST) {
8794 params = ast_http_get_post_vars(ser, headers);
8795 if (!params) {
8796 switch (errno) {
8797 case EFBIG:
8798 ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
8800 goto auth_callback_out;
8801 case ENOMEM:
8803 ast_http_error(ser, 500, "Server Error", "Out of memory");
8805 goto auth_callback_out;
8806 case EIO:
8807 ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8809 goto auth_callback_out;
8810 }
8811 }
8812 }
8813
8814 astman_append_headers(&m, params);
8815
8816 if (process_message(&s, &m)) {
8817 if (u_displayconnects) {
8818 ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8819 }
8820
8821 session->needdestroy = 1;
8822 }
8823
8825
8826 result_size = lseek(ast_iostream_get_fd(s.stream), 0, SEEK_CUR); /* Calculate approx. size of result */
8827
8828 http_header = ast_str_create(80);
8829 out = ast_str_create(result_size * 2 + 512);
8830 if (http_header == NULL || out == NULL) {
8832 ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
8834 goto auth_callback_out;
8835 }
8836
8837 ast_str_append(&http_header, 0, "Content-type: text/%s\r\n", contenttype[format]);
8838
8839 if (format == FORMAT_XML) {
8840 ast_str_append(&out, 0, "<ajax-response>\n");
8841 } else if (format == FORMAT_HTML) {
8842 ast_str_append(&out, 0,
8843 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
8844 "<html><head>\r\n"
8845 "<title>Asterisk&trade; Manager Interface</title>\r\n"
8846 "</head><body style=\"background-color: #ffffff;\">\r\n"
8847 "<form method=\"POST\">\r\n"
8848 "<table align=\"center\" style=\"background-color: #f1f1f1;\" width=\"500\">\r\n"
8849 "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\"><h1>Manager Tester</h1></th></tr>\r\n"
8850 "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\">Action: <input name=\"action\" /> Cmd: <input name=\"command\" /><br>"
8851 "<input type=\"submit\" value=\"Send request\" /></th></tr>\r\n");
8852 }
8853
8854 process_output(&s, &out, params, format);
8855
8856 if (format == FORMAT_XML) {
8857 ast_str_append(&out, 0, "</ajax-response>\n");
8858 } else if (format == FORMAT_HTML) {
8859 ast_str_append(&out, 0, "</table></form></body></html>\r\n");
8860 }
8861
8862 ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
8863 http_header = NULL;
8864 out = NULL;
8865
8866auth_callback_out:
8868
8869 /* Clear resources and unlock manager session */
8870 if (method == AST_HTTP_POST && params) {
8871 ast_variables_destroy(params);
8872 }
8873
8874 ast_free(http_header);
8875 ast_free(out);
8876
8878 if (session->stream) {
8879 ast_iostream_close(session->stream);
8880 session->stream = NULL;
8881 }
8883
8884 if (session->needdestroy) {
8885 ast_debug(1, "Need destroy, doing it now!\n");
8887 }
8889 return 0;
8890
8891out_401:
8892 if (!nonce) {
8893 nonce = ast_random();
8894 }
8895
8896 ast_http_auth(ser, global_realm, nonce, nonce, stale, NULL);
8898 return 0;
8899}
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:7027
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:970
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:1671
static void session_destroy(struct mansession_session *s)
Definition: manager.c:1010
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:1657
static struct eventqent * grab_last(void)
Definition: manager.c:698
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:472
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:1405
@ 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:638
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:853
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:664
#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:193
#define ast_mutex_destroy(a)
Definition: lock.h:195
int errno
static void close_mansession_file(struct mansession *s)
Definition: manager.c:8323
static struct mansession_session * find_session_by_nonce(const char *username, unsigned long nonce, int *stale)
Definition: manager.c:7967
static void process_output(struct mansession *s, struct ast_str **out, struct ast_variable *params, enum output_format format)
Definition: manager.c:8333
static const char *const contenttype[]
Definition: manager.c:7917
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:327
struct ast_iostream * stream
Definition: manager.c:329
ast_mutex_t lock
Definition: manager.c:334
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 8960 of file manager.c.

8961{
8962 int retval;
8963 struct ast_sockaddr ser_remote_address_tmp;
8964
8965 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8966 retval = auth_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
8967 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8968 return retval;
8969}
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:8578
struct ast_sockaddr remote_address
Definition: tcptls.h:153

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

◆ 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 8971 of file manager.c.

8972{
8973 int retval;
8974 struct ast_sockaddr ser_remote_address_tmp;
8975
8976 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8977 retval = auth_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
8978 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8979 return retval;
8980}

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

◆ 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 8982 of file manager.c.

8983{
8984 int retval;
8985 struct ast_sockaddr ser_remote_address_tmp;
8986
8987 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8988 retval = auth_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
8989 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8990 return retval;
8991}

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

◆ close_mansession_file()

static void close_mansession_file ( struct mansession s)
static

Definition at line 8323 of file manager.c.

8324{
8325 if (s->stream) {
8327 s->stream = NULL;
8328 } else {
8329 ast_log(LOG_ERROR, "Attempted to close file/file descriptor on mansession without a valid file or file descriptor.\n");
8330 }
8331}

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 7928 of file manager.c.

7929{
7930 struct ao2_container *sessions;
7932 struct ao2_iterator i;
7933
7934 if (ident == 0) {
7935 return NULL;
7936 }
7937
7938 sessions = ao2_global_obj_ref(mgr_sessions);
7939 if (!sessions) {
7940 return NULL;
7941 }
7943 ao2_ref(sessions, -1);
7944 while ((session = ao2_iterator_next(&i))) {
7946 if (session->managerid == ident && !session->needdestroy) {
7947 ast_atomic_fetchadd_int(&session->inuse, incinuse ? 1 : 0);
7948 break;
7949 }
7952 }
7954
7955 return session;
7956}
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:764

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 7967 of file manager.c.

7968{
7970 struct ao2_container *sessions;
7971 struct ao2_iterator i;
7972
7973 if (nonce == 0 || username == NULL || stale == NULL) {
7974 return NULL;
7975 }
7976
7977 sessions = ao2_global_obj_ref(mgr_sessions);
7978 if (!sessions) {
7979 return NULL;
7980 }
7982 ao2_ref(sessions, -1);
7983 while ((session = ao2_iterator_next(&i))) {
7985 if (!strcasecmp(session->username, username) && session->managerid == nonce) {
7986 *stale = 0;
7987 break;
7988 } else if (!strcasecmp(session->username, username) && session->oldnonce == nonce) {
7989 *stale = 1;
7990 break;
7991 }
7994 }
7996
7997 return session;
7998}

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 9036 of file manager.c.

9037{
9038 struct ast_manager_user *user = NULL;
9039
9042 AST_APP_ARG(param);
9043 );
9044
9045
9046 if (ast_strlen_zero(data) ) {
9047 ast_log(LOG_WARNING, "AMI_CLIENT() requires two arguments: AMI_CLIENT(<name>[,<arg>])\n");
9048 return -1;
9049 }
9051 args.name = ast_strip(args.name);
9052 args.param = ast_strip(args.param);
9053
9055 if (!(user = get_manager_by_name_locked(args.name))) {
9057 ast_log(LOG_ERROR, "There's no manager user called : \"%s\"\n", args.name);
9058 return -1;
9059 }
9061
9062 if (!strcasecmp(args.param, "sessions")) {
9063 int no_sessions = 0;
9064 struct ao2_container *sessions;
9065
9066 sessions = ao2_global_obj_ref(mgr_sessions);
9067 if (sessions) {
9068 ao2_callback_data(sessions, 0, get_manager_sessions_cb, /*login name*/ data, &no_sessions);
9069 ao2_ref(sessions, -1);
9070 }
9071 snprintf(buf, len, "%d", no_sessions);
9072 } else {
9073 ast_log(LOG_ERROR, "Invalid arguments provided to function AMI_CLIENT: %s\n", args.param);
9074 return -1;
9075
9076 }
9077
9078 return 0;
9079}
#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:9021
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 8366 of file manager.c.

8372{
8373 struct mansession s = { .session = NULL, .tcptls_session = ser };
8375 uint32_t ident;
8376 int fd;
8377 int blastaway = 0;
8378 struct ast_variable *params = get_params;
8379 char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
8380 struct ast_str *http_header = NULL, *out = NULL;
8381 struct message m = { 0 };
8382
8384 ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
8385 return 0;
8386 }
8387
8388 ident = ast_http_manid_from_vars(headers);
8389
8390 if (!(session = find_session(ident, 1))) {
8391
8392 /**/
8393 /* Create new session.
8394 * While it is not in the list we don't need any locking
8395 */
8396 if (!(session = build_mansession(remote_address))) {
8398 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8399 return 0;
8400 }
8402 session->send_events = 0;
8403 session->inuse = 1;
8404 /*!
8405 * \note There is approximately a 1 in 1.8E19 chance that the following
8406 * calculation will produce 0, which is an invalid ID, but due to the
8407 * properties of the rand() function (and the constancy of s), that
8408 * won't happen twice in a row.
8409 */
8410 while ((session->managerid = ast_random() ^ (unsigned long) session) == 0) {
8411 }
8412 session->last_ev = grab_last();
8413 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
8414 }
8416
8417 http_header = ast_str_create(128);
8418 out = ast_str_create(2048);
8419
8420 ast_mutex_init(&s.lock);
8421
8422 if (http_header == NULL || out == NULL) {
8424 ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
8425 goto generic_callback_out;
8426 }
8427
8428 s.session = session;
8429 fd = mkstemp(template); /* create a temporary file for command output */
8430 unlink(template);
8431 if (fd <= -1) {
8432 ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
8433 goto generic_callback_out;
8434 }
8436 if (!s.stream) {
8437 ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
8438 ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
8439 close(fd);
8440 goto generic_callback_out;
8441 }
8442
8443 if (method == AST_HTTP_POST) {
8444 params = ast_http_get_post_vars(ser, headers);
8445 if (!params) {
8446 switch (errno) {
8447 case EFBIG:
8448 ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
8450 goto generic_callback_out;
8451 case ENOMEM:
8453 ast_http_error(ser, 500, "Server Error", "Out of memory");
8455 goto generic_callback_out;
8456 case EIO:
8457 ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8459 goto generic_callback_out;
8460 }
8461 }
8462 }
8463
8464 astman_append_headers(&m, params);
8465
8466 if (process_message(&s, &m)) {
8467 if (session->authenticated) {
8469 ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8470 }
8471 } else {
8472 if (displayconnects) {
8473 ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
8474 }
8475 }
8476 session->needdestroy = 1;
8477 }
8478
8480
8481 ast_str_append(&http_header, 0,
8482 "Content-type: text/%s\r\n"
8483 "Set-Cookie: mansession_id=\"%08x\"; Version=1; Max-Age=%d\r\n"
8484 "Pragma: SuppressEvents\r\n",
8485 contenttype[format],
8486 session->managerid, httptimeout);
8487
8488 if (format == FORMAT_XML) {
8489 ast_str_append(&out, 0, "<ajax-response>\n");
8490 } else if (format == FORMAT_HTML) {
8491 /*
8492 * When handling AMI-over-HTTP in HTML format, we provide a simple form for
8493 * debugging purposes. This HTML code should not be here, we
8494 * should read from some config file...
8495 */
8496
8497#define ROW_FMT "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\">%s</td></tr>\r\n"
8498#define TEST_STRING \
8499 "<form action=\"manager\" method=\"post\">\n\
8500 Action: <select name=\"action\">\n\
8501 <option value=\"\">-----&gt;</option>\n\
8502 <option value=\"login\">login</option>\n\
8503 <option value=\"command\">Command</option>\n\
8504 <option value=\"waitevent\">waitevent</option>\n\
8505 <option value=\"listcommands\">listcommands</option>\n\
8506 </select>\n\
8507 or <input name=\"action\"><br/>\n\
8508 CLI Command <input name=\"command\"><br>\n\
8509 user <input name=\"username\"> pass <input type=\"password\" name=\"secret\"><br>\n\
8510 <input type=\"submit\">\n</form>\n"
8511
8512 ast_str_append(&out, 0, "<title>Asterisk&trade; Manager Interface</title>");
8513 ast_str_append(&out, 0, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n");
8514 ast_str_append(&out, 0, ROW_FMT, "<h1>Manager Tester</h1>");
8516 }
8517
8518 process_output(&s, &out, params, format);
8519
8520 if (format == FORMAT_XML) {
8521 ast_str_append(&out, 0, "</ajax-response>\n");
8522 } else if (format == FORMAT_HTML) {
8523 ast_str_append(&out, 0, "</table></body>\r\n");
8524 }
8525
8527 /* Reset HTTP timeout. If we're not authenticated, keep it extremely short */
8528 session->sessiontimeout = time(NULL) + ((session->authenticated || httptimeout < 5) ? httptimeout : 5);
8529
8530 if (session->needdestroy) {
8531 if (session->inuse == 1) {
8532 ast_debug(1, "Need destroy, doing it now!\n");
8533 blastaway = 1;
8534 } else {
8535 ast_debug(1, "Need destroy, but can't do it yet!\n");
8536 ast_mutex_lock(&session->notify_lock);
8537 if (session->waiting_thread != AST_PTHREADT_NULL) {
8538 pthread_kill(session->waiting_thread, SIGURG);
8539 }
8540 ast_mutex_unlock(&session->notify_lock);
8541 session->inuse--;
8542 }
8543 } else {
8544 session->inuse--;
8545 }
8547
8548 ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
8549 http_header = NULL;
8550 out = NULL;
8551
8552generic_callback_out:
8554
8555 /* Clear resource */
8556
8557 if (method == AST_HTTP_POST && params) {
8558 ast_variables_destroy(params);
8559 }
8560 ast_free(http_header);
8561 ast_free(out);
8562
8563 if (session) {
8564 if (blastaway) {
8566 } else {
8567 if (session->stream) {
8568 ast_iostream_close(session->stream);
8569 session->stream = NULL;
8570 }
8572 }
8573 }
8574
8575 return 0;
8576}
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1063
uint32_t ast_http_manid_from_vars(struct ast_variable *headers) attribute_pure
Return manager id, if exist, from request headers.
Definition: http.c:233
#define AST_PTHREADT_NULL
Definition: lock.h:73
#define ast_mutex_unlock(a)
Definition: lock.h:197
#define ast_mutex_lock(a)
Definition: lock.h:196
#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 9021 of file manager.c.

9022{
9023 struct mansession_session *session = obj;
9024 const char *login = (char *)arg;
9025 int *no_sessions = data;
9026
9027 if (strcasecmp(session->username, login) == 0) {
9028 (*no_sessions)++;
9029 }
9030
9031 return 0;
9032}

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 9313 of file manager.c.

9314{
9316 struct ao2_iterator it_events;
9317 struct ast_xml_doc_item *item, *temp;
9318 int length;
9319
9320 if (cmd == CLI_INIT) {
9321 e->command = "manager show event";
9322 e->usage =
9323 "Usage: manager show event <eventname>\n"
9324 " Provides a detailed description a Manager interface event.\n";
9325 return NULL;
9326 }
9327
9328 events = ao2_global_obj_ref(event_docs);
9329 if (!events) {
9330 ast_cli(a->fd, "No manager event documentation loaded\n");
9331 return CLI_SUCCESS;
9332 }
9333
9334 if (cmd == CLI_GENERATE) {
9335 if (a->pos != 3) {
9336 return NULL;
9337 }
9338
9339 length = strlen(a->word);
9340 it_events = ao2_iterator_init(events, 0);
9341 while ((item = ao2_iterator_next(&it_events))) {
9342 if (!strncasecmp(a->word, item->name, length)) {
9344 ao2_ref(item, -1);
9345 break;
9346 }
9347 }
9348 ao2_ref(item, -1);
9349 }
9350 ao2_iterator_destroy(&it_events);
9351
9352 return NULL;
9353 }
9354
9355 if (a->argc != 4) {
9356 return CLI_SHOWUSAGE;
9357 }
9358
9359 if (!(item = ao2_find(events, a->argv[3], OBJ_KEY))) {
9360 ast_cli(a->fd, "Could not find event '%s'\n", a->argv[3]);
9361 return CLI_SUCCESS;
9362 }
9363
9364 ast_cli(a->fd, "Event: %s\n", a->argv[3]);
9365 for (temp = item; temp; temp = AST_LIST_NEXT(temp, next)) {
9366 print_event_instance(a, temp);
9367 }
9368
9369 ao2_ref(item, -1);
9370 return CLI_SUCCESS;
9371}
static const struct adsi_event events[]
Definition: app_adsiprog.c:88
#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:2768
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:9265
#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:947

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 9184 of file manager.c.

9185{
9186 struct ao2_container *events;
9187 struct ao2_iterator *it_events;
9188 struct ast_xml_doc_item *item;
9189 struct ast_xml_doc_item **items;
9190 struct ast_str *buffer;
9191 int i = 0, totalitems = 0;
9192
9193 switch (cmd) {
9194 case CLI_INIT:
9195 e->command = "manager show events";
9196 e->usage =
9197 "Usage: manager show events\n"
9198 " Prints a listing of the available Asterisk manager interface events.\n";
9199 return NULL;
9200 case CLI_GENERATE:
9201 return NULL;
9202 }
9203 if (a->argc != 3) {
9204 return CLI_SHOWUSAGE;
9205 }
9206
9207 buffer = ast_str_create(128);
9208 if (!buffer) {
9209 return CLI_SUCCESS;
9210 }
9211
9212 events = ao2_global_obj_ref(event_docs);
9213 if (!events) {
9214 ast_cli(a->fd, "No manager event documentation loaded\n");
9215 ast_free(buffer);
9216 return CLI_SUCCESS;
9217 }
9218
9220 if (!(it_events = ao2_callback(events, OBJ_MULTIPLE | OBJ_NOLOCK, NULL, NULL))) {
9222 ast_log(AST_LOG_ERROR, "Unable to create iterator for events container\n");
9223 ast_free(buffer);
9224 ao2_ref(events, -1);
9225 return CLI_SUCCESS;
9226 }
9227 if (!(items = ast_calloc(sizeof(struct ast_xml_doc_item *), ao2_container_count(events)))) {
9229 ast_log(AST_LOG_ERROR, "Unable to create temporary sorting array for events\n");
9230 ao2_iterator_destroy(it_events);
9231 ast_free(buffer);
9232 ao2_ref(events, -1);
9233 return CLI_SUCCESS;
9234 }
9236
9237 while ((item = ao2_iterator_next(it_events))) {
9238 items[totalitems++] = item;
9239 ao2_ref(item, -1);
9240 }
9241
9242 qsort(items, totalitems, sizeof(struct ast_xml_doc_item *), ast_xml_doc_item_cmp_fn);
9243
9244 ast_cli(a->fd, "Events:\n");
9245 ast_cli(a->fd, " -------------------- -------------------- -------------------- \n");
9246 for (i = 0; i < totalitems; i++) {
9247 ast_str_append(&buffer, 0, " %-20.20s", items[i]->name);
9248 if ((i + 1) % 3 == 0) {
9249 ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
9250 ast_str_set(&buffer, 0, "%s", "");
9251 }
9252 }
9253 if ((i + 1) % 3 != 0) {
9254 ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
9255 }
9256
9257 ao2_iterator_destroy(it_events);
9258 ast_free(items);
9259 ao2_ref(events, -1);
9260 ast_free(buffer);
9261
9262 return CLI_SUCCESS;
9263}
#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:9177
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 9133 of file manager.c.

9134{
9135 switch (cmd) {
9136 case CLI_INIT:
9137 e->command = "manager show settings";
9138 e->usage =
9139 "Usage: manager show settings\n"
9140 " Provides detailed list of the configuration of the Manager.\n";
9141 return NULL;
9142 case CLI_GENERATE:
9143 return NULL;
9144 }
9145#define FORMAT " %-25.25s %-15.55s\n"
9146#define FORMAT2 " %-25.25s %-15d\n"
9147#define FORMAT3 " %-25.25s %s\n"
9148 if (a->argc != 3) {
9149 return CLI_SHOWUSAGE;
9150 }
9151 ast_cli(a->fd, "\nGlobal Settings:\n");
9152 ast_cli(a->fd, "----------------\n");
9153 ast_cli(a->fd, FORMAT, "Manager (AMI):", AST_CLI_YESNO(manager_enabled));
9154 ast_cli(a->fd, FORMAT, "Web Manager (AMI/HTTP):", AST_CLI_YESNO(webmanager_enabled));
9155 ast_cli(a->fd, FORMAT, "TCP Bindaddress:", manager_enabled != 0 ? ast_sockaddr_stringify(&ami_desc.local_address) : "Disabled");
9156 ast_cli(a->fd, FORMAT2, "HTTP Timeout (seconds):", httptimeout);
9157 ast_cli(a->fd, FORMAT, "TLS Enable:", AST_CLI_YESNO(ami_tls_cfg.enabled));
9158 ast_cli(a->fd, FORMAT, "TLS Bindaddress:", ami_tls_cfg.enabled != 0 ? ast_sockaddr_stringify(&amis_desc.local_address) : "Disabled");
9159 ast_cli(a->fd, FORMAT, "TLS Certfile:", ami_tls_cfg.certfile);
9160 ast_cli(a->fd, FORMAT, "TLS Privatekey:", ami_tls_cfg.pvtfile);
9161 ast_cli(a->fd, FORMAT, "TLS Cipher:", ami_tls_cfg.cipher);
9162 ast_cli(a->fd, FORMAT, "Allow multiple login:", AST_CLI_YESNO(allowmultiplelogin));
9163 ast_cli(a->fd, FORMAT, "Display connects:", AST_CLI_YESNO(displayconnects));
9164 ast_cli(a->fd, FORMAT, "Timestamp events:", AST_CLI_YESNO(timestampevents));
9165 ast_cli(a->fd, FORMAT3, "Channel vars:", S_OR(manager_channelvars, ""));
9166 ast_cli(a->fd, FORMAT3, "Disabled events:", S_OR(manager_disabledevents, ""));
9167 ast_cli(a->fd, FORMAT, "Debug:", AST_CLI_YESNO(manager_debug));
9168#undef FORMAT
9169#undef FORMAT2
9170#undef FORMAT3
9171
9172 return CLI_SUCCESS;
9173}
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
static char * manager_channelvars
Definition: manager.c:176
static char * manager_disabledevents
Definition: manager.c:177
#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 9398 of file manager.c.

9399{
9400 char *parse = NULL;
9402 AST_APP_ARG(vars)[MAX_VARS];
9403 );
9404
9407
9408 /* parse the setting */
9411
9413}
#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:7829
#define MAX_VARS
Definition: manager.c:209

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 9421 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 10160 of file manager.c.

10161{
10162 int rc = 0;
10165#ifdef TEST_FRAMEWORK
10166 AST_TEST_REGISTER(eventfilter_test_creation);
10167 AST_TEST_REGISTER(eventfilter_test_matching);
10168 AST_TEST_REGISTER(originate_permissions_test);
10169#endif
10170 return rc;
10171}
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:9646
static void manager_shutdown(void)
Definition: manager.c:9450
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

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

◆ manager_event_blob_dtor()

static void manager_event_blob_dtor ( void *  obj)
static

Definition at line 10230 of file manager.c.

10231{
10232 struct ast_manager_event_blob *ev = obj;
10233
10235}

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 9431 of file manager.c.

9432{
9433 ast_free(user->a1_hash);
9434 ast_free(user->secret);
9435 if (user->includefilters) {
9436 ao2_t_ref(user->includefilters, -1, "decrement ref for include container, should be last one");
9437 }
9438 if (user->excludefilters) {
9439 ao2_t_ref(user->excludefilters, -1, "decrement ref for exclude container, should be last one");
9440 }
9441 user->acl = ast_free_acl_list(user->acl);
9442 ast_variables_destroy(user->chanvars);
9443 ast_free(user);
9444}

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 8901 of file manager.c.

8902{
8903 int retval;
8904 struct ast_sockaddr ser_remote_address_tmp;
8905
8906 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8907 retval = generic_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
8908 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8909 return retval;
8910}
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:8366

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

◆ manager_set_defaults()

static void manager_set_defaults ( void  )
static

Definition at line 9618 of file manager.c.

9619{
9620 manager_enabled = 0;
9621 displayconnects = 1;
9623 authtimeout = 30;
9624 authlimit = 50;
9625 manager_debug = 0; /* Debug disabled by default */
9626
9627 /* default values */
9629 sizeof(global_realm));
9632
9633 ami_tls_cfg.enabled = 0;
9644}
#define DEFAULT_REALM
Definition: manager.c:179
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:171
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 9450 of file manager.c.

9451{
9452 struct ast_manager_user *user;
9453
9454#ifdef TEST_FRAMEWORK
9455 AST_TEST_UNREGISTER(eventfilter_test_creation);
9456 AST_TEST_UNREGISTER(eventfilter_test_matching);
9457 AST_TEST_UNREGISTER(originate_permissions_test);
9458#endif
9459
9460 /* This event is not actually transmitted, but causes all TCP sessions to be closed */
9461 manager_event(EVENT_FLAG_SHUTDOWN, "CloseSession", "CloseSession: true\r\n");
9462
9463 ast_manager_unregister("Ping");
9464 ast_manager_unregister("Events");
9465 ast_manager_unregister("Logoff");
9466 ast_manager_unregister("Login");
9467 ast_manager_unregister("Challenge");
9468 ast_manager_unregister("Hangup");
9469 ast_manager_unregister("Status");
9470 ast_manager_unregister("Setvar");
9471 ast_manager_unregister("Getvar");
9472 ast_manager_unregister("GetConfig");
9473 ast_manager_unregister("GetConfigJSON");
9474 ast_manager_unregister("UpdateConfig");
9475 ast_manager_unregister("CreateConfig");
9476 ast_manager_unregister("ListCategories");
9477 ast_manager_unregister("Redirect");
9478 ast_manager_unregister("Atxfer");
9479 ast_manager_unregister("CancelAtxfer");
9480 ast_manager_unregister("Originate");
9481 ast_manager_unregister("Command");
9482 ast_manager_unregister("ExtensionState");
9483 ast_manager_unregister("PresenceState");
9484 ast_manager_unregister("AbsoluteTimeout");
9485 ast_manager_unregister("MailboxStatus");
9486 ast_manager_unregister("MailboxCount");
9487 ast_manager_unregister("ListCommands");
9488 ast_manager_unregister("SendText");
9489 ast_manager_unregister("UserEvent");
9490 ast_manager_unregister("WaitEvent");
9491 ast_manager_unregister("CoreSettings");
9492 ast_manager_unregister("CoreStatus");
9493 ast_manager_unregister("Reload");
9494 ast_manager_unregister("LoggerRotate");
9495 ast_manager_unregister("CoreShowChannels");
9496 ast_manager_unregister("CoreShowChannelMap");
9497 ast_manager_unregister("ModuleLoad");
9498 ast_manager_unregister("ModuleCheck");
9499 ast_manager_unregister("AOCMessage");
9500 ast_manager_unregister("Filter");
9501 ast_manager_unregister("BlindTransfer");
9504
9505#ifdef AST_XML_DOCS
9506 ao2_t_global_obj_release(event_docs, "Dispose of event_docs");
9507#endif
9508
9509#ifdef TEST_FRAMEWORK
9510 stasis_forward_cancel(test_suite_forwarder);
9511 test_suite_forwarder = NULL;
9512#endif
9513
9514 if (stasis_router) {
9517 }
9525
9528
9539
9540 ao2_global_obj_release(mgr_sessions);
9541
9542 while ((user = AST_LIST_REMOVE_HEAD(&users, list))) {
9544 }
9546
9549}
#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:189
static struct stasis_forward * rtp_topic_forwarder
The stasis_subscription for forwarding the RTP topic to the AMI topic.
Definition: manager.c:192
static struct stasis_forward * security_topic_forwarder
The stasis_subscription for forwarding the Security topic to the AMI topic.
Definition: manager.c:195
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:212
int ast_manager_unregister(const char *action)
support functions to register/unregister AMI action handlers,
Definition: manager.c:7699
#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:1575
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.
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

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_TEST_UNREGISTER, 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 9555 of file manager.c.

9556{
9557 int res = 0;
9558
9560 if (!rtp_topic_forwarder) {
9561 return -1;
9562 }
9563
9566 return -1;
9567 }
9568
9570 if (!stasis_router) {
9571 return -1;
9572 }
9575
9578
9581
9582 if (res != 0) {
9583 return -1;
9584 }
9585 return 0;
9586}
static void manager_default_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:572
static void manager_generic_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:603
struct stasis_topic * ast_rtp_topic(void)
Stasis Message Bus API topic for RTP and RTCP related messages
Definition: rtp_engine.c:3742
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 8912 of file manager.c.

8913{
8914 int retval;
8915 struct ast_sockaddr ser_remote_address_tmp;
8916
8917 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8918 retval = generic_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
8919 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8920 return retval;
8921}

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

◆ 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 8333 of file manager.c.

8334{
8335 char *buf;
8336 off_t l;
8337 int fd;
8338
8339 if (!s->stream)
8340 return;
8341
8342 /* Ensure buffer is NULL-terminated */
8343 ast_iostream_write(s->stream, "", 1);
8344
8345 fd = ast_iostream_get_fd(s->stream);
8346
8347 l = lseek(fd, 0, SEEK_CUR);
8348 if (l > 0) {
8349 if (MAP_FAILED == (buf = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))) {
8350 ast_log(LOG_WARNING, "mmap failed. Manager output was not processed\n");
8351 } else {
8352 if (format == FORMAT_XML || format == FORMAT_HTML) {
8353 xml_translate(out, buf, params, format);
8354 } else {
8355 ast_str_append(out, 0, "%s", buf);
8356 }
8357 munmap(buf, l);
8358 }
8359 } else if (format == FORMAT_XML || format == FORMAT_HTML) {
8360 xml_translate(out, "", params, format);
8361 }
8362
8364}
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:8205

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 9094 of file manager.c.

9095{
9096 struct ast_tcptls_session_args *ser = data;
9097 /* purge_sessions will return the number of sessions actually purged,
9098 * up to a maximum of it's arguments, purge one at a time, keeping a
9099 * purge interval of 1ms as long as we purged a session, otherwise
9100 * revert to a purge check every 5s
9101 */
9102 if (purge_sessions(1) == 1) {
9103 ser->poll_timeout = 1;
9104 } else {
9105 ser->poll_timeout = 5000;
9106 }
9107 purge_events();
9108}
static void purge_events(void)
Definition: manager.c:718
static int purge_sessions(int n_max)
remove at most n_max stale session from the list.
Definition: manager.c:7455
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 8923 of file manager.c.

8924{
8925 int retval;
8926 struct ast_sockaddr ser_remote_address_tmp;
8927
8928 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8929 retval = generic_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
8930 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8931 return retval;
8932}

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

◆ subscribe_all()

static int subscribe_all ( void  )
static

Definition at line 9588 of file manager.c.

9589{
9591 ast_log(AST_LOG_ERROR, "Failed to initialize manager subscriptions\n");
9592 return -1;
9593 }
9594 if (manager_system_init()) {
9595 ast_log(AST_LOG_ERROR, "Failed to initialize manager system handling\n");
9596 return -1;
9597 }
9598 if (manager_channels_init()) {
9599 ast_log(AST_LOG_ERROR, "Failed to initialize manager channel handling\n");
9600 return -1;
9601 }
9602 if (manager_mwi_init()) {
9603 ast_log(AST_LOG_ERROR, "Failed to initialize manager MWI handling\n");
9604 return -1;
9605 }
9606 if (manager_bridging_init()) {
9607 return -1;
9608 }
9609 if (manager_endpoints_init()) {
9610 ast_log(AST_LOG_ERROR, "Failed to initialize manager endpoints handling\n");
9611 return -1;
9612 }
9613
9614 subscribed = 1;
9615 return 0;
9616}
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:9555
int manager_mwi_init(void)
Initialize support for AMI MWI events.
Definition: manager_mwi.c:160
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(), ari_conf_init(), session_create(), session_register_apps(), and websocket_attempted_cb().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 10155 of file manager.c.

10156{
10157 return 0;
10158}

◆ variable_count_cmp_fn()

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

Definition at line 8166 of file manager.c.

8167{
8168 /* Due to the simplicity of struct variable_count, it makes no difference
8169 * if you pass in objects or strings, the same operation applies. This is
8170 * due to the fact that the hash occurs on the first element, which means
8171 * the address of both the struct and the string are exactly the same. */
8172 struct variable_count *vc = obj;
8173 char *str = vstr;
8174 return !strcmp(vc->varname, str) ? CMP_MATCH | CMP_STOP : 0;
8175}
const char * str
Definition: app_jack.c:150
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
char * varname
Definition: manager.c:8155

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 8159 of file manager.c.

8160{
8161 const struct variable_count *vc = vvc;
8162
8163 return ast_str_hash(vc->varname);
8164}

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 8087 of file manager.c.

8088{
8089 /* store in a local buffer to avoid calling ast_str_append too often */
8090 char buf[256];
8091 char *dst = buf;
8092 const char *save = src;
8093 int space = sizeof(buf);
8094 /* repeat until done and nothing to flush */
8095 for ( ; *src || dst != buf ; src++) {
8096 if (*src == '\0' || space < 10) { /* flush */
8097 *dst++ = '\0';
8098 ast_str_append(out, 0, "%s", buf);
8099 dst = buf;
8100 space = sizeof(buf);
8101 if (*src == '\0') {
8102 break;
8103 }
8104 }
8105
8106 if (mode & 2) {
8107 if (save == src && isdigit(*src)) {
8108 /* The first character of an XML attribute cannot be a digit */
8109 *dst++ = '_';
8110 *dst++ = *src;
8111 space -= 2;
8112 continue;
8113 } else if (!isalnum(*src)) {
8114 /* Replace non-alphanumeric with an underscore */
8115 *dst++ = '_';
8116 space--;
8117 continue;
8118 }
8119 }
8120 switch (*src) {
8121 case '<':
8122 strcpy(dst, "&lt;");
8123 dst += 4;
8124 space -= 4;
8125 break;
8126 case '>':
8127 strcpy(dst, "&gt;");
8128 dst += 4;
8129 space -= 4;
8130 break;
8131 case '\"':
8132 strcpy(dst, "&quot;");
8133 dst += 6;
8134 space -= 6;
8135 break;
8136 case '\'':
8137 strcpy(dst, "&apos;");
8138 dst += 6;
8139 space -= 6;
8140 break;
8141 case '&':
8142 strcpy(dst, "&amp;");
8143 dst += 5;
8144 space -= 5;
8145 break;
8146
8147 default:
8148 *dst++ = mode ? tolower(*src) : *src;
8149 space--;
8150 }
8151 }
8152}

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 8205 of file manager.c.

8206{
8207 struct ast_variable *v;
8208 const char *dest = NULL;
8209 char *var, *val;
8210 const char *objtype = NULL;
8211 int in_data = 0; /* parsing data */
8212 int inobj = 0;
8213 int xml = (format == FORMAT_XML);
8214 struct variable_count *vc = NULL;
8215 struct ao2_container *vco = NULL;
8216
8217 if (xml) {
8218 /* dest and objtype need only for XML format */
8219 for (v = get_vars; v; v = v->next) {
8220 if (!strcasecmp(v->name, "ajaxdest")) {
8221 dest = v->value;
8222 } else if (!strcasecmp(v->name, "ajaxobjtype")) {
8223 objtype = v->value;
8224 }
8225 }
8226 if (ast_strlen_zero(dest)) {
8227 dest = "unknown";
8228 }
8229 if (ast_strlen_zero(objtype)) {
8230 objtype = "generic";
8231 }
8232 }
8233
8234 /* we want to stop when we find an empty line */
8235 while (in && *in) {
8236 val = strsep(&in, "\r\n"); /* mark start and end of line */
8237 if (in && *in == '\n') { /* remove trailing \n if any */
8238 in++;
8239 }
8241 ast_debug(5, "inobj %d in_data %d line <%s>\n", inobj, in_data, val);
8242 if (ast_strlen_zero(val)) {
8243 /* empty line */
8244 if (in_data) {
8245 /* close data in Opaque mode */
8246 ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
8247 in_data = 0;
8248 }
8249
8250 if (inobj) {
8251 /* close block */
8252 ast_str_append(out, 0, xml ? " /></response>\n" :
8253 "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
8254 inobj = 0;
8255 ao2_ref(vco, -1);
8256 vco = NULL;
8257 }
8258 continue;
8259 }
8260
8261 if (!inobj) {
8262 /* start new block */
8263 if (xml) {
8264 ast_str_append(out, 0, "<response type='object' id='%s'><%s", dest, objtype);
8265 }
8268 inobj = 1;
8269 }
8270
8271 if (in_data) {
8272 /* Process data field in Opaque mode. This is a
8273 * followup, so we re-add line feeds. */
8274 ast_str_append(out, 0, xml ? "\n" : "<br>\n");
8275 xml_copy_escape(out, val, 0); /* data field */
8276 continue;
8277 }
8278
8279 /* We expect "Name: value" line here */
8280 var = strsep(&val, ":");
8281 if (val) {
8282 /* found the field name */
8285 } else {
8286 /* field name not found, switch to opaque mode */
8287 val = var;
8288 var = "Opaque-data";
8289 in_data = 1;
8290 }
8291
8292
8293 ast_str_append(out, 0, xml ? " " : "<tr><td>");
8294 if ((vc = ao2_find(vco, var, 0))) {
8295 vc->count++;
8296 } else {
8297 /* Create a new entry for this one */
8298 vc = ao2_alloc(sizeof(*vc), NULL);
8299 vc->varname = var;
8300 vc->count = 1;
8301 ao2_link(vco, vc);
8302 }
8303
8304 xml_copy_escape(out, var, xml ? 1 | 2 : 0); /* data name */
8305 if (vc->count > 1) {
8306 ast_str_append(out, 0, "-%d", vc->count);
8307 }
8308 ao2_ref(vc, -1);
8309 ast_str_append(out, 0, xml ? "='" : "</td><td>");
8310 xml_copy_escape(out, val, 0); /* data field */
8311 if (!in_data || !*in) {
8312 ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
8313 }
8314 }
8315
8316 if (inobj) {
8317 ast_str_append(out, 0, xml ? " /></response>\n" :
8318 "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
8319 ao2_ref(vco, -1);
8320 }
8321}
char * strsep(char **str, const char *delims)
#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
static void xml_copy_escape(struct ast_str **out, const char *src, int mode)
Definition: manager.c:8087
static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
Definition: manager.c:8166
static int variable_count_hash_fn(const void *vvc, const int flags)
Definition: manager.c:8159
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 10278 of file manager.c.

◆ amanageruri

struct ast_http_uri amanageruri
static

Definition at line 9002 of file manager.c.

Referenced by __init_manager().

◆ amanagerxmluri

struct ast_http_uri amanagerxmluri
static

Definition at line 9011 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 8993 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 10278 of file manager.c.

◆ cli_manager

struct ast_cli_entry cli_manager[]
static

Definition at line 9375 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 7917 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:9036

description of AMI_CLIENT dialplan function

Definition at line 9083 of file manager.c.

Referenced by __init_manager(), and manager_shutdown().

◆ manageruri

struct ast_http_uri manageruri
static

Definition at line 8942 of file manager.c.

Referenced by __init_manager().

◆ managerxmluri

struct ast_http_uri managerxmluri
static

Definition at line 8950 of file manager.c.

Referenced by __init_manager().

◆ rawmanuri

struct ast_http_uri rawmanuri
static

Definition at line 8934 of file manager.c.

Referenced by __init_manager().

◆ webregged

int webregged = 0
static

Definition at line 9089 of file manager.c.

Referenced by __init_manager().

◆ words

const char* words[AST_MAX_CMD_LEN]

Definition at line 226 of file manager.c.

Referenced by check_blacklist().