Wed Jan 8 2020 09:50:14

Asterisk developer's documentation


manager.c File Reference

The Asterisk Management Interface - AMI. More...

#include "asterisk.h"
#include "asterisk/_private.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/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/stringfields.h"

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  channelvars
 
struct  eventqent
 
struct  fast_originate_helper
 helper function for originate More...
 
struct  manager_channel_variable
 
struct  manager_hooks
 list of hooks registered More...
 
struct  mansession
 
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 ASTMAN_APPEND_BUF_INITSIZE   256
 initial allocated size for the astman_append_buf More...
 
#define DEFAULT_REALM   "asterisk"
 
#define FORMAT   " %-25.25s %-15.15s\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   " %-15.15s %-15.15s %-55.55s\n"
 
#define HSMCONN_FORMAT1   " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n"
 
#define HSMCONN_FORMAT2   " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n"
 
#define MANAGER_EVENT_BUF_INITSIZE   256
 
#define MAX_BLACKLIST_CMD_LEN   2
 Descriptor for a manager session, either on the AMI socket or over HTTP. More...
 
#define MSG_MOREDATA   ((char *)astman_send_response)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. More...
 
#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  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
}
 
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)
 
static void __init_manager_event_buf (void)
 
static void __init_manager_event_funcbuf (void)
 
static void __init_userevent_buf (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_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 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_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_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 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)
 
int ast_hook_send_action (struct manager_custom_hook *hook, const char *msg)
 Registered hooks can call this function to invoke actions and they will receive responses through registered callback. More...
 
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
 
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), 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)
 
int ast_manager_unregister (char *action)
 Unregister a registered manager command. More...
 
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired. More...
 
void astman_append (struct mansession *s, const char *fmt,...)
 
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...
 
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_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager list transaction. 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)
 
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, struct sockaddr_in *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 (struct sockaddr_in sin)
 Allocate manager session structure and add it to the list of sessions. More...
 
static int check_blacklist (const char *cmd)
 
int check_manager_enabled (void)
 Check if AMI is enabled. More...
 
static int check_manager_session_inuse (const char *name)
 
int check_webmanager_enabled (void)
 Check if AMI/HTTP is enabled. More...
 
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 void free_channelvars (void)
 
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 int generic_http_callback (struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, struct sockaddr_in *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_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_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)
 
int init_manager (void)
 Called by Asterisk initialization. More...
 
static void json_escape (char *out, const char *in)
 
static void load_channelvars (struct ast_variable *var)
 
static struct ast_variableman_do_variable_value (struct ast_variable *head, const char *hdr_val)
 
static int manager_displayconnects (struct mansession_session *session)
 Get displayconnects config option. More...
 
static void manager_free_user (struct ast_manager_user *user)
 
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 int manager_modulecheck (struct mansession *s, const struct message *m)
 
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 (char *context, char *exten, int state, void *data)
 
static int mansession_cmp_fn (void *obj, void *arg, int flags)
 
static struct sockaddr_in * mansession_encode_sin_local (const struct mansession *s, struct sockaddr_in *sin_local)
 
static enum
ast_security_event_transport_type 
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 int process_events (struct mansession *s)
 
static int process_message (struct mansession *s, const struct message *m)
 
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 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)
 
int reload_manager (void)
 Called by Asterisk module functions and the CLI command. More...
 
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 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...
 

Variables

static struct actions actions = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct all_events all_events = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
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 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
 
static struct channelvars channelvars = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct ast_cli_entry cli_manager []
 
struct {
   const char *   words [AST_MAX_CMD_LEN]
 
command_blacklist []
 
static const char *const contenttype []
 
static const int DEFAULT_AUTHLIMIT = 50
 
static const int DEFAULT_AUTHTIMEOUT = 30
 
static const int DEFAULT_BROKENEVENTSACTION = 0
 
static const int DEFAULT_DISPLAYCONNECTS = 1
 
static const int DEFAULT_ENABLED = 0
 
static const int DEFAULT_HTTPTIMEOUT = 60
 
static const int DEFAULT_MANAGERDEBUG = 0
 
static const int DEFAULT_TIMESTAMPEVENTS = 0
 
static const int DEFAULT_WEBENABLED = 0
 
static int displayconnects
 
static char global_realm [MAXHOSTNAMELEN]
 
static int httptimeout
 
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 ast_threadstorage manager_event_funcbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_funcbuf , .custom_init = NULL , }
 
static struct manager_hooks manager_hooks = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct ast_http_uri manageruri
 
static struct ast_http_uri managerxmluri
 
static struct permalias perms []
 
static struct ast_http_uri rawmanuri
 
static struct ao2_containersessions = NULL
 
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 } , }
 
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
ExtRef:
OpenSSL http://www.openssl.org - for AMI/SSL

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

  • data structures storing AMI state
  • AMI-related API functions, used by internal asterisk components
  • handlers for AMI-related CLI functions
  • handlers for AMI functions (available through the AMI socket)
  • the code for the main AMI listener thread and individual session threads
  • the http handlers invoked for AMI-over-HTTP by the threads in main/http.c

manager.conf

Definition in file manager.c.

Macro Definition Documentation

#define FORMAT   " %-25.25s %-15.15s\n"
#define FORMAT2   " %-25.25s %-15d\n"
#define HSMC_FORMAT   " %-15.15s %-15.15s %-55.55s\n"

Referenced by handle_showmancmds().

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

Referenced by handle_showmanconn().

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

Referenced by handle_showmanconn().

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

Referenced by generic_http_callback().

#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

Enumerator
FORMAT_RAW 
FORMAT_HTML 
FORMAT_XML 

Definition at line 5541 of file manager.c.

5542  {
5543  FORMAT_RAW,
5544  FORMAT_HTML,
5545  FORMAT_XML,

Function Documentation

static int __init_manager ( int  reload)
static

Definition at line 6839 of file manager.c.

References ast_manager_user::a1_hash, action_aocmessage(), action_atxfer(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_listcommands(), action_login(), action_logoff(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_ping(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_updateconfig(), action_userevent(), action_waitevent(), ami_tls_cfg, ao2_container_alloc, ao2_t_alloc, ao2_t_callback, ao2_t_link, ao2_t_ref, append_event(), ARRAY_LEN, ast_append_ha(), 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_ha(), ast_http_uri_link(), ast_http_uri_unlink(), AST_LIST_INSERT_TAIL, ast_log(), ast_manager_register_xml, ast_md5_hash(), ast_register_atexit(), 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_from_sin, ast_sockaddr_to_sin, ast_ssl_setup(), ast_strdup, ast_strlen_zero(), ast_tcptls_server_start(), ast_tcptls_server_stop(), ast_tls_read_conf(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_manager_user::blackfilters, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_HTTPTIMEOUT, DEFAULT_MANAGER_PORT, DEFAULT_MANAGER_TLS_PORT, displayconnects, ast_manager_user::displayconnects, ast_tls_config::enabled, event_filter_destructor(), 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, ast_manager_user::ha, inet_aton(), ast_manager_user::keep, ast_variable::lineno, load_channelvars(), ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, manager_event, manager_free_user(), manager_modulecheck(), manager_moduleload(), manager_set_defaults(), manager_shutdown(), manager_state_cb(), mansession_cmp_fn(), ast_variable::name, ast_variable::next, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, ast_manager_user::readperm, ast_manager_user::secret, ast_tcptls_session_args::tls_cfg, ast_manager_user::username, value, ast_variable::value, var, ast_manager_user::whitefilters, ast_manager_user::writeperm, and ast_manager_user::writetimeout.

Referenced by init_manager(), and reload_manager().

6841 {
6842  struct ast_config *ucfg = NULL, *cfg = NULL;
6843  const char *val;
6844  char *cat = NULL;
6845  int newhttptimeout = DEFAULT_HTTPTIMEOUT;
6846  struct ast_manager_user *user = NULL;
6847  struct ast_variable *var;
6848  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
6849  char a1[256];
6850  char a1_hash[256];
6851  struct sockaddr_in ami_desc_local_address_tmp = { 0, };
6852  struct sockaddr_in amis_desc_local_address_tmp = { 0, };
6853  int tls_was_enabled = 0;
6854 
6855  if (!reload) {
6857 
6858  /* Register default actions */
6863  ast_manager_register_xml("Challenge", 0, action_challenge);
6881  ast_manager_register_xml("ListCommands", 0, action_listcommands);
6884  ast_manager_register_xml("WaitEvent", 0, action_waitevent);
6892 
6894  ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
6895 
6896  /* Append placeholder event so master_eventq never runs dry */
6897  if (append_event("Event: Placeholder\r\n\r\n", 0)) {
6898  return -1;
6899  }
6900 
6901  /* If you have a NULL hash fn, you only need a single bucket */
6903  if (!sessions) {
6904  return -1;
6905  }
6906 
6907  /* Initialize all settings before first configuration load. */
6909  }
6910 
6911  cfg = ast_config_load2("manager.conf", "manager", config_flags);
6912  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
6913  return 0;
6914  } else if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
6915  ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid.\n");
6916  return 0;
6917  }
6918 
6919  if (reload) {
6920  /* Reset all settings before reloading configuration */
6921  tls_was_enabled = ami_tls_cfg.enabled;
6923  }
6924 
6925  ami_desc_local_address_tmp.sin_family = AF_INET;
6926  amis_desc_local_address_tmp.sin_family = AF_INET;
6927 
6928  ami_desc_local_address_tmp.sin_port = htons(DEFAULT_MANAGER_PORT);
6929 
6930  for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
6931  val = var->value;
6932 
6933  /* read tls config options while preventing unsupported options from being set */
6934  if (strcasecmp(var->name, "tlscafile")
6935  && strcasecmp(var->name, "tlscapath")
6936  && strcasecmp(var->name, "tlscadir")
6937  && strcasecmp(var->name, "tlsverifyclient")
6938  && strcasecmp(var->name, "tlsdontverifyserver")
6939  && strcasecmp(var->name, "tlsclientmethod")
6940  && strcasecmp(var->name, "sslclientmethod")
6941  && !ast_tls_read_conf(&ami_tls_cfg, &amis_desc, var->name, val)) {
6942  continue;
6943  }
6944 
6945  if (!strcasecmp(var->name, "enabled")) {
6946  manager_enabled = ast_true(val);
6947  } else if (!strcasecmp(var->name, "webenabled")) {
6949  } else if (!strcasecmp(var->name, "port")) {
6950  ami_desc_local_address_tmp.sin_port = htons(atoi(val));
6951  } else if (!strcasecmp(var->name, "bindaddr")) {
6952  if (!inet_aton(val, &ami_desc_local_address_tmp.sin_addr)) {
6953  ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val);
6954  memset(&ami_desc_local_address_tmp.sin_addr, 0,
6955  sizeof(ami_desc_local_address_tmp.sin_addr));
6956  }
6957  } else if (!strcasecmp(var->name, "brokeneventsaction")) {
6959  } else if (!strcasecmp(var->name, "allowmultiplelogin")) {
6961  } else if (!strcasecmp(var->name, "displayconnects")) {
6962  displayconnects = ast_true(val);
6963  } else if (!strcasecmp(var->name, "timestampevents")) {
6964  timestampevents = ast_true(val);
6965  } else if (!strcasecmp(var->name, "debug")) {
6966  manager_debug = ast_true(val);
6967  } else if (!strcasecmp(var->name, "httptimeout")) {
6968  newhttptimeout = atoi(val);
6969  } else if (!strcasecmp(var->name, "authtimeout")) {
6970  int timeout = atoi(var->value);
6971 
6972  if (timeout < 1) {
6973  ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", var->value);
6974  } else {
6975  authtimeout = timeout;
6976  }
6977  } else if (!strcasecmp(var->name, "authlimit")) {
6978  int limit = atoi(var->value);
6979 
6980  if (limit < 1) {
6981  ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", var->value);
6982  } else {
6983  authlimit = limit;
6984  }
6985  } else if (!strcasecmp(var->name, "channelvars")) {
6986  load_channelvars(var);
6987  } else {
6988  ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
6989  var->name, val);
6990  }
6991  }
6992 
6993  ast_sockaddr_to_sin(&amis_desc.local_address, &amis_desc_local_address_tmp);
6994 
6995  /* if the amis address has not been set, default is the same as non secure ami */
6996  if (!amis_desc_local_address_tmp.sin_addr.s_addr) {
6997  amis_desc_local_address_tmp.sin_addr =
6998  ami_desc_local_address_tmp.sin_addr;
6999  }
7000 
7001  if (!amis_desc_local_address_tmp.sin_port) {
7002  amis_desc_local_address_tmp.sin_port = htons(DEFAULT_MANAGER_TLS_PORT);
7003  }
7004 
7005  if (manager_enabled) {
7006  ast_sockaddr_from_sin(&ami_desc.local_address, &ami_desc_local_address_tmp);
7007  ast_sockaddr_from_sin(&amis_desc.local_address, &amis_desc_local_address_tmp);
7008  }
7009 
7011 
7012  /* First, get users from users.conf */
7013  ucfg = ast_config_load2("users.conf", "manager", config_flags);
7014  if (ucfg && (ucfg != CONFIG_STATUS_FILEUNCHANGED) && ucfg != CONFIG_STATUS_FILEINVALID) {
7015  const char *hasmanager;
7016  int genhasmanager = ast_true(ast_variable_retrieve(ucfg, "general", "hasmanager"));
7017 
7018  while ((cat = ast_category_browse(ucfg, cat))) {
7019  if (!strcasecmp(cat, "general")) {
7020  continue;
7021  }
7022 
7023  hasmanager = ast_variable_retrieve(ucfg, cat, "hasmanager");
7024  if ((!hasmanager && genhasmanager) || ast_true(hasmanager)) {
7025  const char *user_secret = ast_variable_retrieve(ucfg, cat, "secret");
7026  const char *user_read = ast_variable_retrieve(ucfg, cat, "read");
7027  const char *user_write = ast_variable_retrieve(ucfg, cat, "write");
7028  const char *user_displayconnects = ast_variable_retrieve(ucfg, cat, "displayconnects");
7029  const char *user_writetimeout = ast_variable_retrieve(ucfg, cat, "writetimeout");
7030 
7031  /* Look for an existing entry,
7032  * if none found - create one and add it to the list
7033  */
7034  if (!(user = get_manager_by_name_locked(cat))) {
7035  if (!(user = ast_calloc(1, sizeof(*user)))) {
7036  break;
7037  }
7038 
7039  /* Copy name over */
7040  ast_copy_string(user->username, cat, sizeof(user->username));
7041  /* Insert into list */
7042  AST_LIST_INSERT_TAIL(&users, user, list);
7043  user->ha = NULL;
7044  user->keep = 1;
7045  user->readperm = -1;
7046  user->writeperm = -1;
7047  /* Default displayconnect from [general] */
7049  user->writetimeout = 100;
7050  }
7051 
7052  if (!user_secret) {
7053  user_secret = ast_variable_retrieve(ucfg, "general", "secret");
7054  }
7055  if (!user_read) {
7056  user_read = ast_variable_retrieve(ucfg, "general", "read");
7057  }
7058  if (!user_write) {
7059  user_write = ast_variable_retrieve(ucfg, "general", "write");
7060  }
7061  if (!user_displayconnects) {
7062  user_displayconnects = ast_variable_retrieve(ucfg, "general", "displayconnects");
7063  }
7064  if (!user_writetimeout) {
7065  user_writetimeout = ast_variable_retrieve(ucfg, "general", "writetimeout");
7066  }
7067 
7068  if (!ast_strlen_zero(user_secret)) {
7069  ast_free(user->secret);
7070  user->secret = ast_strdup(user_secret);
7071  }
7072 
7073  if (user_read) {
7074  user->readperm = get_perm(user_read);
7075  }
7076  if (user_write) {
7077  user->writeperm = get_perm(user_write);
7078  }
7079  if (user_displayconnects) {
7080  user->displayconnects = ast_true(user_displayconnects);
7081  }
7082  if (user_writetimeout) {
7083  int value = atoi(user_writetimeout);
7084  if (value < 100) {
7085  ast_log(LOG_WARNING, "Invalid writetimeout value '%d' in users.conf\n", value);
7086  } else {
7087  user->writetimeout = value;
7088  }
7089  }
7090  }
7091  }
7092  ast_config_destroy(ucfg);
7093  }
7094 
7095  /* cat is NULL here in any case */
7096 
7097  while ((cat = ast_category_browse(cfg, cat))) {
7098  struct ast_ha *oldha;
7099 
7100  if (!strcasecmp(cat, "general")) {
7101  continue;
7102  }
7103 
7104  /* Look for an existing entry, if none found - create one and add it to the list */
7105  if (!(user = get_manager_by_name_locked(cat))) {
7106  if (!(user = ast_calloc(1, sizeof(*user)))) {
7107  break;
7108  }
7109  /* Copy name over */
7110  ast_copy_string(user->username, cat, sizeof(user->username));
7111 
7112  user->ha = NULL;
7113  user->readperm = 0;
7114  user->writeperm = 0;
7115  /* Default displayconnect from [general] */
7117  user->writetimeout = 100;
7118  user->whitefilters = ao2_container_alloc(1, NULL, NULL);
7119  user->blackfilters = ao2_container_alloc(1, NULL, NULL);
7120  if (!user->whitefilters || !user->blackfilters) {
7121  manager_free_user(user);
7122  break;
7123  }
7124 
7125  /* Insert into list */
7126  AST_RWLIST_INSERT_TAIL(&users, user, list);
7127  } else {
7128  ao2_t_callback(user->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters");
7129  ao2_t_callback(user->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters");
7130  }
7131 
7132  /* Make sure we keep this user and don't destroy it during cleanup */
7133  user->keep = 1;
7134  oldha = user->ha;
7135  user->ha = NULL;
7136 
7137  var = ast_variable_browse(cfg, cat);
7138  for (; var; var = var->next) {
7139  if (!strcasecmp(var->name, "secret")) {
7140  ast_free(user->secret);
7141  user->secret = ast_strdup(var->value);
7142  } else if (!strcasecmp(var->name, "deny") ||
7143  !strcasecmp(var->name, "permit")) {
7144  user->ha = ast_append_ha(var->name, var->value, user->ha, NULL);
7145  } else if (!strcasecmp(var->name, "read") ) {
7146  user->readperm = get_perm(var->value);
7147  } else if (!strcasecmp(var->name, "write") ) {
7148  user->writeperm = get_perm(var->value);
7149  } else if (!strcasecmp(var->name, "displayconnects") ) {
7150  user->displayconnects = ast_true(var->value);
7151  } else if (!strcasecmp(var->name, "writetimeout")) {
7152  int value = atoi(var->value);
7153  if (value < 100) {
7154  ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", var->value, var->lineno);
7155  } else {
7156  user->writetimeout = value;
7157  }
7158  } else if (!strcasecmp(var->name, "eventfilter")) {
7159  const char *value = var->value;
7160  regex_t *new_filter = ao2_t_alloc(sizeof(*new_filter), event_filter_destructor, "event_filter allocation");
7161  if (new_filter) {
7162  int is_blackfilter;
7163  if (value[0] == '!') {
7164  is_blackfilter = 1;
7165  value++;
7166  } else {
7167  is_blackfilter = 0;
7168  }
7169  if (regcomp(new_filter, value, 0)) { /* XXX: the only place we use non-REG_EXTENDED */
7170  ao2_t_ref(new_filter, -1, "failed to make regex");
7171  } else {
7172  if (is_blackfilter) {
7173  ao2_t_link(user->blackfilters, new_filter, "link new filter into black user container");
7174  } else {
7175  ao2_t_link(user->whitefilters, new_filter, "link new filter into white user container");
7176  }
7177  }
7178  }
7179  } else {
7180  ast_debug(1, "%s is an unknown option.\n", var->name);
7181  }
7182  }
7183  ast_free_ha(oldha);
7184  }
7185  ast_config_destroy(cfg);
7186 
7187  /* Perform cleanup - essentially prune out old users that no longer exist */
7188  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&users, user, list) {
7189  if (user->keep) { /* valid record. clear flag for the next round */
7190  user->keep = 0;
7191 
7192  /* Calculate A1 for Digest auth */
7193  snprintf(a1, sizeof(a1), "%s:%s:%s", user->username, global_realm, user->secret);
7194  ast_md5_hash(a1_hash,a1);
7195  ast_free(user->a1_hash);
7196  user->a1_hash = ast_strdup(a1_hash);
7197  continue;
7198  }
7199  /* We do not need to keep this user so take them out of the list */
7201  ast_debug(4, "Pruning user '%s'\n", user->username);
7202  manager_free_user(user);
7203  }
7205 
7207 
7209  if (!webregged) {
7213 
7217  webregged = 1;
7218  }
7219  } else {
7220  if (webregged) {
7224 
7228  webregged = 0;
7229  }
7230  }
7231 
7232  if (newhttptimeout > 0) {
7233  httptimeout = newhttptimeout;
7234  }
7235 
7236  manager_event(EVENT_FLAG_SYSTEM, "Reload",
7237  "Module: Manager\r\n"
7238  "Status: %s\r\n"
7239  "Message: Manager reload Requested\r\n",
7240  manager_enabled ? "Enabled" : "Disabled");
7241 
7243  if (tls_was_enabled && !ami_tls_cfg.enabled) {
7245  } else if (ast_ssl_setup(amis_desc.tls_cfg)) {
7247  }
7248 
7249  return 0;
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
static int action_challenge(struct mansession *s, const struct message *m)
Definition: manager.c:3149
struct ao2_container * blackfilters
Definition: manager.c:1049
static int action_command(struct mansession *s, const struct message *m)
Manager command &quot;command&quot; - execute CLI command.
Definition: manager.c:3732
char username[80]
Definition: manager.c:1040
struct ao2_container * whitefilters
Definition: manager.c:1048
static int action_originate(struct mansession *s, const struct message *m)
Definition: manager.c:4124
static int action_mailboxstatus(struct mansession *s, const struct message *m)
Definition: manager.c:4268
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
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:964
#define ast_strdup(a)
Definition: astmm.h:109
Definition: ast_expr2.c:325
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Allocate and initialize an object.
Definition: astobj2.h:429
int ast_ssl_setup(struct ast_tls_config *cfg)
Set up an SSL server.
Definition: tcptls.c:850
static int action_reload(struct mansession *s, const struct message *m)
Send a reload event.
Definition: manager.c:4550
static int displayconnects
Definition: manager.c:899
static int action_userevent(struct mansession *s, const struct message *m)
Definition: manager.c:4448
static int webregged
Definition: manager.c:6612
static int action_ping(struct mansession *s, const struct message *m)
Definition: manager.c:2519
#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:1435
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:544
#define EVENT_FLAG_COMMAND
Definition: manager.h:75
int lineno
Definition: config.h:87
static int action_login(struct mansession *s, const struct message *m)
Definition: manager.c:3117
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static int get_perm(const char *instr)
Definition: manager.c:1278
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static int action_createconfig(struct mansession *s, const struct message *m)
Definition: manager.c:2923
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:574
#define EVENT_FLAG_CALL
Definition: manager.h:72
static int authtimeout
Definition: manager.c:907
static int manager_moduleload(struct mansession *s, const struct message *m)
Definition: manager.c:4703
static int action_aocmessage(struct mansession *s, const struct message *m)
Definition: manager.c:3919
struct ast_ha * ha
Definition: manager.c:1042
static int action_getconfigjson(struct mansession *s, const struct message *m)
Definition: manager.c:2647
#define EVENT_FLAG_AOC
Definition: manager.h:87
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:6624
user descriptor, as read from the config file.
Definition: manager.c:1039
static int action_sendtext(struct mansession *s, const struct message *m)
Definition: manager.c:3459
int value
Definition: syslog.c:39
list of users found in the config file
static int append_event(const char *str, int category)
Definition: manager.c:5214
static int action_atxfer(struct mansession *s, const struct message *m)
Definition: manager.c:3647
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
#define EVENT_FLAG_ORIGINATE
Definition: manager.h:83
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static void manager_free_user(struct ast_manager_user *user)
Definition: manager.c:6735
static struct ast_http_uri arawmanuri
Definition: manager.c:6585
static int httptimeout
Definition: manager.c:902
#define ao2_t_link(arg1, arg2, arg3)
Add an object to a container.
Definition: astobj2.h:784
static int action_events(struct mansession *s, const struct message *m)
Definition: manager.c:3067
internal representation of acl entries In principle user applications would have no need for this...
Definition: acl.h:48
static int action_getconfig(struct mansession *s, const struct message *m)
Definition: manager.c:2537
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int manager_modulecheck(struct mansession *s, const struct message *m)
Definition: manager.c:4660
const char * value
Definition: config.h:79
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:172
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int action_coreshowchannels(struct mansession *s, const struct message *m)
Manager command &quot;CoreShowChannels&quot; - List currently defined channels and some information about them...
Definition: manager.c:4577
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
static int action_logoff(struct mansession *s, const struct message *m)
Definition: manager.c:3111
char * a1_hash
Definition: manager.c:1050
static struct ast_http_uri managerxmluri
Definition: manager.c:6542
static struct ast_http_uri manageruri
Definition: manager.c:6534
const char * name
Definition: config.h:77
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:6623
static int authlimit
Definition: manager.c:908
static int timestampevents
Definition: manager.c:901
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:6635
static void manager_shutdown(void)
Definition: manager.c:6750
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
static int action_listcommands(struct mansession *s, const struct message *m)
Definition: manager.c:3048
static int reload(void)
Definition: app_amd.c:497
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
#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 &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
static int action_mailboxcount(struct mansession *s, const struct message *m)
Definition: manager.c:4285
static int manager_debug
Definition: manager.c:906
#define EVENT_FLAG_USER
Definition: manager.h:77
#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:909
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int action_waitevent(struct mansession *s, const struct message *m)
Definition: manager.c:2941
#define LOG_NOTICE
Definition: logger.h:133
static int action_timeout(struct mansession *s, const struct message *m)
Definition: manager.c:4331
static int action_getvar(struct mansession *s, const struct message *m)
Definition: manager.c:3243
static void event_filter_destructor(void *obj)
Definition: manager.c:1339
#define ast_free(a)
Definition: astmm.h:97
static int broken_events_action
Definition: manager.c:903
static int action_status(struct mansession *s, const struct message *m)
Manager &quot;status&quot; command to show channels.
Definition: manager.c:3297
#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:4468
Structure used to handle boolean flags.
Definition: utils.h:200
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:223
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
static struct ast_http_uri amanageruri
Definition: manager.c:6594
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
static void load_channelvars(struct ast_variable *var)
Definition: manager.c:6705
static struct ast_cli_entry cli_manager[]
Definition: manager.c:6685
#define DEFAULT_MANAGER_PORT
Definition: manager.h:58
static struct ast_http_uri amanagerxmluri
Definition: manager.c:6603
static int manager_enabled
Definition: manager.c:904
#define ast_calloc(a, b)
Definition: astmm.h:82
static int action_updateconfig(struct mansession *s, const struct message *m)
Definition: manager.c:2845
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static int action_hangup(struct mansession *s, const struct message *m)
Definition: manager.c:3167
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:1072
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:912
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition: acl.c:399
static int action_extensionstate(struct mansession *s, const struct message *m)
Definition: manager.c:4306
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
struct ast_variable * next
Definition: config.h:82
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition: tcptls.c:1058
struct ast_tls_config * tls_cfg
Definition: tcptls.h:128
static int manager_state_cb(char *context, char *exten, int state, void *data)
Definition: manager.c:5404
static int allowmultiplelogin
Definition: manager.c:900
struct ast_sockaddr local_address
Definition: tcptls.h:124
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static int action_corestatus(struct mansession *s, const struct message *m)
Show PBX core status information.
Definition: manager.c:4510
static int webmanager_enabled
Definition: manager.c:905
int ast_extension_state_add(const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
Registers a state change callback.
Definition: pbx.c:5135
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: utils.c:245
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
static void manager_set_defaults(void)
Definition: manager.c:6810
static int mansession_cmp_fn(void *obj, void *arg, int flags)
Definition: manager.c:1404
static int action_redirect(struct mansession *s, const struct message *m)
action_redirect: The redirect manager command
Definition: manager.c:3494
int inet_aton(const char *cp, struct in_addr *pin)
static int action_listcategories(struct mansession *s, const struct message *m)
Definition: manager.c:2581
static const int DEFAULT_HTTPTIMEOUT
Definition: manager.c:893
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
static struct ast_http_uri rawmanuri
Definition: manager.c:6526
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static int action_setvar(struct mansession *s, const struct message *m)
Definition: manager.c:3210
int enabled
Definition: tcptls.h:86
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 7272 of file manager.c.

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

7274 {
7275  AST_LIST_INSERT_HEAD(&s->session->datastores, datastore, entry);
7276 
7277  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:696
struct mansession_session * session
Definition: manager.c:1013
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 7284 of file manager.c.

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

7286 {
7287  struct ast_datastore *datastore = NULL;
7288 
7289  if (info == NULL)
7290  return NULL;
7291 
7293  if (datastore->info != info) {
7294  continue;
7295  }
7296 
7297  if (uid == NULL) {
7298  /* matched by type only */
7299  break;
7300  }
7301 
7302  if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
7303  /* Matched by type AND uid */
7304  break;
7305  }
7306  }
7308 
7309  return datastore;
struct ast_datastore::@163 entry
struct mansession_session::mansession_datastores datastores
struct ast_datastore_info * info
Definition: datastore.h:57
Structure for a data store object.
Definition: datastore.h:54
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
const char * uid
Definition: datastore.h:55
struct mansession_session * session
Definition: manager.c:1013
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
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 7279 of file manager.c.

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

7281 {
7282  return AST_LIST_REMOVE(&s->session->datastores, datastore, entry) ? 0 : -1;
struct ast_datastore::@163 entry
struct mansession_session::mansession_datastores datastores
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:841
struct mansession_session * session
Definition: manager.c:1013
int astman_is_authed ( uint32_t  ident)

Determinie if a manager session ident is authenticated.

Definition at line 5617 of file manager.c.

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

Referenced by http_post_callback(), and static_callback().

5619 {
5620  int authed;
5621  struct mansession_session *session;
5622 
5623  if (!(session = find_session(ident, 0)))
5624  return 0;
5625 
5626  authed = (session->authenticated != 0);
5627 
5628  ao2_unlock(session);
5629  unref_mansession(session);
5630 
5631  return authed;
#define ao2_unlock(a)
Definition: astobj2.h:497
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:1330
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:5558
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 5633 of file manager.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, mansession_session::managerid, mansession_session::readperm, and unref_mansession().

5635 {
5636  int result = 0;
5637  struct mansession_session *session;
5638  struct ao2_iterator i;
5639 
5640  if (ident == 0) {
5641  return 0;
5642  }
5643 
5644  i = ao2_iterator_init(sessions, 0);
5645  while ((session = ao2_iterator_next(&i))) {
5646  ao2_lock(session);
5647  if ((session->managerid == ident) && (session->readperm & perm)) {
5648  result = 1;
5649  ao2_unlock(session);
5650  unref_mansession(session);
5651  break;
5652  }
5653  ao2_unlock(session);
5654  unref_mansession(session);
5655  }
5657  return result;
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
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:1330
#define ao2_lock(a)
Definition: astobj2.h:488
uint32_t managerid
Definition: manager.c:976
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
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 5659 of file manager.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, mansession_session::managerid, unref_mansession(), and mansession_session::writeperm.

Referenced by http_post_callback().

5661 {
5662  int result = 0;
5663  struct mansession_session *session;
5664  struct ao2_iterator i;
5665 
5666  if (ident == 0) {
5667  return 0;
5668  }
5669 
5670  i = ao2_iterator_init(sessions, 0);
5671  while ((session = ao2_iterator_next(&i))) {
5672  ao2_lock(session);
5673  if ((session->managerid == ident) && (session->writeperm & perm)) {
5674  result = 1;
5675  ao2_unlock(session);
5676  unref_mansession(session);
5677  break;
5678  }
5679  ao2_unlock(session);
5680  unref_mansession(session);
5681  }
5683  return result;
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
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:1330
#define ao2_lock(a)
Definition: astobj2.h:488
uint32_t managerid
Definition: manager.c:976
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
static int auth_http_callback ( struct ast_tcptls_session_instance ser,
enum ast_http_method  method,
enum output_format  format,
struct sockaddr_in *  remote_address,
const char *  uri,
struct ast_variable get_params,
struct ast_variable headers 
)
static

Definition at line 6180 of file manager.c.

References ast_manager_user::a1_hash, ao2_lock, ao2_unlock, ARRAY_LEN, ast_apply_ha(), 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_send(), ast_inet_ntoa(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_malloc, ast_md5_hash(), ast_mutex_destroy, ast_mutex_init, ast_parse_digest(), ast_random(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sockaddr_from_sin, ast_str_append(), ast_str_create(), ast_string_field_free_memory, ast_string_field_init, ast_strlen_zero(), ast_variables_destroy(), ast_verb, mansession_session::authenticated, build_mansession(), ast_http_digest::cnonce, mansession_session::datastores, ast_manager_user::displayconnects, errno, mansession_session::f, mansession::f, mansession_session::fd, mansession::fd, find_session_by_nonce(), FORMAT_HTML, FORMAT_XML, get_manager_by_name_locked(), get_params(), global_realm, grab_last(), ast_manager_user::ha, message::hdrcount, message::headers, 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, mansession_session::oldnonce, process_message(), process_output(), ast_http_digest::qop, mansession_session::readperm, ast_manager_user::readperm, ast_http_digest::response, mansession::session, session_destroy(), mansession_session::sessionstart, mansession_session::sessiontimeout, mansession_session::sin, 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().

6187 {
6188  struct mansession_session *session = NULL;
6189  struct mansession s = { .session = NULL, .tcptls_session = ser };
6190  struct ast_variable *v, *params = get_params;
6191  char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
6192  struct ast_str *http_header = NULL, *out = NULL;
6193  size_t result_size = 512;
6194  struct message m = { 0 };
6195  unsigned int idx;
6196  size_t hdrlen;
6197 
6198  time_t time_now = time(NULL);
6199  unsigned long nonce = 0, nc;
6200  struct ast_http_digest d = { NULL, };
6201  struct ast_manager_user *user = NULL;
6202  int stale = 0;
6203  char resp_hash[256]="";
6204  /* Cache for user data */
6205  char u_username[80];
6206  int u_readperm;
6207  int u_writeperm;
6208  int u_writetimeout;
6209  int u_displayconnects;
6210  struct ast_sockaddr addr;
6211 
6212  if (method != AST_HTTP_GET && method != AST_HTTP_HEAD && method != AST_HTTP_POST) {
6213  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
6214  return -1;
6215  }
6216 
6217  /* Find "Authorization: " header */
6218  for (v = headers; v; v = v->next) {
6219  if (!strcasecmp(v->name, "Authorization")) {
6220  break;
6221  }
6222  }
6223 
6224  if (!v || ast_strlen_zero(v->value)) {
6225  goto out_401; /* Authorization Header not present - send auth request */
6226  }
6227 
6228  /* Digest found - parse */
6229  if (ast_string_field_init(&d, 128)) {
6230  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)\n");
6231  return -1;
6232  }
6233 
6234  if (ast_parse_digest(v->value, &d, 0, 1)) {
6235  /* Error in Digest - send new one */
6236  nonce = 0;
6237  goto out_401;
6238  }
6239  if (sscanf(d.nonce, "%30lx", &nonce) != 1) {
6240  ast_log(LOG_WARNING, "Received incorrect nonce in Digest <%s>\n", d.nonce);
6241  nonce = 0;
6242  goto out_401;
6243  }
6244 
6247  if(!user) {
6249  ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(remote_address->sin_addr), d.username);
6250  nonce = 0;
6251  goto out_401;
6252  }
6253 
6254  ast_sockaddr_from_sin(&addr, remote_address);
6255  /* --- We have User for this auth, now check ACL */
6256  if (user->ha && !ast_apply_ha(user->ha, &addr)) {
6258  ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(remote_address->sin_addr), d.username);
6259  ast_http_error(ser, 403, "Permission denied", "Permission denied\n");
6260  return -1;
6261  }
6262 
6263  /* --- We have auth, so check it */
6264 
6265  /* compute the expected response to compare with what we received */
6266  {
6267  char a2[256];
6268  char a2_hash[256];
6269  char resp[256];
6270 
6271  /* XXX Now request method are hardcoded in A2 */
6272  snprintf(a2, sizeof(a2), "%s:%s", ast_get_http_method(method), d.uri);
6273  ast_md5_hash(a2_hash, a2);
6274 
6275  if (d.qop) {
6276  /* RFC 2617 */
6277  snprintf(resp, sizeof(resp), "%s:%08lx:%s:%s:auth:%s", user->a1_hash, nonce, d.nc, d.cnonce, a2_hash);
6278  } else {
6279  /* RFC 2069 */
6280  snprintf(resp, sizeof(resp), "%s:%08lx:%s", user->a1_hash, nonce, a2_hash);
6281  }
6282  ast_md5_hash(resp_hash, resp);
6283  }
6284 
6285  if (strncasecmp(d.response, resp_hash, strlen(resp_hash))) {
6286  /* Something was wrong, so give the client to try with a new challenge */
6288  nonce = 0;
6289  goto out_401;
6290  }
6291 
6292  /*
6293  * User are pass Digest authentication.
6294  * Now, cache the user data and unlock user list.
6295  */
6296  ast_copy_string(u_username, user->username, sizeof(u_username));
6297  u_readperm = user->readperm;
6298  u_writeperm = user->writeperm;
6299  u_displayconnects = user->displayconnects;
6300  u_writetimeout = user->writetimeout;
6302 
6303  if (!(session = find_session_by_nonce(d.username, nonce, &stale))) {
6304  /*
6305  * Create new session.
6306  * While it is not in the list we don't need any locking
6307  */
6308  if (!(session = build_mansession(*remote_address))) {
6309  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)\n");
6310  return -1;
6311  }
6312  ao2_lock(session);
6313 
6314  ast_copy_string(session->username, u_username, sizeof(session->username));
6315  session->managerid = nonce;
6316  session->last_ev = grab_last();
6318 
6319  session->readperm = u_readperm;
6320  session->writeperm = u_writeperm;
6321  session->writetimeout = u_writetimeout;
6322 
6323  if (u_displayconnects) {
6324  ast_verb(2, "HTTP Manager '%s' logged in from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
6325  }
6326  session->noncetime = session->sessionstart = time_now;
6327  session->authenticated = 1;
6328  } else if (stale) {
6329  /*
6330  * Session found, but nonce is stale.
6331  *
6332  * This could be because an old request (w/old nonce) arrived.
6333  *
6334  * This may be as the result of http proxy usage (separate delay or
6335  * multipath) or in a situation where a page was refreshed too quickly
6336  * (seen in Firefox).
6337  *
6338  * In this situation, we repeat the 401 auth with the current nonce
6339  * value.
6340  */
6341  nonce = session->managerid;
6342  ao2_unlock(session);
6343  stale = 1;
6344  goto out_401;
6345  } else {
6346  sscanf(d.nc, "%30lx", &nc);
6347  if (session->nc >= nc || ((time_now - session->noncetime) > 62) ) {
6348  /*
6349  * Nonce time expired (> 2 minutes) or something wrong with nonce
6350  * counter.
6351  *
6352  * Create new nonce key and resend Digest auth request. Old nonce
6353  * is saved for stale checking...
6354  */
6355  session->nc = 0; /* Reset nonce counter */
6356  session->oldnonce = session->managerid;
6357  nonce = session->managerid = ast_random();
6358  session->noncetime = time_now;
6359  ao2_unlock(session);
6360  stale = 1;
6361  goto out_401;
6362  } else {
6363  session->nc = nc; /* All OK, save nonce counter */
6364  }
6365  }
6366 
6367 
6368  /* Reset session timeout. */
6369  session->sessiontimeout = time(NULL) + (httptimeout > 5 ? httptimeout : 5);
6370  ao2_unlock(session);
6371 
6372  ast_mutex_init(&s.lock);
6373  s.session = session;
6374  s.fd = mkstemp(template); /* create a temporary file for command output */
6375  unlink(template);
6376  if (s.fd <= -1) {
6377  ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)\n");
6378  goto auth_callback_out;
6379  }
6380  s.f = fdopen(s.fd, "w+");
6381  if (!s.f) {
6382  ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
6383  ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)\n");
6384  close(s.fd);
6385  goto auth_callback_out;
6386  }
6387 
6388  if (method == AST_HTTP_POST) {
6389  params = ast_http_get_post_vars(ser, headers);
6390  }
6391 
6392  for (v = params; v && m.hdrcount < ARRAY_LEN(m.headers); v = v->next) {
6393  hdrlen = strlen(v->name) + strlen(v->value) + 3;
6394  m.headers[m.hdrcount] = ast_malloc(hdrlen);
6395  if (!m.headers[m.hdrcount]) {
6396  /* Allocation failure */
6397  continue;
6398  }
6399  snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", v->name, v->value);
6400  ast_verb(4, "HTTP Manager add header %s\n", m.headers[m.hdrcount]);
6401  ++m.hdrcount;
6402  }
6403 
6404  if (process_message(&s, &m)) {
6405  if (u_displayconnects) {
6406  ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
6407  }
6408 
6409  session->needdestroy = 1;
6410  }
6411 
6412  /* Free request headers. */
6413  for (idx = 0; idx < m.hdrcount; ++idx) {
6414  ast_free((void *) m.headers[idx]);
6415  m.headers[idx] = NULL;
6416  }
6417 
6418  if (s.f) {
6419  result_size = ftell(s.f); /* Calculate approx. size of result */
6420  }
6421 
6422  http_header = ast_str_create(80);
6423  out = ast_str_create(result_size * 2 + 512);
6424 
6425  if (http_header == NULL || out == NULL) {
6426  ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)\n");
6427  goto auth_callback_out;
6428  }
6429 
6430  ast_str_append(&http_header, 0, "Content-type: text/%s\r\n", contenttype[format]);
6431 
6432  if (format == FORMAT_XML) {
6433  ast_str_append(&out, 0, "<ajax-response>\n");
6434  } else if (format == FORMAT_HTML) {
6435  ast_str_append(&out, 0,
6436  "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
6437  "<html><head>\r\n"
6438  "<title>Asterisk&trade; Manager Interface</title>\r\n"
6439  "</head><body style=\"background-color: #ffffff;\">\r\n"
6440  "<form method=\"POST\">\r\n"
6441  "<table align=\"center\" style=\"background-color: #f1f1f1;\" width=\"500\">\r\n"
6442  "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\"><h1>Manager Tester</h1></th></tr>\r\n"
6443  "<tr><th colspan=\"2\" style=\"background-color: #f1f1ff;\">Action: <input name=\"action\" /> Cmd: <input name=\"command\" /><br>"
6444  "<input type=\"submit\" value=\"Send request\" /></th></tr>\r\n");
6445  }
6446 
6447  process_output(&s, &out, params, format);
6448 
6449  if (format == FORMAT_XML) {
6450  ast_str_append(&out, 0, "</ajax-response>\n");
6451  } else if (format == FORMAT_HTML) {
6452  ast_str_append(&out, 0, "</table></form></body></html>\r\n");
6453  }
6454 
6455  ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
6456  http_header = out = NULL;
6457 
6458 auth_callback_out:
6459  ast_mutex_destroy(&s.lock);
6460 
6461  /* Clear resources and unlock manager session */
6462  if (method == AST_HTTP_POST && params) {
6463  ast_variables_destroy(params);
6464  }
6465 
6466  ast_free(http_header);
6467  ast_free(out);
6468 
6469  ao2_lock(session);
6470  if (session->f) {
6471  fclose(session->f);
6472  }
6473  session->f = NULL;
6474  session->fd = -1;
6475  ao2_unlock(session);
6476 
6477  if (session->needdestroy) {
6478  ast_debug(1, "Need destroy, doing it now!\n");
6479  session_destroy(session);
6480  }
6482  return 0;
6483 
6484 out_401:
6485  if (!nonce) {
6486  nonce = ast_random();
6487  }
6488 
6489  ast_http_auth(ser, global_realm, nonce, nonce, stale, NULL);
6491  return 0;
const ast_string_field cnonce
Definition: utils.h:714
FILE * f
Definition: manager.c:1015
char username[80]
Definition: manager.c:1040
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char username[80]
Definition: manager.c:980
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:506
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 &quot;401 Unauthorized&quot; response and close socket.
Definition: http.c:468
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
int ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
Definition: acl.c:518
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:1435
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct eventqent * last_ev
Definition: manager.c:989
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct sockaddr_in sin
Definition: manager.c:970
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:900
struct ast_ha * ha
Definition: manager.c:1042
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ao2_unlock(a)
Definition: astobj2.h:497
ast_mutex_t lock
Definition: manager.c:1020
const ast_string_field username
Definition: utils.h:714
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static const char *const contenttype[]
Definition: manager.c:5547
user descriptor, as read from the config file.
Definition: manager.c:1039
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:5939
Socket address structure.
Definition: netsock2.h:63
#define ast_verb(level,...)
Definition: logger.h:243
static int process_message(struct mansession *s, const struct message *m)
Definition: manager.c:4762
static int httptimeout
Definition: manager.c:902
time_t sessiontimeout
Definition: manager.c:979
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, const int fd, unsigned int static_content)
Generic function for sending http/1.1 response.
Definition: http.c:393
const ast_string_field uri
Definition: utils.h:714
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
const ast_string_field response
Definition: utils.h:714
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
long int ast_random(void)
Definition: utils.c:1640
#define ao2_lock(a)
Definition: astobj2.h:488
char * a1_hash
Definition: manager.c:1050
static struct mansession_session * find_session_by_nonce(const char *username, unsigned long nonce, int *stale)
Definition: manager.c:5591
const char * name
Definition: config.h:77
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
time_t noncetime
Definition: manager.c:993
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const ast_string_field nc
Definition: utils.h:714
#define LOG_NOTICE
Definition: logger.h:133
int errno
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define ast_free(a)
Definition: astmm.h:97
unsigned long nc
Definition: manager.c:997
uint32_t managerid
Definition: manager.c:976
const char * ast_get_http_method(enum ast_http_method method) attribute_pure
Return http method name string.
Definition: http.c:153
structure to hold users read from users.conf
static size_t get_params(va_list ap, const char ***params_ptr, const char ***vals_ptr, int warn)
Helper function to parse a va_list object into 2 dynamic arrays of strings, parameters and values...
const ast_string_field nonce
Definition: utils.h:714
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
static struct eventqent * grab_last(void)
Definition: manager.c:1121
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
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:624
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:135
static void session_destroy(struct mansession_session *s)
Definition: manager.c:1411
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic)
Parse digest authorization header.
Definition: utils.c:2216
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:912
struct mansession_session * session
Definition: manager.c:1013
struct ast_variable * next
Definition: config.h:82
static struct mansession_session * build_mansession(struct sockaddr_in sin)
Allocate manager session structure and add it to the list of sessions.
Definition: manager.c:1375
#define ast_mutex_init(pmutex)
Definition: lock.h:152
#define ast_mutex_destroy(a)
Definition: lock.h:154
time_t sessionstart
Definition: manager.c:977
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: utils.c:245
#define ast_malloc(a)
Definition: astmm.h:91
unsigned int hdrcount
Definition: manager.h:134
static snd_pcm_format_t format
Definition: chan_alsa.c:93
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
unsigned long oldnonce
Definition: manager.c:996
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 6552 of file manager.c.

References ast_sockaddr_from_sin, ast_sockaddr_to_sin, auth_http_callback(), FORMAT_HTML, and ast_tcptls_session_instance::remote_address.

6554 {
6555  int retval;
6556  struct sockaddr_in ser_remote_address_tmp;
6557 
6558  ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp);
6559  retval = auth_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
6560  ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp);
6561  return retval;
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
static int auth_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, struct sockaddr_in *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:6180
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
struct ast_sockaddr remote_address
Definition: tcptls.h:207
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 6563 of file manager.c.

References ast_sockaddr_from_sin, ast_sockaddr_to_sin, auth_http_callback(), FORMAT_XML, and ast_tcptls_session_instance::remote_address.

6565 {
6566  int retval;
6567  struct sockaddr_in ser_remote_address_tmp;
6568 
6569  ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp);
6570  retval = auth_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
6571  ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp);
6572  return retval;
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
static int auth_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, struct sockaddr_in *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:6180
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
struct ast_sockaddr remote_address
Definition: tcptls.h:207
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 6574 of file manager.c.

References ast_sockaddr_from_sin, ast_sockaddr_to_sin, auth_http_callback(), FORMAT_RAW, and ast_tcptls_session_instance::remote_address.

6576 {
6577  int retval;
6578  struct sockaddr_in ser_remote_address_tmp;
6579 
6580  ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp);
6581  retval = auth_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
6582  ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp);
6583  return retval;
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
static int auth_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, struct sockaddr_in *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:6180
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
struct ast_sockaddr remote_address
Definition: tcptls.h:207
static void close_mansession_file ( struct mansession s)
static

Definition at line 5915 of file manager.c.

References ast_log(), errno, mansession::f, mansession::fd, and LOG_ERROR.

Referenced by process_output().

5917 {
5918  if (s->f) {
5919  if (fclose(s->f)) {
5920  ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
5921  }
5922  s->f = NULL;
5923  s->fd = -1;
5924  } else if (s->fd != -1) {
5925  /*
5926  * Issuing shutdown() is necessary here to avoid a race
5927  * condition where the last data written may not appear
5928  * in the TCP stream. See ASTERISK-23548
5929  */
5930  shutdown(s->fd, SHUT_RDWR);
5931  if (close(s->fd)) {
5932  ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
5933  }
5934  s->fd = -1;
5935  } else {
5936  ast_log(LOG_ERROR, "Attempted to close file/file descriptor on mansession without a valid file or file descriptor.\n");
5937  }
FILE * f
Definition: manager.c:1015
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
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 5558 of file manager.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_atomic_fetchadd_int(), mansession_session::inuse, mansession_session::managerid, mansession_session::needdestroy, and unref_mansession().

Referenced by astman_is_authed(), and generic_http_callback().

5560 {
5561  struct mansession_session *session;
5562  struct ao2_iterator i;
5563 
5564  if (ident == 0) {
5565  return NULL;
5566  }
5567 
5568  i = ao2_iterator_init(sessions, 0);
5569  while ((session = ao2_iterator_next(&i))) {
5570  ao2_lock(session);
5571  if (session->managerid == ident && !session->needdestroy) {
5572  ast_atomic_fetchadd_int(&session->inuse, incinuse ? 1 : 0);
5573  break;
5574  }
5575  ao2_unlock(session);
5576  unref_mansession(session);
5577  }
5579 
5580  return session;
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
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:1330
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
#define ao2_lock(a)
Definition: astobj2.h:488
uint32_t managerid
Definition: manager.c:976
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
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 5591 of file manager.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, mansession_session::managerid, mansession_session::oldnonce, unref_mansession(), and mansession_session::username.

Referenced by auth_http_callback().

5593 {
5594  struct mansession_session *session;
5595  struct ao2_iterator i;
5596 
5597  if (nonce == 0 || username == NULL || stale == NULL) {
5598  return NULL;
5599  }
5600 
5601  i = ao2_iterator_init(sessions, 0);
5602  while ((session = ao2_iterator_next(&i))) {
5603  ao2_lock(session);
5604  if (!strcasecmp(session->username, username) && session->managerid == nonce) {
5605  *stale = 0;
5606  break;
5607  } else if (!strcasecmp(session->username, username) && session->oldnonce == nonce) {
5608  *stale = 1;
5609  break;
5610  }
5611  ao2_unlock(session);
5612  unref_mansession(session);
5613  }
5615  return session;
char username[80]
Definition: manager.c:980
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
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:1330
#define ao2_lock(a)
Definition: astobj2.h:488
uint32_t managerid
Definition: manager.c:976
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
unsigned long oldnonce
Definition: manager.c:996
static int generic_http_callback ( struct ast_tcptls_session_instance ser,
enum ast_http_method  method,
enum output_format  format,
struct sockaddr_in *  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 5969 of file manager.c.

References ao2_lock, ao2_unlock, ARRAY_LEN, ast_debug, ast_free, ast_http_error(), AST_HTTP_GET, ast_http_get_cookies(), ast_http_get_post_vars(), AST_HTTP_HEAD, AST_HTTP_POST, ast_http_send(), ast_inet_ntoa(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_malloc, ast_mutex_destroy, ast_mutex_init, AST_PTHREADT_NULL, ast_random(), ast_str_append(), ast_str_create(), ast_variables_destroy(), ast_verb, mansession_session::authenticated, build_mansession(), errno, mansession_session::f, mansession::f, mansession_session::fd, mansession::fd, find_session(), FORMAT_HTML, FORMAT_XML, get_params(), grab_last(), message::hdrcount, message::headers, mansession_session::inuse, mansession::lock, LOG_WARNING, manager_displayconnects(), mansession_session::managerid, ast_variable::name, mansession_session::needdestroy, ast_variable::next, process_message(), process_output(), ROW_FMT, mansession_session::send_events, mansession::session, session_destroy(), mansession_session::sessiontimeout, mansession_session::sin, TEST_STRING, mansession_session::username, ast_variable::value, and mansession_session::waiting_thread.

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

5976 {
5977  struct mansession s = { .session = NULL, .tcptls_session = ser };
5978  struct mansession_session *session = NULL;
5979  uint32_t ident = 0;
5980  int blastaway = 0;
5981  struct ast_variable *v, *cookies, *params = get_params;
5982  char template[] = "/tmp/ast-http-XXXXXX"; /* template for temporary file */
5983  struct ast_str *http_header = NULL, *out = NULL;
5984  struct message m = { 0 };
5985  unsigned int idx;
5986  size_t hdrlen;
5987 
5988  if (method != AST_HTTP_GET && method != AST_HTTP_HEAD && method != AST_HTTP_POST) {
5989  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
5990  return -1;
5991  }
5992 
5993  cookies = ast_http_get_cookies(headers);
5994  for (v = cookies; v; v = v->next) {
5995  if (!strcasecmp(v->name, "mansession_id")) {
5996  sscanf(v->value, "%30x", &ident);
5997  break;
5998  }
5999  }
6000  if (cookies) {
6001  ast_variables_destroy(cookies);
6002  }
6003 
6004  if (!(session = find_session(ident, 1))) {
6005 
6006  /**/
6007  /* Create new session.
6008  * While it is not in the list we don't need any locking
6009  */
6010  if (!(session = build_mansession(*remote_address))) {
6011  ast_http_error(ser, 500, "Server Error", "Internal Server Error (out of memory)\n");
6012  return -1;
6013  }
6014  ao2_lock(session);
6015  session->sin = *remote_address;
6016  session->fd = -1;
6017  session->waiting_thread = AST_PTHREADT_NULL;
6018  session->send_events = 0;
6019  session->inuse = 1;
6020  /*!\note There is approximately a 1 in 1.8E19 chance that the following
6021  * calculation will produce 0, which is an invalid ID, but due to the
6022  * properties of the rand() function (and the constantcy of s), that
6023  * won't happen twice in a row.
6024  */
6025  while ((session->managerid = ast_random() ^ (unsigned long) session) == 0);
6026  session->last_ev = grab_last();
6027  AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
6028  }
6029  ao2_unlock(session);
6030 
6031  http_header = ast_str_create(128);
6032  out = ast_str_create(2048);
6033 
6034  ast_mutex_init(&s.lock);
6035 
6036  if (http_header == NULL || out == NULL) {
6037  ast_http_error(ser, 500, "Server Error", "Internal Server Error (ast_str_create() out of memory)\n");
6038  goto generic_callback_out;
6039  }
6040 
6041  s.session = session;
6042  s.fd = mkstemp(template); /* create a temporary file for command output */
6043  unlink(template);
6044  if (s.fd <= -1) {
6045  ast_http_error(ser, 500, "Server Error", "Internal Server Error (mkstemp failed)\n");
6046  goto generic_callback_out;
6047  }
6048  s.f = fdopen(s.fd, "w+");
6049  if (!s.f) {
6050  ast_log(LOG_WARNING, "HTTP Manager, fdopen failed: %s!\n", strerror(errno));
6051  ast_http_error(ser, 500, "Server Error", "Internal Server Error (fdopen failed)\n");
6052  close(s.fd);
6053  goto generic_callback_out;
6054  }
6055 
6056  if (method == AST_HTTP_POST) {
6057  params = ast_http_get_post_vars(ser, headers);
6058  }
6059 
6060  for (v = params; v && m.hdrcount < ARRAY_LEN(m.headers); v = v->next) {
6061  hdrlen = strlen(v->name) + strlen(v->value) + 3;
6062  m.headers[m.hdrcount] = ast_malloc(hdrlen);
6063  if (!m.headers[m.hdrcount]) {
6064  /* Allocation failure */
6065  continue;
6066  }
6067  snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", v->name, v->value);
6068  ast_debug(1, "HTTP Manager add header %s\n", m.headers[m.hdrcount]);
6069  ++m.hdrcount;
6070  }
6071 
6072  if (process_message(&s, &m)) {
6073  if (session->authenticated) {
6074  if (manager_displayconnects(session)) {
6075  ast_verb(2, "HTTP Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
6076  }
6077  } else {
6078  if (displayconnects) {
6079  ast_verb(2, "HTTP Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr));
6080  }
6081  }
6082  session->needdestroy = 1;
6083  }
6084 
6085  /* Free request headers. */
6086  for (idx = 0; idx < m.hdrcount; ++idx) {
6087  ast_free((void *) m.headers[idx]);
6088  m.headers[idx] = NULL;
6089  }
6090 
6091  ast_str_append(&http_header, 0,
6092  "Content-type: text/%s\r\n"
6093  "Cache-Control: no-cache;\r\n"
6094  "Set-Cookie: mansession_id=\"%08x\"; Version=1; Max-Age=%d\r\n"
6095  "Pragma: SuppressEvents\r\n",
6097  session->managerid, httptimeout);
6098 
6099  if (format == FORMAT_XML) {
6100  ast_str_append(&out, 0, "<ajax-response>\n");
6101  } else if (format == FORMAT_HTML) {
6102  /*
6103  * When handling AMI-over-HTTP in HTML format, we provide a simple form for
6104  * debugging purposes. This HTML code should not be here, we
6105  * should read from some config file...
6106  */
6107 
6108 #define ROW_FMT "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\">%s</td></tr>\r\n"
6109 #define TEST_STRING \
6110  "<form action=\"manager\" method=\"post\">\n\
6111  Action: <select name=\"action\">\n\
6112  <option value=\"\">-----&gt;</option>\n\
6113  <option value=\"login\">login</option>\n\
6114  <option value=\"command\">Command</option>\n\
6115  <option value=\"waitevent\">waitevent</option>\n\
6116  <option value=\"listcommands\">listcommands</option>\n\
6117  </select>\n\
6118  or <input name=\"action\"><br/>\n\
6119  CLI Command <input name=\"command\"><br>\n\
6120  user <input name=\"username\"> pass <input type=\"password\" name=\"secret\"><br>\n\
6121  <input type=\"submit\">\n</form>\n"
6122 
6123  ast_str_append(&out, 0, "<title>Asterisk&trade; Manager Interface</title>");
6124  ast_str_append(&out, 0, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n");
6125  ast_str_append(&out, 0, ROW_FMT, "<h1>Manager Tester</h1>");
6126  ast_str_append(&out, 0, ROW_FMT, TEST_STRING);
6127  }
6128 
6129  process_output(&s, &out, params, format);
6130 
6131  if (format == FORMAT_XML) {
6132  ast_str_append(&out, 0, "</ajax-response>\n");
6133  } else if (format == FORMAT_HTML) {
6134  ast_str_append(&out, 0, "</table></body>\r\n");
6135  }
6136 
6137  ao2_lock(session);
6138  /* Reset HTTP timeout. If we're not authenticated, keep it extremely short */
6139  session->sessiontimeout = time(NULL) + ((session->authenticated || httptimeout < 5) ? httptimeout : 5);
6140 
6141  if (session->needdestroy) {
6142  if (session->inuse == 1) {
6143  ast_debug(1, "Need destroy, doing it now!\n");
6144  blastaway = 1;
6145  } else {
6146  ast_debug(1, "Need destroy, but can't do it yet!\n");
6147  if (session->waiting_thread != AST_PTHREADT_NULL) {
6148  pthread_kill(session->waiting_thread, SIGURG);
6149  }
6150  session->inuse--;
6151  }
6152  } else {
6153  session->inuse--;
6154  }
6155  ao2_unlock(session);
6156 
6157  ast_http_send(ser, method, 200, NULL, http_header, out, 0, 0);
6158  http_header = out = NULL;
6159 
6160 generic_callback_out:
6161  ast_mutex_destroy(&s.lock);
6162 
6163  /* Clear resource */
6164 
6165  if (method == AST_HTTP_POST && params) {
6166  ast_variables_destroy(params);
6167  }
6168  ast_free(http_header);
6169  ast_free(out);
6170 
6171  if (session && blastaway) {
6172  session_destroy(session);
6173  } else if (session && session->f) {
6174  fclose(session->f);
6175  session->f = NULL;
6176  }
6177 
6178  return 0;
FILE * f
Definition: manager.c:1015
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char username[80]
Definition: manager.c:980
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:506
static int displayconnects
Definition: manager.c:899
pthread_t waiting_thread
Definition: manager.c:975
#define LOG_WARNING
Definition: logger.h:144
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct sockaddr_in sin
Definition: manager.c:970
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:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ao2_unlock(a)
Definition: astobj2.h:497
ast_mutex_t lock
Definition: manager.c:1020
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static const char *const contenttype[]
Definition: manager.c:5547
static void process_output(struct mansession *s, struct ast_str **out, struct ast_variable *params, enum output_format format)
Definition: manager.c:5939
#define ast_verb(level,...)
Definition: logger.h:243
static int process_message(struct mansession *s, const struct message *m)
Definition: manager.c:4762
static int httptimeout
Definition: manager.c:902
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:5558
#define TEST_STRING
time_t sessiontimeout
Definition: manager.c:979
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, const int fd, unsigned int static_content)
Generic function for sending http/1.1 response.
Definition: http.c:393
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
#define AST_PTHREADT_NULL
Definition: lock.h:65
long int ast_random(void)
Definition: utils.c:1640
#define ao2_lock(a)
Definition: astobj2.h:488
const char * name
Definition: config.h:77
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define ast_free(a)
Definition: astmm.h:97
uint32_t managerid
Definition: manager.c:976
static size_t get_params(va_list ap, const char ***params_ptr, const char ***vals_ptr, int warn)
Helper function to parse a va_list object into 2 dynamic arrays of strings, parameters and values...
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
static struct eventqent * grab_last(void)
Definition: manager.c:1121
#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:624
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:135
static void session_destroy(struct mansession_session *s)
Definition: manager.c:1411
struct mansession_session * session
Definition: manager.c:1013
struct ast_variable * next
Definition: config.h:82
static struct mansession_session * build_mansession(struct sockaddr_in sin)
Allocate manager session structure and add it to the list of sessions.
Definition: manager.c:1375
#define ast_mutex_init(pmutex)
Definition: lock.h:152
#define ast_mutex_destroy(a)
Definition: lock.h:154
#define ast_malloc(a)
Definition: astmm.h:91
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1452
unsigned int hdrcount
Definition: manager.h:134
static snd_pcm_format_t format
Definition: chan_alsa.c:93
struct ast_variable * ast_http_get_cookies(struct ast_variable *headers)
Get cookie from Request headers.
Definition: http.c:862
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 6646 of file manager.c.

References 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, ast_tls_config::enabled, ast_cli_args::fd, FORMAT, FORMAT2, ast_tcptls_session_args::local_address, ast_tls_config::pvtfile, S_OR, and ast_cli_entry::usage.

6648 {
6649  switch (cmd) {
6650  case CLI_INIT:
6651  e->command = "manager show settings";
6652  e->usage =
6653  "Usage: manager show settings\n"
6654  " Provides detailed list of the configuration of the Manager.\n";
6655  return NULL;
6656  case CLI_GENERATE:
6657  return NULL;
6658  }
6659 #define FORMAT " %-25.25s %-15.15s\n"
6660 #define FORMAT2 " %-25.25s %-15d\n"
6661  if (a->argc != 3) {
6662  return CLI_SHOWUSAGE;
6663  }
6664  ast_cli(a->fd, "\nGlobal Settings:\n");
6665  ast_cli(a->fd, "----------------\n");
6666  ast_cli(a->fd, FORMAT, "Manager (AMI):", AST_CLI_YESNO(manager_enabled));
6667  ast_cli(a->fd, FORMAT, "Web Manager (AMI/HTTP):", AST_CLI_YESNO(webmanager_enabled));
6668  ast_cli(a->fd, FORMAT, "TCP Bindaddress:", manager_enabled != 0 ? ast_sockaddr_stringify(&ami_desc.local_address) : "Disabled");
6669  ast_cli(a->fd, FORMAT2, "HTTP Timeout (minutes):", httptimeout);
6670  ast_cli(a->fd, FORMAT, "TLS Enable:", AST_CLI_YESNO(ami_tls_cfg.enabled));
6671  ast_cli(a->fd, FORMAT, "TLS Bindaddress:", ami_tls_cfg.enabled != 0 ? ast_sockaddr_stringify(&amis_desc.local_address) : "Disabled");
6672  ast_cli(a->fd, FORMAT, "TLS Certfile:", ami_tls_cfg.certfile);
6673  ast_cli(a->fd, FORMAT, "TLS Privatekey:", ami_tls_cfg.pvtfile);
6674  ast_cli(a->fd, FORMAT, "TLS Cipher:", ami_tls_cfg.cipher);
6675  ast_cli(a->fd, FORMAT, "Allow multiple login:", AST_CLI_YESNO(allowmultiplelogin));
6676  ast_cli(a->fd, FORMAT, "Display connects:", AST_CLI_YESNO(displayconnects));
6677  ast_cli(a->fd, FORMAT, "Timestamp events:", AST_CLI_YESNO(timestampevents));
6678  ast_cli(a->fd, FORMAT, "Channel vars:", S_OR(manager_channelvars, ""));
6679  ast_cli(a->fd, FORMAT, "Debug:", AST_CLI_YESNO(manager_debug));
6680 #undef FORMAT
6681 #undef FORMAT2
6682 
6683  return CLI_SUCCESS;
char * pvtfile
Definition: tcptls.h:88
static int displayconnects
Definition: manager.c:899
const int argc
Definition: cli.h:154
Definition: cli.h:146
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:6624
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int httptimeout
Definition: manager.c:902
const int fd
Definition: cli.h:153
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:6623
static int timestampevents
Definition: manager.c:901
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:6635
static int manager_debug
Definition: manager.c:906
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define FORMAT
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
char * command
Definition: cli.h:180
char * certfile
Definition: tcptls.h:87
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int manager_enabled
Definition: manager.c:904
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static int allowmultiplelogin
Definition: manager.c:900
#define AST_CLI_YESNO(x)
return Yes or No depending on the argument. This is used in many places in CLI command, having a function to generate this helps maintaining a consistent output (and possibly emitting the output in other languages, at some point).
Definition: cli.h:65
struct ast_sockaddr local_address
Definition: tcptls.h:124
static int webmanager_enabled
Definition: manager.c:905
#define FORMAT2
char * cipher
Definition: tcptls.h:89
static char * manager_channelvars
Definition: manager.c:909
int enabled
Definition: tcptls.h:86
int init_manager ( void  )

Called by Asterisk initialization.

Definition at line 7262 of file manager.c.

References __init_manager().

Referenced by main().

7264 {
7265  return __init_manager(0);
static int __init_manager(int reload)
Definition: manager.c:6839
static void load_channelvars ( struct ast_variable var)
static

Definition at line 6705 of file manager.c.

References ast_calloc, ast_free, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_strdupa, free_channelvars(), manager_channel_variable::isfunc, manager_channel_variable::name, manager_channel_variable::next, strsep(), and ast_variable::value.

Referenced by __init_manager().

6707 {
6708  struct manager_channel_variable *mcv;
6709  char *remaining = ast_strdupa(var->value);
6710  char *next;
6711 
6714 
6715  /*
6716  * XXX TODO: To allow dialplan functions to have more than one
6717  * parameter requires eliminating the '|' as a separator so we
6718  * could use AST_STANDARD_APP_ARGS() to separate items.
6719  */
6720  free_channelvars();
6722  while ((next = strsep(&remaining, ",|"))) {
6723  if (!(mcv = ast_calloc(1, sizeof(*mcv) + strlen(next) + 1))) {
6724  break;
6725  }
6726  strcpy(mcv->name, next); /* SAFE */
6727  if (strchr(next, '(')) {
6728  mcv->isfunc = 1;
6729  }
6731  }
char * strsep(char **str, const char *delims)
#define ast_strdup(a)
Definition: astmm.h:109
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * value
Definition: config.h:79
unsigned int isfunc
Definition: manager.c:1027
struct manager_channel_variable::@288 entry
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define ast_free(a)
Definition: astmm.h:97
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define ast_calloc(a, b)
Definition: astmm.h:82
static void free_channelvars(void)
Definition: manager.c:7252
struct manager_channel_variable * next
Definition: manager.c:1026
static char * manager_channelvars
Definition: manager.c:909
static void manager_free_user ( struct ast_manager_user user)
static

Definition at line 6735 of file manager.c.

References ast_manager_user::a1_hash, ao2_t_ref, ast_free, ast_free_ha(), ast_manager_user::blackfilters, ast_manager_user::ha, ast_manager_user::secret, and ast_manager_user::whitefilters.

Referenced by __init_manager(), and manager_shutdown().

6737 {
6738  ast_free(user->a1_hash);
6739  ast_free(user->secret);
6740  if (user->whitefilters) {
6741  ao2_t_ref(user->whitefilters, -1, "decrement ref for white container, should be last one");
6742  }
6743  if (user->blackfilters) {
6744  ao2_t_ref(user->blackfilters, -1, "decrement ref for black container, should be last one");
6745  }
6746  ast_free_ha(user->ha);
6747  ast_free(user);
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
struct ao2_container * blackfilters
Definition: manager.c:1049
struct ao2_container * whitefilters
Definition: manager.c:1048
struct ast_ha * ha
Definition: manager.c:1042
char * a1_hash
Definition: manager.c:1050
#define ast_free(a)
Definition: astmm.h:97
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:223
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 6493 of file manager.c.

References ast_sockaddr_from_sin, ast_sockaddr_to_sin, FORMAT_HTML, generic_http_callback(), and ast_tcptls_session_instance::remote_address.

6495 {
6496  int retval;
6497  struct sockaddr_in ser_remote_address_tmp;
6498 
6499  ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp);
6500  retval = generic_http_callback(ser, method, FORMAT_HTML, &ser_remote_address_tmp, uri, get_params, headers);
6501  ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp);
6502  return retval;
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
static int generic_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, struct sockaddr_in *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:5969
struct ast_sockaddr remote_address
Definition: tcptls.h:207
static void manager_set_defaults ( void  )
static

Definition at line 6810 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, ast_tls_config::certfile, ast_tls_config::cipher, DEFAULT_AUTHLIMIT, DEFAULT_AUTHTIMEOUT, DEFAULT_BROKENEVENTSACTION, DEFAULT_DISPLAYCONNECTS, DEFAULT_ENABLED, DEFAULT_HTTPTIMEOUT, DEFAULT_MANAGERDEBUG, DEFAULT_REALM, DEFAULT_TIMESTAMPEVENTS, DEFAULT_WEBENABLED, ast_tls_config::enabled, free_channelvars(), global_realm, ast_tcptls_session_args::local_address, ast_tls_config::pvtfile, and S_OR.

Referenced by __init_manager().

6812 {
6822 
6823  /* default values */
6825  sizeof(global_realm));
6828 
6829  ami_tls_cfg.enabled = 0;
6836 
6837  free_channelvars();
char * pvtfile
Definition: tcptls.h:88
#define AST_CERTFILE
Definition: tcptls.h:68
static const int DEFAULT_DISPLAYCONNECTS
Definition: manager.c:891
#define ast_strdup(a)
Definition: astmm.h:109
static int displayconnects
Definition: manager.c:899
static int authtimeout
Definition: manager.c:907
static const int DEFAULT_AUTHTIMEOUT
Definition: manager.c:895
static const int DEFAULT_MANAGERDEBUG
Definition: manager.c:897
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:6624
static const int DEFAULT_BROKENEVENTSACTION
Definition: manager.c:894
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:106
static int httptimeout
Definition: manager.c:902
const char * ast_config_AST_SYSTEM_NAME
Definition: asterisk.c:273
static const int DEFAULT_ENABLED
Definition: manager.c:889
static const int DEFAULT_TIMESTAMPEVENTS
Definition: manager.c:892
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:6623
static int authlimit
Definition: manager.c:908
static int timestampevents
Definition: manager.c:901
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:6635
static int manager_debug
Definition: manager.c:906
static const int DEFAULT_WEBENABLED
Definition: manager.c:890
#define ast_free(a)
Definition: astmm.h:97
static int broken_events_action
Definition: manager.c:903
char * certfile
Definition: tcptls.h:87
#define DEFAULT_REALM
Definition: manager.c:911
static int manager_enabled
Definition: manager.c:904
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static void free_channelvars(void)
Definition: manager.c:7252
static char global_realm[MAXHOSTNAMELEN]
Definition: manager.c:912
static const int DEFAULT_AUTHLIMIT
Definition: manager.c:896
struct ast_sockaddr local_address
Definition: tcptls.h:124
static int webmanager_enabled
Definition: manager.c:905
char * cipher
Definition: tcptls.h:89
static const int DEFAULT_HTTPTIMEOUT
Definition: manager.c:893
int enabled
Definition: tcptls.h:86
static void manager_shutdown ( void  )
static

Definition at line 6750 of file manager.c.

References ami_tls_cfg, ARRAY_LEN, ast_cli_unregister_multiple(), ast_free, AST_LIST_REMOVE_HEAD, ast_manager_unregister(), ast_tcptls_server_stop(), ast_tls_config::certfile, ast_tls_config::cipher, manager_free_user(), ast_tls_config::pvtfile, and user.

Referenced by __init_manager().

6752 {
6753  struct ast_manager_user *user;
6754 
6755  ast_manager_unregister("Ping");
6756  ast_manager_unregister("Events");
6757  ast_manager_unregister("Logoff");
6758  ast_manager_unregister("Login");
6759  ast_manager_unregister("Challenge");
6760  ast_manager_unregister("Hangup");
6761  ast_manager_unregister("Status");
6762  ast_manager_unregister("Setvar");
6763  ast_manager_unregister("Getvar");
6764  ast_manager_unregister("GetConfig");
6765  ast_manager_unregister("GetConfigJSON");
6766  ast_manager_unregister("UpdateConfig");
6767  ast_manager_unregister("CreateConfig");
6768  ast_manager_unregister("ListCategories");
6769  ast_manager_unregister("Redirect");
6770  ast_manager_unregister("Atxfer");
6771  ast_manager_unregister("Originate");
6772  ast_manager_unregister("Command");
6773  ast_manager_unregister("ExtensionState");
6774  ast_manager_unregister("AbsoluteTimeout");
6775  ast_manager_unregister("MailboxStatus");
6776  ast_manager_unregister("MailboxCount");
6777  ast_manager_unregister("ListCommands");
6778  ast_manager_unregister("SendText");
6779  ast_manager_unregister("UserEvent");
6780  ast_manager_unregister("WaitEvent");
6781  ast_manager_unregister("CoreSettings");
6782  ast_manager_unregister("CoreStatus");
6783  ast_manager_unregister("Reload");
6784  ast_manager_unregister("CoreShowChannels");
6785  ast_manager_unregister("ModuleLoad");
6786  ast_manager_unregister("ModuleCheck");
6787  ast_manager_unregister("AOCMessage");
6788  ast_manager_unregister("Filter");
6790 
6793 
6795  ami_tls_cfg.certfile = NULL;
6797  ami_tls_cfg.pvtfile = NULL;
6799  ami_tls_cfg.cipher = NULL;
6800 
6801  /*
6802  * We cannot destroy the global sessions container.
6803  * References to it have no protection against shutdown.
6804  */
6805 
6806  while ((user = AST_LIST_REMOVE_HEAD(&users, list))) {
6807  manager_free_user(user);
6808  }
static char user[512]
char * pvtfile
Definition: tcptls.h:88
#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: cli.c:2177
static struct ast_tcptls_session_args ami_desc
Definition: manager.c:6624
user descriptor, as read from the config file.
Definition: manager.c:1039
list of users found in the config file
static void manager_free_user(struct ast_manager_user *user)
Definition: manager.c:6735
static struct ast_tls_config ami_tls_cfg
Definition: manager.c:6623
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
static struct ast_tcptls_session_args amis_desc
Definition: manager.c:6635
#define ast_free(a)
Definition: astmm.h:97
char * certfile
Definition: tcptls.h:87
static struct ast_cli_entry cli_manager[]
Definition: manager.c:6685
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition: tcptls.c:1058
char * cipher
Definition: tcptls.h:89
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355
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 6504 of file manager.c.

References ast_sockaddr_from_sin, ast_sockaddr_to_sin, FORMAT_XML, generic_http_callback(), and ast_tcptls_session_instance::remote_address.

6506 {
6507  int retval;
6508  struct sockaddr_in ser_remote_address_tmp;
6509 
6510  ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp);
6511  retval = generic_http_callback(ser, method, FORMAT_XML, &ser_remote_address_tmp, uri, get_params, headers);
6512  ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp);
6513  return retval;
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
static int generic_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, struct sockaddr_in *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:5969
struct ast_sockaddr remote_address
Definition: tcptls.h:207
static void process_output ( struct mansession s,
struct ast_str **  out,
struct ast_variable params,
enum output_format  format 
)
static

Definition at line 5939 of file manager.c.

References ast_log(), ast_str_append(), close_mansession_file(), mansession::f, mansession::fd, FORMAT_HTML, FORMAT_XML, LOG_WARNING, and xml_translate().

Referenced by auth_http_callback(), and generic_http_callback().

5941 {
5942  char *buf;
5943  size_t l;
5944 
5945  if (!s->f)
5946  return;
5947 
5948  /* Ensure buffer is NULL-terminated */
5949  fprintf(s->f, "%c", 0);
5950  fflush(s->f);
5951 
5952  if ((l = ftell(s->f)) > 0) {
5953  if (MAP_FAILED == (buf = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, s->fd, 0))) {
5954  ast_log(LOG_WARNING, "mmap failed. Manager output was not processed\n");
5955  } else {
5956  if (format == FORMAT_XML || format == FORMAT_HTML) {
5957  xml_translate(out, buf, params, format);
5958  } else {
5959  ast_str_append(out, 0, "%s", buf);
5960  }
5961  munmap(buf, l);
5962  }
5963  } else if (format == FORMAT_XML || format == FORMAT_HTML) {
5964  xml_translate(out, "", params, format);
5965  }
5966 
FILE * f
Definition: manager.c:1015
static void close_mansession_file(struct mansession *s)
Definition: manager.c:5915
#define LOG_WARNING
Definition: logger.h:144
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:900
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:5798
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static snd_pcm_format_t format
Definition: chan_alsa.c:93
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 6617 of file manager.c.

References purge_events(), and purge_sessions().

6619 {
6620  purge_sessions(1);
6621  purge_events();
static void purge_events(void)
Definition: manager.c:1141
static void purge_sessions(int n_max)
remove at most n_max stale session from the list.
Definition: manager.c:5181
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 6515 of file manager.c.

References ast_sockaddr_from_sin, ast_sockaddr_to_sin, FORMAT_RAW, generic_http_callback(), and ast_tcptls_session_instance::remote_address.

6517 {
6518  int retval;
6519  struct sockaddr_in ser_remote_address_tmp;
6520 
6521  ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp);
6522  retval = generic_http_callback(ser, method, FORMAT_RAW, &ser_remote_address_tmp, uri, get_params, headers);
6523  ast_sockaddr_from_sin(&ser->remote_address, &ser_remote_address_tmp);
6524  return retval;
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
static int generic_http_callback(struct ast_tcptls_session_instance *ser, enum ast_http_method method, enum output_format format, struct sockaddr_in *remote_address, const char *uri, struct ast_variable *get_params, struct ast_variable *headers)
Definition: manager.c:5969
struct ast_sockaddr remote_address
Definition: tcptls.h:207
int reload_manager ( void  )

Called by Asterisk module functions and the CLI command.

Definition at line 7267 of file manager.c.

References __init_manager().

Referenced by handle_manager_reload().

7269 {
7270  return __init_manager(1);
static int __init_manager(int reload)
Definition: manager.c:6839
static int variable_count_cmp_fn ( void *  obj,
void *  vstr,
int  flags 
)
static

Definition at line 5759 of file manager.c.

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

Referenced by xml_translate().

5761 {
5762  /* Due to the simplicity of struct variable_count, it makes no difference
5763  * if you pass in objects or strings, the same operation applies. This is
5764  * due to the fact that the hash occurs on the first element, which means
5765  * the address of both the struct and the string are exactly the same. */
5766  struct variable_count *vc = obj;
5767  char *str = vstr;
5768  return !strcmp(vc->varname, str) ? CMP_MATCH | CMP_STOP : 0;
const char * str
Definition: app_jack.c:144
char * varname
Definition: manager.c:5748
static int variable_count_hash_fn ( const void *  vvc,
const int  flags 
)
static

Definition at line 5752 of file manager.c.

References ast_str_hash(), and variable_count::varname.

Referenced by xml_translate().

5754 {
5755  const struct variable_count *vc = vvc;
5756 
5757  return ast_str_hash(vc->varname);
char * varname
Definition: manager.c:5748
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:949
static void xml_copy_escape ( struct ast_str **  out,
const char *  src,
int  mode 
)
static

Definition at line 5690 of file manager.c.

References ast_str_append(), and ast_frame::src.

Referenced by xml_translate().

5692 {
5693  /* store in a local buffer to avoid calling ast_str_append too often */
5694  char buf[256];
5695  char *dst = buf;
5696  int space = sizeof(buf);
5697  /* repeat until done and nothing to flush */
5698  for ( ; *src || dst != buf ; src++) {
5699  if (*src == '\0' || space < 10) { /* flush */
5700  *dst++ = '\0';
5701  ast_str_append(out, 0, "%s", buf);
5702  dst = buf;
5703  space = sizeof(buf);
5704  if (*src == '\0') {
5705  break;
5706  }
5707  }
5708 
5709  if ( (mode & 2) && !isalnum(*src)) {
5710  *dst++ = '_';
5711  space--;
5712  continue;
5713  }
5714  switch (*src) {
5715  case '<':
5716  strcpy(dst, "&lt;");
5717  dst += 4;
5718  space -= 4;
5719  break;
5720  case '>':
5721  strcpy(dst, "&gt;");
5722  dst += 4;
5723  space -= 4;
5724  break;
5725  case '\"':
5726  strcpy(dst, "&quot;");
5727  dst += 6;
5728  space -= 6;
5729  break;
5730  case '\'':
5731  strcpy(dst, "&apos;");
5732  dst += 6;
5733  space -= 6;
5734  break;
5735  case '&':
5736  strcpy(dst, "&amp;");
5737  dst += 5;
5738  space -= 5;
5739  break;
5740 
5741  default:
5742  *dst++ = mode ? tolower(*src) : *src;
5743  space--;
5744  }
5745  }
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:900
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 5798 of file manager.c.

References ao2_alloc, ao2_container_alloc, 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, strsep(), ast_variable::value, var, variable_count_cmp_fn(), variable_count_hash_fn(), variable_count::varname, and xml_copy_escape().

Referenced by process_output().

5800 {
5801  struct ast_variable *v;
5802  const char *dest = NULL;
5803  char *var, *val;
5804  const char *objtype = NULL;
5805  int in_data = 0; /* parsing data */
5806  int inobj = 0;
5807  int xml = (format == FORMAT_XML);
5808  struct variable_count *vc = NULL;
5809  struct ao2_container *vco = NULL;
5810 
5811  if (xml) {
5812  /* dest and objtype need only for XML format */
5813  for (v = get_vars; v; v = v->next) {
5814  if (!strcasecmp(v->name, "ajaxdest")) {
5815  dest = v->value;
5816  } else if (!strcasecmp(v->name, "ajaxobjtype")) {
5817  objtype = v->value;
5818  }
5819  }
5820  if (ast_strlen_zero(dest)) {
5821  dest = "unknown";
5822  }
5823  if (ast_strlen_zero(objtype)) {
5824  objtype = "generic";
5825  }
5826  }
5827 
5828  /* we want to stop when we find an empty line */
5829  while (in && *in) {
5830  val = strsep(&in, "\r\n"); /* mark start and end of line */
5831  if (in && *in == '\n') { /* remove trailing \n if any */
5832  in++;
5833  }
5834  ast_trim_blanks(val);
5835  ast_debug(5, "inobj %d in_data %d line <%s>\n", inobj, in_data, val);
5836  if (ast_strlen_zero(val)) {
5837  /* empty line */
5838  if (in_data) {
5839  /* close data in Opaque mode */
5840  ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
5841  in_data = 0;
5842  }
5843 
5844  if (inobj) {
5845  /* close block */
5846  ast_str_append(out, 0, xml ? " /></response>\n" :
5847  "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
5848  inobj = 0;
5849  ao2_ref(vco, -1);
5850  vco = NULL;
5851  }
5852  continue;
5853  }
5854 
5855  if (!inobj) {
5856  /* start new block */
5857  if (xml) {
5858  ast_str_append(out, 0, "<response type='object' id='%s'><%s", dest, objtype);
5859  }
5861  inobj = 1;
5862  }
5863 
5864  if (in_data) {
5865  /* Process data field in Opaque mode. This is a
5866  * followup, so we re-add line feeds. */
5867  ast_str_append(out, 0, xml ? "\n" : "<br>\n");
5868  xml_copy_escape(out, val, 0); /* data field */
5869  continue;
5870  }
5871 
5872  /* We expect "Name: value" line here */
5873  var = strsep(&val, ":");
5874  if (val) {
5875  /* found the field name */
5876  val = ast_skip_blanks(val);
5877  ast_trim_blanks(var);
5878  } else {
5879  /* field name not found, switch to opaque mode */
5880  val = var;
5881  var = "Opaque-data";
5882  in_data = 1;
5883  }
5884 
5885 
5886  ast_str_append(out, 0, xml ? " " : "<tr><td>");
5887  if ((vc = ao2_find(vco, var, 0))) {
5888  vc->count++;
5889  } else {
5890  /* Create a new entry for this one */
5891  vc = ao2_alloc(sizeof(*vc), NULL);
5892  vc->varname = var;
5893  vc->count = 1;
5894  ao2_link(vco, vc);
5895  }
5896 
5897  xml_copy_escape(out, var, xml ? 1 | 2 : 0); /* data name */
5898  if (vc->count > 1) {
5899  ast_str_append(out, 0, "-%d", vc->count);
5900  }
5901  ao2_ref(vc, -1);
5902  ast_str_append(out, 0, xml ? "='" : "</td><td>");
5903  xml_copy_escape(out, val, 0); /* data field */
5904  if (!in_data || !*in) {
5905  ast_str_append(out, 0, xml ? "'" : "</td></tr>\n");
5906  }
5907  }
5908 
5909  if (inobj) {
5910  ast_str_append(out, 0, xml ? " /></response>\n" :
5911  "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
5912  ao2_ref(vco, -1);
5913  }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
char * strsep(char **str, const char *delims)
Definition: ast_expr2.c:325
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
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:900
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
const char * name
Definition: config.h:77
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:97
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:122
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
Definition: manager.c:5759
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
char * varname
Definition: manager.c:5748
struct ast_variable * next
Definition: config.h:82
static void xml_copy_escape(struct ast_str **out, const char *src, int mode)
Definition: manager.c:5690
static snd_pcm_format_t format
Definition: chan_alsa.c:93
static int variable_count_hash_fn(const void *vvc, const int flags)
Definition: manager.c:5752

Variable Documentation

struct ast_http_uri amanageruri
static

Definition at line 6594 of file manager.c.

struct ast_http_uri amanagerxmluri
static

Definition at line 6603 of file manager.c.

struct ast_tcptls_session_args ami_desc
static

Definition at line 6624 of file manager.c.

struct ast_tls_config ami_tls_cfg
static
struct ast_tcptls_session_args amis_desc
static

Definition at line 6635 of file manager.c.

struct ast_http_uri arawmanuri
static

Definition at line 6585 of file manager.c.

struct ast_cli_entry cli_manager[]
static

Definition at line 6685 of file manager.c.

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

Definition at line 5547 of file manager.c.

struct ast_http_uri manageruri
static

Definition at line 6534 of file manager.c.

struct ast_http_uri managerxmluri
static

Definition at line 6542 of file manager.c.

struct ast_http_uri rawmanuri
static

Definition at line 6526 of file manager.c.

int webregged = 0
static

Definition at line 6612 of file manager.c.

const char* words[AST_MAX_CMD_LEN]

Definition at line 929 of file manager.c.

Referenced by check_blacklist().