]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
manager.c: Add unit test for Originate app and appdata permissions
authorGeorge Joseph <gjoseph@sangoma.com>
Thu, 3 Oct 2024 15:10:36 +0000 (09:10 -0600)
committerGeorge Joseph <gjoseph@sangoma.com>
Tue, 8 Oct 2024 13:40:15 +0000 (13:40 +0000)
This unit test checks that dialplan apps and app data specified
as parameters for the Originate action are allowed with the
permissions the user has.

main/manager.c

index a59889f22d745aca8e39692410c8845f831f8c95..68e4e877259a06adefa1bb0668aa4eec318ecbc4 100644 (file)
@@ -4942,6 +4942,9 @@ static int app_match(const char *app, const char *data, const char *search)
  */
 static int appdata_match(const char *app, const char *data, const char *search)
 {
+       if (ast_strlen_zero(data)) {
+               return 0;
+       }
        return !!(strstr(data, search));
 }
 
@@ -4972,7 +4975,7 @@ static int queue_match(const char *app, const char *data, const char *search)
                AST_APP_ARG(position);
        );
 
-       if (!strcasestr(app, "queue")) {
+       if (!strcasestr(app, "queue") || ast_strlen_zero(data)) {
                return 0;
        }
 
@@ -5044,6 +5047,98 @@ static int is_originate_app_permitted(const char *app, const char *data,
        return 1;
 }
 
+#ifdef TEST_FRAMEWORK
+#define ALL_PERMISSIONS (INT_MAX)
+#define NO_PERMISSIONS (0)
+AST_TEST_DEFINE(originate_permissions_test)
+{
+       enum ast_test_result_state res = AST_TEST_PASS;
+
+       switch (cmd) {
+       case TEST_INIT:
+               info->name = "originate_permissions_test";
+               info->category = "/main/manager/";
+               info->summary = "Test permissions for originate action";
+               info->description =
+                       "Make sure that dialplan apps/functions that need special "
+                       "permissions are prohibited if the user doesn't have the permission.";
+               return AST_TEST_NOT_RUN;
+       case TEST_EXECUTE:
+               break;
+       }
+
+       /*
+        * Check application matching. We don't need to check every one.
+        * The code is the same.
+        */
+
+       ast_test_validate(test, is_originate_app_permitted("exec",
+               NULL, EVENT_FLAG_SYSTEM), "exec permission check failed");
+       ast_test_validate(test, is_originate_app_permitted("exec",
+               NULL, EVENT_FLAG_SYSTEM | EVENT_FLAG_AGI), "exec check permission failed");
+       ast_test_validate(test, is_originate_app_permitted("exec",
+               NULL, ALL_PERMISSIONS), "exec check permission failed");
+       ast_test_validate(test, !is_originate_app_permitted("exec",
+               NULL, EVENT_FLAG_AGI), "exec permission check failed");
+       ast_test_validate(test, !is_originate_app_permitted("exec",
+               NULL, EVENT_FLAG_VERBOSE), "exec permission check failed");
+       ast_test_validate(test, !is_originate_app_permitted("exec",
+               NULL, NO_PERMISSIONS), "exec permission check failed");
+
+       /*
+        * If queue is used with the AGI parameter but without the SYSTEM or AGI
+        * permission, it should be denied. Queue param order:
+        * queuename,options,url,announceoverride,queuetimeoutstr,AGI,gosub,rule,position
+        * The values of the options aren't checked. They just have to be present.
+        */
+
+       /* AGI not specified should always be allowed */
+       ast_test_validate(test, is_originate_app_permitted("queue",
+               NULL, NO_PERMISSIONS), "Queue permission check failed");
+       ast_test_validate(test, is_originate_app_permitted("queue",
+               "somequeue,CcdHh,someURL,tt-monkeys,100,,gosub,rule,666",
+               EVENT_FLAG_ORIGINATE | EVENT_FLAG_HOOKRESPONSE ), "Queue permission check failed");
+
+       /* AGI specified with SYSTEM or AGI permission should be allowed */
+       ast_test_validate(test, is_originate_app_permitted("queue",
+               "somequeue,CcdHh,someURL,tt-monkeys,100,SomeAGIScript,gosub,rule,666",
+               EVENT_FLAG_SYSTEM | EVENT_FLAG_HOOKRESPONSE ), "Queue permission check failed");
+       ast_test_validate(test, is_originate_app_permitted("queue",
+               "somequeue,CcdHh,someURL,tt-monkeys,100,SomeAGIScript,gosub,rule,666",
+               EVENT_FLAG_AGI | EVENT_FLAG_HOOKRESPONSE ), "Queue permission check failed");
+       ast_test_validate(test, is_originate_app_permitted("queue",
+               "somequeue,CcdHh,someURL,tt-monkeys,100,SomeAGIScript,gosub,rule,666",
+               ALL_PERMISSIONS), "Queue permission check failed");
+
+       /* AGI specified without SYSTEM or AGI permission should be denied */
+       ast_test_validate(test, !is_originate_app_permitted("queue",
+               "somequeue,CcdHh,someURL,tt-monkeys,100,SomeAGIScript,gosub,rule,666",
+               NO_PERMISSIONS), "Queue permission check failed");
+       ast_test_validate(test, !is_originate_app_permitted("queue",
+               "somequeue,CcdHh,someURL,tt-monkeys,100,SomeAGIScript,gosub,rule,666",
+               EVENT_FLAG_ORIGINATE | EVENT_FLAG_HOOKRESPONSE ), "Queue permission check failed");
+
+       /*
+        * Check appdata.  The function name can appear anywhere in appdata.
+        */
+       ast_test_validate(test, is_originate_app_permitted("someapp",
+               "aaaDBbbb", EVENT_FLAG_SYSTEM), "exec permission check failed");
+       ast_test_validate(test, is_originate_app_permitted("someapp",
+               "aaa DB bbb", ALL_PERMISSIONS), "exec permission check failed");
+       ast_test_validate(test, !is_originate_app_permitted("someapp",
+               "aaaDBbbb", NO_PERMISSIONS), "exec permission check failed");
+       ast_test_validate(test, !is_originate_app_permitted("someapp",
+               "aaa DB bbb", NO_PERMISSIONS), "exec permission check failed");
+       /* The check is case-sensitive so although DB is a match, db isn't. */
+       ast_test_validate(test, is_originate_app_permitted("someapp",
+               "aaa db bbb", NO_PERMISSIONS), "exec permission check failed");
+
+       return res;
+}
+#undef ALL_PERMISSIONS
+#undef NO_PERMISSIONS
+#endif
+
 static int action_originate(struct mansession *s, const struct message *m)
 {
        const char *name = astman_get_header(m, "Channel");
@@ -9246,6 +9341,7 @@ static void manager_shutdown(void)
 #ifdef TEST_FRAMEWORK
        AST_TEST_UNREGISTER(eventfilter_test_creation);
        AST_TEST_UNREGISTER(eventfilter_test_matching);
+       AST_TEST_UNREGISTER(originate_permissions_test);
 #endif
 
        /* This event is not actually transmitted, but causes all TCP sessions to be closed */
@@ -9956,6 +10052,7 @@ static int load_module(void)
 #ifdef TEST_FRAMEWORK
        AST_TEST_REGISTER(eventfilter_test_creation);
        AST_TEST_REGISTER(eventfilter_test_matching);
+       AST_TEST_REGISTER(originate_permissions_test);
 #endif
        return rc;
 }