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

The Asterisk Management Interface - AMI. More...

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

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

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

Variables

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

Detailed Description

The Asterisk Management Interface - AMI.

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

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

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

manager.conf

Definition in file manager.c.

Macro Definition Documentation

◆ FORMAT

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

◆ FORMAT2

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

◆ FORMAT3

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

◆ HSMC_FORMAT

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

◆ HSMCONN_FORMAT1

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

◆ HSMCONN_FORMAT2

#define HSMCONN_FORMAT2   " %-15.15s %-55.55s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\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 8090 of file manager.c.

8090 {
8091 FORMAT_RAW,
8093 FORMAT_XML,
8094};
@ FORMAT_RAW
Definition: manager.c:8091
@ FORMAT_HTML
Definition: manager.c:8092
@ FORMAT_XML
Definition: manager.c:8093

Function Documentation

◆ __init_manager()

static int __init_manager ( int  reload,
int  by_external_config 
)
static

Definition at line 9807 of file manager.c.

9808{
9809 struct ast_config *ucfg = NULL, *cfg = NULL;
9810 const char *val;
9811 char *cat = NULL;
9812 int newhttptimeout = 60;
9813 struct ast_manager_user *user = NULL;
9814 struct ast_variable *var;
9815 struct ast_flags config_flags = { (reload && !by_external_config) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
9816 char a1[256];
9817 char a1_hash[256];
9818 struct ast_sockaddr ami_desc_local_address_tmp;
9819 struct ast_sockaddr amis_desc_local_address_tmp;
9820 int tls_was_enabled = 0;
9821 int acl_subscription_flag = 0;
9822
9823 if (!reload) {
9824 struct ao2_container *sessions;
9825#ifdef AST_XML_DOCS
9826 struct ao2_container *temp_event_docs;
9827#endif
9828 int res;
9829
9831 if (res != 0) {
9832 return -1;
9833 }
9834 manager_topic = stasis_topic_create("manager:core");
9835 if (!manager_topic) {
9836 return -1;
9837 }
9838
9839 /* Register default actions */
9879
9880#ifdef TEST_FRAMEWORK
9881 test_suite_forwarder = stasis_forward_all(ast_test_suite_topic(), manager_topic);
9882#endif
9883
9887
9888 /* Append placeholder event so master_eventq never runs dry */
9889 if (append_event("Event: Placeholder\r\n\r\n", 0)) {
9890 return -1;
9891 }
9892
9893#ifdef AST_XML_DOCS
9894 temp_event_docs = ast_xmldoc_build_documentation("managerEvent");
9895 if (temp_event_docs) {
9896 ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs");
9897 ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now");
9898 }
9899#endif
9900
9901 /* If you have a NULL hash fn, you only need a single bucket */
9903 if (!sessions) {
9904 return -1;
9905 }
9907 ao2_ref(sessions, -1);
9908
9909 /* Initialize all settings before first configuration load. */
9911 }
9912
9913 cfg = ast_config_load2("manager.conf", "manager", config_flags);
9914 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
9915 return 0;
9916 } else if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
9917 ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid.\n");
9918 return 0;
9919 }
9920
9921 /* 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. */
9922 if (!by_external_config) {
9924 }
9925
9926 if (reload) {
9927 /* Reset all settings before reloading configuration */
9928 tls_was_enabled = ami_tls_cfg.enabled;
9930 }
9931
9932 ast_sockaddr_parse(&ami_desc_local_address_tmp, "[::]", 0);
9933 ast_sockaddr_set_port(&ami_desc_local_address_tmp, DEFAULT_MANAGER_PORT);
9934
9935 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
9936 val = var->value;
9937
9938 /* read tls config options while preventing unsupported options from being set */
9939 if (strcasecmp(var->name, "tlscafile")
9940 && strcasecmp(var->name, "tlscapath")
9941 && strcasecmp(var->name, "tlscadir")
9942 && strcasecmp(var->name, "tlsverifyclient")
9943 && strcasecmp(var->name, "tlsdontverifyserver")
9944 && strcasecmp(var->name, "tlsclientmethod")
9945 && strcasecmp(var->name, "sslclientmethod")
9946 && !ast_tls_read_conf(&ami_tls_cfg, &amis_desc, var->name, val)) {
9947 continue;
9948 }
9949
9950 if (!strcasecmp(var->name, "enabled")) {
9952 } else if (!strcasecmp(var->name, "webenabled")) {
9954 } else if (!strcasecmp(var->name, "port")) {
9955 int bindport;
9956 if (ast_parse_arg(val, PARSE_UINT32|PARSE_IN_RANGE, &bindport, 1024, 65535)) {
9957 ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
9958 }
9959 ast_sockaddr_set_port(&ami_desc_local_address_tmp, bindport);
9960 } else if (!strcasecmp(var->name, "bindaddr")) {
9961 /* remember port if it has already been set */
9962 int setport = ast_sockaddr_port(&ami_desc_local_address_tmp);
9963
9965 ast_log(LOG_WARNING, "Invalid address '%s' specified, default '%s' will be used\n", val,
9966 ast_sockaddr_stringify_addr(&ami_desc_local_address_tmp));
9967 } else {
9968 ast_sockaddr_parse(&ami_desc_local_address_tmp, val, PARSE_PORT_IGNORE);
9969 }
9970
9971 if (setport) {
9972 ast_sockaddr_set_port(&ami_desc_local_address_tmp, setport);
9973 }
9974
9975 } else if (!strcasecmp(var->name, "brokeneventsaction")) {
9977 } else if (!strcasecmp(var->name, "allowmultiplelogin")) {
9979 } else if (!strcasecmp(var->name, "displayconnects")) {
9981 } else if (!strcasecmp(var->name, "timestampevents")) {
9983 } else if (!strcasecmp(var->name, "debug")) {
9985 } else if (!strcasecmp(var->name, "httptimeout")) {
9986 newhttptimeout = atoi(val);
9987 } else if (!strcasecmp(var->name, "authtimeout")) {
9988 int timeout = atoi(var->value);
9989
9990 if (timeout < 1) {
9991 ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", var->value);
9992 } else {
9993 authtimeout = timeout;
9994 }
9995 } else if (!strcasecmp(var->name, "authlimit")) {
9996 int limit = atoi(var->value);
9997
9998 if (limit < 1) {
9999 ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", var->value);
10000 } else {
10001 authlimit = limit;
10002 }
10003 } else if (!strcasecmp(var->name, "channelvars")) {
10005 } else if (!strcasecmp(var->name, "disabledevents")) {
10007 } else {
10008 ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
10009 var->name, val);
10010 }
10011 }
10012
10013 if (manager_enabled && !subscribed) {
10014 if (subscribe_all() != 0) {
10015 ast_log(LOG_ERROR, "Manager subscription error\n");
10016 return -1;
10017 }
10018 }
10019
10020 ast_sockaddr_copy(&amis_desc_local_address_tmp, &amis_desc.local_address);
10021
10022 /* if the amis address has not been set, default is the same as non secure ami */
10023 if (ast_sockaddr_isnull(&amis_desc_local_address_tmp)) {
10024 ast_sockaddr_copy(&amis_desc_local_address_tmp, &ami_desc_local_address_tmp);
10025 }
10026
10027 /* if the amis address was not set, it will have non-secure ami port set; if
10028 amis address was set, we need to check that a port was set or not, if not
10029 use the default tls port */
10030 if (ast_sockaddr_port(&amis_desc_local_address_tmp) == 0 ||
10031 (ast_sockaddr_port(&ami_desc_local_address_tmp) == ast_sockaddr_port(&amis_desc_local_address_tmp))) {
10032
10033 ast_sockaddr_set_port(&amis_desc_local_address_tmp, DEFAULT_MANAGER_TLS_PORT);
10034 }
10035
10036 if (manager_enabled) {
10037 ast_sockaddr_copy(&ami_desc.local_address, &ami_desc_local_address_tmp);
10038 ast_sockaddr_copy(&amis_desc.local_address, &amis_desc_local_address_tmp);
10039 }
10040
10042
10043 /* First, get users from users.conf */
10044 ucfg = ast_config_load2("users.conf", "manager", config_flags);
10045 if (ucfg && (ucfg != CONFIG_STATUS_FILEUNCHANGED) && ucfg != CONFIG_STATUS_FILEINVALID) {
10046 const char *hasmanager;
10047 int genhasmanager = ast_true(ast_variable_retrieve(ucfg, "general", "hasmanager"));
10048
10049 while ((cat = ast_category_browse(ucfg, cat))) {
10050 if (!strcasecmp(cat, "general")) {
10051 continue;
10052 }
10053
10054 hasmanager = ast_variable_retrieve(ucfg, cat, "hasmanager");
10055 if ((!hasmanager && genhasmanager) || ast_true(hasmanager)) {
10056 const char *user_secret = ast_variable_retrieve(ucfg, cat, "secret");
10057 const char *user_read = ast_variable_retrieve(ucfg, cat, "read");
10058 const char *user_write = ast_variable_retrieve(ucfg, cat, "write");
10059 const char *user_displayconnects = ast_variable_retrieve(ucfg, cat, "displayconnects");
10060 const char *user_allowmultiplelogin = ast_variable_retrieve(ucfg, cat, "allowmultiplelogin");
10061 const char *user_writetimeout = ast_variable_retrieve(ucfg, cat, "writetimeout");
10062
10063 /* Look for an existing entry,
10064 * if none found - create one and add it to the list
10065 */
10066 if (!(user = get_manager_by_name_locked(cat))) {
10067 if (!(user = ast_calloc(1, sizeof(*user)))) {
10068 break;
10069 }
10070
10071 /* Copy name over */
10072 ast_copy_string(user->username, cat, sizeof(user->username));
10073 /* Insert into list */
10075 user->acl = NULL;
10076 user->keep = 1;
10077 user->readperm = -1;
10078 user->writeperm = -1;
10079 /* Default displayconnect from [general] */
10080 user->displayconnects = displayconnects;
10081 /* Default allowmultiplelogin from [general] */
10082 user->allowmultiplelogin = allowmultiplelogin;
10083 user->writetimeout = 100;
10084 }
10085
10086 if (!user_secret) {
10087 user_secret = ast_variable_retrieve(ucfg, "general", "secret");
10088 }
10089 if (!user_read) {
10090 user_read = ast_variable_retrieve(ucfg, "general", "read");
10091 }
10092 if (!user_write) {
10093 user_write = ast_variable_retrieve(ucfg, "general", "write");
10094 }
10095 if (!user_displayconnects) {
10096 user_displayconnects = ast_variable_retrieve(ucfg, "general", "displayconnects");
10097 }
10098 if (!user_allowmultiplelogin) {
10099 user_allowmultiplelogin = ast_variable_retrieve(ucfg, "general", "allowmultiplelogin");
10100 }
10101 if (!user_writetimeout) {
10102 user_writetimeout = ast_variable_retrieve(ucfg, "general", "writetimeout");
10103 }
10104
10105 if (!ast_strlen_zero(user_secret)) {
10106 ast_free(user->secret);
10107 user->secret = ast_strdup(user_secret);
10108 }
10109
10110 if (user_read) {
10111 user->readperm = get_perm(user_read);
10112 }
10113 if (user_write) {
10114 user->writeperm = get_perm(user_write);
10115 }
10116 if (user_displayconnects) {
10117 user->displayconnects = ast_true(user_displayconnects);
10118 }
10119 if (user_allowmultiplelogin) {
10120 user->allowmultiplelogin = ast_true(user_allowmultiplelogin);
10121 }
10122 if (user_writetimeout) {
10123 int value = atoi(user_writetimeout);
10124 if (value < 100) {
10125 ast_log(LOG_WARNING, "Invalid writetimeout value '%d' in users.conf\n", value);
10126 } else {
10127 user->writetimeout = value;
10128 }
10129 }
10130 }
10131 }
10132 ast_config_destroy(ucfg);
10133 }
10134
10135 /* cat is NULL here in any case */
10136
10137 while ((cat = ast_category_browse(cfg, cat))) {
10138 struct ast_acl_list *oldacl;
10139
10140 if (!strcasecmp(cat, "general")) {
10141 continue;
10142 }
10143
10144 /* Look for an existing entry, if none found - create one and add it to the list */
10145 if (!(user = get_manager_by_name_locked(cat))) {
10146 if (!(user = ast_calloc(1, sizeof(*user)))) {
10147 break;
10148 }
10149 /* Copy name over */
10150 ast_copy_string(user->username, cat, sizeof(user->username));
10151
10152 user->acl = NULL;
10153 user->readperm = 0;
10154 user->writeperm = 0;
10155 /* Default displayconnect from [general] */
10156 user->displayconnects = displayconnects;
10157 /* Default allowmultiplelogin from [general] */
10158 user->allowmultiplelogin = allowmultiplelogin;
10159 user->writetimeout = 100;
10162 if (!user->whitefilters || !user->blackfilters) {
10164 break;
10165 }
10166
10167 /* Insert into list */
10169 } else {
10170 ao2_t_callback(user->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters");
10171 ao2_t_callback(user->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters");
10172 }
10173
10174 /* Make sure we keep this user and don't destroy it during cleanup */
10175 user->keep = 1;
10176 oldacl = user->acl;
10177 user->acl = NULL;
10178 ast_variables_destroy(user->chanvars);
10179
10180 var = ast_variable_browse(cfg, cat);
10181 for (; var; var = var->next) {
10182 if (!strcasecmp(var->name, "secret")) {
10183 ast_free(user->secret);
10184 user->secret = ast_strdup(var->value);
10185 } else if (!strcasecmp(var->name, "deny") ||
10186 !strcasecmp(var->name, "permit") ||
10187 !strcasecmp(var->name, "acl")) {
10188 int acl_error = 0;
10189
10190 ast_append_acl(var->name, var->value, &user->acl, &acl_error, &acl_subscription_flag);
10191 if (acl_error) {
10192 ast_log(LOG_ERROR, "Invalid ACL '%s' for manager user '%s' on line %d. Deleting user\n",
10193 var->value, user->username, var->lineno);
10194 user->keep = 0;
10195 }
10196 } else if (!strcasecmp(var->name, "read") ) {
10197 user->readperm = get_perm(var->value);
10198 } else if (!strcasecmp(var->name, "write") ) {
10199 user->writeperm = get_perm(var->value);
10200 } else if (!strcasecmp(var->name, "displayconnects") ) {
10201 user->displayconnects = ast_true(var->value);
10202 } else if (!strcasecmp(var->name, "allowmultiplelogin") ) {
10203 user->allowmultiplelogin = ast_true(var->value);
10204 } else if (!strcasecmp(var->name, "writetimeout")) {
10205 int value = atoi(var->value);
10206 if (value < 100) {
10207 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", var->value, var->lineno);
10208 } else {
10209 user->writetimeout = value;
10210 }
10211 } else if (!strcasecmp(var->name, "setvar")) {
10212 struct ast_variable *tmpvar;
10213 char varbuf[256];
10214 char *varval;
10215 char *varname;
10216
10217 ast_copy_string(varbuf, var->value, sizeof(varbuf));
10218 varname = varbuf;
10219
10220 if ((varval = strchr(varname,'='))) {
10221 *varval++ = '\0';
10222 if ((tmpvar = ast_variable_new(varname, varval, ""))) {
10223 tmpvar->next = user->chanvars;
10224 user->chanvars = tmpvar;
10225 }
10226 }
10227 } else if (!strcasecmp(var->name, "eventfilter")) {
10228 const char *value = var->value;
10229 manager_add_filter(value, user->whitefilters, user->blackfilters);
10230 } else {
10231 ast_debug(1, "%s is an unknown option.\n", var->name);
10232 }
10233 }
10234
10235 oldacl = ast_free_acl_list(oldacl);
10236 }
10237 ast_config_destroy(cfg);
10238
10239 /* Check the flag for named ACL event subscription and if we need to, register a subscription. */
10240 if (acl_subscription_flag && !by_external_config) {
10242 }
10243
10244 /* Perform cleanup - essentially prune out old users that no longer exist */
10246 if (user->keep) { /* valid record. clear flag for the next round */
10247 user->keep = 0;
10248
10249 /* Calculate A1 for Digest auth */
10250 snprintf(a1, sizeof(a1), "%s:%s:%s", user->username, global_realm, user->secret);
10251 ast_md5_hash(a1_hash,a1);
10252 ast_free(user->a1_hash);
10253 user->a1_hash = ast_strdup(a1_hash);
10254 continue;
10255 }
10256 /* We do not need to keep this user so take them out of the list */
10258 ast_debug(4, "Pruning user '%s'\n", user->username);
10260 }
10262
10264
10266 if (!webregged) {
10270
10274 webregged = 1;
10275 }
10276 } else {
10277 if (webregged) {
10281
10285 webregged = 0;
10286 }
10287 }
10288
10289 if (newhttptimeout > 0) {
10290 httptimeout = newhttptimeout;
10291 }
10292
10294 if (tls_was_enabled && !ami_tls_cfg.enabled) {
10296 } else if (ast_ssl_setup(amis_desc.tls_cfg)) {
10298 }
10299
10300 return 0;
10301}
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:4733
static int action_createconfig(struct mansession *s, const struct message *m)
Definition: manager.c:4344
static int manager_state_cb(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
Definition: manager.c:7917
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:7082
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:2426
static void acl_change_stasis_subscribe(void)
Definition: manager.c:1655
static int manager_enabled
Definition: manager.c:1590
static int action_sendtext(struct mansession *s, const struct message *m)
Definition: manager.c:5089
static int action_mailboxcount(struct mansession *s, const struct message *m)
Definition: manager.c:6400
static int action_getconfigjson(struct mansession *s, const struct message *m)
Definition: manager.c:3897
static int action_listcategories(struct mansession *s, const struct message *m)
Definition: manager.c:3831
static int action_hangup(struct mansession *s, const struct message *m)
Definition: manager.c:4616
static int action_listcommands(struct mansession *s, const struct message *m)
Definition: manager.c:4480
static int action_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:5323
static int action_timeout(struct mansession *s, const struct message *m)
Definition: manager.c:6491
static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
Add an event filter to a manager session.
Definition: manager.c:6610
static int action_coresettings(struct mansession *s, const struct message *m)
Show PBX core settings information.
Definition: manager.c:6724
static int mansession_cmp_fn(void *obj, void *arg, int flags)
Definition: manager.c:2383
static int displayconnects
Definition: manager.c:1585
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:6558
static int manager_debug
Definition: manager.c:1593
static int action_mailboxstatus(struct mansession *s, const struct message *m)
Definition: manager.c:6383
static int action_login(struct mansession *s, const struct message *m)
Definition: manager.c:4549
static int action_getvar(struct mansession *s, const struct message *m)
Definition: manager.c:4766
static int action_blind_transfer(struct mansession *s, const struct message *m)
Definition: manager.c:5277
static int action_extensionstate(struct mansession *s, const struct message *m)
Definition: manager.c:6421
static int action_getconfig(struct mansession *s, const struct message *m)
Definition: manager.c:3764
static int action_logoff(struct mansession *s, const struct message *m)
Definition: manager.c:4543
static int action_updateconfig(struct mansession *s, const struct message *m)
Definition: manager.c:4254
static int manager_moduleload(struct mansession *s, const struct message *m)
Definition: manager.c:7123
static void acl_change_stasis_unsubscribe(void)
Definition: manager.c:1665
static int action_reload(struct mansession *s, const struct message *m)
Send a reload event.
Definition: manager.c:6808
static int authlimit
Definition: manager.c:1595
static int action_aocmessage(struct mansession *s, const struct message *m)
Definition: manager.c:6113
static int action_events(struct mansession *s, const struct message *m)
Definition: manager.c:4499
static int action_redirect(struct mansession *s, const struct message *m)
action_redirect: The redirect manager command
Definition: manager.c:5132
static int action_presencestate(struct mansession *s, const struct message *m)
Definition: manager.c:6451
static int allowmultiplelogin
Definition: manager.c:1586
static int action_cancel_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:5377
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:1600
static int action_originate(struct mansession *s, const struct message *m)
Definition: manager.c:6172
static int action_userevent(struct mansession *s, const struct message *m)
Definition: manager.c:6703
static int action_command(struct mansession *s, const struct message *m)
Manager command "command" - execute CLI command.
Definition: manager.c:5454
static int broken_events_action
Definition: manager.c:1589
static int timestampevents
Definition: manager.c:1587
static int subscribed
Definition: manager.c:1591
static int authtimeout
Definition: manager.c:1594
static int manager_modulecheck(struct mansession *s, const struct message *m)
Manager function to check if module is loaded.
Definition: manager.c:7094
static int webmanager_enabled
Definition: manager.c:1592
static int action_status(struct mansession *s, const struct message *m)
Manager "status" command to show channels.
Definition: manager.c:4933
static int get_perm(const char *instr)
Definition: manager.c:2252
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:6840
static int action_corestatus(struct mansession *s, const struct message *m)
Show PBX core status information.
Definition: manager.c:6768
static int action_challenge(struct mansession *s, const struct message *m)
Definition: manager.c:4598
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1606
static int action_waitevent(struct mansession *s, const struct message *m)
Definition: manager.c:4362
static int append_event(const char *str, int category)
events are appended to a queue from where they can be dispatched to clients.
Definition: manager.c:7689
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:7008
static int action_ping(struct mansession *s, const struct message *m)
Definition: manager.c:3723
static int httptimeout
Definition: manager.c:1588
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:708
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:676
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3232
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:3738
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
@ CONFIG_FLAG_FILEUNCHANGED
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_NOTICE
#define LOG_WARNING
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:9289
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:9290
static struct ast_http_uri managerxmluri
Definition: manager.c:9129
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:9301
static struct ast_custom_function managerclient_function
description of AMI_CLIENT dialplan function
Definition: manager.c:9262
static void load_channelvars(struct ast_variable *var)
Definition: manager.c:9565
static struct ast_http_uri manageruri
Definition: manager.c:9121
static void manager_set_defaults(void)
Definition: manager.c:9779
static struct ast_http_uri arawmanuri
Definition: manager.c:9172
static struct ast_http_uri rawmanuri
Definition: manager.c:9113
static struct ast_cli_entry cli_manager[]
Definition: manager.c:9543
static void manager_free_user(struct ast_manager_user *user)
Definition: manager.c:9598
static struct ast_http_uri amanageruri
Definition: manager.c:9181
static int webregged
Definition: manager.c:9268
static int subscribe_all(void)
Definition: manager.c:9749
static struct ast_http_uri amanagerxmluri
Definition: manager.c:9190
static void load_disabledevents(struct ast_variable *var)
Definition: manager.c:9588
#define EVENT_FLAG_REPORTING
Definition: manager.h:84
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:202
#define EVENT_FLAG_CONFIG
Definition: manager.h:82
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
#define DEFAULT_MANAGER_PORT
Definition: manager.h:58
#define DEFAULT_MANAGER_TLS_PORT
Definition: manager.h:59
#define EVENT_FLAG_CALL
Definition: manager.h:76
#define EVENT_FLAG_COMMAND
Definition: manager.h:79
#define EVENT_FLAG_USER
Definition: manager.h:81
#define EVENT_FLAG_AOC
Definition: manager.h:91
#define EVENT_FLAG_ORIGINATE
Definition: manager.h:87
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
int ast_extension_state_add(const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
Add watcher for extension states.
Definition: pbx.c:3823
static int reload(void)
#define NULL
Definition: resample.c:96
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:617
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1578
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2197
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Generic container type.
Wrapper for an ast_acl linked list.
Definition: acl.h:76
Structure used to handle boolean flags.
Definition: utils.h:199
user descriptor, as read from the config file.
Definition: manager.c:1765
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:914
int ast_ssl_setup(struct ast_tls_config *cfg)
Set up an SSL server.
Definition: tcptls.c:570
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a ...
Definition: tcptls.c:749
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:940
#define ARRAY_LEN(a)
Definition: utils.h:666
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: utils.c:250
struct ao2_container * ast_xmldoc_build_documentation(const char *type)
Build the documentation for a particular source type.
Definition: xmldoc.c:2684

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

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

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 10432 of file manager.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

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

10398{
10399 struct ast_manager_event_blob *ev;
10400 va_list argp;
10401
10402 ast_assert(extra_fields_fmt != NULL);
10404
10406 if (!ev) {
10407 return NULL;
10408 }
10409
10410 if (ast_string_field_init(ev, 20)) {
10411 ao2_ref(ev, -1);
10412 return NULL;
10413 }
10414
10417
10418 va_start(argp, extra_fields_fmt);
10419 ast_string_field_ptr_build_va(ev, &ev->extra_fields, extra_fields_fmt, argp);
10420 va_end(argp);
10421
10422 return ev;
10423}
@ 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:10384
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
#define ast_string_field_ptr_build_va(x, ptr, fmt, args)
Set a field to a complex (built) value with prebuilt va_lists.
Definition: stringfields.h:573
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Struct containing info for an AMI event to send out.
Definition: manager.h:502
const ast_string_field extra_fields
Definition: manager.h:507
const char * manager_event
Definition: manager.h:504
#define ast_assert(a)
Definition: utils.h:739

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

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

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

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

10373{
10374 if (!*fields_string) {
10375 *fields_string = ast_str_create(128);
10376 if (!*fields_string) {
10377 return -1;
10378 }
10379 }
10380
10381 return (ast_str_append(fields_string, 0, "%s: %s\r\n", header, value) < 0) ? -1 : 0;
10382}
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:1136
#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 9356 of file manager.c.

9357{
9358 struct ast_xml_doc_item **item_a = (struct ast_xml_doc_item **)a;
9359 struct ast_xml_doc_item **item_b = (struct ast_xml_doc_item **)b;
9360 return strcmp((*item_a)->name, (*item_b)->name);
9361}
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 10332 of file manager.c.

10333{
10334 AST_LIST_INSERT_HEAD(&s->session->datastores, datastore, entry);
10335
10336 return 0;
10337}
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
Definition: search.h:40
struct mansession_session::mansession_datastores datastores
struct mansession_session * session
Definition: manager.c:1747

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

10345{
10346 struct ast_datastore *datastore = NULL;
10347
10348 if (info == NULL)
10349 return NULL;
10350
10352 if (datastore->info != info) {
10353 continue;
10354 }
10355
10356 if (uid == NULL) {
10357 /* matched by type only */
10358 break;
10359 }
10360
10361 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
10362 /* Matched by type AND uid */
10363 break;
10364 }
10365 }
10367
10368 return datastore;
10369}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
def info(msg)
Structure for a data store object.
Definition: datastore.h:64
const struct ast_datastore_info * info
Definition: datastore.h:67
const char * uid
Definition: datastore.h:65

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

◆ astman_datastore_remove()

int astman_datastore_remove ( struct mansession s,
struct ast_datastore datastore 
)

Remove a datastore from a session.

Return values
0success
non-zerofailure
Since
1.6.1

Definition at line 10339 of file manager.c.

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

8180{
8181 int authed;
8183
8184 if (!(session = find_session(ident, 0)))
8185 return 0;
8186
8187 authed = (session->authenticated != 0);
8188
8191
8192 return authed;
8193}
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:2304
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:8107

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

8196{
8197 int result = 0;
8199 struct ao2_container *sessions;
8200 struct ao2_iterator i;
8201
8202 if (ident == 0) {
8203 return 0;
8204 }
8205
8206 sessions = ao2_global_obj_ref(mgr_sessions);
8207 if (!sessions) {
8208 return 0;
8209 }
8211 ao2_ref(sessions, -1);
8212 while ((session = ao2_iterator_next(&i))) {
8214 if ((session->managerid == ident) && (session->readperm & perm)) {
8215 result = 1;
8218 break;
8219 }
8222 }
8224
8225 return result;
8226}
#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 8228 of file manager.c.

8229{
8230 int result = 0;
8232 struct ao2_container *sessions;
8233 struct ao2_iterator i;
8234
8235 if (ident == 0) {
8236 return 0;
8237 }
8238
8239 sessions = ao2_global_obj_ref(mgr_sessions);
8240 if (!sessions) {
8241 return 0;
8242 }
8244 ao2_ref(sessions, -1);
8245 while ((session = ao2_iterator_next(&i))) {
8247 if ((session->managerid == ident) && (session->writeperm & perm)) {
8248 result = 1;
8251 break;
8252 }
8255 }
8257
8258 return result;
8259}

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

8763{
8765 struct mansession s = { .session = NULL, .tcptls_session = ser };
8766 struct ast_variable *v, *params = get_params;
8767 char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
8768 struct ast_str *http_header = NULL, *out = NULL;
8769 size_t result_size;
8770 struct message m = { 0 };
8771 int fd;
8772
8773 time_t time_now = time(NULL);
8774 unsigned long nonce = 0, nc;
8775 struct ast_http_digest d = { NULL, };
8776 struct ast_manager_user *user = NULL;
8777 int stale = 0;
8778 char resp_hash[256]="";
8779 /* Cache for user data */
8780 char u_username[80];
8781 int u_readperm;
8782 int u_writeperm;
8783 int u_writetimeout;
8784 int u_displayconnects;
8785
8787 ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
8788 return 0;
8789 }
8790
8791 /* Find "Authorization: " header */
8792 for (v = headers; v; v = v->next) {
8793 if (!strcasecmp(v->name, "Authorization")) {
8794 break;
8795 }
8796 }
8797
8798 if (!v || ast_strlen_zero(v->value)) {
8799 goto out_401; /* Authorization Header not present - send auth request */
8800 }
8801
8802 /* Digest found - parse */
8803 if (ast_string_field_init(&d, 128)) {
8805 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8806 return 0;
8807 }
8808
8809 if (ast_parse_digest(v->value, &d, 0, 1)) {
8810 /* Error in Digest - send new one */
8811 nonce = 0;
8812 goto out_401;
8813 }
8814 if (sscanf(d.nonce, "%30lx", &nonce) != 1) {
8815 ast_log(LOG_WARNING, "Received incorrect nonce in Digest <%s>\n", d.nonce);
8816 nonce = 0;
8817 goto out_401;
8818 }
8819
8821 user = get_manager_by_name_locked(d.username);
8822 if(!user) {
8824 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8825 nonce = 0;
8826 goto out_401;
8827 }
8828
8829 /* --- We have User for this auth, now check ACL */
8830 if (user->acl && !ast_apply_acl(user->acl, remote_address, "Manager User ACL:")) {
8832 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8834 ast_http_error(ser, 403, "Permission denied", "Permission denied");
8835 return 0;
8836 }
8837
8838 /* --- We have auth, so check it */
8839
8840 /* compute the expected response to compare with what we received */
8841 {
8842 char *a2;
8843 /* ast_md5_hash outputs 32 characters plus NULL terminator. */
8844 char a2_hash[33];
8845 char resp[256];
8846
8847 /* XXX Now request method are hardcoded in A2 */
8848 if (ast_asprintf(&a2, "%s:%s", ast_get_http_method(method), d.uri) < 0) {
8851 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8852 return 0;
8853 }
8854
8855 ast_md5_hash(a2_hash, a2);
8856 ast_free(a2);
8857
8858 if (d.qop) {
8859 /* RFC 2617 */
8860 snprintf(resp, sizeof(resp), "%s:%08lx:%s:%s:auth:%s", user->a1_hash, nonce, d.nc, d.cnonce, a2_hash);
8861 } else {
8862 /* RFC 2069 */
8863 snprintf(resp, sizeof(resp), "%s:%08lx:%s", user->a1_hash, nonce, a2_hash);
8864 }
8865 ast_md5_hash(resp_hash, resp);
8866 }
8867
8868 if (strncasecmp(d.response, resp_hash, strlen(resp_hash))) {
8869 /* Something was wrong, so give the client to try with a new challenge */
8871 nonce = 0;
8872 goto out_401;
8873 }
8874
8875 /*
8876 * User are pass Digest authentication.
8877 * Now, cache the user data and unlock user list.
8878 */
8879 ast_copy_string(u_username, user->username, sizeof(u_username));
8880 u_readperm = user->readperm;
8881 u_writeperm = user->writeperm;
8882 u_displayconnects = user->displayconnects;
8883 u_writetimeout = user->writetimeout;
8885
8886 if (!(session = find_session_by_nonce(d.username, nonce, &stale))) {
8887 /*
8888 * Create new session.
8889 * While it is not in the list we don't need any locking
8890 */
8891 if (!(session = build_mansession(remote_address))) {
8893 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8894 return 0;
8895 }
8897
8898 ast_copy_string(session->username, u_username, sizeof(session->username));
8899 session->managerid = nonce;
8900 session->last_ev = grab_last();
8901 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
8902
8903 session->readperm = u_readperm;
8904 session->writeperm = u_writeperm;
8905 session->writetimeout = u_writetimeout;
8906
8907 if (u_displayconnects) {
8908 ast_verb(2, "HTTP Manager '%s' logged in from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8909 }
8910 session->noncetime = session->sessionstart = time_now;
8911 session->authenticated = 1;
8912 } else if (stale) {
8913 /*
8914 * Session found, but nonce is stale.
8915 *
8916 * This could be because an old request (w/old nonce) arrived.
8917 *
8918 * This may be as the result of http proxy usage (separate delay or
8919 * multipath) or in a situation where a page was refreshed too quickly
8920 * (seen in Firefox).
8921 *
8922 * In this situation, we repeat the 401 auth with the current nonce
8923 * value.
8924 */
8925 nonce = session->managerid;
8927 stale = 1;
8928 goto out_401;
8929 } else {
8930 sscanf(d.nc, "%30lx", &nc);
8931 if (session->nc >= nc || ((time_now - session->noncetime) > 62) ) {
8932 /*
8933 * Nonce time expired (> 2 minutes) or something wrong with nonce
8934 * counter.
8935 *
8936 * Create new nonce key and resend Digest auth request. Old nonce
8937 * is saved for stale checking...
8938 */
8939 session->nc = 0; /* Reset nonce counter */
8940 session->oldnonce = session->managerid;
8941 nonce = session->managerid = ast_random();
8942 session->noncetime = time_now;
8944 stale = 1;
8945 goto out_401;
8946 } else {
8947 session->nc = nc; /* All OK, save nonce counter */
8948 }
8949 }
8950
8951
8952 /* Reset session timeout. */
8953 session->sessiontimeout = time(NULL) + (httptimeout > 5 ? httptimeout : 5);
8955
8956 ast_mutex_init(&s.lock);
8957 s.session = session;
8958 fd = mkstemp(template); /* create a temporary file for command output */
8959 unlink(template);
8960 if (fd <= -1) {
8961 ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
8962 goto auth_callback_out;
8963 }
8965 if (!s.stream) {
8966 ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
8967 ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
8968 close(fd);
8969 goto auth_callback_out;
8970 }
8971
8972 if (method == AST_HTTP_POST) {
8973 params = ast_http_get_post_vars(ser, headers);
8974 if (!params) {
8975 switch (errno) {
8976 case EFBIG:
8977 ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
8979 goto auth_callback_out;
8980 case ENOMEM:
8982 ast_http_error(ser, 500, "Server Error", "Out of memory");
8984 goto auth_callback_out;
8985 case EIO:
8986 ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8988 goto auth_callback_out;
8989 }
8990 }
8991 }
8992
8993 astman_append_headers(&m, params);
8994
8995 if (process_message(&s, &m)) {
8996 if (u_displayconnects) {
8997 ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8998 }
8999
9000 session->needdestroy = 1;
9001 }
9002
9004
9005 result_size = lseek(ast_iostream_get_fd(s.stream), 0, SEEK_CUR); /* Calculate approx. size of result */
9006
9007 http_header = ast_str_create(80);
9008 out = ast_str_create(result_size * 2 + 512);
9009 if (http_header == NULL || out == NULL) {
9011 ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
9013 goto auth_callback_out;
9014 }
9015
9016 ast_str_append(&http_header, 0, "Content-type: text/%s\r\n", contenttype[format]);
9017
9018 if (format == FORMAT_XML) {
9019 ast_str_append(&out, 0, "<ajax-response>\n");
9020 } else if (format == FORMAT_HTML) {
9021 ast_str_append(&out, 0,
9022 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
9023 "<html><head>\r\n"
9024 "<title>Asterisk&trade; Manager Interface</title>\r\n"
9025 "</head><body style=\"background-color: #ffffff;\">\r\n"
9026 "<form method=\"POST\">\r\n"
9027 "<table align=\"center\" style=\"background-color: #f1f1f1;\" width=\"500\">\r\n"
9028 "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\"><h1>Manager Tester</h1></th></tr>\r\n"
9029 "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\">Action: <input name=\"action\" /> Cmd: <input name=\"command\" /><br>"
9030 "<input type=\"submit\" value=\"Send request\" /></th></tr>\r\n");
9031 }
9032
9033 process_output(&s, &out, params, format);
9034
9035 if (format == FORMAT_XML) {
9036 ast_str_append(&out, 0, "</ajax-response>\n");
9037 } else if (format == FORMAT_HTML) {
9038 ast_str_append(&out, 0, "</table></form></body></html>\r\n");
9039 }
9040
9041 ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
9042 http_header = NULL;
9043 out = NULL;
9044
9045auth_callback_out:
9047
9048 /* Clear resources and unlock manager session */
9049 if (method == AST_HTTP_POST && params) {
9050 ast_variables_destroy(params);
9051 }
9052
9053 ast_free(http_header);
9054 ast_free(out);
9055
9057 if (session->stream) {
9058 ast_iostream_close(session->stream);
9059 session->stream = NULL;
9060 }
9062
9063 if (session->needdestroy) {
9064 ast_debug(1, "Need destroy, doing it now!\n");
9066 }
9068 return 0;
9069
9070out_401:
9071 if (!nonce) {
9072 nonce = ast_random();
9073 }
9074
9075 ast_http_auth(ser, global_realm, nonce, nonce, stale, NULL);
9077 return 0;
9078}
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:7225
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:2350
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:2965
static void session_destroy(struct mansession_session *s)
Definition: manager.c:2390
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:2951
static struct eventqent * grab_last(void)
Definition: manager.c:2084
void ast_http_send(struct ast_tcptls_session_instance *ser, enum ast_http_method method, int status_code, const char *status_title, struct ast_str *http_header, struct ast_str *out, int fd, unsigned int static_content)
Generic function for sending HTTP/1.1 response.
Definition: http.c:459
struct ast_variable * ast_http_get_post_vars(struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
Get post variables from client Request Entity-Body, if content type is application/x-www-form-urlenco...
Definition: http.c:1356
@ AST_HTTP_POST
Definition: http.h:61
@ AST_HTTP_GET
Definition: http.h:60
@ AST_HTTP_HEAD
Definition: http.h:62
const char * ast_get_http_method(enum ast_http_method method) attribute_pure
Return http method name string.
Definition: http.c:193
void ast_http_auth(struct ast_tcptls_session_instance *ser, const char *realm, const unsigned long nonce, const unsigned long opaque, int stale, const char *text)
Send http "401 Unauthorized" response and close socket.
Definition: http.c:625
void ast_http_request_close_on_completion(struct ast_tcptls_session_instance *ser)
Request the HTTP connection be closed after this HTTP request.
Definition: http.c:840
void ast_http_error(struct ast_tcptls_session_instance *ser, int status, const char *title, const char *text)
Send HTTP error message and close socket.
Definition: http.c:651
#define ast_verb(level,...)
struct ast_iostream * ast_iostream_from_fd(int *fd)
Create an iostream from a file descriptor.
Definition: iostream.c:604
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition: iostream.c:84
int ast_iostream_close(struct ast_iostream *stream)
Close an iostream.
Definition: iostream.c:528
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_mutex_destroy(a)
Definition: lock.h:188
int errno
static void close_mansession_file(struct mansession *s)
Definition: manager.c:8502
static struct mansession_session * find_session_by_nonce(const char *username, unsigned long nonce, int *stale)
Definition: manager.c:8146
static void process_output(struct mansession *s, struct ast_str **out, struct ast_variable *params, enum output_format format)
Definition: manager.c:8512
static const char *const contenttype[]
Definition: manager.c:8096
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:1746
struct ast_iostream * stream
Definition: manager.c:1748
ast_mutex_t lock
Definition: manager.c:1753
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:2636
long int ast_random(void)
Definition: utils.c:2310

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

9140{
9141 int retval;
9142 struct ast_sockaddr ser_remote_address_tmp;
9143
9144 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9145 retval = auth_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
9146 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9147 return retval;
9148}
static ENTRY retval
Definition: hsearch.c:50
static int auth_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, const struct ast_sockaddr *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:8757
struct ast_sockaddr remote_address
Definition: tcptls.h:152

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

◆ auth_mxml_http_callback()

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

Definition at line 9150 of file manager.c.

9151{
9152 int retval;
9153 struct ast_sockaddr ser_remote_address_tmp;
9154
9155 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9156 retval = auth_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
9157 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9158 return retval;
9159}

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

◆ auth_rawman_http_callback()

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

Definition at line 9161 of file manager.c.

9162{
9163 int retval;
9164 struct ast_sockaddr ser_remote_address_tmp;
9165
9166 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9167 retval = auth_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
9168 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9169 return retval;
9170}

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

◆ close_mansession_file()

static void close_mansession_file ( struct mansession s)
static

Definition at line 8502 of file manager.c.

8503{
8504 if (s->stream) {
8506 s->stream = NULL;
8507 } else {
8508 ast_log(LOG_ERROR, "Attempted to close file/file descriptor on mansession without a valid file or file descriptor.\n");
8509 }
8510}

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

8108{
8109 struct ao2_container *sessions;
8111 struct ao2_iterator i;
8112
8113 if (ident == 0) {
8114 return NULL;
8115 }
8116
8117 sessions = ao2_global_obj_ref(mgr_sessions);
8118 if (!sessions) {
8119 return NULL;
8120 }
8122 ao2_ref(sessions, -1);
8123 while ((session = ao2_iterator_next(&i))) {
8125 if (session->managerid == ident && !session->needdestroy) {
8126 ast_atomic_fetchadd_int(&session->inuse, incinuse ? 1 : 0);
8127 break;
8128 }
8131 }
8133
8134 return session;
8135}
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757

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

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

◆ find_session_by_nonce()

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

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

Definition at line 8146 of file manager.c.

8147{
8149 struct ao2_container *sessions;
8150 struct ao2_iterator i;
8151
8152 if (nonce == 0 || username == NULL || stale == NULL) {
8153 return NULL;
8154 }
8155
8156 sessions = ao2_global_obj_ref(mgr_sessions);
8157 if (!sessions) {
8158 return NULL;
8159 }
8161 ao2_ref(sessions, -1);
8162 while ((session = ao2_iterator_next(&i))) {
8164 if (!strcasecmp(session->username, username) && session->managerid == nonce) {
8165 *stale = 0;
8166 break;
8167 } else if (!strcasecmp(session->username, username) && session->oldnonce == nonce) {
8168 *stale = 1;
8169 break;
8170 }
8173 }
8175
8176 return session;
8177}

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

9216{
9217 struct ast_manager_user *user = NULL;
9218
9221 AST_APP_ARG(param);
9222 );
9223
9224
9225 if (ast_strlen_zero(data) ) {
9226 ast_log(LOG_WARNING, "AMI_CLIENT() requires two arguments: AMI_CLIENT(<name>[,<arg>])\n");
9227 return -1;
9228 }
9230 args.name = ast_strip(args.name);
9231 args.param = ast_strip(args.param);
9232
9234 if (!(user = get_manager_by_name_locked(args.name))) {
9236 ast_log(LOG_ERROR, "There's no manager user called : \"%s\"\n", args.name);
9237 return -1;
9238 }
9240
9241 if (!strcasecmp(args.param, "sessions")) {
9242 int no_sessions = 0;
9243 struct ao2_container *sessions;
9244
9245 sessions = ao2_global_obj_ref(mgr_sessions);
9246 if (sessions) {
9247 ao2_callback_data(sessions, 0, get_manager_sessions_cb, /*login name*/ data, &no_sessions);
9248 ao2_ref(sessions, -1);
9249 }
9250 snprintf(buf, len, "%d", no_sessions);
9251 } else {
9252 ast_log(LOG_ERROR, "Invalid arguments provided to function AMI_CLIENT: %s\n", args.param);
9253 return -1;
9254
9255 }
9256
9257 return 0;
9258}
#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:9200
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 8545 of file manager.c.

8551{
8552 struct mansession s = { .session = NULL, .tcptls_session = ser };
8554 uint32_t ident;
8555 int fd;
8556 int blastaway = 0;
8557 struct ast_variable *params = get_params;
8558 char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
8559 struct ast_str *http_header = NULL, *out = NULL;
8560 struct message m = { 0 };
8561
8563 ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
8564 return 0;
8565 }
8566
8567 ident = ast_http_manid_from_vars(headers);
8568
8569 if (!(session = find_session(ident, 1))) {
8570
8571 /**/
8572 /* Create new session.
8573 * While it is not in the list we don't need any locking
8574 */
8575 if (!(session = build_mansession(remote_address))) {
8577 ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8578 return 0;
8579 }
8581 session->send_events = 0;
8582 session->inuse = 1;
8583 /*!
8584 * \note There is approximately a 1 in 1.8E19 chance that the following
8585 * calculation will produce 0, which is an invalid ID, but due to the
8586 * properties of the rand() function (and the constancy of s), that
8587 * won't happen twice in a row.
8588 */
8589 while ((session->managerid = ast_random() ^ (unsigned long) session) == 0) {
8590 }
8591 session->last_ev = grab_last();
8592 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
8593 }
8595
8596 http_header = ast_str_create(128);
8597 out = ast_str_create(2048);
8598
8599 ast_mutex_init(&s.lock);
8600
8601 if (http_header == NULL || out == NULL) {
8603 ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
8604 goto generic_callback_out;
8605 }
8606
8607 s.session = session;
8608 fd = mkstemp(template); /* create a temporary file for command output */
8609 unlink(template);
8610 if (fd <= -1) {
8611 ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
8612 goto generic_callback_out;
8613 }
8615 if (!s.stream) {
8616 ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
8617 ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
8618 close(fd);
8619 goto generic_callback_out;
8620 }
8621
8622 if (method == AST_HTTP_POST) {
8623 params = ast_http_get_post_vars(ser, headers);
8624 if (!params) {
8625 switch (errno) {
8626 case EFBIG:
8627 ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
8629 goto generic_callback_out;
8630 case ENOMEM:
8632 ast_http_error(ser, 500, "Server Error", "Out of memory");
8634 goto generic_callback_out;
8635 case EIO:
8636 ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8638 goto generic_callback_out;
8639 }
8640 }
8641 }
8642
8643 astman_append_headers(&m, params);
8644
8645 if (process_message(&s, &m)) {
8646 if (session->authenticated) {
8648 ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8649 }
8650 } else {
8651 if (displayconnects) {
8652 ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
8653 }
8654 }
8655 session->needdestroy = 1;
8656 }
8657
8659
8660 ast_str_append(&http_header, 0,
8661 "Content-type: text/%s\r\n"
8662 "Set-Cookie: mansession_id=\"%08x\"; Version=1; Max-Age=%d\r\n"
8663 "Pragma: SuppressEvents\r\n",
8664 contenttype[format],
8665 session->managerid, httptimeout);
8666
8667 if (format == FORMAT_XML) {
8668 ast_str_append(&out, 0, "<ajax-response>\n");
8669 } else if (format == FORMAT_HTML) {
8670 /*
8671 * When handling AMI-over-HTTP in HTML format, we provide a simple form for
8672 * debugging purposes. This HTML code should not be here, we
8673 * should read from some config file...
8674 */
8675
8676#define ROW_FMT "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\">%s</td></tr>\r\n"
8677#define TEST_STRING \
8678 "<form action=\"manager\" method=\"post\">\n\
8679 Action: <select name=\"action\">\n\
8680 <option value=\"\">-----&gt;</option>\n\
8681 <option value=\"login\">login</option>\n\
8682 <option value=\"command\">Command</option>\n\
8683 <option value=\"waitevent\">waitevent</option>\n\
8684 <option value=\"listcommands\">listcommands</option>\n\
8685 </select>\n\
8686 or <input name=\"action\"><br/>\n\
8687 CLI Command <input name=\"command\"><br>\n\
8688 user <input name=\"username\"> pass <input type=\"password\" name=\"secret\"><br>\n\
8689 <input type=\"submit\">\n</form>\n"
8690
8691 ast_str_append(&out, 0, "<title>Asterisk&trade; Manager Interface</title>");
8692 ast_str_append(&out, 0, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n");
8693 ast_str_append(&out, 0, ROW_FMT, "<h1>Manager Tester</h1>");
8695 }
8696
8697 process_output(&s, &out, params, format);
8698
8699 if (format == FORMAT_XML) {
8700 ast_str_append(&out, 0, "</ajax-response>\n");
8701 } else if (format == FORMAT_HTML) {
8702 ast_str_append(&out, 0, "</table></body>\r\n");
8703 }
8704
8706 /* Reset HTTP timeout. If we're not authenticated, keep it extremely short */
8707 session->sessiontimeout = time(NULL) + ((session->authenticated || httptimeout < 5) ? httptimeout : 5);
8708
8709 if (session->needdestroy) {
8710 if (session->inuse == 1) {
8711 ast_debug(1, "Need destroy, doing it now!\n");
8712 blastaway = 1;
8713 } else {
8714 ast_debug(1, "Need destroy, but can't do it yet!\n");
8715 ast_mutex_lock(&session->notify_lock);
8716 if (session->waiting_thread != AST_PTHREADT_NULL) {
8717 pthread_kill(session->waiting_thread, SIGURG);
8718 }
8719 ast_mutex_unlock(&session->notify_lock);
8720 session->inuse--;
8721 }
8722 } else {
8723 session->inuse--;
8724 }
8726
8727 ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
8728 http_header = NULL;
8729 out = NULL;
8730
8731generic_callback_out:
8733
8734 /* Clear resource */
8735
8736 if (method == AST_HTTP_POST && params) {
8737 ast_variables_destroy(params);
8738 }
8739 ast_free(http_header);
8740 ast_free(out);
8741
8742 if (session) {
8743 if (blastaway) {
8745 } else {
8746 if (session->stream) {
8747 ast_iostream_close(session->stream);
8748 session->stream = NULL;
8749 }
8751 }
8752 }
8753
8754 return 0;
8755}
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:2443
uint32_t ast_http_manid_from_vars(struct ast_variable *headers) attribute_pure
Return manager id, if exist, from request headers.
Definition: http.c:220
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
#define ROW_FMT
#define TEST_STRING

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

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

◆ get_manager_sessions_cb()

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

Get number of logged in sessions for a login name.

Definition at line 9200 of file manager.c.

9201{
9202 struct mansession_session *session = obj;
9203 const char *login = (char *)arg;
9204 int *no_sessions = data;
9205
9206 if (strcasecmp(session->username, login) == 0) {
9207 (*no_sessions)++;
9208 }
9209
9210 return 0;
9211}

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

9482{
9484 struct ao2_iterator it_events;
9485 struct ast_xml_doc_item *item, *temp;
9486 int length;
9487
9488 if (cmd == CLI_INIT) {
9489 e->command = "manager show event";
9490 e->usage =
9491 "Usage: manager show event <eventname>\n"
9492 " Provides a detailed description a Manager interface event.\n";
9493 return NULL;
9494 }
9495
9496 events = ao2_global_obj_ref(event_docs);
9497 if (!events) {
9498 ast_cli(a->fd, "No manager event documentation loaded\n");
9499 return CLI_SUCCESS;
9500 }
9501
9502 if (cmd == CLI_GENERATE) {
9503 if (a->pos != 3) {
9504 return NULL;
9505 }
9506
9507 length = strlen(a->word);
9508 it_events = ao2_iterator_init(events, 0);
9509 while ((item = ao2_iterator_next(&it_events))) {
9510 if (!strncasecmp(a->word, item->name, length)) {
9512 ao2_ref(item, -1);
9513 break;
9514 }
9515 }
9516 ao2_ref(item, -1);
9517 }
9518 ao2_iterator_destroy(&it_events);
9519
9520 return NULL;
9521 }
9522
9523 if (a->argc != 4) {
9524 return CLI_SHOWUSAGE;
9525 }
9526
9527 if (!(item = ao2_find(events, a->argv[3], OBJ_KEY))) {
9528 ast_cli(a->fd, "Could not find event '%s'\n", a->argv[3]);
9529 return CLI_SUCCESS;
9530 }
9531
9532 ast_cli(a->fd, "Event: %s\n", a->argv[3]);
9533 for (temp = item; temp; temp = AST_LIST_NEXT(temp, next)) {
9534 print_event_instance(a, temp);
9535 }
9536
9537 ao2_ref(item, -1);
9538 return CLI_SUCCESS;
9539}
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
#define OBJ_KEY
Definition: astobj2.h:1151
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2758
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:9444
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
const char * name
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
struct ast_xml_doc_item * next
Definition: xmldoc.h:80
static struct aco_type item
Definition: test_config.c:1463
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

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

◆ handle_manager_show_events()

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

Definition at line 9363 of file manager.c.

9364{
9365 struct ao2_container *events;
9366 struct ao2_iterator *it_events;
9367 struct ast_xml_doc_item *item;
9368 struct ast_xml_doc_item **items;
9369 struct ast_str *buffer;
9370 int i = 0, totalitems = 0;
9371
9372 switch (cmd) {
9373 case CLI_INIT:
9374 e->command = "manager show events";
9375 e->usage =
9376 "Usage: manager show events\n"
9377 " Prints a listing of the available Asterisk manager interface events.\n";
9378 return NULL;
9379 case CLI_GENERATE:
9380 return NULL;
9381 }
9382 if (a->argc != 3) {
9383 return CLI_SHOWUSAGE;
9384 }
9385
9386 buffer = ast_str_create(128);
9387 if (!buffer) {
9388 return CLI_SUCCESS;
9389 }
9390
9391 events = ao2_global_obj_ref(event_docs);
9392 if (!events) {
9393 ast_cli(a->fd, "No manager event documentation loaded\n");
9394 ast_free(buffer);
9395 return CLI_SUCCESS;
9396 }
9397
9399 if (!(it_events = ao2_callback(events, OBJ_MULTIPLE | OBJ_NOLOCK, NULL, NULL))) {
9401 ast_log(AST_LOG_ERROR, "Unable to create iterator for events container\n");
9402 ast_free(buffer);
9403 ao2_ref(events, -1);
9404 return CLI_SUCCESS;
9405 }
9406 if (!(items = ast_calloc(sizeof(struct ast_xml_doc_item *), ao2_container_count(events)))) {
9408 ast_log(AST_LOG_ERROR, "Unable to create temporary sorting array for events\n");
9409 ao2_iterator_destroy(it_events);
9410 ast_free(buffer);
9411 ao2_ref(events, -1);
9412 return CLI_SUCCESS;
9413 }
9415
9416 while ((item = ao2_iterator_next(it_events))) {
9417 items[totalitems++] = item;
9418 ao2_ref(item, -1);
9419 }
9420
9421 qsort(items, totalitems, sizeof(struct ast_xml_doc_item *), ast_xml_doc_item_cmp_fn);
9422
9423 ast_cli(a->fd, "Events:\n");
9424 ast_cli(a->fd, " -------------------- -------------------- -------------------- \n");
9425 for (i = 0; i < totalitems; i++) {
9426 ast_str_append(&buffer, 0, " %-20.20s", items[i]->name);
9427 if ((i + 1) % 3 == 0) {
9428 ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
9429 ast_str_set(&buffer, 0, "%s", "");
9430 }
9431 }
9432 if ((i + 1) % 3 != 0) {
9433 ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
9434 }
9435
9436 ao2_iterator_destroy(it_events);
9437 ast_free(items);
9438 ao2_ref(events, -1);
9439 ast_free(buffer);
9440
9441 return CLI_SUCCESS;
9442}
#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:9356
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:758
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:1110

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

9313{
9314 switch (cmd) {
9315 case CLI_INIT:
9316 e->command = "manager show settings";
9317 e->usage =
9318 "Usage: manager show settings\n"
9319 " Provides detailed list of the configuration of the Manager.\n";
9320 return NULL;
9321 case CLI_GENERATE:
9322 return NULL;
9323 }
9324#define FORMAT " %-25.25s %-15.55s\n"
9325#define FORMAT2 " %-25.25s %-15d\n"
9326#define FORMAT3 " %-25.25s %s\n"
9327 if (a->argc != 3) {
9328 return CLI_SHOWUSAGE;
9329 }
9330 ast_cli(a->fd, "\nGlobal Settings:\n");
9331 ast_cli(a->fd, "----------------\n");
9332 ast_cli(a->fd, FORMAT, "Manager (AMI):", AST_CLI_YESNO(manager_enabled));
9333 ast_cli(a->fd, FORMAT, "Web Manager (AMI/HTTP):", AST_CLI_YESNO(webmanager_enabled));
9334 ast_cli(a->fd, FORMAT, "TCP Bindaddress:", manager_enabled != 0 ? ast_sockaddr_stringify(&ami_desc.local_address) : "Disabled");
9335 ast_cli(a->fd, FORMAT2, "HTTP Timeout (seconds):", httptimeout);
9336 ast_cli(a->fd, FORMAT, "TLS Enable:", AST_CLI_YESNO(ami_tls_cfg.enabled));
9337 ast_cli(a->fd, FORMAT, "TLS Bindaddress:", ami_tls_cfg.enabled != 0 ? ast_sockaddr_stringify(&amis_desc.local_address) : "Disabled");
9338 ast_cli(a->fd, FORMAT, "TLS Certfile:", ami_tls_cfg.certfile);
9339 ast_cli(a->fd, FORMAT, "TLS Privatekey:", ami_tls_cfg.pvtfile);
9340 ast_cli(a->fd, FORMAT, "TLS Cipher:", ami_tls_cfg.cipher);
9341 ast_cli(a->fd, FORMAT, "Allow multiple login:", AST_CLI_YESNO(allowmultiplelogin));
9342 ast_cli(a->fd, FORMAT, "Display connects:", AST_CLI_YESNO(displayconnects));
9343 ast_cli(a->fd, FORMAT, "Timestamp events:", AST_CLI_YESNO(timestampevents));
9344 ast_cli(a->fd, FORMAT3, "Channel vars:", S_OR(manager_channelvars, ""));
9345 ast_cli(a->fd, FORMAT3, "Disabled events:", S_OR(manager_disabledevents, ""));
9346 ast_cli(a->fd, FORMAT, "Debug:", AST_CLI_YESNO(manager_debug));
9347#undef FORMAT
9348#undef FORMAT2
9349#undef FORMAT3
9350
9351 return CLI_SUCCESS;
9352}
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
static char * manager_channelvars
Definition: manager.c:1596
static char * manager_disabledevents
Definition: manager.c:1597
#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 9565 of file manager.c.

9566{
9567 char *parse = NULL;
9569 AST_APP_ARG(vars)[MAX_VARS];
9570 );
9571
9574
9575 /* parse the setting */
9578
9580}
#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:7880
#define MAX_VARS
Definition: manager.c:1629

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

10321{
10323
10325}
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:9807
static void manager_shutdown(void)
Definition: manager.c:9617
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

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

◆ manager_event_blob_dtor()

static void manager_event_blob_dtor ( void *  obj)
static

Definition at line 10384 of file manager.c.

10385{
10386 struct ast_manager_event_blob *ev = obj;
10387
10389}

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

9599{
9600 ast_free(user->a1_hash);
9601 ast_free(user->secret);
9602 if (user->whitefilters) {
9603 ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one");
9604 }
9605 if (user->blackfilters) {
9606 ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one");
9607 }
9608 user->acl = ast_free_acl_list(user->acl);
9609 ast_variables_destroy(user->chanvars);
9610 ast_free(user);
9611}

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

9081{
9082 int retval;
9083 struct ast_sockaddr ser_remote_address_tmp;
9084
9085 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9086 retval = generic_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
9087 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9088 return retval;
9089}
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:8545

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

◆ manager_set_defaults()

static void manager_set_defaults ( void  )
static

Definition at line 9779 of file manager.c.

9780{
9781 manager_enabled = 0;
9782 displayconnects = 1;
9784 authtimeout = 30;
9785 authlimit = 50;
9786 manager_debug = 0; /* Debug disabled by default */
9787
9788 /* default values */
9790 sizeof(global_realm));
9793
9794 ami_tls_cfg.enabled = 0;
9805}
#define DEFAULT_REALM
Definition: manager.c:1599
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
char * capath
Definition: tcptls.h:94
char * cafile
Definition: tcptls.h:93
#define AST_CERTFILE
Definition: tcptls.h:63

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

Referenced by __init_manager().

◆ manager_shutdown()

static void manager_shutdown ( void  )
static

Definition at line 9617 of file manager.c.

9618{
9619 struct ast_manager_user *user;
9620
9621 /* This event is not actually transmitted, but causes all TCP sessions to be closed */
9622 manager_event(EVENT_FLAG_SHUTDOWN, "CloseSession", "CloseSession: true\r\n");
9623
9624 ast_manager_unregister("Ping");
9625 ast_manager_unregister("Events");
9626 ast_manager_unregister("Logoff");
9627 ast_manager_unregister("Login");
9628 ast_manager_unregister("Challenge");
9629 ast_manager_unregister("Hangup");
9630 ast_manager_unregister("Status");
9631 ast_manager_unregister("Setvar");
9632 ast_manager_unregister("Getvar");
9633 ast_manager_unregister("GetConfig");
9634 ast_manager_unregister("GetConfigJSON");
9635 ast_manager_unregister("UpdateConfig");
9636 ast_manager_unregister("CreateConfig");
9637 ast_manager_unregister("ListCategories");
9638 ast_manager_unregister("Redirect");
9639 ast_manager_unregister("Atxfer");
9640 ast_manager_unregister("CancelAtxfer");
9641 ast_manager_unregister("Originate");
9642 ast_manager_unregister("Command");
9643 ast_manager_unregister("ExtensionState");
9644 ast_manager_unregister("PresenceState");
9645 ast_manager_unregister("AbsoluteTimeout");
9646 ast_manager_unregister("MailboxStatus");
9647 ast_manager_unregister("MailboxCount");
9648 ast_manager_unregister("ListCommands");
9649 ast_manager_unregister("SendText");
9650 ast_manager_unregister("UserEvent");
9651 ast_manager_unregister("WaitEvent");
9652 ast_manager_unregister("CoreSettings");
9653 ast_manager_unregister("CoreStatus");
9654 ast_manager_unregister("Reload");
9655 ast_manager_unregister("LoggerRotate");
9656 ast_manager_unregister("CoreShowChannels");
9657 ast_manager_unregister("CoreShowChannelMap");
9658 ast_manager_unregister("ModuleLoad");
9659 ast_manager_unregister("ModuleCheck");
9660 ast_manager_unregister("AOCMessage");
9661 ast_manager_unregister("Filter");
9662 ast_manager_unregister("BlindTransfer");
9665
9666#ifdef AST_XML_DOCS
9667 ao2_t_global_obj_release(event_docs, "Dispose of event_docs");
9668#endif
9669
9670#ifdef TEST_FRAMEWORK
9671 stasis_forward_cancel(test_suite_forwarder);
9672 test_suite_forwarder = NULL;
9673#endif
9674
9675 if (stasis_router) {
9678 }
9686
9689
9700
9701 ao2_global_obj_release(mgr_sessions);
9702
9703 while ((user = AST_LIST_REMOVE_HEAD(&users, list))) {
9705 }
9707
9710}
#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:1609
static struct stasis_forward * rtp_topic_forwarder
The stasis_subscription for forwarding the RTP topic to the AMI topic.
Definition: manager.c:1612
static struct stasis_forward * security_topic_forwarder
The stasis_subscription for forwarding the Security topic to the AMI topic.
Definition: manager.c:1615
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:1632
int ast_manager_unregister(const char *action)
support functions to register/unregister AMI action handlers,
Definition: manager.c:7887
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static char user[512]
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548
void stasis_message_router_unsubscribe_and_join(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic, blocking until the final message has been processed.

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

Referenced by load_module().

◆ manager_subscriptions_init()

static int manager_subscriptions_init ( void  )
static

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

Definition at line 9716 of file manager.c.

9717{
9718 int res = 0;
9719
9721 if (!rtp_topic_forwarder) {
9722 return -1;
9723 }
9724
9727 return -1;
9728 }
9729
9731 if (!stasis_router) {
9732 return -1;
9733 }
9736
9739
9742
9743 if (res != 0) {
9744 return -1;
9745 }
9746 return 0;
9747}
static void manager_default_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:1959
static void manager_generic_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:1990
struct stasis_topic * ast_rtp_topic(void)
Stasis Message Bus API topic for RTP and RTCP related messages
Definition: rtp_engine.c:3569
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 9091 of file manager.c.

9092{
9093 int retval;
9094 struct ast_sockaddr ser_remote_address_tmp;
9095
9096 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9097 retval = generic_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
9098 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9099 return retval;
9100}

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

◆ process_output()

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

Definition at line 8512 of file manager.c.

8513{
8514 char *buf;
8515 off_t l;
8516 int fd;
8517
8518 if (!s->stream)
8519 return;
8520
8521 /* Ensure buffer is NULL-terminated */
8522 ast_iostream_write(s->stream, "", 1);
8523
8524 fd = ast_iostream_get_fd(s->stream);
8525
8526 l = lseek(fd, 0, SEEK_CUR);
8527 if (l > 0) {
8528 if (MAP_FAILED == (buf = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))) {
8529 ast_log(LOG_WARNING, "mmap failed. Manager output was not processed\n");
8530 } else {
8531 if (format == FORMAT_XML || format == FORMAT_HTML) {
8532 xml_translate(out, buf, params, format);
8533 } else {
8534 ast_str_append(out, 0, "%s", buf);
8535 }
8536 munmap(buf, l);
8537 }
8538 } else if (format == FORMAT_XML || format == FORMAT_HTML) {
8539 xml_translate(out, "", params, format);
8540 }
8541
8543}
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t count)
Write data to an iostream.
Definition: iostream.c:374
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:8384

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

9274{
9275 struct ast_tcptls_session_args *ser = data;
9276 /* purge_sessions will return the number of sessions actually purged,
9277 * up to a maximum of it's arguments, purge one at a time, keeping a
9278 * purge interval of 1ms as long as we purged a session, otherwise
9279 * revert to a purge check every 5s
9280 */
9281 if (purge_sessions(1) == 1) {
9282 ser->poll_timeout = 1;
9283 } else {
9284 ser->poll_timeout = 5000;
9285 }
9286 purge_events();
9287}
static void purge_events(void)
Definition: manager.c:2104
static int purge_sessions(int n_max)
remove at most n_max stale session from the list.
Definition: manager.c:7649
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 9102 of file manager.c.

9103{
9104 int retval;
9105 struct ast_sockaddr ser_remote_address_tmp;
9106
9107 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
9108 retval = generic_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
9109 ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
9110 return retval;
9111}

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

◆ subscribe_all()

static int subscribe_all ( void  )
static

Definition at line 9749 of file manager.c.

9750{
9752 ast_log(AST_LOG_ERROR, "Failed to initialize manager subscriptions\n");
9753 return -1;
9754 }
9755 if (manager_system_init()) {
9756 ast_log(AST_LOG_ERROR, "Failed to initialize manager system handling\n");
9757 return -1;
9758 }
9759 if (manager_channels_init()) {
9760 ast_log(AST_LOG_ERROR, "Failed to initialize manager channel handling\n");
9761 return -1;
9762 }
9763 if (manager_mwi_init()) {
9764 ast_log(AST_LOG_ERROR, "Failed to initialize manager MWI handling\n");
9765 return -1;
9766 }
9767 if (manager_bridging_init()) {
9768 return -1;
9769 }
9770 if (manager_endpoints_init()) {
9771 ast_log(AST_LOG_ERROR, "Failed to initialize manager endpoints handling\n");
9772 return -1;
9773 }
9774
9775 subscribed = 1;
9776 return 0;
9777}
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:9716
int manager_mwi_init(void)
Initialize support for AMI MWI events.
Definition: manager_mwi.c:155
int manager_bridging_init(void)
Initialize support for AMI channel events.
int manager_endpoints_init(void)
Initialize support for AMI endpoint events.
int manager_system_init(void)
Initialize support for AMI system events.
int manager_channels_init(void)
Initialize support for AMI channel events.

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

Referenced by __init_manager().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 10315 of file manager.c.

10316{
10317 return 0;
10318}

◆ variable_count_cmp_fn()

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

Definition at line 8345 of file manager.c.

8346{
8347 /* Due to the simplicity of struct variable_count, it makes no difference
8348 * if you pass in objects or strings, the same operation applies. This is
8349 * due to the fact that the hash occurs on the first element, which means
8350 * the address of both the struct and the string are exactly the same. */
8351 struct variable_count *vc = obj;
8352 char *str = vstr;
8353 return !strcmp(vc->varname, str) ? CMP_MATCH | CMP_STOP : 0;
8354}
const char * str
Definition: app_jack.c:147
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
char * varname
Definition: manager.c:8334

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

8339{
8340 const struct variable_count *vc = vvc;
8341
8342 return ast_str_hash(vc->varname);
8343}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1256

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

8267{
8268 /* store in a local buffer to avoid calling ast_str_append too often */
8269 char buf[256];
8270 char *dst = buf;
8271 const char *save = src;
8272 int space = sizeof(buf);
8273 /* repeat until done and nothing to flush */
8274 for ( ; *src || dst != buf ; src++) {
8275 if (*src == '\0' || space < 10) { /* flush */
8276 *dst++ = '\0';
8277 ast_str_append(out, 0, "%s", buf);
8278 dst = buf;
8279 space = sizeof(buf);
8280 if (*src == '\0') {
8281 break;
8282 }
8283 }
8284
8285 if (mode & 2) {
8286 if (save == src && isdigit(*src)) {
8287 /* The first character of an XML attribute cannot be a digit */
8288 *dst++ = '_';
8289 *dst++ = *src;
8290 space -= 2;
8291 continue;
8292 } else if (!isalnum(*src)) {
8293 /* Replace non-alphanumeric with an underscore */
8294 *dst++ = '_';
8295 space--;
8296 continue;
8297 }
8298 }
8299 switch (*src) {
8300 case '<':
8301 strcpy(dst, "&lt;");
8302 dst += 4;
8303 space -= 4;
8304 break;
8305 case '>':
8306 strcpy(dst, "&gt;");
8307 dst += 4;
8308 space -= 4;
8309 break;
8310 case '\"':
8311 strcpy(dst, "&quot;");
8312 dst += 6;
8313 space -= 6;
8314 break;
8315 case '\'':
8316 strcpy(dst, "&apos;");
8317 dst += 6;
8318 space -= 6;
8319 break;
8320 case '&':
8321 strcpy(dst, "&amp;");
8322 dst += 5;
8323 space -= 5;
8324 break;
8325
8326 default:
8327 *dst++ = mode ? tolower(*src) : *src;
8328 space--;
8329 }
8330 }
8331}

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

8385{
8386 struct ast_variable *v;
8387 const char *dest = NULL;
8388 char *var, *val;
8389 const char *objtype = NULL;
8390 int in_data = 0; /* parsing data */
8391 int inobj = 0;
8392 int xml = (format == FORMAT_XML);
8393 struct variable_count *vc = NULL;
8394 struct ao2_container *vco = NULL;
8395
8396 if (xml) {
8397 /* dest and objtype need only for XML format */
8398 for (v = get_vars; v; v = v->next) {
8399 if (!strcasecmp(v->name, "ajaxdest")) {
8400 dest = v->value;
8401 } else if (!strcasecmp(v->name, "ajaxobjtype")) {
8402 objtype = v->value;
8403 }
8404 }
8405 if (ast_strlen_zero(dest)) {
8406 dest = "unknown";
8407 }
8408 if (ast_strlen_zero(objtype)) {
8409 objtype = "generic";
8410 }
8411 }
8412
8413 /* we want to stop when we find an empty line */
8414 while (in && *in) {
8415 val = strsep(&in, "\r\n"); /* mark start and end of line */
8416 if (in && *in == '\n') { /* remove trailing \n if any */
8417 in++;
8418 }
8420 ast_debug(5, "inobj %d in_data %d line <%s>\n", inobj, in_data, val);
8421 if (ast_strlen_zero(val)) {
8422 /* empty line */
8423 if (in_data) {
8424 /* close data in Opaque mode */
8425 ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
8426 in_data = 0;
8427 }
8428
8429 if (inobj) {
8430 /* close block */
8431 ast_str_append(out, 0, xml ? " /></response>\n" :
8432 "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
8433 inobj = 0;
8434 ao2_ref(vco, -1);
8435 vco = NULL;
8436 }
8437 continue;
8438 }
8439
8440 if (!inobj) {
8441 /* start new block */
8442 if (xml) {
8443 ast_str_append(out, 0, "<response type='object' id='%s'><%s", dest, objtype);
8444 }
8447 inobj = 1;
8448 }
8449
8450 if (in_data) {
8451 /* Process data field in Opaque mode. This is a
8452 * followup, so we re-add line feeds. */
8453 ast_str_append(out, 0, xml ? "\n" : "<br>\n");
8454 xml_copy_escape(out, val, 0); /* data field */
8455 continue;
8456 }
8457
8458 /* We expect "Name: value" line here */
8459 var = strsep(&val, ":");
8460 if (val) {
8461 /* found the field name */
8464 } else {
8465 /* field name not found, switch to opaque mode */
8466 val = var;
8467 var = "Opaque-data";
8468 in_data = 1;
8469 }
8470
8471
8472 ast_str_append(out, 0, xml ? " " : "<tr><td>");
8473 if ((vc = ao2_find(vco, var, 0))) {
8474 vc->count++;
8475 } else {
8476 /* Create a new entry for this one */
8477 vc = ao2_alloc(sizeof(*vc), NULL);
8478 vc->varname = var;
8479 vc->count = 1;
8480 ao2_link(vco, vc);
8481 }
8482
8483 xml_copy_escape(out, var, xml ? 1 | 2 : 0); /* data name */
8484 if (vc->count > 1) {
8485 ast_str_append(out, 0, "-%d", vc->count);
8486 }
8487 ao2_ref(vc, -1);
8488 ast_str_append(out, 0, xml ? "='" : "</td><td>");
8489 xml_copy_escape(out, val, 0); /* data field */
8490 if (!in_data || !*in) {
8491 ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
8492 }
8493 }
8494
8495 if (inobj) {
8496 ast_str_append(out, 0, xml ? " /></response>\n" :
8497 "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
8498 ao2_ref(vco, -1);
8499 }
8500}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
char * strsep(char **str, const char *delims)
static void xml_copy_escape(struct ast_str **out, const char *src, int mode)
Definition: manager.c:8266
static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
Definition: manager.c:8345
static int variable_count_hash_fn(const void *vvc, const int flags)
Definition: manager.c:8338
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 10432 of file manager.c.

◆ amanageruri

struct ast_http_uri amanageruri
static

Definition at line 9181 of file manager.c.

Referenced by __init_manager().

◆ amanagerxmluri

struct ast_http_uri amanagerxmluri
static

Definition at line 9190 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 9172 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 10432 of file manager.c.

◆ cli_manager

struct ast_cli_entry cli_manager[]
static

Definition at line 9543 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 8096 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:9215

description of AMI_CLIENT dialplan function

Definition at line 9262 of file manager.c.

Referenced by __init_manager(), and manager_shutdown().

◆ manageruri

struct ast_http_uri manageruri
static

Definition at line 9121 of file manager.c.

Referenced by __init_manager().

◆ managerxmluri

struct ast_http_uri managerxmluri
static

Definition at line 9129 of file manager.c.

Referenced by __init_manager().

◆ rawmanuri

struct ast_http_uri rawmanuri
static

Definition at line 9113 of file manager.c.

Referenced by __init_manager().

◆ webregged

int webregged = 0
static

Definition at line 9268 of file manager.c.

Referenced by __init_manager().

◆ words

const char* words[AST_MAX_CMD_LEN]

Definition at line 1646 of file manager.c.

Referenced by check_blacklist().