]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
manager: prevent file access outside of config dir
authorMike Bradeen <mbradeen@sangoma.com>
Mon, 3 Oct 2022 18:54:40 +0000 (12:54 -0600)
committerBenjamin Keith Ford <bford@digium.com>
Thu, 1 Dec 2022 17:48:11 +0000 (11:48 -0600)
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

configs/samples/asterisk.conf.sample
doc/UPGRADE-staging/manager_config_live_dangerously.txt [new file with mode: 0644]
include/asterisk/manager.h
main/manager.c
main/options.c

index b2a4da88d5064f28dcd9020359cbabe083bb7e7b..0d0d2a05501ec79ffd5f186c8bf85dba2203e304 100644 (file)
@@ -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 (file)
index 0000000..56f39f9
--- /dev/null
@@ -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.
index 3d882ef250bc717d8dde603eb44f794e4ea60991..107f83c1c3090171cba47e281b2ff60bd274366c 100644 (file)
@@ -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 */
index eb0459ead36d987852ecc7f6ecca08a47ff3f3cb..f4212e915a727bf9e353b9ed9a375e654206f6a7 100644 (file)
@@ -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;
index 07afd796d310a83953fcdde560c2ca429284ac5a..1507bc6ba5d56b2fc42fce10701aac5570f0fbe7 100644 (file)
@@ -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;