Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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/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 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 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_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_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 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 void 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 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 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"

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

7471  {
7472  FORMAT_RAW,
7473  FORMAT_HTML,
7474  FORMAT_XML,
7475 };
@ FORMAT_RAW
Definition: manager.c:7472
@ FORMAT_HTML
Definition: manager.c:7473
@ FORMAT_XML
Definition: manager.c:7474

Function Documentation

◆ __init_manager()

static int __init_manager ( int  reload,
int  by_external_config 
)
static

Definition at line 9175 of file manager.c.

9176 {
9177  struct ast_config *ucfg = NULL, *cfg = NULL;
9178  const char *val;
9179  char *cat = NULL;
9180  int newhttptimeout = 60;
9181  struct ast_manager_user *user = NULL;
9182  struct ast_variable *var;
9183  struct ast_flags config_flags = { (reload && !by_external_config) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
9184  char a1[256];
9185  char a1_hash[256];
9186  struct ast_sockaddr ami_desc_local_address_tmp;
9187  struct ast_sockaddr amis_desc_local_address_tmp;
9188  int tls_was_enabled = 0;
9189  int acl_subscription_flag = 0;
9190 
9191  if (!reload) {
9192  struct ao2_container *sessions;
9193 #ifdef AST_XML_DOCS
9194  struct ao2_container *temp_event_docs;
9195 #endif
9196  int res;
9197 
9199  if (res != 0) {
9200  return -1;
9201  }
9202  manager_topic = stasis_topic_create("manager:core");
9203  if (!manager_topic) {
9204  return -1;
9205  }
9206 
9207  /* Register default actions */
9246 
9247 #ifdef TEST_FRAMEWORK
9248  test_suite_forwarder = stasis_forward_all(ast_test_suite_topic(), manager_topic);
9249 #endif
9250 
9254 
9255  /* Append placeholder event so master_eventq never runs dry */
9256  if (append_event("Event: Placeholder\r\n\r\n", 0)) {
9257  return -1;
9258  }
9259 
9260 #ifdef AST_XML_DOCS
9261  temp_event_docs = ast_xmldoc_build_documentation("managerEvent");
9262  if (temp_event_docs) {
9263  ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs");
9264  ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now");
9265  }
9266 #endif
9267 
9268  /* If you have a NULL hash fn, you only need a single bucket */
9270  if (!sessions) {
9271  return -1;
9272  }
9273  ao2_global_obj_replace_unref(mgr_sessions, sessions);
9274  ao2_ref(sessions, -1);
9275 
9276  /* Initialize all settings before first configuration load. */
9278  }
9279 
9280  cfg = ast_config_load2("manager.conf", "manager", config_flags);
9281  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
9282  return 0;
9283  } else if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
9284  ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid.\n");
9285  return 0;
9286  }
9287 
9288  /* 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. */
9289  if (!by_external_config) {
9291  }
9292 
9293  if (reload) {
9294  /* Reset all settings before reloading configuration */
9295  tls_was_enabled = ami_tls_cfg.enabled;
9297  }
9298 
9299  ast_sockaddr_parse(&ami_desc_local_address_tmp, "[::]", 0);
9300  ast_sockaddr_set_port(&ami_desc_local_address_tmp, DEFAULT_MANAGER_PORT);
9301 
9302  for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
9303  val = var->value;
9304 
9305  /* read tls config options while preventing unsupported options from being set */
9306  if (strcasecmp(var->name, "tlscafile")
9307  && strcasecmp(var->name, "tlscapath")
9308  && strcasecmp(var->name, "tlscadir")
9309  && strcasecmp(var->name, "tlsverifyclient")
9310  && strcasecmp(var->name, "tlsdontverifyserver")
9311  && strcasecmp(var->name, "tlsclientmethod")
9312  && strcasecmp(var->name, "sslclientmethod")
9313  && !ast_tls_read_conf(&ami_tls_cfg, &amis_desc, var->name, val)) {
9314  continue;
9315  }
9316 
9317  if (!strcasecmp(var->name, "enabled")) {
9319  } else if (!strcasecmp(var->name, "webenabled")) {
9321  } else if (!strcasecmp(var->name, "port")) {
9322  int bindport;
9323  if (ast_parse_arg(val, PARSE_UINT32|PARSE_IN_RANGE, &bindport, 1024, 65535)) {
9324  ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
9325  }
9326  ast_sockaddr_set_port(&ami_desc_local_address_tmp, bindport);
9327  } else if (!strcasecmp(var->name, "bindaddr")) {
9328  /* remember port if it has already been set */
9329  int setport = ast_sockaddr_port(&ami_desc_local_address_tmp);
9330 
9332  ast_log(LOG_WARNING, "Invalid address '%s' specified, default '%s' will be used\n", val,
9333  ast_sockaddr_stringify_addr(&ami_desc_local_address_tmp));
9334  } else {
9335  ast_sockaddr_parse(&ami_desc_local_address_tmp, val, PARSE_PORT_IGNORE);
9336  }
9337 
9338  if (setport) {
9339  ast_sockaddr_set_port(&ami_desc_local_address_tmp, setport);
9340  }
9341 
9342  } else if (!strcasecmp(var->name, "brokeneventsaction")) {
9344  } else if (!strcasecmp(var->name, "allowmultiplelogin")) {
9346  } else if (!strcasecmp(var->name, "displayconnects")) {
9348  } else if (!strcasecmp(var->name, "timestampevents")) {
9350  } else if (!strcasecmp(var->name, "debug")) {
9352  } else if (!strcasecmp(var->name, "httptimeout")) {
9353  newhttptimeout = atoi(val);
9354  } else if (!strcasecmp(var->name, "authtimeout")) {
9355  int timeout = atoi(var->value);
9356 
9357  if (timeout < 1) {
9358  ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", var->value);
9359  } else {
9360  authtimeout = timeout;
9361  }
9362  } else if (!strcasecmp(var->name, "authlimit")) {
9363  int limit = atoi(var->value);
9364 
9365  if (limit < 1) {
9366  ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", var->value);
9367  } else {
9368  authlimit = limit;
9369  }
9370  } else if (!strcasecmp(var->name, "channelvars")) {
9372  } else if (!strcasecmp(var->name, "disabledevents")) {
9374  } else {
9375  ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
9376  var->name, val);
9377  }
9378  }
9379 
9380  if (manager_enabled && !subscribed) {
9381  if (subscribe_all() != 0) {
9382  ast_log(LOG_ERROR, "Manager subscription error\n");
9383  return -1;
9384  }
9385  }
9386 
9387  ast_sockaddr_copy(&amis_desc_local_address_tmp, &amis_desc.local_address);
9388 
9389  /* if the amis address has not been set, default is the same as non secure ami */
9390  if (ast_sockaddr_isnull(&amis_desc_local_address_tmp)) {
9391  ast_sockaddr_copy(&amis_desc_local_address_tmp, &ami_desc_local_address_tmp);
9392  }
9393 
9394  /* if the amis address was not set, it will have non-secure ami port set; if
9395  amis address was set, we need to check that a port was set or not, if not
9396  use the default tls port */
9397  if (ast_sockaddr_port(&amis_desc_local_address_tmp) == 0 ||
9398  (ast_sockaddr_port(&ami_desc_local_address_tmp) == ast_sockaddr_port(&amis_desc_local_address_tmp))) {
9399 
9400  ast_sockaddr_set_port(&amis_desc_local_address_tmp, DEFAULT_MANAGER_TLS_PORT);
9401  }
9402 
9403  if (manager_enabled) {
9404  ast_sockaddr_copy(&ami_desc.local_address, &ami_desc_local_address_tmp);
9405  ast_sockaddr_copy(&amis_desc.local_address, &amis_desc_local_address_tmp);
9406  }
9407 
9409 
9410  /* First, get users from users.conf */
9411  ucfg = ast_config_load2("users.conf", "manager", config_flags);
9412  if (ucfg && (ucfg != CONFIG_STATUS_FILEUNCHANGED) && ucfg != CONFIG_STATUS_FILEINVALID) {
9413  const char *hasmanager;
9414  int genhasmanager = ast_true(ast_variable_retrieve(ucfg, "general", "hasmanager"));
9415 
9416  while ((cat = ast_category_browse(ucfg, cat))) {
9417  if (!strcasecmp(cat, "general")) {
9418  continue;
9419  }
9420 
9421  hasmanager = ast_variable_retrieve(ucfg, cat, "hasmanager");
9422  if ((!hasmanager && genhasmanager) || ast_true(hasmanager)) {
9423  const char *user_secret = ast_variable_retrieve(ucfg, cat, "secret");
9424  const char *user_read = ast_variable_retrieve(ucfg, cat, "read");
9425  const char *user_write = ast_variable_retrieve(ucfg, cat, "write");
9426  const char *user_displayconnects = ast_variable_retrieve(ucfg, cat, "displayconnects");
9427  const char *user_allowmultiplelogin = ast_variable_retrieve(ucfg, cat, "allowmultiplelogin");
9428  const char *user_writetimeout = ast_variable_retrieve(ucfg, cat, "writetimeout");
9429 
9430  /* Look for an existing entry,
9431  * if none found - create one and add it to the list
9432  */
9433  if (!(user = get_manager_by_name_locked(cat))) {
9434  if (!(user = ast_calloc(1, sizeof(*user)))) {
9435  break;
9436  }
9437 
9438  /* Copy name over */
9439  ast_copy_string(user->username, cat, sizeof(user->username));
9440  /* Insert into list */
9441  AST_LIST_INSERT_TAIL(&users, user, list);
9442  user->acl = NULL;
9443  user->keep = 1;
9444  user->readperm = -1;
9445  user->writeperm = -1;
9446  /* Default displayconnect from [general] */
9447  user->displayconnects = displayconnects;
9448  /* Default allowmultiplelogin from [general] */
9449  user->allowmultiplelogin = allowmultiplelogin;
9450  user->writetimeout = 100;
9451  }
9452 
9453  if (!user_secret) {
9454  user_secret = ast_variable_retrieve(ucfg, "general", "secret");
9455  }
9456  if (!user_read) {
9457  user_read = ast_variable_retrieve(ucfg, "general", "read");
9458  }
9459  if (!user_write) {
9460  user_write = ast_variable_retrieve(ucfg, "general", "write");
9461  }
9462  if (!user_displayconnects) {
9463  user_displayconnects = ast_variable_retrieve(ucfg, "general", "displayconnects");
9464  }
9465  if (!user_allowmultiplelogin) {
9466  user_allowmultiplelogin = ast_variable_retrieve(ucfg, "general", "allowmultiplelogin");
9467  }
9468  if (!user_writetimeout) {
9469  user_writetimeout = ast_variable_retrieve(ucfg, "general", "writetimeout");
9470  }
9471 
9472  if (!ast_strlen_zero(user_secret)) {
9473  ast_free(user->secret);
9474  user->secret = ast_strdup(user_secret);
9475  }
9476 
9477  if (user_read) {
9478  user->readperm = get_perm(user_read);
9479  }
9480  if (user_write) {
9481  user->writeperm = get_perm(user_write);
9482  }
9483  if (user_displayconnects) {
9484  user->displayconnects = ast_true(user_displayconnects);
9485  }
9486  if (user_allowmultiplelogin) {
9487  user->allowmultiplelogin = ast_true(user_allowmultiplelogin);
9488  }
9489  if (user_writetimeout) {
9490  int value = atoi(user_writetimeout);
9491  if (value < 100) {
9492  ast_log(LOG_WARNING, "Invalid writetimeout value '%d' in users.conf\n", value);
9493  } else {
9494  user->writetimeout = value;
9495  }
9496  }
9497  }
9498  }
9499  ast_config_destroy(ucfg);
9500  }
9501 
9502  /* cat is NULL here in any case */
9503 
9504  while ((cat = ast_category_browse(cfg, cat))) {
9505  struct ast_acl_list *oldacl;
9506 
9507  if (!strcasecmp(cat, "general")) {
9508  continue;
9509  }
9510 
9511  /* Look for an existing entry, if none found - create one and add it to the list */
9512  if (!(user = get_manager_by_name_locked(cat))) {
9513  if (!(user = ast_calloc(1, sizeof(*user)))) {
9514  break;
9515  }
9516  /* Copy name over */
9517  ast_copy_string(user->username, cat, sizeof(user->username));
9518 
9519  user->acl = NULL;
9520  user->readperm = 0;
9521  user->writeperm = 0;
9522  /* Default displayconnect from [general] */
9523  user->displayconnects = displayconnects;
9524  /* Default allowmultiplelogin from [general] */
9525  user->allowmultiplelogin = allowmultiplelogin;
9526  user->writetimeout = 100;
9529  if (!user->whitefilters || !user->blackfilters) {
9531  break;
9532  }
9533 
9534  /* Insert into list */
9536  } else {
9537  ao2_t_callback(user->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters");
9538  ao2_t_callback(user->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters");
9539  }
9540 
9541  /* Make sure we keep this user and don't destroy it during cleanup */
9542  user->keep = 1;
9543  oldacl = user->acl;
9544  user->acl = NULL;
9545  ast_variables_destroy(user->chanvars);
9546 
9547  var = ast_variable_browse(cfg, cat);
9548  for (; var; var = var->next) {
9549  if (!strcasecmp(var->name, "secret")) {
9550  ast_free(user->secret);
9551  user->secret = ast_strdup(var->value);
9552  } else if (!strcasecmp(var->name, "deny") ||
9553  !strcasecmp(var->name, "permit") ||
9554  !strcasecmp(var->name, "acl")) {
9555  int acl_error = 0;
9556 
9557  ast_append_acl(var->name, var->value, &user->acl, &acl_error, &acl_subscription_flag);
9558  if (acl_error) {
9559  ast_log(LOG_ERROR, "Invalid ACL '%s' for manager user '%s' on line %d. Deleting user\n",
9560  var->value, user->username, var->lineno);
9561  user->keep = 0;
9562  }
9563  } else if (!strcasecmp(var->name, "read") ) {
9564  user->readperm = get_perm(var->value);
9565  } else if (!strcasecmp(var->name, "write") ) {
9566  user->writeperm = get_perm(var->value);
9567  } else if (!strcasecmp(var->name, "displayconnects") ) {
9568  user->displayconnects = ast_true(var->value);
9569  } else if (!strcasecmp(var->name, "allowmultiplelogin") ) {
9570  user->allowmultiplelogin = ast_true(var->value);
9571  } else if (!strcasecmp(var->name, "writetimeout")) {
9572  int value = atoi(var->value);
9573  if (value < 100) {
9574  ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", var->value, var->lineno);
9575  } else {
9576  user->writetimeout = value;
9577  }
9578  } else if (!strcasecmp(var->name, "setvar")) {
9579  struct ast_variable *tmpvar;
9580  char varbuf[256];
9581  char *varval;
9582  char *varname;
9583 
9584  ast_copy_string(varbuf, var->value, sizeof(varbuf));
9585  varname = varbuf;
9586 
9587  if ((varval = strchr(varname,'='))) {
9588  *varval++ = '\0';
9589  if ((tmpvar = ast_variable_new(varname, varval, ""))) {
9590  tmpvar->next = user->chanvars;
9591  user->chanvars = tmpvar;
9592  }
9593  }
9594  } else if (!strcasecmp(var->name, "eventfilter")) {
9595  const char *value = var->value;
9596  manager_add_filter(value, user->whitefilters, user->blackfilters);
9597  } else {
9598  ast_debug(1, "%s is an unknown option.\n", var->name);
9599  }
9600  }
9601 
9602  oldacl = ast_free_acl_list(oldacl);
9603  }
9604  ast_config_destroy(cfg);
9605 
9606  /* Check the flag for named ACL event subscription and if we need to, register a subscription. */
9607  if (acl_subscription_flag && !by_external_config) {
9609  }
9610 
9611  /* Perform cleanup - essentially prune out old users that no longer exist */
9613  if (user->keep) { /* valid record. clear flag for the next round */
9614  user->keep = 0;
9615 
9616  /* Calculate A1 for Digest auth */
9617  snprintf(a1, sizeof(a1), "%s:%s:%s", user->username, global_realm, user->secret);
9618  ast_md5_hash(a1_hash,a1);
9619  ast_free(user->a1_hash);
9620  user->a1_hash = ast_strdup(a1_hash);
9621  continue;
9622  }
9623  /* We do not need to keep this user so take them out of the list */
9625  ast_debug(4, "Pruning user '%s'\n", user->username);
9627  }
9629 
9631 
9633  if (!webregged) {
9637 
9641  webregged = 1;
9642  }
9643  } else {
9644  if (webregged) {
9648 
9652  webregged = 0;
9653  }
9654  }
9655 
9656  if (newhttptimeout > 0) {
9657  httptimeout = newhttptimeout;
9658  }
9659 
9661  if (tls_was_enabled && !ami_tls_cfg.enabled) {
9663  } else if (ast_ssl_setup(amis_desc.tls_cfg)) {
9665  }
9666 
9667  return 0;
9668 }
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:430
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:614
#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 sessions 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:4582
static int action_createconfig(struct mansession *s, const struct message *m)
Definition: manager.c:4193
static int manager_state_cb(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
Definition: manager.c:7298
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:6465
static void acl_change_stasis_subscribe(void)
Definition: manager.c:1541
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:2312
static int manager_enabled
Definition: manager.c:1481
static int action_sendtext(struct mansession *s, const struct message *m)
Definition: manager.c:4938
static int action_mailboxcount(struct mansession *s, const struct message *m)
Definition: manager.c:5959
static int action_getconfigjson(struct mansession *s, const struct message *m)
Definition: manager.c:3755
static int action_listcategories(struct mansession *s, const struct message *m)
Definition: manager.c:3689
static int action_hangup(struct mansession *s, const struct message *m)
Definition: manager.c:4465
static int action_listcommands(struct mansession *s, const struct message *m)
Definition: manager.c:4329
static int action_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:5172
static int action_timeout(struct mansession *s, const struct message *m)
Definition: manager.c:6050
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:6169
static int action_coresettings(struct mansession *s, const struct message *m)
Show PBX core settings information.
Definition: manager.c:6283
static int mansession_cmp_fn(void *obj, void *arg, int flags)
Definition: manager.c:2269
static int displayconnects
Definition: manager.c:1476
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:6117
static int manager_debug
Definition: manager.c:1484
static int action_mailboxstatus(struct mansession *s, const struct message *m)
Definition: manager.c:5942
static int action_login(struct mansession *s, const struct message *m)
Definition: manager.c:4398
static int action_getvar(struct mansession *s, const struct message *m)
Definition: manager.c:4615
static int action_blind_transfer(struct mansession *s, const struct message *m)
Definition: manager.c:5126
static int action_extensionstate(struct mansession *s, const struct message *m)
Definition: manager.c:5980
static int action_getconfig(struct mansession *s, const struct message *m)
Definition: manager.c:3627
static int action_logoff(struct mansession *s, const struct message *m)
Definition: manager.c:4392
static int action_updateconfig(struct mansession *s, const struct message *m)
Definition: manager.c:4107
static int manager_moduleload(struct mansession *s, const struct message *m)
Definition: manager.c:6506
static void acl_change_stasis_unsubscribe(void)
Definition: manager.c:1551
static int action_reload(struct mansession *s, const struct message *m)
Send a reload event.
Definition: manager.c:6365
static int authlimit
Definition: manager.c:1486
static int action_aocmessage(struct mansession *s, const struct message *m)
Definition: manager.c:5524
static int action_events(struct mansession *s, const struct message *m)
Definition: manager.c:4348
static int action_redirect(struct mansession *s, const struct message *m)
action_redirect: The redirect manager command
Definition: manager.c:4981
static int action_presencestate(struct mansession *s, const struct message *m)
Definition: manager.c:6010
static int allowmultiplelogin
Definition: manager.c:1477
static int action_cancel_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:5226
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:1491
static int action_originate(struct mansession *s, const struct message *m)
Definition: manager.c:5729
static int action_userevent(struct mansession *s, const struct message *m)
Definition: manager.c:6262
static int action_command(struct mansession *s, const struct message *m)
Manager command "command" - execute CLI command.
Definition: manager.c:5303
static int broken_events_action
Definition: manager.c:1480
static int timestampevents
Definition: manager.c:1478
static int subscribed
Definition: manager.c:1482
static int authtimeout
Definition: manager.c:1485
static int manager_modulecheck(struct mansession *s, const struct message *m)
Manager function to check if module is loaded.
Definition: manager.c:6477
static int webmanager_enabled
Definition: manager.c:1483
static int action_status(struct mansession *s, const struct message *m)
Manager "status" command to show channels.
Definition: manager.c:4782
static int get_perm(const char *instr)
Definition: manager.c:2138
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:6397
static int action_corestatus(struct mansession *s, const struct message *m)
Show PBX core status information.
Definition: manager.c:6325
static int action_challenge(struct mansession *s, const struct message *m)
Definition: manager.c:4447
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1497
static int action_waitevent(struct mansession *s, const struct message *m)
Definition: manager.c:4211
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:7069
static int action_ping(struct mansession *s, const struct message *m)
Definition: manager.c:3609
static int httptimeout
Definition: manager.c:1479
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
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3327
#define ast_variable_new(name, value, filename)
@ CONFIG_FLAG_FILEUNCHANGED
#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:3726
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:768
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:3220
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
#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:8660
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:8661
static struct ast_http_uri managerxmluri
Definition: manager.c:8510
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:8672
static struct ast_custom_function managerclient_function
description of AMI_CLIENT dialplan function
Definition: manager.c:8643
static void load_channelvars(struct ast_variable *var)
Definition: manager.c:8934
static struct ast_http_uri manageruri
Definition: manager.c:8502
static void manager_set_defaults(void)
Definition: manager.c:9147
static struct ast_http_uri arawmanuri
Definition: manager.c:8553
static struct ast_http_uri rawmanuri
Definition: manager.c:8494
static struct ast_cli_entry cli_manager[]
Definition: manager.c:8912
static void manager_free_user(struct ast_manager_user *user)
Definition: manager.c:8967
static struct ast_http_uri amanageruri
Definition: manager.c:8562
static int webregged
Definition: manager.c:8649
static int subscribe_all(void)
Definition: manager.c:9117
static struct ast_http_uri amanagerxmluri
Definition: manager.c:8571
static void load_disabledevents(struct ast_variable *var)
Definition: manager.c:8957
#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
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_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
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:3830
static int reload(void)
#define NULL
Definition: resample.c:96
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:1580
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:619
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: main/utils.c:2097
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:406
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:1651
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:913
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:939
#define ARRAY_LEN(a)
Definition: utils.h:661
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: main/utils.c:250
struct ao2_container * ast_xmldoc_build_documentation(const char *type)
Build the documentation for a particular source type.
Definition: xmldoc.c:2655

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

◆ __unreg_module()

static void __unreg_module ( void  )
static

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

9765 {
9766  struct ast_manager_event_blob *ev;
9767  va_list argp;
9768 
9769  ast_assert(extra_fields_fmt != NULL);
9771 
9773  if (!ev) {
9774  return NULL;
9775  }
9776 
9777  if (ast_string_field_init(ev, 20)) {
9778  ao2_ref(ev, -1);
9779  return NULL;
9780  }
9781 
9783  ev->event_flags = event_flags;
9784 
9785  va_start(argp, extra_fields_fmt);
9786  ast_string_field_ptr_build_va(ev, &ev->extra_fields, extra_fields_fmt, argp);
9787  va_end(argp);
9788 
9789  return ev;
9790 }
@ 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:9751
#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:490
const ast_string_field extra_fields
Definition: manager.h:495
const char * manager_event
Definition: manager.h:492
#define ast_assert(a)
Definition: utils.h:734

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(), session_timeout_to_ami(), 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 9799 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 9738 of file manager.c.

9740 {
9741  if (!*fields_string) {
9742  *fields_string = ast_str_create(128);
9743  if (!*fields_string) {
9744  return -1;
9745  }
9746  }
9747 
9748  return (ast_str_append(fields_string, 0, "%s: %s\r\n", header, value) < 0) ? -1 : 0;
9749 }
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:1117
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:640

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

8726 {
8727  struct ast_xml_doc_item **item_a = (struct ast_xml_doc_item **)a;
8728  struct ast_xml_doc_item **item_b = (struct ast_xml_doc_item **)b;
8729  return strcmp((*item_a)->name, (*item_b)->name);
8730 }
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 9699 of file manager.c.

9700 {
9701  AST_LIST_INSERT_HEAD(&s->session->datastores, datastore, entry);
9702 
9703  return 0;
9704 }
#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:1633

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

9712 {
9713  struct ast_datastore *datastore = NULL;
9714 
9715  if (info == NULL)
9716  return NULL;
9717 
9719  if (datastore->info != info) {
9720  continue;
9721  }
9722 
9723  if (uid == NULL) {
9724  /* matched by type only */
9725  break;
9726  }
9727 
9728  if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
9729  /* Matched by type AND uid */
9730  break;
9731  }
9732  }
9734 
9735  return datastore;
9736 }
#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 9706 of file manager.c.

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

7561 {
7562  int authed;
7563  struct mansession_session *session;
7564 
7565  if (!(session = find_session(ident, 0)))
7566  return 0;
7567 
7568  authed = (session->authenticated != 0);
7569 
7572 
7573  return authed;
7574 }
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:2190
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:7488

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

7577 {
7578  int result = 0;
7579  struct mansession_session *session;
7580  struct ao2_container *sessions;
7581  struct ao2_iterator i;
7582 
7583  if (ident == 0) {
7584  return 0;
7585  }
7586 
7587  sessions = ao2_global_obj_ref(mgr_sessions);
7588  if (!sessions) {
7589  return 0;
7590  }
7591  i = ao2_iterator_init(sessions, 0);
7592  ao2_ref(sessions, -1);
7593  while ((session = ao2_iterator_next(&i))) {
7594  ao2_lock(session);
7595  if ((session->managerid == ident) && (session->readperm & perm)) {
7596  result = 1;
7599  break;
7600  }
7603  }
7605 
7606  return result;
7607 }
#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 7609 of file manager.c.

7610 {
7611  int result = 0;
7612  struct mansession_session *session;
7613  struct ao2_container *sessions;
7614  struct ao2_iterator i;
7615 
7616  if (ident == 0) {
7617  return 0;
7618  }
7619 
7620  sessions = ao2_global_obj_ref(mgr_sessions);
7621  if (!sessions) {
7622  return 0;
7623  }
7624  i = ao2_iterator_init(sessions, 0);
7625  ao2_ref(sessions, -1);
7626  while ((session = ao2_iterator_next(&i))) {
7627  ao2_lock(session);
7628  if ((session->managerid == ident) && (session->writeperm & perm)) {
7629  result = 1;
7632  break;
7633  }
7636  }
7638 
7639  return result;
7640 }

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

8144 {
8145  struct mansession_session *session = NULL;
8146  struct mansession s = { .session = NULL, .tcptls_session = ser };
8147  struct ast_variable *v, *params = get_params;
8148  char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
8149  struct ast_str *http_header = NULL, *out = NULL;
8150  size_t result_size;
8151  struct message m = { 0 };
8152  int fd;
8153 
8154  time_t time_now = time(NULL);
8155  unsigned long nonce = 0, nc;
8156  struct ast_http_digest d = { NULL, };
8157  struct ast_manager_user *user = NULL;
8158  int stale = 0;
8159  char resp_hash[256]="";
8160  /* Cache for user data */
8161  char u_username[80];
8162  int u_readperm;
8163  int u_writeperm;
8164  int u_writetimeout;
8165  int u_displayconnects;
8166 
8168  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
8169  return 0;
8170  }
8171 
8172  /* Find "Authorization: " header */
8173  for (v = headers; v; v = v->next) {
8174  if (!strcasecmp(v->name, "Authorization")) {
8175  break;
8176  }
8177  }
8178 
8179  if (!v || ast_strlen_zero(v->value)) {
8180  goto out_401; /* Authorization Header not present - send auth request */
8181  }
8182 
8183  /* Digest found - parse */
8184  if (ast_string_field_init(&d, 128)) {
8186  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8187  return 0;
8188  }
8189 
8190  if (ast_parse_digest(v->value, &d, 0, 1)) {
8191  /* Error in Digest - send new one */
8192  nonce = 0;
8193  goto out_401;
8194  }
8195  if (sscanf(d.nonce, "%30lx", &nonce) != 1) {
8196  ast_log(LOG_WARNING, "Received incorrect nonce in Digest <%s>\n", d.nonce);
8197  nonce = 0;
8198  goto out_401;
8199  }
8200 
8202  user = get_manager_by_name_locked(d.username);
8203  if(!user) {
8205  ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8206  nonce = 0;
8207  goto out_401;
8208  }
8209 
8210  /* --- We have User for this auth, now check ACL */
8211  if (user->acl && !ast_apply_acl(user->acl, remote_address, "Manager User ACL:")) {
8213  ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8215  ast_http_error(ser, 403, "Permission denied", "Permission denied");
8216  return 0;
8217  }
8218 
8219  /* --- We have auth, so check it */
8220 
8221  /* compute the expected response to compare with what we received */
8222  {
8223  char *a2;
8224  /* ast_md5_hash outputs 32 characters plus NULL terminator. */
8225  char a2_hash[33];
8226  char resp[256];
8227 
8228  /* XXX Now request method are hardcoded in A2 */
8229  if (ast_asprintf(&a2, "%s:%s", ast_get_http_method(method), d.uri) < 0) {
8232  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8233  return 0;
8234  }
8235 
8236  ast_md5_hash(a2_hash, a2);
8237  ast_free(a2);
8238 
8239  if (d.qop) {
8240  /* RFC 2617 */
8241  snprintf(resp, sizeof(resp), "%s:%08lx:%s:%s:auth:%s", user->a1_hash, nonce, d.nc, d.cnonce, a2_hash);
8242  } else {
8243  /* RFC 2069 */
8244  snprintf(resp, sizeof(resp), "%s:%08lx:%s", user->a1_hash, nonce, a2_hash);
8245  }
8246  ast_md5_hash(resp_hash, resp);
8247  }
8248 
8249  if (strncasecmp(d.response, resp_hash, strlen(resp_hash))) {
8250  /* Something was wrong, so give the client to try with a new challenge */
8252  nonce = 0;
8253  goto out_401;
8254  }
8255 
8256  /*
8257  * User are pass Digest authentication.
8258  * Now, cache the user data and unlock user list.
8259  */
8260  ast_copy_string(u_username, user->username, sizeof(u_username));
8261  u_readperm = user->readperm;
8262  u_writeperm = user->writeperm;
8263  u_displayconnects = user->displayconnects;
8264  u_writetimeout = user->writetimeout;
8266 
8267  if (!(session = find_session_by_nonce(d.username, nonce, &stale))) {
8268  /*
8269  * Create new session.
8270  * While it is not in the list we don't need any locking
8271  */
8272  if (!(session = build_mansession(remote_address))) {
8274  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8275  return 0;
8276  }
8277  ao2_lock(session);
8278 
8279  ast_copy_string(session->username, u_username, sizeof(session->username));
8280  session->managerid = nonce;
8281  session->last_ev = grab_last();
8282  AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
8283 
8284  session->readperm = u_readperm;
8285  session->writeperm = u_writeperm;
8286  session->writetimeout = u_writetimeout;
8287 
8288  if (u_displayconnects) {
8289  ast_verb(2, "HTTP Manager '%s' logged in from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8290  }
8291  session->noncetime = session->sessionstart = time_now;
8292  session->authenticated = 1;
8293  } else if (stale) {
8294  /*
8295  * Session found, but nonce is stale.
8296  *
8297  * This could be because an old request (w/old nonce) arrived.
8298  *
8299  * This may be as the result of http proxy usage (separate delay or
8300  * multipath) or in a situation where a page was refreshed too quickly
8301  * (seen in Firefox).
8302  *
8303  * In this situation, we repeat the 401 auth with the current nonce
8304  * value.
8305  */
8306  nonce = session->managerid;
8308  stale = 1;
8309  goto out_401;
8310  } else {
8311  sscanf(d.nc, "%30lx", &nc);
8312  if (session->nc >= nc || ((time_now - session->noncetime) > 62) ) {
8313  /*
8314  * Nonce time expired (> 2 minutes) or something wrong with nonce
8315  * counter.
8316  *
8317  * Create new nonce key and resend Digest auth request. Old nonce
8318  * is saved for stale checking...
8319  */
8320  session->nc = 0; /* Reset nonce counter */
8321  session->oldnonce = session->managerid;
8322  nonce = session->managerid = ast_random();
8323  session->noncetime = time_now;
8325  stale = 1;
8326  goto out_401;
8327  } else {
8328  session->nc = nc; /* All OK, save nonce counter */
8329  }
8330  }
8331 
8332 
8333  /* Reset session timeout. */
8334  session->sessiontimeout = time(NULL) + (httptimeout > 5 ? httptimeout : 5);
8336 
8337  ast_mutex_init(&s.lock);
8338  s.session = session;
8339  fd = mkstemp(template); /* create a temporary file for command output */
8340  unlink(template);
8341  if (fd <= -1) {
8342  ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
8343  goto auth_callback_out;
8344  }
8345  s.stream = ast_iostream_from_fd(&fd);
8346  if (!s.stream) {
8347  ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
8348  ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
8349  close(fd);
8350  goto auth_callback_out;
8351  }
8352 
8353  if (method == AST_HTTP_POST) {
8354  params = ast_http_get_post_vars(ser, headers);
8355  if (!params) {
8356  switch (errno) {
8357  case EFBIG:
8358  ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
8360  goto auth_callback_out;
8361  case ENOMEM:
8363  ast_http_error(ser, 500, "Server Error", "Out of memory");
8365  goto auth_callback_out;
8366  case EIO:
8367  ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8369  goto auth_callback_out;
8370  }
8371  }
8372  }
8373 
8374  astman_append_headers(&m, params);
8375 
8376  if (process_message(&s, &m)) {
8377  if (u_displayconnects) {
8378  ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8379  }
8380 
8381  session->needdestroy = 1;
8382  }
8383 
8384  astman_free_headers(&m);
8385 
8386  result_size = lseek(ast_iostream_get_fd(s.stream), 0, SEEK_CUR); /* Calculate approx. size of result */
8387 
8388  http_header = ast_str_create(80);
8389  out = ast_str_create(result_size * 2 + 512);
8390  if (http_header == NULL || out == NULL) {
8392  ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
8394  goto auth_callback_out;
8395  }
8396 
8397  ast_str_append(&http_header, 0, "Content-type: text/%s\r\n", contenttype[format]);
8398 
8399  if (format == FORMAT_XML) {
8400  ast_str_append(&out, 0, "<ajax-response>\n");
8401  } else if (format == FORMAT_HTML) {
8402  ast_str_append(&out, 0,
8403  "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
8404  "<html><head>\r\n"
8405  "<title>Asterisk&trade; Manager Interface</title>\r\n"
8406  "</head><body style=\"background-color: #ffffff;\">\r\n"
8407  "<form method=\"POST\">\r\n"
8408  "<table align=\"center\" style=\"background-color: #f1f1f1;\" width=\"500\">\r\n"
8409  "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\"><h1>Manager Tester</h1></th></tr>\r\n"
8410  "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\">Action: <input name=\"action\" /> Cmd: <input name=\"command\" /><br>"
8411  "<input type=\"submit\" value=\"Send request\" /></th></tr>\r\n");
8412  }
8413 
8414  process_output(&s, &out, params, format);
8415 
8416  if (format == FORMAT_XML) {
8417  ast_str_append(&out, 0, "</ajax-response>\n");
8418  } else if (format == FORMAT_HTML) {
8419  ast_str_append(&out, 0, "</table></form></body></html>\r\n");
8420  }
8421 
8422  ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
8423  http_header = NULL;
8424  out = NULL;
8425 
8426 auth_callback_out:
8427  ast_mutex_destroy(&s.lock);
8428 
8429  /* Clear resources and unlock manager session */
8430  if (method == AST_HTTP_POST && params) {
8431  ast_variables_destroy(params);
8432  }
8433 
8434  ast_free(http_header);
8435  ast_free(out);
8436 
8437  ao2_lock(session);
8438  if (session->stream) {
8439  ast_iostream_close(session->stream);
8440  session->stream = NULL;
8441  }
8443 
8444  if (session->needdestroy) {
8445  ast_debug(1, "Need destroy, doing it now!\n");
8447  }
8449  return 0;
8450 
8451 out_401:
8452  if (!nonce) {
8453  nonce = ast_random();
8454  }
8455 
8456  ast_http_auth(ser, global_realm, nonce, nonce, stale, NULL);
8458  return 0;
8459 }
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:800
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
static snd_pcm_format_t format
Definition: chan_alsa.c:106
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:6608
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:2851
static void session_destroy(struct mansession_session *s)
Definition: manager.c:2276
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:2837
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:2236
static struct eventqent * grab_last(void)
Definition: manager.c:1970
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
@ 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
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
#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:184
#define ast_mutex_destroy(a)
Definition: lock.h:186
int errno
static void close_mansession_file(struct mansession *s)
Definition: manager.c:7883
static void process_output(struct mansession *s, struct ast_str **out, struct ast_variable *params, enum output_format format)
Definition: manager.c:7893
static struct mansession_session * find_session_by_nonce(const char *username, unsigned long nonce, int *stale)
Definition: manager.c:7527
static const char *const contenttype[]
Definition: manager.c:7477
const char * method
Definition: res_pjsip.c:1130
#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:604
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:1632
struct ast_iostream * stream
Definition: manager.c:1634
ast_mutex_t lock
Definition: manager.c:1639
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: main/utils.c:2536
long int ast_random(void)
Definition: main/utils.c:2210

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, 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(), and auth_mxml_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 8520 of file manager.c.

8521 {
8522  int retval;
8523  struct ast_sockaddr ser_remote_address_tmp;
8524 
8525  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8526  retval = auth_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
8527  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8528  return retval;
8529 }
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:8138
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 8531 of file manager.c.

8532 {
8533  int retval;
8534  struct ast_sockaddr ser_remote_address_tmp;
8535 
8536  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8537  retval = auth_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
8538  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8539  return retval;
8540 }

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

8543 {
8544  int retval;
8545  struct ast_sockaddr ser_remote_address_tmp;
8546 
8547  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8548  retval = auth_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
8549  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8550  return retval;
8551 }

◆ close_mansession_file()

static void close_mansession_file ( struct mansession s)
static

Definition at line 7883 of file manager.c.

7884 {
7885  if (s->stream) {
7887  s->stream = NULL;
7888  } else {
7889  ast_log(LOG_ERROR, "Attempted to close file/file descriptor on mansession without a valid file or file descriptor.\n");
7890  }
7891 }

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

7489 {
7490  struct ao2_container *sessions;
7491  struct mansession_session *session;
7492  struct ao2_iterator i;
7493 
7494  if (ident == 0) {
7495  return NULL;
7496  }
7497 
7498  sessions = ao2_global_obj_ref(mgr_sessions);
7499  if (!sessions) {
7500  return NULL;
7501  }
7502  i = ao2_iterator_init(sessions, 0);
7503  ao2_ref(sessions, -1);
7504  while ((session = ao2_iterator_next(&i))) {
7505  ao2_lock(session);
7506  if (session->managerid == ident && !session->needdestroy) {
7507  ast_atomic_fetchadd_int(&session->inuse, incinuse ? 1 : 0);
7508  break;
7509  }
7512  }
7514 
7515  return session;
7516 }
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:755

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

7528 {
7529  struct mansession_session *session;
7530  struct ao2_container *sessions;
7531  struct ao2_iterator i;
7532 
7533  if (nonce == 0 || username == NULL || stale == NULL) {
7534  return NULL;
7535  }
7536 
7537  sessions = ao2_global_obj_ref(mgr_sessions);
7538  if (!sessions) {
7539  return NULL;
7540  }
7541  i = ao2_iterator_init(sessions, 0);
7542  ao2_ref(sessions, -1);
7543  while ((session = ao2_iterator_next(&i))) {
7544  ao2_lock(session);
7545  if (!strcasecmp(session->username, username) && session->managerid == nonce) {
7546  *stale = 0;
7547  break;
7548  } else if (!strcasecmp(session->username, username) && session->oldnonce == nonce) {
7549  *stale = 1;
7550  break;
7551  }
7554  }
7556 
7557  return session;
7558 }

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

8597 {
8598  struct ast_manager_user *user = NULL;
8599 
8601  AST_APP_ARG(name);
8602  AST_APP_ARG(param);
8603  );
8604 
8605 
8606  if (ast_strlen_zero(data) ) {
8607  ast_log(LOG_WARNING, "AMI_CLIENT() requires two arguments: AMI_CLIENT(<name>[,<arg>])\n");
8608  return -1;
8609  }
8610  AST_STANDARD_APP_ARGS(args, data);
8611  args.name = ast_strip(args.name);
8612  args.param = ast_strip(args.param);
8613 
8615  if (!(user = get_manager_by_name_locked(args.name))) {
8617  ast_log(LOG_ERROR, "There's no manager user called : \"%s\"\n", args.name);
8618  return -1;
8619  }
8621 
8622  if (!strcasecmp(args.param, "sessions")) {
8623  int no_sessions = 0;
8624  struct ao2_container *sessions;
8625 
8626  sessions = ao2_global_obj_ref(mgr_sessions);
8627  if (sessions) {
8628  ao2_callback_data(sessions, 0, get_manager_sessions_cb, /*login name*/ data, &no_sessions);
8629  ao2_ref(sessions, -1);
8630  }
8631  snprintf(buf, len, "%d", no_sessions);
8632  } else {
8633  ast_log(LOG_ERROR, "Invalid arguments provided to function AMI_CLIENT: %s\n", args.param);
8634  return -1;
8635 
8636  }
8637 
8638  return 0;
8639 }
#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:8581
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 7926 of file manager.c.

7932 {
7933  struct mansession s = { .session = NULL, .tcptls_session = ser };
7934  struct mansession_session *session = NULL;
7935  uint32_t ident;
7936  int fd;
7937  int blastaway = 0;
7938  struct ast_variable *params = get_params;
7939  char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
7940  struct ast_str *http_header = NULL, *out = NULL;
7941  struct message m = { 0 };
7942 
7944  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
7945  return 0;
7946  }
7947 
7948  ident = ast_http_manid_from_vars(headers);
7949 
7950  if (!(session = find_session(ident, 1))) {
7951 
7952  /**/
7953  /* Create new session.
7954  * While it is not in the list we don't need any locking
7955  */
7956  if (!(session = build_mansession(remote_address))) {
7958  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
7959  return 0;
7960  }
7961  ao2_lock(session);
7962  session->send_events = 0;
7963  session->inuse = 1;
7964  /*!
7965  * \note There is approximately a 1 in 1.8E19 chance that the following
7966  * calculation will produce 0, which is an invalid ID, but due to the
7967  * properties of the rand() function (and the constancy of s), that
7968  * won't happen twice in a row.
7969  */
7970  while ((session->managerid = ast_random() ^ (unsigned long) session) == 0) {
7971  }
7972  session->last_ev = grab_last();
7973  AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
7974  }
7976 
7977  http_header = ast_str_create(128);
7978  out = ast_str_create(2048);
7979 
7980  ast_mutex_init(&s.lock);
7981 
7982  if (http_header == NULL || out == NULL) {
7984  ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
7985  goto generic_callback_out;
7986  }
7987 
7988  s.session = session;
7989  fd = mkstemp(template); /* create a temporary file for command output */
7990  unlink(template);
7991  if (fd <= -1) {
7992  ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
7993  goto generic_callback_out;
7994  }
7995  s.stream = ast_iostream_from_fd(&fd);
7996  if (!s.stream) {
7997  ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
7998  ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
7999  close(fd);
8000  goto generic_callback_out;
8001  }
8002 
8003  if (method == AST_HTTP_POST) {
8004  params = ast_http_get_post_vars(ser, headers);
8005  if (!params) {
8006  switch (errno) {
8007  case EFBIG:
8008  ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
8010  goto generic_callback_out;
8011  case ENOMEM:
8013  ast_http_error(ser, 500, "Server Error", "Out of memory");
8015  goto generic_callback_out;
8016  case EIO:
8017  ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8019  goto generic_callback_out;
8020  }
8021  }
8022  }
8023 
8024  astman_append_headers(&m, params);
8025 
8026  if (process_message(&s, &m)) {
8027  if (session->authenticated) {
8029  ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8030  }
8031  } else {
8032  if (displayconnects) {
8033  ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
8034  }
8035  }
8036  session->needdestroy = 1;
8037  }
8038 
8039  astman_free_headers(&m);
8040 
8041  ast_str_append(&http_header, 0,
8042  "Content-type: text/%s\r\n"
8043  "Set-Cookie: mansession_id=\"%08x\"; Version=1; Max-Age=%d\r\n"
8044  "Pragma: SuppressEvents\r\n",
8046  session->managerid, httptimeout);
8047 
8048  if (format == FORMAT_XML) {
8049  ast_str_append(&out, 0, "<ajax-response>\n");
8050  } else if (format == FORMAT_HTML) {
8051  /*
8052  * When handling AMI-over-HTTP in HTML format, we provide a simple form for
8053  * debugging purposes. This HTML code should not be here, we
8054  * should read from some config file...
8055  */
8056 
8057 #define ROW_FMT "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\">%s</td></tr>\r\n"
8058 #define TEST_STRING \
8059  "<form action=\"manager\" method=\"post\">\n\
8060  Action: <select name=\"action\">\n\
8061  <option value=\"\">-----&gt;</option>\n\
8062  <option value=\"login\">login</option>\n\
8063  <option value=\"command\">Command</option>\n\
8064  <option value=\"waitevent\">waitevent</option>\n\
8065  <option value=\"listcommands\">listcommands</option>\n\
8066  </select>\n\
8067  or <input name=\"action\"><br/>\n\
8068  CLI Command <input name=\"command\"><br>\n\
8069  user <input name=\"username\"> pass <input type=\"password\" name=\"secret\"><br>\n\
8070  <input type=\"submit\">\n</form>\n"
8071 
8072  ast_str_append(&out, 0, "<title>Asterisk&trade; Manager Interface</title>");
8073  ast_str_append(&out, 0, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n");
8074  ast_str_append(&out, 0, ROW_FMT, "<h1>Manager Tester</h1>");
8076  }
8077 
8078  process_output(&s, &out, params, format);
8079 
8080  if (format == FORMAT_XML) {
8081  ast_str_append(&out, 0, "</ajax-response>\n");
8082  } else if (format == FORMAT_HTML) {
8083  ast_str_append(&out, 0, "</table></body>\r\n");
8084  }
8085 
8086  ao2_lock(session);
8087  /* Reset HTTP timeout. If we're not authenticated, keep it extremely short */
8088  session->sessiontimeout = time(NULL) + ((session->authenticated || httptimeout < 5) ? httptimeout : 5);
8089 
8090  if (session->needdestroy) {
8091  if (session->inuse == 1) {
8092  ast_debug(1, "Need destroy, doing it now!\n");
8093  blastaway = 1;
8094  } else {
8095  ast_debug(1, "Need destroy, but can't do it yet!\n");
8096  ast_mutex_lock(&session->notify_lock);
8097  if (session->waiting_thread != AST_PTHREADT_NULL) {
8098  pthread_kill(session->waiting_thread, SIGURG);
8099  }
8100  ast_mutex_unlock(&session->notify_lock);
8101  session->inuse--;
8102  }
8103  } else {
8104  session->inuse--;
8105  }
8107 
8108  ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
8109  http_header = NULL;
8110  out = NULL;
8111 
8112 generic_callback_out:
8113  ast_mutex_destroy(&s.lock);
8114 
8115  /* Clear resource */
8116 
8117  if (method == AST_HTTP_POST && params) {
8118  ast_variables_destroy(params);
8119  }
8120  ast_free(http_header);
8121  ast_free(out);
8122 
8123  if (session) {
8124  if (blastaway) {
8126  } else {
8127  if (session->stream) {
8128  ast_iostream_close(session->stream);
8129  session->stream = NULL;
8130  }
8132  }
8133  }
8134 
8135  return 0;
8136 }
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:2329
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:188
#define ast_mutex_lock(a)
Definition: lock.h:187
#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, 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(), and mxml_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 8581 of file manager.c.

8582 {
8583  struct mansession_session *session = obj;
8584  const char *login = (char *)arg;
8585  int *no_sessions = data;
8586 
8587  if (strcasecmp(session->username, login) == 0) {
8588  (*no_sessions)++;
8589  }
8590 
8591  return 0;
8592 }

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

8851 {
8853  struct ao2_iterator it_events;
8854  struct ast_xml_doc_item *item, *temp;
8855  int length;
8856 
8857  if (cmd == CLI_INIT) {
8858  e->command = "manager show event";
8859  e->usage =
8860  "Usage: manager show event <eventname>\n"
8861  " Provides a detailed description a Manager interface event.\n";
8862  return NULL;
8863  }
8864 
8865  events = ao2_global_obj_ref(event_docs);
8866  if (!events) {
8867  ast_cli(a->fd, "No manager event documentation loaded\n");
8868  return CLI_SUCCESS;
8869  }
8870 
8871  if (cmd == CLI_GENERATE) {
8872  if (a->pos != 3) {
8873  return NULL;
8874  }
8875 
8876  length = strlen(a->word);
8877  it_events = ao2_iterator_init(events, 0);
8878  while ((item = ao2_iterator_next(&it_events))) {
8879  if (!strncasecmp(a->word, item->name, length)) {
8881  ao2_ref(item, -1);
8882  break;
8883  }
8884  }
8885  ao2_ref(item, -1);
8886  }
8887  ao2_iterator_destroy(&it_events);
8888 
8889  return NULL;
8890  }
8891 
8892  if (a->argc != 4) {
8893  return CLI_SHOWUSAGE;
8894  }
8895 
8896  if (!(item = ao2_find(events, a->argv[3], OBJ_KEY))) {
8897  ast_cli(a->fd, "Could not find event '%s'\n", a->argv[3]);
8898  return CLI_SUCCESS;
8899  }
8900 
8901  ast_cli(a->fd, "Event: %s\n", a->argv[3]);
8902  for (temp = item; temp; temp = AST_LIST_NEXT(temp, next)) {
8903  print_event_instance(a, temp);
8904  }
8905 
8906  ao2_ref(item, -1);
8907  return CLI_SUCCESS;
8908 }
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:2760
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:8813
#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:936

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

8733 {
8734  struct ao2_container *events;
8735  struct ao2_iterator *it_events;
8736  struct ast_xml_doc_item *item;
8737  struct ast_xml_doc_item **items;
8738  struct ast_str *buffer;
8739  int i = 0, totalitems = 0;
8740 
8741  switch (cmd) {
8742  case CLI_INIT:
8743  e->command = "manager show events";
8744  e->usage =
8745  "Usage: manager show events\n"
8746  " Prints a listing of the available Asterisk manager interface events.\n";
8747  return NULL;
8748  case CLI_GENERATE:
8749  return NULL;
8750  }
8751  if (a->argc != 3) {
8752  return CLI_SHOWUSAGE;
8753  }
8754 
8755  buffer = ast_str_create(128);
8756  if (!buffer) {
8757  return CLI_SUCCESS;
8758  }
8759 
8760  events = ao2_global_obj_ref(event_docs);
8761  if (!events) {
8762  ast_cli(a->fd, "No manager event documentation loaded\n");
8763  ast_free(buffer);
8764  return CLI_SUCCESS;
8765  }
8766 
8767  ao2_lock(events);
8768  if (!(it_events = ao2_callback(events, OBJ_MULTIPLE | OBJ_NOLOCK, NULL, NULL))) {
8769  ao2_unlock(events);
8770  ast_log(AST_LOG_ERROR, "Unable to create iterator for events container\n");
8771  ast_free(buffer);
8772  ao2_ref(events, -1);
8773  return CLI_SUCCESS;
8774  }
8775  if (!(items = ast_calloc(sizeof(struct ast_xml_doc_item *), ao2_container_count(events)))) {
8776  ao2_unlock(events);
8777  ast_log(AST_LOG_ERROR, "Unable to create temporary sorting array for events\n");
8778  ao2_iterator_destroy(it_events);
8779  ast_free(buffer);
8780  ao2_ref(events, -1);
8781  return CLI_SUCCESS;
8782  }
8783  ao2_unlock(events);
8784 
8785  while ((item = ao2_iterator_next(it_events))) {
8786  items[totalitems++] = item;
8787  ao2_ref(item, -1);
8788  }
8789 
8790  qsort(items, totalitems, sizeof(struct ast_xml_doc_item *), ast_xml_doc_item_cmp_fn);
8791 
8792  ast_cli(a->fd, "Events:\n");
8793  ast_cli(a->fd, " -------------------- -------------------- -------------------- \n");
8794  for (i = 0; i < totalitems; i++) {
8795  ast_str_append(&buffer, 0, " %-20.20s", items[i]->name);
8796  if ((i + 1) % 3 == 0) {
8797  ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
8798  ast_str_set(&buffer, 0, "%s", "");
8799  }
8800  }
8801  if ((i + 1) % 3 != 0) {
8802  ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
8803  }
8804 
8805  ao2_iterator_destroy(it_events);
8806  ast_free(items);
8807  ao2_ref(events, -1);
8808  ast_free(buffer);
8809 
8810  return CLI_SUCCESS;
8811 }
#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:8725
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
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:1091

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

8684 {
8685  switch (cmd) {
8686  case CLI_INIT:
8687  e->command = "manager show settings";
8688  e->usage =
8689  "Usage: manager show settings\n"
8690  " Provides detailed list of the configuration of the Manager.\n";
8691  return NULL;
8692  case CLI_GENERATE:
8693  return NULL;
8694  }
8695 #define FORMAT " %-25.25s %-15.55s\n"
8696 #define FORMAT2 " %-25.25s %-15d\n"
8697  if (a->argc != 3) {
8698  return CLI_SHOWUSAGE;
8699  }
8700  ast_cli(a->fd, "\nGlobal Settings:\n");
8701  ast_cli(a->fd, "----------------\n");
8702  ast_cli(a->fd, FORMAT, "Manager (AMI):", AST_CLI_YESNO(manager_enabled));
8703  ast_cli(a->fd, FORMAT, "Web Manager (AMI/HTTP):", AST_CLI_YESNO(webmanager_enabled));
8704  ast_cli(a->fd, FORMAT, "TCP Bindaddress:", manager_enabled != 0 ? ast_sockaddr_stringify(&ami_desc.local_address) : "Disabled");
8705  ast_cli(a->fd, FORMAT2, "HTTP Timeout (seconds):", httptimeout);
8706  ast_cli(a->fd, FORMAT, "TLS Enable:", AST_CLI_YESNO(ami_tls_cfg.enabled));
8707  ast_cli(a->fd, FORMAT, "TLS Bindaddress:", ami_tls_cfg.enabled != 0 ? ast_sockaddr_stringify(&amis_desc.local_address) : "Disabled");
8708  ast_cli(a->fd, FORMAT, "TLS Certfile:", ami_tls_cfg.certfile);
8709  ast_cli(a->fd, FORMAT, "TLS Privatekey:", ami_tls_cfg.pvtfile);
8710  ast_cli(a->fd, FORMAT, "TLS Cipher:", ami_tls_cfg.cipher);
8711  ast_cli(a->fd, FORMAT, "Allow multiple login:", AST_CLI_YESNO(allowmultiplelogin));
8712  ast_cli(a->fd, FORMAT, "Display connects:", AST_CLI_YESNO(displayconnects));
8713  ast_cli(a->fd, FORMAT, "Timestamp events:", AST_CLI_YESNO(timestampevents));
8714  ast_cli(a->fd, FORMAT, "Channel vars:", S_OR(manager_channelvars, ""));
8715  ast_cli(a->fd, FORMAT, "Disabled events:", S_OR(manager_disabledevents, ""));
8716  ast_cli(a->fd, FORMAT, "Debug:", AST_CLI_YESNO(manager_debug));
8717 #undef FORMAT
8718 #undef FORMAT2
8719 
8720  return CLI_SUCCESS;
8721 }
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
static char * manager_channelvars
Definition: manager.c:1487
static char * manager_disabledevents
Definition: manager.c:1488
#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, 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 8934 of file manager.c.

8935 {
8936  char *parse = NULL;
8938  AST_APP_ARG(vars)[MAX_VARS];
8939  );
8940 
8943 
8944  /* parse the setting */
8947 
8949 }
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1844
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:7970
#define MAX_VARS
Definition: manager.c:1515

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, parse(), and var.

Referenced by __init_manager().

◆ load_disabledevents()

static void load_disabledevents ( struct ast_variable var)
static

Definition at line 8957 of file manager.c.

8958 {
8961 }

References ast_free, ast_strdup, manager_disabledevents, and var.

Referenced by __init_manager().

◆ load_module()

static int load_module ( void  )
static

Definition at line 9687 of file manager.c.

9688 {
9690 
9692 }
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:9175
static void manager_shutdown(void)
Definition: manager.c:8986
@ 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 9751 of file manager.c.

9752 {
9753  struct ast_manager_event_blob *ev = obj;
9754 
9756 }

References ast_string_field_free_memory.

◆ manager_free_user()

static void manager_free_user ( struct ast_manager_user user)
static

Definition at line 8967 of file manager.c.

8968 {
8969  ast_free(user->a1_hash);
8970  ast_free(user->secret);
8971  if (user->whitefilters) {
8972  ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one");
8973  }
8974  if (user->blackfilters) {
8975  ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one");
8976  }
8977  user->acl = ast_free_acl_list(user->acl);
8978  ast_variables_destroy(user->chanvars);
8979  ast_free(user);
8980 }

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

8462 {
8463  int retval;
8464  struct ast_sockaddr ser_remote_address_tmp;
8465 
8466  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8467  retval = generic_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
8468  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8469  return retval;
8470 }
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:7926

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

9148 {
9149  manager_enabled = 0;
9150  displayconnects = 1;
9152  authtimeout = 30;
9153  authlimit = 50;
9154  manager_debug = 0; /* Debug disabled by default */
9155 
9156  /* default values */
9158  sizeof(global_realm));
9161 
9162  ami_tls_cfg.enabled = 0;
9173 }
#define DEFAULT_REALM
Definition: manager.c:1490
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 8986 of file manager.c.

8987 {
8988  struct ast_manager_user *user;
8989 
8990  /* This event is not actually transmitted, but causes all TCP sessions to be closed */
8991  manager_event(EVENT_FLAG_SHUTDOWN, "CloseSession", "CloseSession: true\r\n");
8992 
8993  ast_manager_unregister("Ping");
8994  ast_manager_unregister("Events");
8995  ast_manager_unregister("Logoff");
8996  ast_manager_unregister("Login");
8997  ast_manager_unregister("Challenge");
8998  ast_manager_unregister("Hangup");
8999  ast_manager_unregister("Status");
9000  ast_manager_unregister("Setvar");
9001  ast_manager_unregister("Getvar");
9002  ast_manager_unregister("GetConfig");
9003  ast_manager_unregister("GetConfigJSON");
9004  ast_manager_unregister("UpdateConfig");
9005  ast_manager_unregister("CreateConfig");
9006  ast_manager_unregister("ListCategories");
9007  ast_manager_unregister("Redirect");
9008  ast_manager_unregister("Atxfer");
9009  ast_manager_unregister("CancelAtxfer");
9010  ast_manager_unregister("Originate");
9011  ast_manager_unregister("Command");
9012  ast_manager_unregister("ExtensionState");
9013  ast_manager_unregister("PresenceState");
9014  ast_manager_unregister("AbsoluteTimeout");
9015  ast_manager_unregister("MailboxStatus");
9016  ast_manager_unregister("MailboxCount");
9017  ast_manager_unregister("ListCommands");
9018  ast_manager_unregister("SendText");
9019  ast_manager_unregister("UserEvent");
9020  ast_manager_unregister("WaitEvent");
9021  ast_manager_unregister("CoreSettings");
9022  ast_manager_unregister("CoreStatus");
9023  ast_manager_unregister("Reload");
9024  ast_manager_unregister("LoggerRotate");
9025  ast_manager_unregister("CoreShowChannels");
9026  ast_manager_unregister("ModuleLoad");
9027  ast_manager_unregister("ModuleCheck");
9028  ast_manager_unregister("AOCMessage");
9029  ast_manager_unregister("Filter");
9030  ast_manager_unregister("BlindTransfer");
9033 
9034 #ifdef AST_XML_DOCS
9035  ao2_t_global_obj_release(event_docs, "Dispose of event_docs");
9036 #endif
9037 
9038 #ifdef TEST_FRAMEWORK
9039  stasis_forward_cancel(test_suite_forwarder);
9040  test_suite_forwarder = NULL;
9041 #endif
9042 
9043  if (stasis_router) {
9045  stasis_router = NULL;
9046  }
9052  manager_topic = NULL;
9054 
9057 
9068 
9069  ao2_global_obj_release(mgr_sessions);
9070 
9071  while ((user = AST_LIST_REMOVE_HEAD(&users, list))) {
9073  }
9075 
9078 }
#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:1500
static struct stasis_forward * rtp_topic_forwarder
The stasis_subscription for forwarding the RTP topic to the AMI topic.
Definition: manager.c:1503
static struct stasis_forward * security_topic_forwarder
The stasis_subscription for forwarding the Security topic to the AMI topic.
Definition: manager.c:1506
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:1518
int ast_manager_unregister(const char *action)
support functions to register/unregister AMI action handlers,
Definition: manager.c:7268
#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:1550
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 9084 of file manager.c.

9085 {
9086  int res = 0;
9087 
9089  if (!rtp_topic_forwarder) {
9090  return -1;
9091  }
9092 
9094  if (!security_topic_forwarder) {
9095  return -1;
9096  }
9097 
9099  if (!stasis_router) {
9100  return -1;
9101  }
9104 
9107 
9110 
9111  if (res != 0) {
9112  return -1;
9113  }
9114  return 0;
9115 }
static void manager_default_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:1845
static void manager_generic_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:1876
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
struct stasis_topic * ast_rtp_topic(void)
Stasis Message Bus API topic for RTP and RTCP related messages
Definition: rtp_engine.c:3524
@ 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 8472 of file manager.c.

8473 {
8474  int retval;
8475  struct ast_sockaddr ser_remote_address_tmp;
8476 
8477  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8478  retval = generic_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
8479  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8480  return retval;
8481 }

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

7894 {
7895  char *buf;
7896  off_t l;
7897  int fd;
7898 
7899  if (!s->stream)
7900  return;
7901 
7902  /* Ensure buffer is NULL-terminated */
7903  ast_iostream_write(s->stream, "", 1);
7904 
7905  fd = ast_iostream_get_fd(s->stream);
7906 
7907  l = lseek(fd, 0, SEEK_CUR);
7908  if (l > 0) {
7909  if (MAP_FAILED == (buf = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))) {
7910  ast_log(LOG_WARNING, "mmap failed. Manager output was not processed\n");
7911  } else {
7912  if (format == FORMAT_XML || format == FORMAT_HTML) {
7913  xml_translate(out, buf, params, format);
7914  } else {
7915  ast_str_append(out, 0, "%s", buf);
7916  }
7917  munmap(buf, l);
7918  }
7919  } else if (format == FORMAT_XML || format == FORMAT_HTML) {
7920  xml_translate(out, "", params, format);
7921  }
7922 
7924 }
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:7765

References ast_iostream_get_fd(), ast_iostream_write(), ast_log, ast_str_append(), buf, close_mansession_file(), format, 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 8654 of file manager.c.

8655 {
8656  purge_sessions(1);
8657  purge_events();
8658 }
static void purge_events(void)
Definition: manager.c:1990
static void purge_sessions(int n_max)
remove at most n_max stale session from the list.
Definition: manager.c:7032

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

8484 {
8485  int retval;
8486  struct ast_sockaddr ser_remote_address_tmp;
8487 
8488  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8489  retval = generic_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
8490  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8491  return retval;
8492 }

◆ subscribe_all()

static int subscribe_all ( void  )
static

Definition at line 9117 of file manager.c.

9118 {
9120  ast_log(AST_LOG_ERROR, "Failed to initialize manager subscriptions\n");
9121  return -1;
9122  }
9123  if (manager_system_init()) {
9124  ast_log(AST_LOG_ERROR, "Failed to initialize manager system handling\n");
9125  return -1;
9126  }
9127  if (manager_channels_init()) {
9128  ast_log(AST_LOG_ERROR, "Failed to initialize manager channel handling\n");
9129  return -1;
9130  }
9131  if (manager_mwi_init()) {
9132  ast_log(AST_LOG_ERROR, "Failed to initialize manager MWI handling\n");
9133  return -1;
9134  }
9135  if (manager_bridging_init()) {
9136  return -1;
9137  }
9138  if (manager_endpoints_init()) {
9139  ast_log(AST_LOG_ERROR, "Failed to initialize manager endpoints handling\n");
9140  return -1;
9141  }
9142 
9143  subscribed = 1;
9144  return 0;
9145 }
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:9084
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 9682 of file manager.c.

9683 {
9684  return 0;
9685 }

◆ variable_count_cmp_fn()

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

Definition at line 7726 of file manager.c.

7727 {
7728  /* Due to the simplicity of struct variable_count, it makes no difference
7729  * if you pass in objects or strings, the same operation applies. This is
7730  * due to the fact that the hash occurs on the first element, which means
7731  * the address of both the struct and the string are exactly the same. */
7732  struct variable_count *vc = obj;
7733  char *str = vstr;
7734  return !strcmp(vc->varname, str) ? CMP_MATCH | CMP_STOP : 0;
7735 }
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:7715

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

7720 {
7721  const struct variable_count *vc = vvc;
7722 
7723  return ast_str_hash(vc->varname);
7724 }
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1237

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

7648 {
7649  /* store in a local buffer to avoid calling ast_str_append too often */
7650  char buf[256];
7651  char *dst = buf;
7652  const char *save = src;
7653  int space = sizeof(buf);
7654  /* repeat until done and nothing to flush */
7655  for ( ; *src || dst != buf ; src++) {
7656  if (*src == '\0' || space < 10) { /* flush */
7657  *dst++ = '\0';
7658  ast_str_append(out, 0, "%s", buf);
7659  dst = buf;
7660  space = sizeof(buf);
7661  if (*src == '\0') {
7662  break;
7663  }
7664  }
7665 
7666  if (mode & 2) {
7667  if (save == src && isdigit(*src)) {
7668  /* The first character of an XML attribute cannot be a digit */
7669  *dst++ = '_';
7670  *dst++ = *src;
7671  space -= 2;
7672  continue;
7673  } else if (!isalnum(*src)) {
7674  /* Replace non-alphanumeric with an underscore */
7675  *dst++ = '_';
7676  space--;
7677  continue;
7678  }
7679  }
7680  switch (*src) {
7681  case '<':
7682  strcpy(dst, "&lt;");
7683  dst += 4;
7684  space -= 4;
7685  break;
7686  case '>':
7687  strcpy(dst, "&gt;");
7688  dst += 4;
7689  space -= 4;
7690  break;
7691  case '\"':
7692  strcpy(dst, "&quot;");
7693  dst += 6;
7694  space -= 6;
7695  break;
7696  case '\'':
7697  strcpy(dst, "&apos;");
7698  dst += 6;
7699  space -= 6;
7700  break;
7701  case '&':
7702  strcpy(dst, "&amp;");
7703  dst += 5;
7704  space -= 5;
7705  break;
7706 
7707  default:
7708  *dst++ = mode ? tolower(*src) : *src;
7709  space--;
7710  }
7711  }
7712 }

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

7766 {
7767  struct ast_variable *v;
7768  const char *dest = NULL;
7769  char *var, *val;
7770  const char *objtype = NULL;
7771  int in_data = 0; /* parsing data */
7772  int inobj = 0;
7773  int xml = (format == FORMAT_XML);
7774  struct variable_count *vc = NULL;
7775  struct ao2_container *vco = NULL;
7776 
7777  if (xml) {
7778  /* dest and objtype need only for XML format */
7779  for (v = get_vars; v; v = v->next) {
7780  if (!strcasecmp(v->name, "ajaxdest")) {
7781  dest = v->value;
7782  } else if (!strcasecmp(v->name, "ajaxobjtype")) {
7783  objtype = v->value;
7784  }
7785  }
7786  if (ast_strlen_zero(dest)) {
7787  dest = "unknown";
7788  }
7789  if (ast_strlen_zero(objtype)) {
7790  objtype = "generic";
7791  }
7792  }
7793 
7794  /* we want to stop when we find an empty line */
7795  while (in && *in) {
7796  val = strsep(&in, "\r\n"); /* mark start and end of line */
7797  if (in && *in == '\n') { /* remove trailing \n if any */
7798  in++;
7799  }
7801  ast_debug(5, "inobj %d in_data %d line <%s>\n", inobj, in_data, val);
7802  if (ast_strlen_zero(val)) {
7803  /* empty line */
7804  if (in_data) {
7805  /* close data in Opaque mode */
7806  ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
7807  in_data = 0;
7808  }
7809 
7810  if (inobj) {
7811  /* close block */
7812  ast_str_append(out, 0, xml ? " /></response>\n" :
7813  "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
7814  inobj = 0;
7815  ao2_ref(vco, -1);
7816  vco = NULL;
7817  }
7818  continue;
7819  }
7820 
7821  if (!inobj) {
7822  /* start new block */
7823  if (xml) {
7824  ast_str_append(out, 0, "<response type='object' id='%s'><%s", dest, objtype);
7825  }
7828  inobj = 1;
7829  }
7830 
7831  if (in_data) {
7832  /* Process data field in Opaque mode. This is a
7833  * followup, so we re-add line feeds. */
7834  ast_str_append(out, 0, xml ? "\n" : "<br>\n");
7835  xml_copy_escape(out, val, 0); /* data field */
7836  continue;
7837  }
7838 
7839  /* We expect "Name: value" line here */
7840  var = strsep(&val, ":");
7841  if (val) {
7842  /* found the field name */
7843  val = ast_skip_blanks(val);
7845  } else {
7846  /* field name not found, switch to opaque mode */
7847  val = var;
7848  var = "Opaque-data";
7849  in_data = 1;
7850  }
7851 
7852 
7853  ast_str_append(out, 0, xml ? " " : "<tr><td>");
7854  if ((vc = ao2_find(vco, var, 0))) {
7855  vc->count++;
7856  } else {
7857  /* Create a new entry for this one */
7858  vc = ao2_alloc(sizeof(*vc), NULL);
7859  vc->varname = var;
7860  vc->count = 1;
7861  ao2_link(vco, vc);
7862  }
7863 
7864  xml_copy_escape(out, var, xml ? 1 | 2 : 0); /* data name */
7865  if (vc->count > 1) {
7866  ast_str_append(out, 0, "-%d", vc->count);
7867  }
7868  ao2_ref(vc, -1);
7869  ast_str_append(out, 0, xml ? "='" : "</td><td>");
7870  xml_copy_escape(out, val, 0); /* data field */
7871  if (!in_data || !*in) {
7872  ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
7873  }
7874  }
7875 
7876  if (inobj) {
7877  ast_str_append(out, 0, xml ? " /></response>\n" :
7878  "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
7879  ao2_ref(vco, -1);
7880  }
7881 }
#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:7647
static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
Definition: manager.c:7726
static int variable_count_hash_fn(const void *vvc, const int flags)
Definition: manager.c:7719
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, 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 9760 of file manager.c.

◆ amanageruri

struct ast_http_uri amanageruri
static

Definition at line 8542 of file manager.c.

Referenced by __init_manager().

◆ amanagerxmluri

struct ast_http_uri amanagerxmluri
static

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

◆ cli_manager

struct ast_cli_entry cli_manager[]
static

Definition at line 8850 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 7477 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:8596

description of AMI_CLIENT dialplan function

Definition at line 8596 of file manager.c.

Referenced by __init_manager(), and manager_shutdown().

◆ manageruri

struct ast_http_uri manageruri
static

Definition at line 8483 of file manager.c.

Referenced by __init_manager().

◆ managerxmluri

struct ast_http_uri managerxmluri
static

Definition at line 8483 of file manager.c.

Referenced by __init_manager().

◆ rawmanuri

struct ast_http_uri rawmanuri
static

Definition at line 8483 of file manager.c.

Referenced by __init_manager().

◆ webregged

int webregged = 0
static

Definition at line 8649 of file manager.c.

Referenced by __init_manager().

◆ words

const char* words[AST_MAX_CMD_LEN]

Definition at line 1532 of file manager.c.

Referenced by check_blacklist().