Asterisk - The Open Source Telephony Project  18.5.0
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 struct 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 (mgr_sessions)
 
static AO2_GLOBAL_OBJ_STATIC (event_docs)
 A container of event documentation nodes. More...
 
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)
 Determinie 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 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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 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 struct stasis_forwardtest_suite_forwarder
 The stasis_subscription for forwarding the Test topic to the AMI topic. More...
 
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"

Referenced by handle_showmancmds().

◆ HSMCONN_FORMAT1

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

Referenced by handle_showmanconn().

◆ HSMCONN_FORMAT2

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

Referenced by handle_showmanconn().

◆ ROW_FMT

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

Referenced by generic_http_callback().

◆ 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"

Referenced by generic_http_callback().

Enumeration Type Documentation

◆ output_format

Enumerator
FORMAT_RAW 
FORMAT_HTML 
FORMAT_XML 

Definition at line 7462 of file manager.c.

7463  {
7464  FORMAT_RAW,
7465  FORMAT_HTML,
7466  FORMAT_XML,

Function Documentation

◆ __init_manager()

static int __init_manager ( int  reload,
int  by_external_config 
)
static

Definition at line 9144 of file manager.c.

References __ast_custom_function_register(), ast_manager_user::a1_hash, ast_manager_user::acl, 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, ast_manager_user::allowmultiplelogin, ami_tls_cfg, 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(), 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_test_suite_topic(), ast_tls_read_conf(), ast_true(), ast_variable_browse(), ast_variable_new, ast_variable_retrieve(), ast_variables_destroy(), ast_xmldoc_build_documentation(), authlimit, authtimeout, ast_manager_user::blackfilters, broken_events_action, ast_manager_user::chanvars, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MANAGER_PORT, DEFAULT_MANAGER_TLS_PORT, displayconnects, ast_manager_user::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, ast_manager_user::keep, ast_variable::lineno, load_channelvars(), 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(), mansession_cmp_fn(), ast_variable::name, ast_variable::next, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, PARSE_ADDR, PARSE_IN_RANGE, PARSE_PORT_IGNORE, PARSE_UINT32, ast_manager_user::readperm, ast_manager_user::secret, sessions, stasis_forward_all(), STASIS_MESSAGE_TYPE_INIT, stasis_topic_create(), subscribe_all(), subscribed, timeout, timestampevents, ast_tcptls_session_args::tls_cfg, ast_manager_user::username, value, ast_variable::value, var, webmanager_enabled, ast_manager_user::whitefilters, ast_manager_user::writeperm, and ast_manager_user::writetimeout.

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

9146 {
9147  struct ast_config *ucfg = NULL, *cfg = NULL;
9148  const char *val;
9149  char *cat = NULL;
9150  int newhttptimeout = 60;
9151  struct ast_manager_user *user = NULL;
9152  struct ast_variable *var;
9153  struct ast_flags config_flags = { (reload && !by_external_config) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
9154  char a1[256];
9155  char a1_hash[256];
9156  struct ast_sockaddr ami_desc_local_address_tmp;
9157  struct ast_sockaddr amis_desc_local_address_tmp;
9158  int tls_was_enabled = 0;
9159  int acl_subscription_flag = 0;
9160 
9161  if (!reload) {
9162  struct ao2_container *sessions;
9163 #ifdef AST_XML_DOCS
9164  struct ao2_container *temp_event_docs;
9165 #endif
9166  int res;
9167 
9169  if (res != 0) {
9170  return -1;
9171  }
9172  manager_topic = stasis_topic_create("manager:core");
9173  if (!manager_topic) {
9174  return -1;
9175  }
9176 
9177  /* Register default actions */
9216 
9217 #ifdef TEST_FRAMEWORK
9219 #endif
9220 
9224 
9225  /* Append placeholder event so master_eventq never runs dry */
9226  if (append_event("Event: Placeholder\r\n\r\n", 0)) {
9227  return -1;
9228  }
9229 
9230 #ifdef AST_XML_DOCS
9231  temp_event_docs = ast_xmldoc_build_documentation("managerEvent");
9232  if (temp_event_docs) {
9233  ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs");
9234  ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now");
9235  }
9236 #endif
9237 
9238  /* If you have a NULL hash fn, you only need a single bucket */
9240  if (!sessions) {
9241  return -1;
9242  }
9243  ao2_global_obj_replace_unref(mgr_sessions, sessions);
9244  ao2_ref(sessions, -1);
9245 
9246  /* Initialize all settings before first configuration load. */
9248  }
9249 
9250  cfg = ast_config_load2("manager.conf", "manager", config_flags);
9251  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
9252  return 0;
9253  } else if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
9254  ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid.\n");
9255  return 0;
9256  }
9257 
9258  /* 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. */
9259  if (!by_external_config) {
9261  }
9262 
9263  if (reload) {
9264  /* Reset all settings before reloading configuration */
9265  tls_was_enabled = ami_tls_cfg.enabled;
9267  }
9268 
9269  ast_sockaddr_parse(&ami_desc_local_address_tmp, "[::]", 0);
9270  ast_sockaddr_set_port(&ami_desc_local_address_tmp, DEFAULT_MANAGER_PORT);
9271 
9272  for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
9273  val = var->value;
9274 
9275  /* read tls config options while preventing unsupported options from being set */
9276  if (strcasecmp(var->name, "tlscafile")
9277  && strcasecmp(var->name, "tlscapath")
9278  && strcasecmp(var->name, "tlscadir")
9279  && strcasecmp(var->name, "tlsverifyclient")
9280  && strcasecmp(var->name, "tlsdontverifyserver")
9281  && strcasecmp(var->name, "tlsclientmethod")
9282  && strcasecmp(var->name, "sslclientmethod")
9283  && !ast_tls_read_conf(&ami_tls_cfg, &amis_desc, var->name, val)) {
9284  continue;
9285  }
9286 
9287  if (!strcasecmp(var->name, "enabled")) {
9288  manager_enabled = ast_true(val);
9289  } else if (!strcasecmp(var->name, "webenabled")) {
9291  } else if (!strcasecmp(var->name, "port")) {
9292  int bindport;
9293  if (ast_parse_arg(val, PARSE_UINT32|PARSE_IN_RANGE, &bindport, 1024, 65535)) {
9294  ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
9295  }
9296  ast_sockaddr_set_port(&ami_desc_local_address_tmp, bindport);
9297  } else if (!strcasecmp(var->name, "bindaddr")) {
9298  /* remember port if it has already been set */
9299  int setport = ast_sockaddr_port(&ami_desc_local_address_tmp);
9300 
9302  ast_log(LOG_WARNING, "Invalid address '%s' specified, default '%s' will be used\n", val,
9303  ast_sockaddr_stringify_addr(&ami_desc_local_address_tmp));
9304  } else {
9305  ast_sockaddr_parse(&ami_desc_local_address_tmp, val, PARSE_PORT_IGNORE);
9306  }
9307 
9308  if (setport) {
9309  ast_sockaddr_set_port(&ami_desc_local_address_tmp, setport);
9310  }
9311 
9312  } else if (!strcasecmp(var->name, "brokeneventsaction")) {
9314  } else if (!strcasecmp(var->name, "allowmultiplelogin")) {
9316  } else if (!strcasecmp(var->name, "displayconnects")) {
9317  displayconnects = ast_true(val);
9318  } else if (!strcasecmp(var->name, "timestampevents")) {
9319  timestampevents = ast_true(val);
9320  } else if (!strcasecmp(var->name, "debug")) {
9321  manager_debug = ast_true(val);
9322  } else if (!strcasecmp(var->name, "httptimeout")) {
9323  newhttptimeout = atoi(val);
9324  } else if (!strcasecmp(var->name, "authtimeout")) {
9325  int timeout = atoi(var->value);
9326 
9327  if (timeout < 1) {
9328  ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", var->value);
9329  } else {
9330  authtimeout = timeout;
9331  }
9332  } else if (!strcasecmp(var->name, "authlimit")) {
9333  int limit = atoi(var->value);
9334 
9335  if (limit < 1) {
9336  ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", var->value);
9337  } else {
9338  authlimit = limit;
9339  }
9340  } else if (!strcasecmp(var->name, "channelvars")) {
9341  load_channelvars(var);
9342  } else {
9343  ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
9344  var->name, val);
9345  }
9346  }
9347 
9348  if (manager_enabled && !subscribed) {
9349  if (subscribe_all() != 0) {
9350  ast_log(LOG_ERROR, "Manager subscription error\n");
9351  return -1;
9352  }
9353  }
9354 
9355  ast_sockaddr_copy(&amis_desc_local_address_tmp, &amis_desc.local_address);
9356 
9357  /* if the amis address has not been set, default is the same as non secure ami */
9358  if (ast_sockaddr_isnull(&amis_desc_local_address_tmp)) {
9359  ast_sockaddr_copy(&amis_desc_local_address_tmp, &ami_desc_local_address_tmp);
9360  }
9361 
9362  /* if the amis address was not set, it will have non-secure ami port set; if
9363  amis address was set, we need to check that a port was set or not, if not
9364  use the default tls port */
9365  if (ast_sockaddr_port(&amis_desc_local_address_tmp) == 0 ||
9366  (ast_sockaddr_port(&ami_desc_local_address_tmp) == ast_sockaddr_port(&amis_desc_local_address_tmp))) {
9367 
9368  ast_sockaddr_set_port(&amis_desc_local_address_tmp, DEFAULT_MANAGER_TLS_PORT);
9369  }
9370 
9371  if (manager_enabled) {
9372  ast_sockaddr_copy(&ami_desc.local_address, &ami_desc_local_address_tmp);
9373  ast_sockaddr_copy(&amis_desc.local_address, &amis_desc_local_address_tmp);
9374  }
9375 
9377 
9378  /* First, get users from users.conf */
9379  ucfg = ast_config_load2("users.conf", "manager", config_flags);
9380  if (ucfg && (ucfg != CONFIG_STATUS_FILEUNCHANGED) && ucfg != CONFIG_STATUS_FILEINVALID) {
9381  const char *hasmanager;
9382  int genhasmanager = ast_true(ast_variable_retrieve(ucfg, "general", "hasmanager"));
9383 
9384  while ((cat = ast_category_browse(ucfg, cat))) {
9385  if (!strcasecmp(cat, "general")) {
9386  continue;
9387  }
9388 
9389  hasmanager = ast_variable_retrieve(ucfg, cat, "hasmanager");
9390  if ((!hasmanager && genhasmanager) || ast_true(hasmanager)) {
9391  const char *user_secret = ast_variable_retrieve(ucfg, cat, "secret");
9392  const char *user_read = ast_variable_retrieve(ucfg, cat, "read");
9393  const char *user_write = ast_variable_retrieve(ucfg, cat, "write");
9394  const char *user_displayconnects = ast_variable_retrieve(ucfg, cat, "displayconnects");
9395  const char *user_allowmultiplelogin = ast_variable_retrieve(ucfg, cat, "allowmultiplelogin");
9396  const char *user_writetimeout = ast_variable_retrieve(ucfg, cat, "writetimeout");
9397 
9398  /* Look for an existing entry,
9399  * if none found - create one and add it to the list
9400  */
9401  if (!(user = get_manager_by_name_locked(cat))) {
9402  if (!(user = ast_calloc(1, sizeof(*user)))) {
9403  break;
9404  }
9405 
9406  /* Copy name over */
9407  ast_copy_string(user->username, cat, sizeof(user->username));
9408  /* Insert into list */
9409  AST_LIST_INSERT_TAIL(&users, user, list);
9410  user->acl = NULL;
9411  user->keep = 1;
9412  user->readperm = -1;
9413  user->writeperm = -1;
9414  /* Default displayconnect from [general] */
9416  /* Default allowmultiplelogin from [general] */
9418  user->writetimeout = 100;
9419  }
9420 
9421  if (!user_secret) {
9422  user_secret = ast_variable_retrieve(ucfg, "general", "secret");
9423  }
9424  if (!user_read) {
9425  user_read = ast_variable_retrieve(ucfg, "general", "read");
9426  }
9427  if (!user_write) {
9428  user_write = ast_variable_retrieve(ucfg, "general", "write");
9429  }
9430  if (!user_displayconnects) {
9431  user_displayconnects = ast_variable_retrieve(ucfg, "general", "displayconnects");
9432  }
9433  if (!user_allowmultiplelogin) {
9434  user_allowmultiplelogin = ast_variable_retrieve(ucfg, "general", "allowmultiplelogin");
9435  }
9436  if (!user_writetimeout) {
9437  user_writetimeout = ast_variable_retrieve(ucfg, "general", "writetimeout");
9438  }
9439 
9440  if (!ast_strlen_zero(user_secret)) {
9441  ast_free(user->secret);
9442  user->secret = ast_strdup(user_secret);
9443  }
9444 
9445  if (user_read) {
9446  user->readperm = get_perm(user_read);
9447  }
9448  if (user_write) {
9449  user->writeperm = get_perm(user_write);
9450  }
9451  if (user_displayconnects) {
9452  user->displayconnects = ast_true(user_displayconnects);
9453  }
9454  if (user_allowmultiplelogin) {
9455  user->allowmultiplelogin = ast_true(user_allowmultiplelogin);
9456  }
9457  if (user_writetimeout) {
9458  int value = atoi(user_writetimeout);
9459  if (value < 100) {
9460  ast_log(LOG_WARNING, "Invalid writetimeout value '%d' in users.conf\n", value);
9461  } else {
9462  user->writetimeout = value;
9463  }
9464  }
9465  }
9466  }
9467  ast_config_destroy(ucfg);
9468  }
9469 
9470  /* cat is NULL here in any case */
9471 
9472  while ((cat = ast_category_browse(cfg, cat))) {
9473  struct ast_acl_list *oldacl;
9474 
9475  if (!strcasecmp(cat, "general")) {
9476  continue;
9477  }
9478 
9479  /* Look for an existing entry, if none found - create one and add it to the list */
9480  if (!(user = get_manager_by_name_locked(cat))) {
9481  if (!(user = ast_calloc(1, sizeof(*user)))) {
9482  break;
9483  }
9484  /* Copy name over */
9485  ast_copy_string(user->username, cat, sizeof(user->username));
9486 
9487  user->acl = NULL;
9488  user->readperm = 0;
9489  user->writeperm = 0;
9490  /* Default displayconnect from [general] */
9492  /* Default allowmultiplelogin from [general] */
9494  user->writetimeout = 100;
9497  if (!user->whitefilters || !user->blackfilters) {
9498  manager_free_user(user);
9499  break;
9500  }
9501 
9502  /* Insert into list */
9503  AST_RWLIST_INSERT_TAIL(&users, user, list);
9504  } else {
9505  ao2_t_callback(user->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters");
9506  ao2_t_callback(user->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters");
9507  }
9508 
9509  /* Make sure we keep this user and don't destroy it during cleanup */
9510  user->keep = 1;
9511  oldacl = user->acl;
9512  user->acl = NULL;
9514 
9515  var = ast_variable_browse(cfg, cat);
9516  for (; var; var = var->next) {
9517  if (!strcasecmp(var->name, "secret")) {
9518  ast_free(user->secret);
9519  user->secret = ast_strdup(var->value);
9520  } else if (!strcasecmp(var->name, "deny") ||
9521  !strcasecmp(var->name, "permit") ||
9522  !strcasecmp(var->name, "acl")) {
9523  int acl_error = 0;
9524 
9525  ast_append_acl(var->name, var->value, &user->acl, &acl_error, &acl_subscription_flag);
9526  if (acl_error) {
9527  ast_log(LOG_ERROR, "Invalid ACL '%s' for manager user '%s' on line %d. Deleting user\n",
9528  var->value, user->username, var->lineno);
9529  user->keep = 0;
9530  }
9531  } else if (!strcasecmp(var->name, "read") ) {
9532  user->readperm = get_perm(var->value);
9533  } else if (!strcasecmp(var->name, "write") ) {
9534  user->writeperm = get_perm(var->value);
9535  } else if (!strcasecmp(var->name, "displayconnects") ) {
9536  user->displayconnects = ast_true(var->value);
9537  } else if (!strcasecmp(var->name, "allowmultiplelogin") ) {
9538  user->allowmultiplelogin = ast_true(var->value);
9539  } else if (!strcasecmp(var->name, "writetimeout")) {
9540  int value = atoi(var->value);
9541  if (value < 100) {
9542  ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", var->value, var->lineno);
9543  } else {
9544  user->writetimeout = value;
9545  }
9546  } else if (!strcasecmp(var->name, "setvar")) {
9547  struct ast_variable *tmpvar;
9548  char varbuf[256];
9549  char *varval;
9550  char *varname;
9551 
9552  ast_copy_string(varbuf, var->value, sizeof(varbuf));
9553  varname = varbuf;
9554 
9555  if ((varval = strchr(varname,'='))) {
9556  *varval++ = '\0';
9557  if ((tmpvar = ast_variable_new(varname, varval, ""))) {
9558  tmpvar->next = user->chanvars;
9559  user->chanvars = tmpvar;
9560  }
9561  }
9562  } else if (!strcasecmp(var->name, "eventfilter")) {
9563  const char *value = var->value;
9564  manager_add_filter(value, user->whitefilters, user->blackfilters);
9565  } else {
9566  ast_debug(1, "%s is an unknown option.\n", var->name);
9567  }
9568  }
9569 
9570  oldacl = ast_free_acl_list(oldacl);
9571  }
9572  ast_config_destroy(cfg);
9573 
9574  /* Check the flag for named ACL event subscription and if we need to, register a subscription. */
9575  if (acl_subscription_flag && !by_external_config) {
9577  }
9578 
9579  /* Perform cleanup - essentially prune out old users that no longer exist */
9580  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&users, user, list) {
9581  if (user->keep) { /* valid record. clear flag for the next round */
9582  user->keep = 0;
9583 
9584  /* Calculate A1 for Digest auth */
9585  snprintf(a1, sizeof(a1), "%s:%s:%s", user->username, global_realm, user->secret);
9586  ast_md5_hash(a1_hash,a1);
9587  ast_free(user->a1_hash);
9588  user->a1_hash = ast_strdup(a1_hash);
9589  continue;
9590  }
9591  /* We do not need to keep this user so take them out of the list */
9593  ast_debug(4, "Pruning user '%s'\n", user->username);
9594  manager_free_user(user);
9595  }
9597 
9599 
9601  if (!webregged) {
9605 
9609  webregged = 1;
9610  }
9611  } else {
9612  if (webregged) {
9616 
9620  webregged = 0;
9621  }
9622  }
9623 
9624  if (newhttptimeout > 0) {
9625  httptimeout = newhttptimeout;
9626  }
9627 
9629  if (tls_was_enabled && !ami_tls_cfg.enabled) {
9631  } else if (ast_ssl_setup(amis_desc.tls_cfg)) {
9633  }
9634 
9635  return 0;
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:290
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
static int action_challenge(struct mansession *s, const struct message *m)
Definition: manager.c:4442
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:6458
struct ast_variable * next
struct ao2_container * blackfilters
Definition: manager.c:1654
static int action_command(struct mansession *s, const struct message *m)
Manager command "command" - execute CLI command.
Definition: manager.c:5295
char username[80]
Definition: manager.c:1645
struct ao2_container * whitefilters
Definition: manager.c:1653
static int action_originate(struct mansession *s, const struct message *m)
Definition: manager.c:5723
static int action_mailboxstatus(struct mansession *s, const struct message *m)
Definition: manager.c:5936
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int subscribe_all(void)
Definition: manager.c:9086
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:685
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Definition: ast_expr2.c:325
int ast_ssl_setup(struct ast_tls_config *cfg)
Set up an SSL server.
Definition: tcptls.c:570
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 action_reload(struct mansession *s, const struct message *m)
Send a reload event.
Definition: manager.c:6358
static int displayconnects
Definition: manager.c:1470
static int action_userevent(struct mansession *s, const struct message *m)
Definition: manager.c:6255
static int webregged
Definition: manager.c:8630
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
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:171
static int action_ping(struct mansession *s, const struct message *m)
Definition: manager.c:3602
static struct sessions sessions
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
#define ao2_t_global_obj_replace_unref(holder, obj, tag)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:906
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:2305
#define LOG_WARNING
Definition: logger.h:274
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:673
#define CONFIG_STATUS_FILEINVALID
#define EVENT_FLAG_COMMAND
Definition: manager.h:75
static int action_login(struct mansession *s, const struct message *m)
Definition: manager.c:4393
static int timeout
Definition: cdr_mysql.c:86
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
static int get_perm(const char *instr)
Definition: manager.c:2131
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:3154
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
struct ao2_container * ast_xmldoc_build_documentation(const char *type)
Build the documentation for a particular source type.
Definition: xmldoc.c:2653
static int action_createconfig(struct mansession *s, const struct message *m)
Definition: manager.c:4188
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:705
#define EVENT_FLAG_CALL
Definition: manager.h:72
static int authtimeout
Definition: manager.c:1479
static int manager_moduleload(struct mansession *s, const struct message *m)
Definition: manager.c:6505
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static int action_aocmessage(struct mansession *s, const struct message *m)
Definition: manager.c:5518
static int action_getconfigjson(struct mansession *s, const struct message *m)
Definition: manager.c:3750
#define EVENT_FLAG_AOC
Definition: manager.h:87
Wrapper for an ast_acl linked list.
Definition: acl.h:76
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:8642
#define NULL
Definition: resample.c:96
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1490
user descriptor, as read from the config file.
Definition: manager.c:1644
static int action_sendtext(struct mansession *s, const struct message *m)
Definition: manager.c:4930
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:197
int value
Definition: syslog.c:37
list of users found in the config file
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:7068
static int action_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:5164
Socket address structure.
Definition: netsock2.h:97
#define EVENT_FLAG_ORIGINATE
Definition: manager.h:83
static int manager_state_cb(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
Definition: manager.c:7288
static void manager_free_user(struct ast_manager_user *user)
Definition: manager.c:8937
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:6111
static struct ast_http_uri arawmanuri
Definition: manager.c:8534
static int httptimeout
Definition: manager.c:1473
static struct ast_custom_function managerclient_function
description of AMI_CLIENT dialplan function
Definition: manager.c:8624
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int action_events(struct mansession *s, const struct message *m)
Definition: manager.c:4343
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
static int action_getconfig(struct mansession *s, const struct message *m)
Definition: manager.c:3620
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
#define ast_log
Definition: astobj2.c:42
static int manager_modulecheck(struct mansession *s, const struct message *m)
Manager function to check if module is loaded.
Definition: manager.c:6470
static int action_blind_transfer(struct mansession *s, const struct message *m)
Definition: manager.c:5118
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:6390
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int action_cancel_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:5218
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
struct ast_variable * chanvars
Definition: manager.c:1657
static int action_logoff(struct mansession *s, const struct message *m)
Definition: manager.c:4387
char * a1_hash
Definition: manager.c:1656
static struct stasis_forward * test_suite_forwarder
The stasis_subscription for forwarding the Test topic to the AMI topic.
Definition: manager.c:1503
static struct ast_http_uri managerxmluri
Definition: manager.c:8491
static struct ast_http_uri manageruri
Definition: manager.c:8483
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:618
#define ast_variable_new(name, value, filename)
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:8641
static int authlimit
Definition: manager.c:1480
static int timestampevents
Definition: manager.c:1472
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:8653
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
#define CONFIG_STATUS_FILEUNCHANGED
static void acl_change_stasis_unsubscribe(void)
Definition: manager.c:1544
struct ast_acl_list * acl
Definition: manager.c:1655
static int action_listcommands(struct mansession *s, const struct message *m)
Definition: manager.c:4324
static int subscribed
Definition: manager.c:1476
static void acl_change_stasis_subscribe(void)
Definition: manager.c:1534
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define EVENT_FLAG_CONFIG
Definition: manager.h:78
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
static int action_mailboxcount(struct mansession *s, const struct message *m)
Definition: manager.c:5953
static int manager_debug
Definition: manager.c:1478
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
#define EVENT_FLAG_USER
Definition: manager.h:77
struct stasis_topic * ast_test_suite_topic(void)
Definition: test.c:1069
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1714
int allowmultiplelogin
Definition: manager.c:1651
static int action_waitevent(struct mansession *s, const struct message *m)
Definition: manager.c:4206
#define LOG_NOTICE
Definition: logger.h:263
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:6162
static int action_timeout(struct mansession *s, const struct message *m)
Definition: manager.c:6044
static int action_getvar(struct mansession *s, const struct message *m)
Definition: manager.c:4610
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int reload(void)
Definition: cdr_mysql.c:741
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *result,...)
The argument parsing routine.
Definition: main/config.c:3657
static int broken_events_action
Definition: manager.c:1474
static int action_status(struct mansession *s, const struct message *m)
Manager "status" command to show channels.
Definition: manager.c:4777
#define DEFAULT_MANAGER_TLS_PORT
Definition: manager.h:59
structure to hold users read from users.conf
static int action_coresettings(struct mansession *s, const struct message *m)
Show PBX core settings information.
Definition: manager.c:6276
Structure used to handle boolean flags.
Definition: utils.h:199
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
#define ao2_global_obj_replace_unref(holder, obj)
Definition: astobj2.h:908
static struct ast_http_uri amanageruri
Definition: manager.c:8543
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
static void load_channelvars(struct ast_variable *var)
Definition: manager.c:8916
static struct ast_cli_entry cli_manager[]
Definition: manager.c:8892
#define DEFAULT_MANAGER_PORT
Definition: manager.h:58
static struct ast_http_uri amanagerxmluri
Definition: manager.c:8552
static int manager_enabled
Definition: manager.c:1475
static int action_updateconfig(struct mansession *s, const struct message *m)
Definition: manager.c:4102
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
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
static int action_hangup(struct mansession *s, const struct message *m)
Definition: manager.c:4460
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:875
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:1484
static int action_extensionstate(struct mansession *s, const struct message *m)
Definition: manager.c:5974
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition: tcptls.c:849
struct ast_tls_config * tls_cfg
Definition: tcptls.h:134
static int allowmultiplelogin
Definition: manager.c:1471
Generic container type.
struct ast_sockaddr local_address
Definition: tcptls.h:130
static int action_corestatus(struct mansession *s, const struct message *m)
Show PBX core status information.
Definition: manager.c:6318
static int webmanager_enabled
Definition: manager.c:1477
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:3825
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1578
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: main/utils.c:248
static void manager_set_defaults(void)
Definition: manager.c:9116
static int mansession_cmp_fn(void *obj, void *arg, int flags)
Definition: manager.c:2262
static int action_redirect(struct mansession *s, const struct message *m)
action_redirect: The redirect manager command
Definition: manager.c:4973
static int action_listcategories(struct mansession *s, const struct message *m)
Definition: manager.c:3682
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616
static struct ast_http_uri rawmanuri
Definition: manager.c:8475
static int action_presencestate(struct mansession *s, const struct message *m)
Definition: manager.c:6004
static int action_setvar(struct mansession *s, const struct message *m)
Definition: manager.c:4577
int enabled
Definition: tcptls.h:88

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 9766 of file manager.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 9766 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_snapshot_event object.
NULL on error.

Definition at line 9727 of file manager.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_assert, AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CORE, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_string_field_init, ast_string_field_ptr_build_va, ASTERISK_GPL_KEY, ast_manager_event_blob::event_flags, ast_manager_event_blob::extra_fields, load_module(), manager_event, ast_manager_event_blob::manager_event, manager_event_blob_dtor(), NULL, reload(), and unload_module().

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(), test_suite_event_to_ami(), and varset_to_ami().

9733 {
9734  struct ast_manager_event_blob *ev;
9735  va_list argp;
9736 
9737  ast_assert(extra_fields_fmt != NULL);
9739 
9741  if (!ev) {
9742  return NULL;
9743  }
9744 
9745  if (ast_string_field_init(ev, 20)) {
9746  ao2_ref(ev, -1);
9747  return NULL;
9748  }
9749 
9751  ev->event_flags = event_flags;
9752 
9753  va_start(argp, extra_fields_fmt);
9754  ast_string_field_ptr_build_va(ev, &ev->extra_fields, extra_fields_fmt, argp);
9755  va_end(argp);
9756 
9757  return ev;
Struct containing info for an AMI event to send out.
Definition: manager.h:491
const ast_string_field extra_fields
Definition: manager.h:496
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#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:569
const char * manager_event
Definition: manager.h:493
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:248
static void manager_event_blob_dtor(void *obj)
Definition: manager.c:9718

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

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

References ast_str_append(), and ast_str_create.

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

9708 {
9709  if (!*fields_string) {
9710  *fields_string = ast_str_create(128);
9711  if (!*fields_string) {
9712  return -1;
9713  }
9714  }
9715 
9716  return (ast_str_append(fields_string, 0, "%s: %s\r\n", header, value) < 0) ? -1 : 0;
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:1091
int value
Definition: syslog.c:37
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ ast_xml_doc_item_cmp_fn()

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

Definition at line 8705 of file manager.c.

Referenced by handle_manager_show_events().

8707 {
8708  struct ast_xml_doc_item **item_a = (struct ast_xml_doc_item **)a;
8709  struct ast_xml_doc_item **item_b = (struct ast_xml_doc_item **)b;
8710  return strcmp((*item_a)->name, (*item_b)->name);
static struct test_val b
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 a

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

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

9668 {
9669  AST_LIST_INSERT_HEAD(&s->session->datastores, datastore, entry);
9670 
9671  return 0;
struct mansession_session::mansession_datastores datastores
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
struct mansession_session * session
Definition: manager.c:1626
Definition: search.h:40

◆ 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.

Return values
pointerto the datastore if found
NULLif not found
Since
1.6.1

Definition at line 9678 of file manager.c.

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

9680 {
9681  struct ast_datastore *datastore = NULL;
9682 
9683  if (info == NULL)
9684  return NULL;
9685 
9687  if (datastore->info != info) {
9688  continue;
9689  }
9690 
9691  if (uid == NULL) {
9692  /* matched by type only */
9693  break;
9694  }
9695 
9696  if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
9697  /* Matched by type AND uid */
9698  break;
9699  }
9700  }
9702 
9703  return datastore;
struct mansession_session::mansession_datastores datastores
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
const char * uid
Definition: datastore.h:69
const struct ast_datastore_info * info
Definition: datastore.h:71
struct mansession_session * session
Definition: manager.c:1626
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

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

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

9675 {
9676  return AST_LIST_REMOVE(&s->session->datastores, datastore, entry) ? 0 : -1;
struct mansession_session::mansession_datastores datastores
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
struct mansession_session * session
Definition: manager.c:1626
Definition: search.h:40

◆ astman_is_authed()

int astman_is_authed ( uint32_t  ident)

Determinie if a manager session ident is authenticated.

Definition at line 7551 of file manager.c.

References ao2_unlock, mansession_session::authenticated, find_session(), session, and unref_mansession().

Referenced by http_post_callback(), and static_callback().

7553 {
7554  int authed;
7555  struct mansession_session *session;
7556 
7557  if (!(session = find_session(ident, 0)))
7558  return 0;
7559 
7560  authed = (session->authenticated != 0);
7561 
7562  ao2_unlock(session);
7563  unref_mansession(session);
7564 
7565  return authed;
#define ao2_unlock(a)
Definition: astobj2.h:730
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:2183
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:7479
static struct ast_mansession session

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

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

7569 {
7570  int result = 0;
7571  struct mansession_session *session;
7572  struct ao2_container *sessions;
7573  struct ao2_iterator i;
7574 
7575  if (ident == 0) {
7576  return 0;
7577  }
7578 
7579  sessions = ao2_global_obj_ref(mgr_sessions);
7580  if (!sessions) {
7581  return 0;
7582  }
7583  i = ao2_iterator_init(sessions, 0);
7584  ao2_ref(sessions, -1);
7585  while ((session = ao2_iterator_next(&i))) {
7586  ao2_lock(session);
7587  if ((session->managerid == ident) && (session->readperm & perm)) {
7588  result = 1;
7589  ao2_unlock(session);
7590  unref_mansession(session);
7591  break;
7592  }
7593  ao2_unlock(session);
7594  unref_mansession(session);
7595  }
7597 
7598  return result;
static struct sessions sessions
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
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:2183
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
uint32_t managerid
Definition: manager.c:1588
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
static PGresult * result
Definition: cel_pgsql.c:88
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

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

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

Referenced by http_post_callback().

7602 {
7603  int result = 0;
7604  struct mansession_session *session;
7605  struct ao2_container *sessions;
7606  struct ao2_iterator i;
7607 
7608  if (ident == 0) {
7609  return 0;
7610  }
7611 
7612  sessions = ao2_global_obj_ref(mgr_sessions);
7613  if (!sessions) {
7614  return 0;
7615  }
7616  i = ao2_iterator_init(sessions, 0);
7617  ao2_ref(sessions, -1);
7618  while ((session = ao2_iterator_next(&i))) {
7619  ao2_lock(session);
7620  if ((session->managerid == ident) && (session->writeperm & perm)) {
7621  result = 1;
7622  ao2_unlock(session);
7623  unref_mansession(session);
7624  break;
7625  }
7626  ao2_unlock(session);
7627  unref_mansession(session);
7628  }
7630 
7631  return result;
static struct sessions sessions
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
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:2183
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
uint32_t managerid
Definition: manager.c:1588
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
static PGresult * result
Definition: cel_pgsql.c:88
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

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

References ast_manager_user::a1_hash, ast_manager_user::acl, mansession_session::addr, 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(), mansession_session::authenticated, build_mansession(), close_mansession_file(), ast_http_digest::cnonce, d, mansession_session::datastores, ast_manager_user::displayconnects, errno, find_session_by_nonce(), FORMAT_HTML, FORMAT_XML, get_manager_by_name_locked(), global_realm, grab_last(), httptimeout, mansession_session::last_ev, mansession::lock, LOG_NOTICE, LOG_WARNING, mansession_session::managerid, ast_variable::name, ast_http_digest::nc, mansession_session::nc, mansession_session::needdestroy, ast_variable::next, ast_http_digest::nonce, mansession_session::noncetime, NULL, mansession_session::oldnonce, out, process_message(), process_output(), ast_http_digest::qop, mansession_session::readperm, ast_manager_user::readperm, ast_http_digest::response, session, mansession::session, session_destroy(), mansession_session::sessionstart, mansession_session::sessiontimeout, mansession_session::stream, mansession::stream, ast_http_digest::uri, ast_http_digest::username, mansession_session::username, ast_manager_user::username, ast_variable::value, mansession_session::writeperm, ast_manager_user::writeperm, mansession_session::writetimeout, and ast_manager_user::writetimeout.

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

8126 {
8127  struct mansession_session *session = NULL;
8128  struct mansession s = { .session = NULL, .tcptls_session = ser };
8129  struct ast_variable *v, *params = get_params;
8130  char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
8131  struct ast_str *http_header = NULL, *out = NULL;
8132  size_t result_size;
8133  struct message m = { 0 };
8134  int fd;
8135 
8136  time_t time_now = time(NULL);
8137  unsigned long nonce = 0, nc;
8138  struct ast_http_digest d = { NULL, };
8139  struct ast_manager_user *user = NULL;
8140  int stale = 0;
8141  char resp_hash[256]="";
8142  /* Cache for user data */
8143  char u_username[80];
8144  int u_readperm;
8145  int u_writeperm;
8146  int u_writetimeout;
8147  int u_displayconnects;
8148 
8150  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
8151  return 0;
8152  }
8153 
8154  /* Find "Authorization: " header */
8155  for (v = headers; v; v = v->next) {
8156  if (!strcasecmp(v->name, "Authorization")) {
8157  break;
8158  }
8159  }
8160 
8161  if (!v || ast_strlen_zero(v->value)) {
8162  goto out_401; /* Authorization Header not present - send auth request */
8163  }
8164 
8165  /* Digest found - parse */
8166  if (ast_string_field_init(&d, 128)) {
8168  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8169  return 0;
8170  }
8171 
8172  if (ast_parse_digest(v->value, &d, 0, 1)) {
8173  /* Error in Digest - send new one */
8174  nonce = 0;
8175  goto out_401;
8176  }
8177  if (sscanf(d.nonce, "%30lx", &nonce) != 1) {
8178  ast_log(LOG_WARNING, "Received incorrect nonce in Digest <%s>\n", d.nonce);
8179  nonce = 0;
8180  goto out_401;
8181  }
8182 
8185  if(!user) {
8187  ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8188  nonce = 0;
8189  goto out_401;
8190  }
8191 
8192  /* --- We have User for this auth, now check ACL */
8193  if (user->acl && !ast_apply_acl(user->acl, remote_address, "Manager User ACL:")) {
8195  ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&session->addr), d.username);
8197  ast_http_error(ser, 403, "Permission denied", "Permission denied");
8198  return 0;
8199  }
8200 
8201  /* --- We have auth, so check it */
8202 
8203  /* compute the expected response to compare with what we received */
8204  {
8205  char *a2;
8206  /* ast_md5_hash outputs 32 characters plus NULL terminator. */
8207  char a2_hash[33];
8208  char resp[256];
8209 
8210  /* XXX Now request method are hardcoded in A2 */
8211  if (ast_asprintf(&a2, "%s:%s", ast_get_http_method(method), d.uri) < 0) {
8214  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8215  return 0;
8216  }
8217 
8218  ast_md5_hash(a2_hash, a2);
8219  ast_free(a2);
8220 
8221  if (d.qop) {
8222  /* RFC 2617 */
8223  snprintf(resp, sizeof(resp), "%s:%08lx:%s:%s:auth:%s", user->a1_hash, nonce, d.nc, d.cnonce, a2_hash);
8224  } else {
8225  /* RFC 2069 */
8226  snprintf(resp, sizeof(resp), "%s:%08lx:%s", user->a1_hash, nonce, a2_hash);
8227  }
8228  ast_md5_hash(resp_hash, resp);
8229  }
8230 
8231  if (strncasecmp(d.response, resp_hash, strlen(resp_hash))) {
8232  /* Something was wrong, so give the client to try with a new challenge */
8234  nonce = 0;
8235  goto out_401;
8236  }
8237 
8238  /*
8239  * User are pass Digest authentication.
8240  * Now, cache the user data and unlock user list.
8241  */
8242  ast_copy_string(u_username, user->username, sizeof(u_username));
8243  u_readperm = user->readperm;
8244  u_writeperm = user->writeperm;
8245  u_displayconnects = user->displayconnects;
8246  u_writetimeout = user->writetimeout;
8248 
8249  if (!(session = find_session_by_nonce(d.username, nonce, &stale))) {
8250  /*
8251  * Create new session.
8252  * While it is not in the list we don't need any locking
8253  */
8254  if (!(session = build_mansession(remote_address))) {
8256  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
8257  return 0;
8258  }
8259  ao2_lock(session);
8260 
8261  ast_copy_string(session->username, u_username, sizeof(session->username));
8262  session->managerid = nonce;
8263  session->last_ev = grab_last();
8265 
8266  session->readperm = u_readperm;
8267  session->writeperm = u_writeperm;
8268  session->writetimeout = u_writetimeout;
8269 
8270  if (u_displayconnects) {
8271  ast_verb(2, "HTTP Manager '%s' logged in from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8272  }
8273  session->noncetime = session->sessionstart = time_now;
8274  session->authenticated = 1;
8275  } else if (stale) {
8276  /*
8277  * Session found, but nonce is stale.
8278  *
8279  * This could be because an old request (w/old nonce) arrived.
8280  *
8281  * This may be as the result of http proxy usage (separate delay or
8282  * multipath) or in a situation where a page was refreshed too quickly
8283  * (seen in Firefox).
8284  *
8285  * In this situation, we repeat the 401 auth with the current nonce
8286  * value.
8287  */
8288  nonce = session->managerid;
8289  ao2_unlock(session);
8290  stale = 1;
8291  goto out_401;
8292  } else {
8293  sscanf(d.nc, "%30lx", &nc);
8294  if (session->nc >= nc || ((time_now - session->noncetime) > 62) ) {
8295  /*
8296  * Nonce time expired (> 2 minutes) or something wrong with nonce
8297  * counter.
8298  *
8299  * Create new nonce key and resend Digest auth request. Old nonce
8300  * is saved for stale checking...
8301  */
8302  session->nc = 0; /* Reset nonce counter */
8303  session->oldnonce = session->managerid;
8304  nonce = session->managerid = ast_random();
8305  session->noncetime = time_now;
8306  ao2_unlock(session);
8307  stale = 1;
8308  goto out_401;
8309  } else {
8310  session->nc = nc; /* All OK, save nonce counter */
8311  }
8312  }
8313 
8314 
8315  /* Reset session timeout. */
8316  session->sessiontimeout = time(NULL) + (httptimeout > 5 ? httptimeout : 5);
8317  ao2_unlock(session);
8318 
8319  ast_mutex_init(&s.lock);
8320  s.session = session;
8321  fd = mkstemp(template); /* create a temporary file for command output */
8322  unlink(template);
8323  if (fd <= -1) {
8324  ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
8325  goto auth_callback_out;
8326  }
8327  s.stream = ast_iostream_from_fd(&fd);
8328  if (!s.stream) {
8329  ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
8330  ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
8331  close(fd);
8332  goto auth_callback_out;
8333  }
8334 
8335  if (method == AST_HTTP_POST) {
8336  params = ast_http_get_post_vars(ser, headers);
8337  if (!params) {
8338  switch (errno) {
8339  case EFBIG:
8340  ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
8342  goto auth_callback_out;
8343  case ENOMEM:
8345  ast_http_error(ser, 500, "Server Error", "Out of memory");
8347  goto auth_callback_out;
8348  case EIO:
8349  ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8351  goto auth_callback_out;
8352  }
8353  }
8354  }
8355 
8356  astman_append_headers(&m, params);
8357 
8358  if (process_message(&s, &m)) {
8359  if (u_displayconnects) {
8360  ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8361  }
8362 
8363  session->needdestroy = 1;
8364  }
8365 
8366  astman_free_headers(&m);
8367 
8368  result_size = lseek(ast_iostream_get_fd(s.stream), 0, SEEK_CUR); /* Calculate approx. size of result */
8369 
8370  http_header = ast_str_create(80);
8371  out = ast_str_create(result_size * 2 + 512);
8372  if (http_header == NULL || out == NULL) {
8374  ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
8376  goto auth_callback_out;
8377  }
8378 
8379  ast_str_append(&http_header, 0, "Content-type: text/%s\r\n", contenttype[format]);
8380 
8381  if (format == FORMAT_XML) {
8382  ast_str_append(&out, 0, "<ajax-response>\n");
8383  } else if (format == FORMAT_HTML) {
8384  ast_str_append(&out, 0,
8385  "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
8386  "<html><head>\r\n"
8387  "<title>Asterisk&trade; Manager Interface</title>\r\n"
8388  "</head><body style=\"background-color: #ffffff;\">\r\n"
8389  "<form method=\"POST\">\r\n"
8390  "<table align=\"center\" style=\"background-color: #f1f1f1;\" width=\"500\">\r\n"
8391  "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\"><h1>Manager Tester</h1></th></tr>\r\n"
8392  "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\">Action: <input name=\"action\" /> Cmd: <input name=\"command\" /><br>"
8393  "<input type=\"submit\" value=\"Send request\" /></th></tr>\r\n");
8394  }
8395 
8396  process_output(&s, &out, params, format);
8397 
8398  if (format == FORMAT_XML) {
8399  ast_str_append(&out, 0, "</ajax-response>\n");
8400  } else if (format == FORMAT_HTML) {
8401  ast_str_append(&out, 0, "</table></form></body></html>\r\n");
8402  }
8403 
8404  ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
8405  http_header = NULL;
8406  out = NULL;
8407 
8408 auth_callback_out:
8409  ast_mutex_destroy(&s.lock);
8410 
8411  /* Clear resources and unlock manager session */
8412  if (method == AST_HTTP_POST && params) {
8413  ast_variables_destroy(params);
8414  }
8415 
8416  ast_free(http_header);
8417  ast_free(out);
8418 
8419  ao2_lock(session);
8420  if (session->stream) {
8421  ast_iostream_close(session->stream);
8422  session->stream = NULL;
8423  }
8424  ao2_unlock(session);
8425 
8426  if (session->needdestroy) {
8427  ast_debug(1, "Need destroy, doing it now!\n");
8428  session_destroy(session);
8429  }
8431  return 0;
8432 
8433 out_401:
8434  if (!nonce) {
8435  nonce = ast_random();
8436  }
8437 
8438  ast_http_auth(ser, global_realm, nonce, nonce, stale, NULL);
8440  return 0;
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:290
const ast_string_field cnonce
Definition: utils.h:672
struct ast_iostream * stream
Definition: manager.c:1627
struct ast_variable * next
char username[80]
Definition: manager.c:1645
static void close_mansession_file(struct mansession *s)
Definition: manager.c:7864
char username[80]
Definition: manager.c:1592
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:648
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct mansession_session::mansession_datastores datastores
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:622
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:2830
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:2305
#define LOG_WARNING
Definition: logger.h:274
static struct test_val d
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct eventqent * last_ev
Definition: manager.c:1603
Structure for variables, used for configurations and for channel variables.
struct ast_iostream * ast_iostream_from_fd(int *fd)
Create an iostream from a file descriptor.
Definition: iostream.c:604
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:1091
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream&#39;s file descriptor.
Definition: iostream.c:84
#define ao2_unlock(a)
Definition: astobj2.h:730
ast_mutex_t lock
Definition: manager.c:1632
const ast_string_field username
Definition: utils.h:672
struct ast_sockaddr addr
Definition: manager.c:1583
static const char *const contenttype[]
Definition: manager.c:7468
#define NULL
Definition: resample.c:96
user descriptor, as read from the config file.
Definition: manager.c:1644
list of users found in the config file
static void process_output(struct mansession *s, struct ast_str **out, struct ast_variable *params, enum output_format format)
Definition: manager.c:7874
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:456
#define ast_verb(level,...)
Definition: logger.h:463
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:6607
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
static int httptimeout
Definition: manager.c:1473
#define ast_strlen_zero(foo)
Definition: strings.h:52
time_t sessiontimeout
Definition: manager.c:1591
const ast_string_field uri
Definition: utils.h:672
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_iostream_close(struct ast_iostream *stream)
Close an iostream.
Definition: iostream.c:528
const ast_string_field response
Definition: utils.h:672
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
static struct ast_mansession session
In case you didn&#39;t read that giant block of text above the mansession_session struct, the struct 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.
Definition: manager.c:1625
long int ast_random(void)
Definition: main/utils.c:2064
#define ao2_lock(a)
Definition: astobj2.h:718
char * a1_hash
Definition: manager.c:1656
static struct mansession_session * find_session_by_nonce(const char *username, unsigned long nonce, int *stale)
Definition: manager.c:7518
const char * method
Definition: res_pjsip.c:4335
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
struct ast_acl_list * acl
Definition: manager.c:1655
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
int errno
const ast_string_field nc
Definition: utils.h:672
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
struct ast_iostream * stream
Definition: manager.c:1584
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:2844
unsigned long nc
Definition: manager.c:1609
uint32_t managerid
Definition: manager.c:1588
const char * ast_get_http_method(enum ast_http_method method) attribute_pure
Return http method name string.
Definition: http.c:190
structure to hold users read from users.conf
const ast_string_field nonce
Definition: utils.h:672
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
FILE * out
Definition: utils/frame.c:33
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:2229
static struct eventqent * grab_last(void)
Definition: manager.c:1963
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
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:1353
static void session_destroy(struct mansession_session *s)
Definition: manager.c:2269
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic)
Parse digest authorization header.
Definition: main/utils.c:2390
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:1484
struct mansession_session * session
Definition: manager.c:1626
#define ast_mutex_init(pmutex)
Definition: lock.h:184
#define ast_mutex_destroy(a)
Definition: lock.h:186
time_t sessionstart
Definition: manager.c:1589
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: main/utils.c:248
static snd_pcm_format_t format
Definition: chan_alsa.c:102
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:836
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
unsigned long oldnonce
Definition: manager.c:1608
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

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

8503 {
8504  int retval;
8505  struct ast_sockaddr ser_remote_address_tmp;
8506 
8507  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8508  retval = auth_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
8509  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8510  return retval;
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:171
Socket address structure.
Definition: netsock2.h:97
const char * method
Definition: res_pjsip.c:4335
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:8119
struct ast_sockaddr remote_address
Definition: tcptls.h:151

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

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

8514 {
8515  int retval;
8516  struct ast_sockaddr ser_remote_address_tmp;
8517 
8518  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8519  retval = auth_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
8520  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8521  return retval;
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:171
Socket address structure.
Definition: netsock2.h:97
const char * method
Definition: res_pjsip.c:4335
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:8119
struct ast_sockaddr remote_address
Definition: tcptls.h:151

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

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

8525 {
8526  int retval;
8527  struct ast_sockaddr ser_remote_address_tmp;
8528 
8529  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8530  retval = auth_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
8531  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8532  return retval;
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:171
Socket address structure.
Definition: netsock2.h:97
const char * method
Definition: res_pjsip.c:4335
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:8119
struct ast_sockaddr remote_address
Definition: tcptls.h:151

◆ close_mansession_file()

static void close_mansession_file ( struct mansession s)
static

Definition at line 7864 of file manager.c.

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

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

7866 {
7867  if (s->stream) {
7869  s->stream = NULL;
7870  } else {
7871  ast_log(LOG_ERROR, "Attempted to close file/file descriptor on mansession without a valid file or file descriptor.\n");
7872  }
struct ast_iostream * stream
Definition: manager.c:1627
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
int ast_iostream_close(struct ast_iostream *stream)
Close an iostream.
Definition: iostream.c:528
#define LOG_ERROR
Definition: logger.h:285

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

References ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_atomic_fetchadd_int(), mansession_session::inuse, mansession_session::managerid, mansession_session::needdestroy, NULL, session, sessions, and unref_mansession().

Referenced by astman_is_authed(), and generic_http_callback().

7481 {
7482  struct ao2_container *sessions;
7483  struct mansession_session *session;
7484  struct ao2_iterator i;
7485 
7486  if (ident == 0) {
7487  return NULL;
7488  }
7489 
7490  sessions = ao2_global_obj_ref(mgr_sessions);
7491  if (!sessions) {
7492  return NULL;
7493  }
7494  i = ao2_iterator_init(sessions, 0);
7495  ao2_ref(sessions, -1);
7496  while ((session = ao2_iterator_next(&i))) {
7497  ao2_lock(session);
7498  if (session->managerid == ident && !session->needdestroy) {
7499  ast_atomic_fetchadd_int(&session->inuse, incinuse ? 1 : 0);
7500  break;
7501  }
7502  ao2_unlock(session);
7503  unref_mansession(session);
7504  }
7506 
7507  return session;
static struct sessions sessions
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
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:2183
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
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
uint32_t managerid
Definition: manager.c:1588
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

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

References ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, mansession_session::managerid, NULL, mansession_session::oldnonce, session, sessions, unref_mansession(), and mansession_session::username.

Referenced by auth_http_callback().

7520 {
7521  struct mansession_session *session;
7522  struct ao2_container *sessions;
7523  struct ao2_iterator i;
7524 
7525  if (nonce == 0 || username == NULL || stale == NULL) {
7526  return NULL;
7527  }
7528 
7529  sessions = ao2_global_obj_ref(mgr_sessions);
7530  if (!sessions) {
7531  return NULL;
7532  }
7533  i = ao2_iterator_init(sessions, 0);
7534  ao2_ref(sessions, -1);
7535  while ((session = ao2_iterator_next(&i))) {
7536  ao2_lock(session);
7537  if (!strcasecmp(session->username, username) && session->managerid == nonce) {
7538  *stale = 0;
7539  break;
7540  } else if (!strcasecmp(session->username, username) && session->oldnonce == nonce) {
7541  *stale = 1;
7542  break;
7543  }
7544  ao2_unlock(session);
7545  unref_mansession(session);
7546  }
7548 
7549  return session;
char username[80]
Definition: manager.c:1592
static struct sessions sessions
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
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:2183
static struct ast_mansession session
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
uint32_t managerid
Definition: manager.c:1588
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
unsigned long oldnonce
Definition: manager.c:1608

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

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, get_manager_by_name_locked(), get_manager_sessions_cb(), LOG_ERROR, LOG_WARNING, name, NULL, and sessions.

8579 {
8580  struct ast_manager_user *user = NULL;
8581 
8583  AST_APP_ARG(name);
8584  AST_APP_ARG(param);
8585  );
8586 
8587 
8588  if (ast_strlen_zero(data) ) {
8589  ast_log(LOG_WARNING, "AMI_CLIENT() requires two arguments: AMI_CLIENT(<name>[,<arg>])\n");
8590  return -1;
8591  }
8592  AST_STANDARD_APP_ARGS(args, data);
8593  args.name = ast_strip(args.name);
8594  args.param = ast_strip(args.param);
8595 
8597  if (!(user = get_manager_by_name_locked(args.name))) {
8599  ast_log(LOG_ERROR, "There's no manager user called : \"%s\"\n", args.name);
8600  return -1;
8601  }
8603 
8604  if (!strcasecmp(args.param, "sessions")) {
8605  int no_sessions = 0;
8606  struct ao2_container *sessions;
8607 
8608  sessions = ao2_global_obj_ref(mgr_sessions);
8609  if (sessions) {
8610  ao2_callback_data(sessions, 0, get_manager_sessions_cb, /*login name*/ data, &no_sessions);
8611  ao2_ref(sessions, -1);
8612  }
8613  snprintf(buf, len, "%d", no_sessions);
8614  } else {
8615  ast_log(LOG_ERROR, "Invalid arguments provided to function AMI_CLIENT: %s\n", args.param);
8616  return -1;
8617 
8618  }
8619 
8620  return 0;
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct sessions sessions
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:2305
#define LOG_WARNING
Definition: logger.h:274
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
const char * args
#define NULL
Definition: resample.c:96
user descriptor, as read from the config file.
Definition: manager.c:1644
list of users found in the config file
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_log
Definition: astobj2.c:42
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1743
static const char name[]
Definition: cdr_mysql.c:74
structure to hold users read from users.conf
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:8562
Generic container type.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ 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 constantcy of s), that won't happen twice in a row.

Definition at line 7907 of file manager.c.

References mansession_session::addr, 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(), mansession_session::authenticated, build_mansession(), close_mansession_file(), displayconnects, errno, find_session(), FORMAT_HTML, FORMAT_XML, grab_last(), httptimeout, mansession_session::inuse, mansession::lock, LOG_WARNING, manager_displayconnects(), mansession_session::managerid, mansession_session::needdestroy, mansession_session::notify_lock, NULL, out, process_message(), process_output(), ROW_FMT, mansession_session::send_events, session, mansession::session, session_destroy(), mansession_session::sessiontimeout, mansession_session::stream, mansession::stream, TEST_STRING, unref_mansession(), mansession_session::username, and mansession_session::waiting_thread.

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

7914 {
7915  struct mansession s = { .session = NULL, .tcptls_session = ser };
7916  struct mansession_session *session = NULL;
7917  uint32_t ident;
7918  int fd;
7919  int blastaway = 0;
7920  struct ast_variable *params = get_params;
7921  char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
7922  struct ast_str *http_header = NULL, *out = NULL;
7923  struct message m = { 0 };
7924 
7926  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
7927  return 0;
7928  }
7929 
7930  ident = ast_http_manid_from_vars(headers);
7931 
7932  if (!(session = find_session(ident, 1))) {
7933 
7934  /**/
7935  /* Create new session.
7936  * While it is not in the list we don't need any locking
7937  */
7938  if (!(session = build_mansession(remote_address))) {
7940  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)");
7941  return 0;
7942  }
7943  ao2_lock(session);
7944  session->send_events = 0;
7945  session->inuse = 1;
7946  /*!
7947  * \note There is approximately a 1 in 1.8E19 chance that the following
7948  * calculation will produce 0, which is an invalid ID, but due to the
7949  * properties of the rand() function (and the constantcy of s), that
7950  * won't happen twice in a row.
7951  */
7952  while ((session->managerid = ast_random() ^ (unsigned long) session) == 0) {
7953  }
7954  session->last_ev = grab_last();
7955  AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
7956  }
7957  ao2_unlock(session);
7958 
7959  http_header = ast_str_create(128);
7960  out = ast_str_create(2048);
7961 
7962  ast_mutex_init(&s.lock);
7963 
7964  if (http_header == NULL || out == NULL) {
7966  ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)");
7967  goto generic_callback_out;
7968  }
7969 
7970  s.session = session;
7971  fd = mkstemp(template); /* create a temporary file for command output */
7972  unlink(template);
7973  if (fd <= -1) {
7974  ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)");
7975  goto generic_callback_out;
7976  }
7977  s.stream = ast_iostream_from_fd(&fd);
7978  if (!s.stream) {
7979  ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
7980  ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)");
7981  close(fd);
7982  goto generic_callback_out;
7983  }
7984 
7985  if (method == AST_HTTP_POST) {
7986  params = ast_http_get_post_vars(ser, headers);
7987  if (!params) {
7988  switch (errno) {
7989  case EFBIG:
7990  ast_http_error(ser, 413, "Request Entity Too Large", "Body too large");
7992  goto generic_callback_out;
7993  case ENOMEM:
7995  ast_http_error(ser, 500, "Server Error", "Out of memory");
7997  goto generic_callback_out;
7998  case EIO:
7999  ast_http_error(ser, 400, "Bad Request", "Error parsing request body");
8001  goto generic_callback_out;
8002  }
8003  }
8004  }
8005 
8006  astman_append_headers(&m, params);
8007 
8008  if (process_message(&s, &m)) {
8009  if (session->authenticated) {
8010  if (manager_displayconnects(session)) {
8011  ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
8012  }
8013  } else {
8014  if (displayconnects) {
8015  ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
8016  }
8017  }
8018  session->needdestroy = 1;
8019  }
8020 
8021  astman_free_headers(&m);
8022 
8023  ast_str_append(&http_header, 0,
8024  "Content-type: text/%s\r\n"
8025  "Set-Cookie: mansession_id=\"%08x\"; Version=1; Max-Age=%d\r\n"
8026  "Pragma: SuppressEvents\r\n",
8028  session->managerid, httptimeout);
8029 
8030  if (format == FORMAT_XML) {
8031  ast_str_append(&out, 0, "<ajax-response>\n");
8032  } else if (format == FORMAT_HTML) {
8033  /*
8034  * When handling AMI-over-HTTP in HTML format, we provide a simple form for
8035  * debugging purposes. This HTML code should not be here, we
8036  * should read from some config file...
8037  */
8038 
8039 #define ROW_FMT "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\">%s</td></tr>\r\n"
8040 #define TEST_STRING \
8041  "<form action=\"manager\" method=\"post\">\n\
8042  Action: <select name=\"action\">\n\
8043  <option value=\"\">-----&gt;</option>\n\
8044  <option value=\"login\">login</option>\n\
8045  <option value=\"command\">Command</option>\n\
8046  <option value=\"waitevent\">waitevent</option>\n\
8047  <option value=\"listcommands\">listcommands</option>\n\
8048  </select>\n\
8049  or <input name=\"action\"><br/>\n\
8050  CLI Command <input name=\"command\"><br>\n\
8051  user <input name=\"username\"> pass <input type=\"password\" name=\"secret\"><br>\n\
8052  <input type=\"submit\">\n</form>\n"
8053 
8054  ast_str_append(&out, 0, "<title>Asterisk&trade; Manager Interface</title>");
8055  ast_str_append(&out, 0, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n");
8056  ast_str_append(&out, 0, ROW_FMT, "<h1>Manager Tester</h1>");
8057  ast_str_append(&out, 0, ROW_FMT, TEST_STRING);
8058  }
8059 
8060  process_output(&s, &out, params, format);
8061 
8062  if (format == FORMAT_XML) {
8063  ast_str_append(&out, 0, "</ajax-response>\n");
8064  } else if (format == FORMAT_HTML) {
8065  ast_str_append(&out, 0, "</table></body>\r\n");
8066  }
8067 
8068  ao2_lock(session);
8069  /* Reset HTTP timeout. If we're not authenticated, keep it extremely short */
8070  session->sessiontimeout = time(NULL) + ((session->authenticated || httptimeout < 5) ? httptimeout : 5);
8071 
8072  if (session->needdestroy) {
8073  if (session->inuse == 1) {
8074  ast_debug(1, "Need destroy, doing it now!\n");
8075  blastaway = 1;
8076  } else {
8077  ast_debug(1, "Need destroy, but can't do it yet!\n");
8078  ast_mutex_lock(&session->notify_lock);
8079  if (session->waiting_thread != AST_PTHREADT_NULL) {
8080  pthread_kill(session->waiting_thread, SIGURG);
8081  }
8082  ast_mutex_unlock(&session->notify_lock);
8083  session->inuse--;
8084  }
8085  } else {
8086  session->inuse--;
8087  }
8088  ao2_unlock(session);
8089 
8090  ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
8091  http_header = NULL;
8092  out = NULL;
8093 
8094 generic_callback_out:
8095  ast_mutex_destroy(&s.lock);
8096 
8097  /* Clear resource */
8098 
8099  if (method == AST_HTTP_POST && params) {
8100  ast_variables_destroy(params);
8101  }
8102  ast_free(http_header);
8103  ast_free(out);
8104 
8105  if (session) {
8106  if (blastaway) {
8107  session_destroy(session);
8108  } else {
8109  if (session->stream) {
8110  ast_iostream_close(session->stream);
8111  session->stream = NULL;
8112  }
8113  unref_mansession(session);
8114  }
8115  }
8116 
8117  return 0;
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:290
struct ast_iostream * stream
Definition: manager.c:1627
static void close_mansession_file(struct mansession *s)
Definition: manager.c:7864
char username[80]
Definition: manager.c:1592
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:648
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
static int displayconnects
Definition: manager.c:1470
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:2830
pthread_t waiting_thread
Definition: manager.c:1587
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
struct ast_iostream * ast_iostream_from_fd(int *fd)
Create an iostream from a file descriptor.
Definition: iostream.c:604
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:1091
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ao2_unlock(a)
Definition: astobj2.h:730
ast_mutex_t lock
Definition: manager.c:1632
uint32_t ast_http_manid_from_vars(struct ast_variable *headers) attribute_pure
Return manager id, if exist, from request headers.
Definition: http.c:217
struct ast_sockaddr addr
Definition: manager.c:1583
static const char *const contenttype[]
Definition: manager.c:7468
#define NULL
Definition: resample.c:96
static void process_output(struct mansession *s, struct ast_str **out, struct ast_variable *params, enum output_format format)
Definition: manager.c:7874
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:456
#define ast_verb(level,...)
Definition: logger.h:463
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:2183
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:6607
static int httptimeout
Definition: manager.c:1473
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:7479
#define TEST_STRING
time_t sessiontimeout
Definition: manager.c:1591
ast_mutex_t notify_lock
Definition: manager.c:1610
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_iostream_close(struct ast_iostream *stream)
Close an iostream.
Definition: iostream.c:528
#define AST_PTHREADT_NULL
Definition: lock.h:66
static struct ast_mansession session
In case you didn&#39;t read that giant block of text above the mansession_session struct, the struct 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.
Definition: manager.c:1625
long int ast_random(void)
Definition: main/utils.c:2064
#define ao2_lock(a)
Definition: astobj2.h:718
const char * method
Definition: res_pjsip.c:4335
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
int errno
#define ast_free(a)
Definition: astmm.h:182
struct ast_iostream * stream
Definition: manager.c:1584
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:2844
uint32_t managerid
Definition: manager.c:1588
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
FILE * out
Definition: utils/frame.c:33
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:2229
static struct eventqent * grab_last(void)
Definition: manager.c:1963
#define ROW_FMT
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:1353
static void session_destroy(struct mansession_session *s)
Definition: manager.c:2269
struct mansession_session * session
Definition: manager.c:1626
#define ast_mutex_init(pmutex)
Definition: lock.h:184
#define ast_mutex_destroy(a)
Definition: lock.h:186
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:2322
static snd_pcm_format_t format
Definition: chan_alsa.c:102
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:836
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_mutex_unlock(a)
Definition: lock.h:188

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

References session, and mansession_session::username.

Referenced by function_amiclient().

8564 {
8565  struct mansession_session *session = obj;
8566  const char *login = (char *)arg;
8567  int *no_sessions = data;
8568 
8569  if (strcasecmp(session->username, login) == 0) {
8570  (*no_sessions)++;
8571  }
8572 
8573  return 0;
char username[80]
Definition: manager.c:1592
static struct ast_mansession session

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

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

8832 {
8834  struct ao2_iterator it_events;
8835  struct ast_xml_doc_item *item, *temp;
8836  int length;
8837 
8838  if (cmd == CLI_INIT) {
8839  e->command = "manager show event";
8840  e->usage =
8841  "Usage: manager show event <eventname>\n"
8842  " Provides a detailed description a Manager interface event.\n";
8843  return NULL;
8844  }
8845 
8846  events = ao2_global_obj_ref(event_docs);
8847  if (!events) {
8848  ast_cli(a->fd, "No manager event documentation loaded\n");
8849  return CLI_SUCCESS;
8850  }
8851 
8852  if (cmd == CLI_GENERATE) {
8853  if (a->pos != 3) {
8854  return NULL;
8855  }
8856 
8857  length = strlen(a->word);
8858  it_events = ao2_iterator_init(events, 0);
8859  while ((item = ao2_iterator_next(&it_events))) {
8860  if (!strncasecmp(a->word, item->name, length)) {
8861  if (ast_cli_completion_add(ast_strdup(item->name))) {
8862  ao2_ref(item, -1);
8863  break;
8864  }
8865  }
8866  ao2_ref(item, -1);
8867  }
8868  ao2_iterator_destroy(&it_events);
8869 
8870  return NULL;
8871  }
8872 
8873  if (a->argc != 4) {
8874  return CLI_SHOWUSAGE;
8875  }
8876 
8877  if (!(item = ao2_find(events, a->argv[3], OBJ_KEY))) {
8878  ast_cli(a->fd, "Could not find event '%s'\n", a->argv[3]);
8879  return CLI_SUCCESS;
8880  }
8881 
8882  ast_cli(a->fd, "Event: %s\n", a->argv[3]);
8883  for (temp = item; temp; temp = AST_LIST_NEXT(temp, next)) {
8884  print_event_instance(a, temp);
8885  }
8886 
8887  ao2_ref(item, -1);
8888  return CLI_SUCCESS;
struct ast_xml_doc_item * next
Definition: xmldoc.h:80
#define OBJ_KEY
Definition: astobj2.h:1155
const int argc
Definition: cli.h:160
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
Definition: cli.h:152
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
static struct aco_type item
Definition: test_config.c:1463
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#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:911
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance)
Definition: manager.c:8793
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
const ast_string_field name
Definition: xmldoc.h:74
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const int pos
Definition: cli.h:164
Struct that contains the XML documentation for a particular item. Note that this is an ao2 ref counte...
Definition: xmldoc.h:56
Generic container type.
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

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

References ao2_callback, ao2_container_count(), ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli_args::argc, 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, ast_cli_args::fd, item, name, NULL, OBJ_MULTIPLE, OBJ_NOLOCK, and ast_cli_entry::usage.

8714 {
8715  struct ao2_container *events;
8716  struct ao2_iterator *it_events;
8717  struct ast_xml_doc_item *item;
8718  struct ast_xml_doc_item **items;
8719  struct ast_str *buffer;
8720  int i = 0, totalitems = 0;
8721 
8722  switch (cmd) {
8723  case CLI_INIT:
8724  e->command = "manager show events";
8725  e->usage =
8726  "Usage: manager show events\n"
8727  " Prints a listing of the available Asterisk manager interface events.\n";
8728  return NULL;
8729  case CLI_GENERATE:
8730  return NULL;
8731  }
8732  if (a->argc != 3) {
8733  return CLI_SHOWUSAGE;
8734  }
8735 
8736  buffer = ast_str_create(128);
8737  if (!buffer) {
8738  return CLI_SUCCESS;
8739  }
8740 
8741  events = ao2_global_obj_ref(event_docs);
8742  if (!events) {
8743  ast_cli(a->fd, "No manager event documentation loaded\n");
8744  ast_free(buffer);
8745  return CLI_SUCCESS;
8746  }
8747 
8748  ao2_lock(events);
8749  if (!(it_events = ao2_callback(events, OBJ_MULTIPLE | OBJ_NOLOCK, NULL, NULL))) {
8750  ao2_unlock(events);
8751  ast_log(AST_LOG_ERROR, "Unable to create iterator for events container\n");
8752  ast_free(buffer);
8753  ao2_ref(events, -1);
8754  return CLI_SUCCESS;
8755  }
8756  if (!(items = ast_calloc(sizeof(struct ast_xml_doc_item *), ao2_container_count(events)))) {
8757  ao2_unlock(events);
8758  ast_log(AST_LOG_ERROR, "Unable to create temporary sorting array for events\n");
8759  ao2_iterator_destroy(it_events);
8760  ast_free(buffer);
8761  ao2_ref(events, -1);
8762  return CLI_SUCCESS;
8763  }
8764  ao2_unlock(events);
8765 
8766  while ((item = ao2_iterator_next(it_events))) {
8767  items[totalitems++] = item;
8768  ao2_ref(item, -1);
8769  }
8770 
8771  qsort(items, totalitems, sizeof(struct ast_xml_doc_item *), ast_xml_doc_item_cmp_fn);
8772 
8773  ast_cli(a->fd, "Events:\n");
8774  ast_cli(a->fd, " -------------------- -------------------- -------------------- \n");
8775  for (i = 0; i < totalitems; i++) {
8776  ast_str_append(&buffer, 0, " %-20.20s", items[i]->name);
8777  if ((i + 1) % 3 == 0) {
8778  ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
8779  ast_str_set(&buffer, 0, "%s", "");
8780  }
8781  }
8782  if ((i + 1) % 3 != 0) {
8783  ast_cli(a->fd, "%s\n", ast_str_buffer(buffer));
8784  }
8785 
8786  ao2_iterator_destroy(it_events);
8787  ast_free(items);
8788  ao2_ref(events, -1);
8789  ast_free(buffer);
8790 
8791  return CLI_SUCCESS;
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
const int argc
Definition: cli.h:160
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
Definition: cli.h:152
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
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:1091
static struct aco_type item
Definition: test_config.c:1463
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
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:1065
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static int ast_xml_doc_item_cmp_fn(const void *a, const void *b)
Definition: manager.c:8705
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
Struct that contains the XML documentation for a particular item. Note that this is an ao2 ref counte...
Definition: xmldoc.h:56
Generic container type.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

References allowmultiplelogin, ami_tls_cfg, ast_cli_args::argc, 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, ast_cli_args::fd, FORMAT, FORMAT2, httptimeout, ast_tcptls_session_args::local_address, manager_channelvars, manager_debug, manager_enabled, NULL, ast_tls_config::pvtfile, S_OR, timestampevents, ast_cli_entry::usage, and webmanager_enabled.

8666 {
8667  switch (cmd) {
8668  case CLI_INIT:
8669  e->command = "manager show settings";
8670  e->usage =
8671  "Usage: manager show settings\n"
8672  " Provides detailed list of the configuration of the Manager.\n";
8673  return NULL;
8674  case CLI_GENERATE:
8675  return NULL;
8676  }
8677 #define FORMAT " %-25.25s %-15.55s\n"
8678 #define FORMAT2 " %-25.25s %-15d\n"
8679  if (a->argc != 3) {
8680  return CLI_SHOWUSAGE;
8681  }
8682  ast_cli(a->fd, "\nGlobal Settings:\n");
8683  ast_cli(a->fd, "----------------\n");
8684  ast_cli(a->fd, FORMAT, "Manager (AMI):", AST_CLI_YESNO(manager_enabled));
8685  ast_cli(a->fd, FORMAT, "Web Manager (AMI/HTTP):", AST_CLI_YESNO(webmanager_enabled));
8686  ast_cli(a->fd, FORMAT, "TCP Bindaddress:", manager_enabled != 0 ? ast_sockaddr_stringify(&ami_desc.local_address) : "Disabled");
8687  ast_cli(a->fd, FORMAT2, "HTTP Timeout (seconds):", httptimeout);
8688  ast_cli(a->fd, FORMAT, "TLS Enable:", AST_CLI_YESNO(ami_tls_cfg.enabled));
8689  ast_cli(a->fd, FORMAT, "TLS Bindaddress:", ami_tls_cfg.enabled != 0 ? ast_sockaddr_stringify(&amis_desc.local_address) : "Disabled");
8690  ast_cli(a->fd, FORMAT, "TLS Certfile:", ami_tls_cfg.certfile);
8691  ast_cli(a->fd, FORMAT, "TLS Privatekey:", ami_tls_cfg.pvtfile);
8692  ast_cli(a->fd, FORMAT, "TLS Cipher:", ami_tls_cfg.cipher);
8693  ast_cli(a->fd, FORMAT, "Allow multiple login:", AST_CLI_YESNO(allowmultiplelogin));
8694  ast_cli(a->fd, FORMAT, "Display connects:", AST_CLI_YESNO(displayconnects));
8695  ast_cli(a->fd, FORMAT, "Timestamp events:", AST_CLI_YESNO(timestampevents));
8696  ast_cli(a->fd, FORMAT, "Channel vars:", S_OR(manager_channelvars, ""));
8697  ast_cli(a->fd, FORMAT, "Debug:", AST_CLI_YESNO(manager_debug));
8698 #undef FORMAT
8699 #undef FORMAT2
8700 
8701  return CLI_SUCCESS;
char * pvtfile
Definition: tcptls.h:90
static int displayconnects
Definition: manager.c:1470
const int argc
Definition: cli.h:160
Definition: cli.h:152
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:8642
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static int httptimeout
Definition: manager.c:1473
const int fd
Definition: cli.h:159
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:8641
static int timestampevents
Definition: manager.c:1472
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:8653
static int manager_debug
Definition: manager.c:1478
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define FORMAT
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
char * command
Definition: cli.h:186
char * certfile
Definition: tcptls.h:89
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static int manager_enabled
Definition: manager.c:1475
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static int allowmultiplelogin
Definition: manager.c:1471
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
struct ast_sockaddr local_address
Definition: tcptls.h:130
static int webmanager_enabled
Definition: manager.c:1477
#define FORMAT2
char * cipher
Definition: tcptls.h:91
static char * manager_channelvars
Definition: manager.c:1481
int enabled
Definition: tcptls.h:88

◆ load_channelvars()

static void load_channelvars ( struct ast_variable var)
static

Definition at line 8916 of file manager.c.

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 ast_variable::value.

Referenced by __init_manager().

8918 {
8919  char *parse = NULL;
8921  AST_APP_ARG(vars)[MAX_VARS];
8922  );
8923 
8926 
8927  /* parse the setting */
8929  AST_STANDARD_APP_ARGS(args, parse);
8930 
#define MAX_VARS
Definition: manager.c:1508
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * args
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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:7989
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define ast_free(a)
Definition: astmm.h:182
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
static char * manager_channelvars
Definition: manager.c:1481
#define AST_APP_ARG(name)
Define an application argument.

◆ load_module()

static int load_module ( void  )
static

Definition at line 9654 of file manager.c.

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

Referenced by ast_manager_event_blob_create().

9656 {
9658 
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static void manager_shutdown(void)
Definition: manager.c:8956
static int __init_manager(int reload, int by_external_config)
Definition: manager.c:9144
Module could not be loaded properly.
Definition: module.h:102

◆ manager_event_blob_dtor()

static void manager_event_blob_dtor ( void *  obj)
static

Definition at line 9718 of file manager.c.

References ast_string_field_free_memory.

Referenced by ast_manager_event_blob_create().

9720 {
9721  struct ast_manager_event_blob *ev = obj;
9722 
Struct containing info for an AMI event to send out.
Definition: manager.h:491
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ manager_free_user()

static void manager_free_user ( struct ast_manager_user user)
static

Definition at line 8937 of file manager.c.

References ast_manager_user::a1_hash, ast_manager_user::acl, ao2_t_ref, ast_free, ast_free_acl_list(), ast_variables_destroy(), ast_manager_user::blackfilters, ast_manager_user::chanvars, ast_manager_user::secret, and ast_manager_user::whitefilters.

Referenced by __init_manager(), and manager_shutdown().

8939 {
8940  ast_free(user->a1_hash);
8941  ast_free(user->secret);
8942  if (user->whitefilters) {
8943  ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one");
8944  }
8945  if (user->blackfilters) {
8946  ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one");
8947  }
8948  user->acl = ast_free_acl_list(user->acl);
8950  ast_free(user);
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct ao2_container * blackfilters
Definition: manager.c:1654
struct ao2_container * whitefilters
Definition: manager.c:1653
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_variable * chanvars
Definition: manager.c:1657
char * a1_hash
Definition: manager.c:1656
struct ast_acl_list * acl
Definition: manager.c:1655
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
#define ast_free(a)
Definition: astmm.h:182

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

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

8444 {
8445  int retval;
8446  struct ast_sockaddr ser_remote_address_tmp;
8447 
8448  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8449  retval = generic_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
8450  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8451  return retval;
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:171
Socket address structure.
Definition: netsock2.h:97
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:7907
const char * method
Definition: res_pjsip.c:4335
static ENTRY retval
Definition: hsearch.c:50
struct ast_sockaddr remote_address
Definition: tcptls.h:151

◆ manager_set_defaults()

static void manager_set_defaults ( void  )
static

Definition at line 9116 of file manager.c.

References ami_tls_cfg, 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().

9118 {
9119  manager_enabled = 0;
9120  displayconnects = 1;
9122  authtimeout = 30;
9123  authlimit = 50;
9124  manager_debug = 0; /* Debug disabled by default */
9125 
9126  /* default values */
9128  sizeof(global_realm));
9131 
9132  ami_tls_cfg.enabled = 0;
char * pvtfile
Definition: tcptls.h:90
#define AST_CERTFILE
Definition: tcptls.h:62
static int displayconnects
Definition: manager.c:1470
static int authtimeout
Definition: manager.c:1479
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:8642
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:140
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:8641
static int authlimit
Definition: manager.c:1480
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:8653
static int manager_debug
Definition: manager.c:1478
char * cafile
Definition: tcptls.h:92
#define ast_free(a)
Definition: astmm.h:182
static int broken_events_action
Definition: manager.c:1474
char * certfile
Definition: tcptls.h:89
#define DEFAULT_REALM
Definition: manager.c:1483
static int manager_enabled
Definition: manager.c:1475
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:1484
char * capath
Definition: tcptls.h:93
struct ast_sockaddr local_address
Definition: tcptls.h:130
char * cipher
Definition: tcptls.h:91
int enabled
Definition: tcptls.h:88

◆ manager_shutdown()

static void manager_shutdown ( void  )
static

Definition at line 8956 of file manager.c.

References acl_change_stasis_unsubscribe(), ami_tls_cfg, 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, EVENT_FLAG_SHUTDOWN, manager_channelvars, manager_event, manager_free_user(), NULL, ast_tls_config::pvtfile, stasis_forward_cancel(), stasis_message_router_unsubscribe_and_join(), STASIS_MESSAGE_TYPE_CLEANUP, and user.

Referenced by load_module().

8958 {
8959  struct ast_manager_user *user;
8960 
8961  /* This event is not actually transmitted, but causes all TCP sessions to be closed */
8962  manager_event(EVENT_FLAG_SHUTDOWN, "CloseSession", "CloseSession: true\r\n");
8963 
8964  ast_manager_unregister("Ping");
8965  ast_manager_unregister("Events");
8966  ast_manager_unregister("Logoff");
8967  ast_manager_unregister("Login");
8968  ast_manager_unregister("Challenge");
8969  ast_manager_unregister("Hangup");
8970  ast_manager_unregister("Status");
8971  ast_manager_unregister("Setvar");
8972  ast_manager_unregister("Getvar");
8973  ast_manager_unregister("GetConfig");
8974  ast_manager_unregister("GetConfigJSON");
8975  ast_manager_unregister("UpdateConfig");
8976  ast_manager_unregister("CreateConfig");
8977  ast_manager_unregister("ListCategories");
8978  ast_manager_unregister("Redirect");
8979  ast_manager_unregister("Atxfer");
8980  ast_manager_unregister("CancelAtxfer");
8981  ast_manager_unregister("Originate");
8982  ast_manager_unregister("Command");
8983  ast_manager_unregister("ExtensionState");
8984  ast_manager_unregister("PresenceState");
8985  ast_manager_unregister("AbsoluteTimeout");
8986  ast_manager_unregister("MailboxStatus");
8987  ast_manager_unregister("MailboxCount");
8988  ast_manager_unregister("ListCommands");
8989  ast_manager_unregister("SendText");
8990  ast_manager_unregister("UserEvent");
8991  ast_manager_unregister("WaitEvent");
8992  ast_manager_unregister("CoreSettings");
8993  ast_manager_unregister("CoreStatus");
8994  ast_manager_unregister("Reload");
8995  ast_manager_unregister("LoggerRotate");
8996  ast_manager_unregister("CoreShowChannels");
8997  ast_manager_unregister("ModuleLoad");
8998  ast_manager_unregister("ModuleCheck");
8999  ast_manager_unregister("AOCMessage");
9000  ast_manager_unregister("Filter");
9001  ast_manager_unregister("BlindTransfer");
9004 
9005 #ifdef AST_XML_DOCS
9006  ao2_t_global_obj_release(event_docs, "Dispose of event_docs");
9007 #endif
9008 
9009 #ifdef TEST_FRAMEWORK
9012 #endif
9013 
9014  if (stasis_router) {
9016  stasis_router = NULL;
9017  }
9023  manager_topic = NULL;
9025 
9028 
9039 
9040  ao2_global_obj_release(mgr_sessions);
9041 
9042  while ((user = AST_LIST_REMOVE_HEAD(&users, list))) {
9043  manager_free_user(user);
9044  }
9046 
static char user[512]
char * pvtfile
Definition: tcptls.h:90
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void stasis_message_router_unsubscribe_and_join(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic, blocking until the final message has been processed...
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
#define ao2_t_global_obj_release(holder, tag)
Release the ao2 object held in the global holder.
Definition: astobj2.h:863
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:8642
#define NULL
Definition: resample.c:96
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1490
user descriptor, as read from the config file.
Definition: manager.c:1644
list of users found in the config file
static void manager_free_user(struct ast_manager_user *user)
Definition: manager.c:8937
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static struct ast_custom_function managerclient_function
description of AMI_CLIENT dialplan function
Definition: manager.c:8624
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
static struct stasis_forward * test_suite_forwarder
The stasis_subscription for forwarding the Test topic to the AMI topic.
Definition: manager.c:1503
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:8641
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:8653
static void acl_change_stasis_unsubscribe(void)
Definition: manager.c:1544
int ast_manager_unregister(const char *action)
support functions to register/unregister AMI action handlers,
Definition: manager.c:7258
static struct stasis_message_router * stasis_router
The stasis_message_router for all Stasis Message Bus API messages.
Definition: manager.c:1493
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
char * cafile
Definition: tcptls.h:92
#define ast_free(a)
Definition: astmm.h:182
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548
static struct stasis_forward * security_topic_forwarder
The stasis_subscription for forwarding the Security topic to the AMI topic.
Definition: manager.c:1499
char * certfile
Definition: tcptls.h:89
static struct ast_cli_entry cli_manager[]
Definition: manager.c:8892
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:1511
static struct stasis_forward * rtp_topic_forwarder
The stasis_subscription for forwarding the RTP topic to the AMI topic.
Definition: manager.c:1496
char * capath
Definition: tcptls.h:93
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition: tcptls.c:849
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:248
char * cipher
Definition: tcptls.h:91
static char * manager_channelvars
Definition: manager.c:1481

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

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(), NULL, stasis_forward_all(), stasis_message_router_add(), stasis_message_router_create, stasis_message_router_set_congestion_limits(), stasis_message_router_set_formatters_default(), and STASIS_SUBSCRIPTION_FORMATTER_AMI.

Referenced by subscribe_all().

9055 {
9056  int res = 0;
9057 
9059  if (!rtp_topic_forwarder) {
9060  return -1;
9061  }
9062 
9064  if (!security_topic_forwarder) {
9065  return -1;
9066  }
9067 
9069  if (!stasis_router) {
9070  return -1;
9071  }
9074 
9077 
9080 
9081  if (res != 0) {
9082  return -1;
9083  }
9084  return 0;
static void manager_default_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:1838
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
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.
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
Definition: taskprocessor.h:63
static void manager_generic_msg_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:1869
#define NULL
Definition: resample.c:96
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1490
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.
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
#define stasis_message_router_create(topic)
static struct stasis_message_router * stasis_router
The stasis_message_router for all Stasis Message Bus API messages.
Definition: manager.c:1493
static struct stasis_forward * security_topic_forwarder
The stasis_subscription for forwarding the Security topic to the AMI topic.
Definition: manager.c:1499
static struct stasis_forward * rtp_topic_forwarder
The stasis_subscription for forwarding the RTP topic to the AMI topic.
Definition: manager.c:1496
struct stasis_topic * ast_rtp_topic(void)
Stasis Message Bus API topic for RTP and RTCP related messages
Definition: rtp_engine.c:3531
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1578
int 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.

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

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

8455 {
8456  int retval;
8457  struct ast_sockaddr ser_remote_address_tmp;
8458 
8459  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8460  retval = generic_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
8461  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8462  return retval;
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:171
Socket address structure.
Definition: netsock2.h:97
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:7907
const char * method
Definition: res_pjsip.c:4335
static ENTRY retval
Definition: hsearch.c:50
struct ast_sockaddr remote_address
Definition: tcptls.h:151

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

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

Referenced by auth_http_callback(), and generic_http_callback().

7876 {
7877  char *buf;
7878  off_t l;
7879  int fd;
7880 
7881  if (!s->stream)
7882  return;
7883 
7884  /* Ensure buffer is NULL-terminated */
7885  ast_iostream_write(s->stream, "", 1);
7886 
7887  fd = ast_iostream_get_fd(s->stream);
7888 
7889  l = lseek(fd, 0, SEEK_CUR);
7890  if (l > 0) {
7891  if (MAP_FAILED == (buf = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))) {
7892  ast_log(LOG_WARNING, "mmap failed. Manager output was not processed\n");
7893  } else {
7894  if (format == FORMAT_XML || format == FORMAT_HTML) {
7895  xml_translate(out, buf, params, format);
7896  } else {
7897  ast_str_append(out, 0, "%s", buf);
7898  }
7899  munmap(buf, l);
7900  }
7901  } else if (format == FORMAT_XML || format == FORMAT_HTML) {
7902  xml_translate(out, "", params, format);
7903  }
7904 
struct ast_iostream * stream
Definition: manager.c:1627
static void close_mansession_file(struct mansession *s)
Definition: manager.c:7864
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t count)
Write data to an iostream.
Definition: iostream.c:374
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
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:1091
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream&#39;s file descriptor.
Definition: iostream.c:84
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
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:7746
static snd_pcm_format_t format
Definition: chan_alsa.c:102

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

References purge_events(), and purge_sessions().

8637 {
8638  purge_sessions(1);
8639  purge_events();
static void purge_events(void)
Definition: manager.c:1983
static void purge_sessions(int n_max)
remove at most n_max stale session from the list.
Definition: manager.c:7031

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

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

8466 {
8467  int retval;
8468  struct ast_sockaddr ser_remote_address_tmp;
8469 
8470  ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
8471  retval = generic_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
8472  ast_sockaddr_copy(&ser->remote_address, &ser_remote_address_tmp);
8473  return retval;
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:171
Socket address structure.
Definition: netsock2.h:97
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:7907
const char * method
Definition: res_pjsip.c:4335
static ENTRY retval
Definition: hsearch.c:50
struct ast_sockaddr remote_address
Definition: tcptls.h:151

◆ subscribe_all()

static int subscribe_all ( void  )
static

Definition at line 9086 of file manager.c.

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().

9088 {
9090  ast_log(AST_LOG_ERROR, "Failed to initialize manager subscriptions\n");
9091  return -1;
9092  }
9093  if (manager_system_init()) {
9094  ast_log(AST_LOG_ERROR, "Failed to initialize manager system handling\n");
9095  return -1;
9096  }
9097  if (manager_channels_init()) {
9098  ast_log(AST_LOG_ERROR, "Failed to initialize manager channel handling\n");
9099  return -1;
9100  }
9101  if (manager_mwi_init()) {
9102  ast_log(AST_LOG_ERROR, "Failed to initialize manager MWI handling\n");
9103  return -1;
9104  }
9105  if (manager_bridging_init()) {
9106  return -1;
9107  }
9108  if (manager_endpoints_init()) {
9109  ast_log(AST_LOG_ERROR, "Failed to initialize manager endpoints handling\n");
9110  return -1;
9111  }
9112 
9113  subscribed = 1;
9114  return 0;
int manager_bridging_init(void)
Initialize support for AMI channel events.
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
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:9053
static int subscribed
Definition: manager.c:1476
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.
int manager_mwi_init(void)
Initialize support for AMI MWI events.
Definition: manager_mwi.c:153

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 9649 of file manager.c.

Referenced by ast_manager_event_blob_create().

9651 {
9652  return 0;

◆ variable_count_cmp_fn()

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

Definition at line 7707 of file manager.c.

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

Referenced by xml_translate().

7709 {
7710  /* Due to the simplicity of struct variable_count, it makes no difference
7711  * if you pass in objects or strings, the same operation applies. This is
7712  * due to the fact that the hash occurs on the first element, which means
7713  * the address of both the struct and the string are exactly the same. */
7714  struct variable_count *vc = obj;
7715  char *str = vstr;
7716  return !strcmp(vc->varname, str) ? CMP_MATCH | CMP_STOP : 0;
const char * str
Definition: app_jack.c:147
char * varname
Definition: manager.c:7696

◆ variable_count_hash_fn()

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

Definition at line 7700 of file manager.c.

References ast_str_hash(), and variable_count::varname.

Referenced by xml_translate().

7702 {
7703  const struct variable_count *vc = vvc;
7704 
7705  return ast_str_hash(vc->varname);
char * varname
Definition: manager.c:7696
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ xml_copy_escape()

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

Definition at line 7638 of file manager.c.

References ast_str_append(), and buf.

Referenced by xml_translate().

7640 {
7641  /* store in a local buffer to avoid calling ast_str_append too often */
7642  char buf[256];
7643  char *dst = buf;
7644  int space = sizeof(buf);
7645  /* repeat until done and nothing to flush */
7646  for ( ; *src || dst != buf ; src++) {
7647  if (*src == '\0' || space < 10) { /* flush */
7648  *dst++ = '\0';
7649  ast_str_append(out, 0, "%s", buf);
7650  dst = buf;
7651  space = sizeof(buf);
7652  if (*src == '\0') {
7653  break;
7654  }
7655  }
7656 
7657  if ( (mode & 2) && !isalnum(*src)) {
7658  *dst++ = '_';
7659  space--;
7660  continue;
7661  }
7662  switch (*src) {
7663  case '<':
7664  strcpy(dst, "&lt;");
7665  dst += 4;
7666  space -= 4;
7667  break;
7668  case '>':
7669  strcpy(dst, "&gt;");
7670  dst += 4;
7671  space -= 4;
7672  break;
7673  case '\"':
7674  strcpy(dst, "&quot;");
7675  dst += 6;
7676  space -= 6;
7677  break;
7678  case '\'':
7679  strcpy(dst, "&apos;");
7680  dst += 6;
7681  space -= 6;
7682  break;
7683  case '&':
7684  strcpy(dst, "&amp;");
7685  dst += 5;
7686  space -= 5;
7687  break;
7688 
7689  default:
7690  *dst++ = mode ? tolower(*src) : *src;
7691  space--;
7692  }
7693  }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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:1091

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

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

Referenced by process_output().

7748 {
7749  struct ast_variable *v;
7750  const char *dest = NULL;
7751  char *var, *val;
7752  const char *objtype = NULL;
7753  int in_data = 0; /* parsing data */
7754  int inobj = 0;
7755  int xml = (format == FORMAT_XML);
7756  struct variable_count *vc = NULL;
7757  struct ao2_container *vco = NULL;
7758 
7759  if (xml) {
7760  /* dest and objtype need only for XML format */
7761  for (v = get_vars; v; v = v->next) {
7762  if (!strcasecmp(v->name, "ajaxdest")) {
7763  dest = v->value;
7764  } else if (!strcasecmp(v->name, "ajaxobjtype")) {
7765  objtype = v->value;
7766  }
7767  }
7768  if (ast_strlen_zero(dest)) {
7769  dest = "unknown";
7770  }
7771  if (ast_strlen_zero(objtype)) {
7772  objtype = "generic";
7773  }
7774  }
7775 
7776  /* we want to stop when we find an empty line */
7777  while (in && *in) {
7778  val = strsep(&in, "\r\n"); /* mark start and end of line */
7779  if (in && *in == '\n') { /* remove trailing \n if any */
7780  in++;
7781  }
7782  ast_trim_blanks(val);
7783  ast_debug(5, "inobj %d in_data %d line <%s>\n", inobj, in_data, val);
7784  if (ast_strlen_zero(val)) {
7785  /* empty line */
7786  if (in_data) {
7787  /* close data in Opaque mode */
7788  ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
7789  in_data = 0;
7790  }
7791 
7792  if (inobj) {
7793  /* close block */
7794  ast_str_append(out, 0, xml ? " /></response>\n" :
7795  "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
7796  inobj = 0;
7797  ao2_ref(vco, -1);
7798  vco = NULL;
7799  }
7800  continue;
7801  }
7802 
7803  if (!inobj) {
7804  /* start new block */
7805  if (xml) {
7806  ast_str_append(out, 0, "<response type='object' id='%s'><%s", dest, objtype);
7807  }
7810  inobj = 1;
7811  }
7812 
7813  if (in_data) {
7814  /* Process data field in Opaque mode. This is a
7815  * followup, so we re-add line feeds. */
7816  ast_str_append(out, 0, xml ? "\n" : "<br>\n");
7817  xml_copy_escape(out, val, 0); /* data field */
7818  continue;
7819  }
7820 
7821  /* We expect "Name: value" line here */
7822  var = strsep(&val, ":");
7823  if (val) {
7824  /* found the field name */
7825  val = ast_skip_blanks(val);
7826  ast_trim_blanks(var);
7827  } else {
7828  /* field name not found, switch to opaque mode */
7829  val = var;
7830  var = "Opaque-data";
7831  in_data = 1;
7832  }
7833 
7834 
7835  ast_str_append(out, 0, xml ? " " : "<tr><td>");
7836  if ((vc = ao2_find(vco, var, 0))) {
7837  vc->count++;
7838  } else {
7839  /* Create a new entry for this one */
7840  vc = ao2_alloc(sizeof(*vc), NULL);
7841  vc->varname = var;
7842  vc->count = 1;
7843  ao2_link(vco, vc);
7844  }
7845 
7846  xml_copy_escape(out, var, xml ? 1 | 2 : 0); /* data name */
7847  if (vc->count > 1) {
7848  ast_str_append(out, 0, "-%d", vc->count);
7849  }
7850  ao2_ref(vc, -1);
7851  ast_str_append(out, 0, xml ? "='" : "</td><td>");
7852  xml_copy_escape(out, val, 0); /* data field */
7853  if (!in_data || !*in) {
7854  ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
7855  }
7856  }
7857 
7858  if (inobj) {
7859  ast_str_append(out, 0, xml ? " /></response>\n" :
7860  "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
7861  ao2_ref(vco, -1);
7862  }
struct ast_variable * next
Definition: ast_expr2.c:325
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
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:1091
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
FILE * in
Definition: utils/frame.c:33
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:182
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
char * strsep(char **str, const char *delims)
static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
Definition: manager.c:7707
char * varname
Definition: manager.c:7696
Generic container type.
static void xml_copy_escape(struct ast_str **out, const char *src, int mode)
Definition: manager.c:7638
static snd_pcm_format_t format
Definition: chan_alsa.c:102
static int variable_count_hash_fn(const void *vvc, const int flags)
Definition: manager.c:7700
#define ao2_link(container, obj)
Definition: astobj2.h:1549

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 9766 of file manager.c.

◆ amanageruri

struct ast_http_uri amanageruri
static

Definition at line 8543 of file manager.c.

◆ amanagerxmluri

struct ast_http_uri amanagerxmluri
static

Definition at line 8552 of file manager.c.

◆ ami_desc

struct ast_tcptls_session_args ami_desc
static

Definition at line 8642 of file manager.c.

◆ ami_tls_cfg

struct ast_tls_config ami_tls_cfg
static

◆ amis_desc

struct ast_tcptls_session_args amis_desc
static

Definition at line 8653 of file manager.c.

◆ arawmanuri

struct ast_http_uri arawmanuri
static

Definition at line 8534 of file manager.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 9766 of file manager.c.

◆ cli_manager

struct ast_cli_entry cli_manager[]
static

Definition at line 8892 of file manager.c.

◆ contenttype

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

Definition at line 7468 of file manager.c.

◆ 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:8577

description of AMI_CLIENT dialplan function

Definition at line 8624 of file manager.c.

◆ manageruri

struct ast_http_uri manageruri
static

Definition at line 8483 of file manager.c.

◆ managerxmluri

struct ast_http_uri managerxmluri
static

Definition at line 8491 of file manager.c.

◆ rawmanuri

struct ast_http_uri rawmanuri
static

Definition at line 8475 of file manager.c.

◆ webregged

int webregged = 0
static

Definition at line 8630 of file manager.c.

◆ words

const char* words[AST_MAX_CMD_LEN]

Definition at line 1525 of file manager.c.

Referenced by check_blacklist().