github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/cmd/snap-confine/snap-confine-invocation-test.c (about)

     1  /*
     2   * Copyright (C) 2019 Canonical Ltd
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License version 3 as
     6   * published by the Free Software Foundation.
     7   *
     8   * This program is distributed in the hope that it will be useful,
     9   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11   * GNU General Public License for more details.
    12   *
    13   * You should have received a copy of the GNU General Public License
    14   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15   *
    16   */
    17  
    18  #include "snap-confine-invocation.h"
    19  #include "snap-confine-args.h"
    20  #include "snap-confine-invocation.c"
    21  
    22  #include "../libsnap-confine-private/cleanup-funcs.h"
    23  #include "../libsnap-confine-private/test-utils.h"
    24  
    25  #include <stdarg.h>
    26  
    27  #include <glib.h>
    28  
    29  static struct sc_args *test_prepare_args(const char *base, const char *tag) {
    30      struct sc_args *args = NULL;
    31      sc_error *err SC_CLEANUP(sc_cleanup_error) = NULL;
    32      int argc;
    33      char **argv;
    34  
    35      test_argc_argv(&argc, &argv, "/usr/lib/snapd/snap-confine", "--base", (base != NULL) ? base : "core",
    36                     (tag != NULL) ? tag : "snap.foo.app", "/usr/lib/snapd/snap-exec", NULL);
    37      args = sc_nonfatal_parse_args(&argc, &argv, &err);
    38      g_assert_null(err);
    39      g_assert_nonnull(args);
    40  
    41      return args;
    42  }
    43  
    44  static void test_sc_invocation_basic(void) {
    45      struct sc_args *args SC_CLEANUP(sc_cleanup_args) = test_prepare_args("core", NULL);
    46  
    47      sc_invocation inv SC_CLEANUP(sc_cleanup_invocation);
    48      ;
    49      sc_init_invocation(&inv, args, "foo");
    50  
    51      g_assert_cmpstr(inv.base_snap_name, ==, "core");
    52      g_assert_cmpstr(inv.executable, ==, "/usr/lib/snapd/snap-exec");
    53      g_assert_cmpstr(inv.orig_base_snap_name, ==, "core");
    54      g_assert_cmpstr(inv.rootfs_dir, ==, SNAP_MOUNT_DIR "/core/current");
    55      g_assert_cmpstr(inv.security_tag, ==, "snap.foo.app");
    56      g_assert_cmpstr(inv.snap_instance, ==, "foo");
    57      g_assert_cmpstr(inv.snap_name, ==, "foo");
    58      g_assert_false(inv.classic_confinement);
    59      /* derived later */
    60      g_assert_false(inv.is_normal_mode);
    61  }
    62  
    63  static void test_sc_invocation_instance_key(void) {
    64      struct sc_args *args SC_CLEANUP(sc_cleanup_args) = test_prepare_args("core", "snap.foo_bar.app");
    65  
    66      sc_invocation inv SC_CLEANUP(sc_cleanup_invocation);
    67      ;
    68      sc_init_invocation(&inv, args, "foo_bar");
    69  
    70      // Check the error that we've got
    71      g_assert_cmpstr(inv.snap_instance, ==, "foo_bar");
    72      g_assert_cmpstr(inv.snap_name, ==, "foo");
    73      g_assert_cmpstr(inv.orig_base_snap_name, ==, "core");
    74      g_assert_cmpstr(inv.security_tag, ==, "snap.foo_bar.app");
    75      g_assert_cmpstr(inv.executable, ==, "/usr/lib/snapd/snap-exec");
    76      g_assert_false(inv.classic_confinement);
    77      g_assert_cmpstr(inv.rootfs_dir, ==, SNAP_MOUNT_DIR "/core/current");
    78      g_assert_cmpstr(inv.base_snap_name, ==, "core");
    79      /* derived later */
    80      g_assert_false(inv.is_normal_mode);
    81  }
    82  
    83  static void test_sc_invocation_base_name(void) {
    84      struct sc_args *args SC_CLEANUP(sc_cleanup_args) = test_prepare_args("base-snap", NULL);
    85  
    86      sc_invocation inv SC_CLEANUP(sc_cleanup_invocation);
    87      sc_init_invocation(&inv, args, "foo");
    88  
    89      g_assert_cmpstr(inv.base_snap_name, ==, "base-snap");
    90      g_assert_cmpstr(inv.executable, ==, "/usr/lib/snapd/snap-exec");
    91      g_assert_cmpstr(inv.orig_base_snap_name, ==, "base-snap");
    92      g_assert_cmpstr(inv.rootfs_dir, ==, SNAP_MOUNT_DIR "/base-snap/current");
    93      g_assert_cmpstr(inv.security_tag, ==, "snap.foo.app");
    94      g_assert_cmpstr(inv.snap_instance, ==, "foo");
    95      g_assert_cmpstr(inv.snap_name, ==, "foo");
    96      g_assert_false(inv.classic_confinement);
    97      /* derived later */
    98      g_assert_false(inv.is_normal_mode);
    99  }
   100  
   101  static void test_sc_invocation_bad_instance_name(void) {
   102      struct sc_args *args SC_CLEANUP(sc_cleanup_args) = test_prepare_args(NULL, NULL);
   103  
   104      if (g_test_subprocess()) {
   105          sc_invocation inv SC_CLEANUP(sc_cleanup_invocation) = {0};
   106          sc_init_invocation(&inv, args, "foo_bar_bar_bar");
   107          return;
   108      }
   109  
   110      g_test_trap_subprocess(NULL, 0, 0);
   111      g_test_trap_assert_failed();
   112      g_test_trap_assert_stderr("snap instance name can contain only one underscore\n");
   113  }
   114  
   115  static void test_sc_invocation_classic(void) {
   116      struct sc_args *args SC_CLEANUP(sc_cleanup_args) = NULL;
   117      sc_error *err SC_CLEANUP(sc_cleanup_error) = NULL;
   118      int argc;
   119      char **argv = NULL;
   120  
   121      test_argc_argv(&argc, &argv, "/usr/lib/snapd/snap-confine", "--classic", "--base", "core", "snap.foo-classic.app",
   122                     "/usr/lib/snapd/snap-exec", NULL);
   123      args = sc_nonfatal_parse_args(&argc, &argv, &err);
   124      g_assert_null(err);
   125      g_assert_nonnull(args);
   126  
   127      sc_invocation inv SC_CLEANUP(sc_cleanup_invocation) = {0};
   128      sc_init_invocation(&inv, args, "foo-classic");
   129  
   130      g_assert_cmpstr(inv.base_snap_name, ==, "core");
   131      g_assert_cmpstr(inv.executable, ==, "/usr/lib/snapd/snap-exec");
   132      g_assert_cmpstr(inv.orig_base_snap_name, ==, "core");
   133      g_assert_cmpstr(inv.rootfs_dir, ==, SNAP_MOUNT_DIR "/core/current");
   134      g_assert_cmpstr(inv.security_tag, ==, "snap.foo-classic.app");
   135      g_assert_cmpstr(inv.snap_instance, ==, "foo-classic");
   136      g_assert_cmpstr(inv.snap_name, ==, "foo-classic");
   137      g_assert_true(inv.classic_confinement);
   138  }
   139  
   140  static void test_sc_invocation_tag_name_mismatch(void) {
   141      struct sc_args *args SC_CLEANUP(sc_cleanup_args) = test_prepare_args("core", "snap.foo.app");
   142  
   143      if (g_test_subprocess()) {
   144          sc_invocation inv SC_CLEANUP(sc_cleanup_invocation);
   145          ;
   146          sc_init_invocation(&inv, args, "foo-not-foo");
   147          return;
   148      }
   149  
   150      g_test_trap_subprocess(NULL, 0, 0);
   151      g_test_trap_assert_failed();
   152      g_test_trap_assert_stderr("security tag snap.foo.app not allowed\n");
   153  }
   154  
   155  static void __attribute__((constructor)) init(void) {
   156      g_test_add_func("/invocation/bad_instance_name", test_sc_invocation_bad_instance_name);
   157      g_test_add_func("/invocation/base_name", test_sc_invocation_base_name);
   158      g_test_add_func("/invocation/basic", test_sc_invocation_basic);
   159      g_test_add_func("/invocation/classic", test_sc_invocation_classic);
   160      g_test_add_func("/invocation/instance_key", test_sc_invocation_instance_key);
   161      g_test_add_func("/invocation/tag_name_mismatch", test_sc_invocation_tag_name_mismatch);
   162  }