From: Mike Bradeen Date: Mon, 3 Oct 2022 18:54:40 +0000 (-0600) Subject: manager: prevent file access outside of config dir X-Git-Tag: 19.8.0-rc1~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=764ca3347340b114938f3279f8e3afab121b261c;p=thirdparty%2Fasterisk.git manager: prevent file access outside of config dir Add live_dangerously flag to manager and use this flag to determine if a configuation file outside of AST_CONFIG_DIR should be read. ASTERISK-30176 Change-Id: I46b26af4047433b49ae5c8a85cb8cda806a07404 --- diff --git a/configs/samples/asterisk.conf.sample b/configs/samples/asterisk.conf.sample index b2a4da88d5..0d0d2a0550 100644 --- a/configs/samples/asterisk.conf.sample +++ b/configs/samples/asterisk.conf.sample @@ -95,10 +95,13 @@ documentation_language = en_US ; Set the language you want documentation ; documented in extensions.conf.sample. ; Default gosub. ;live_dangerously = no ; Enable the execution of 'dangerous' dialplan - ; functions from external sources (AMI, - ; etc.) These functions (such as SHELL) are - ; considered dangerous because they can allow - ; privilege escalation. + ; functions and configuration file access from + ; external sources (AMI, etc.) These functions + ; (such as SHELL) are considered dangerous + ; because they can allow privilege escalation. + ; Configuration files are considered dangerous + ; if they exist outside of the Asterisk + ; configuration directory. ; Default no ;entityid=00:11:22:33:44:55 ; Entity ID. ; This is in the form of a MAC address. diff --git a/doc/UPGRADE-staging/manager_config_live_dangerously.txt b/doc/UPGRADE-staging/manager_config_live_dangerously.txt new file mode 100644 index 0000000000..56f39f9c8d --- /dev/null +++ b/doc/UPGRADE-staging/manager_config_live_dangerously.txt @@ -0,0 +1,8 @@ +Subject: AMI (Asterisk Manager Interface) + +Previously, GetConfig and UpdateConfig were able to access files outside of +the Asterisk configuration directory. Now this access is put behind the +live_dangerously configuration option in asterisk.conf, which is disabled by +default. If access to configuration files outside of the Asterisk configuation +directory is required via AMI, then the live_dangerously configuration option +must be set to yes. diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h index 3d882ef250..107f83c1c3 100644 --- a/include/asterisk/manager.h +++ b/include/asterisk/manager.h @@ -350,6 +350,18 @@ void astman_send_list_complete_start(struct mansession *s, const struct message */ void astman_send_list_complete_end(struct mansession *s); +/*! + * \brief Enable/disable the inclusion of 'dangerous' configurations outside + * of the ast_config_AST_CONFIG_DIR + * + * This function can globally enable/disable the loading of configuration files + * outside of ast_config_AST_CONFIG_DIR. + * + * \param new_live_dangerously If true, enable the access of files outside + * ast_config_AST_CONFIG_DIR from astman. + */ +void astman_live_dangerously(int new_live_dangerously); + void __attribute__((format(printf, 2, 3))) astman_append(struct mansession *s, const char *fmt, ...); /*! \brief Determine if a manager session ident is authenticated */ diff --git a/main/manager.c b/main/manager.c index 90333a087a..9d21ac3a67 100644 --- a/main/manager.c +++ b/main/manager.c @@ -1490,6 +1490,11 @@ static struct stasis_forward *rtp_topic_forwarder; /*! \brief The \ref stasis_subscription for forwarding the Security topic to the AMI topic */ static struct stasis_forward *security_topic_forwarder; +/*! + * \brief Set to true (non-zero) to globally allow all dangerous AMI actions to run + */ +static int live_dangerously; + #ifdef TEST_FRAMEWORK /*! \brief The \ref stasis_subscription for forwarding the Test topic to the AMI topic */ static struct stasis_forward *test_suite_forwarder; @@ -3609,6 +3614,29 @@ static int action_ping(struct mansession *s, const struct message *m) return 0; } +void astman_live_dangerously(int new_live_dangerously) +{ + if (new_live_dangerously && !live_dangerously) + { + ast_log(LOG_WARNING, "Manager Configuration load protection disabled.\n"); + } + + if (!new_live_dangerously && live_dangerously) + { + ast_log(LOG_NOTICE, "Manager Configuration load protection enabled.\n"); + } + live_dangerously = new_live_dangerously; +} + +static int restrictedFile(const char *filename) +{ + if (!live_dangerously && !strncasecmp(filename, "/", 1) && + strncasecmp(filename, ast_config_AST_CONFIG_DIR, strlen(ast_config_AST_CONFIG_DIR))) { + return 1; + } + return 0; +} + static int action_getconfig(struct mansession *s, const struct message *m) { struct ast_config *cfg; @@ -3627,6 +3655,11 @@ static int action_getconfig(struct mansession *s, const struct message *m) return 0; } + if (restrictedFile(fn)) { + astman_send_error(s, m, "File requires escalated priveledges"); + return 0; + } + cfg = ast_config_load2(fn, "manager", config_flags); if (cfg == CONFIG_STATUS_FILEMISSING) { astman_send_error(s, m, "Config file not found"); @@ -3754,6 +3787,11 @@ static int action_getconfigjson(struct mansession *s, const struct message *m) return 0; } + if (restrictedFile(fn)) { + astman_send_error(s, m, "File requires escalated priveledges"); + return 0; + } + if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { astman_send_error(s, m, "Config file not found"); return 0; @@ -4105,6 +4143,10 @@ static int action_updateconfig(struct mansession *s, const struct message *m) astman_send_error(s, m, "Filename not specified"); return 0; } + if (restrictedFile(sfn) || restrictedFile(dfn)) { + astman_send_error(s, m, "File requires escalated priveledges"); + return 0; + } if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) { astman_send_error(s, m, "Config file not found"); return 0; diff --git a/main/options.c b/main/options.c index 07afd796d3..1507bc6ba5 100644 --- a/main/options.c +++ b/main/options.c @@ -476,6 +476,7 @@ void load_asterisk_conf(void) } if (!ast_opt_remote) { pbx_live_dangerously(live_dangerously); + astman_live_dangerously(live_dangerously); } option_debug += option_debug_new;