Beispiel #1
0
    def __init__(self, fn, overrides=None):
        peer_hooks = dict()
        my_hook = 'push-helper'
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = ['apparmor']
        peer_hooks[my_hook]['required'] = ['apparmor']

        ClickReview.__init__(self, fn, "push_helper", peer_hooks=peer_hooks,
                             overrides=overrides)

        if not self.is_click and not self.is_snap1:
            return

        self.required_keys = ['exec']
        self.optional_keys = ['app_id']

        self.push_helper_files = dict()  # click-show-files and tests
        self.push_helper = dict()

        if self.manifest is None:
            return

        for app in self.manifest['hooks']:
            if 'push-helper' not in self.manifest['hooks'][app]:
                # msg("Skipped missing push-helper hook for '%s'" % app)
                continue
            if not isinstance(self.manifest['hooks'][app]['push-helper'], str):
                error("manifest malformed: hooks/%s/push-helper is not str" %
                      app)
            (full_fn, jd) = self._extract_push_helper(app)
            self.push_helper_files[app] = full_fn
            self.push_helper[app] = jd
    def __init__(self, fn, overrides=None):
        ClickReview.__init__(self, fn, "framework", overrides=overrides)

        self.frameworks_file = dict()
        self.frameworks = dict()

        if not self.is_snap1:
            return

        if self.manifest is not None:
            for app in self.manifest['hooks']:
                if 'framework' not in self.manifest['hooks'][app]:
                    # msg("Skipped missing framework hook for '%s'" % app)
                    continue
                if not isinstance(self.manifest['hooks'][app]['framework'],
                                  str):
                    error("manifest malformed: hooks/%s/framework is not str" %
                          app)
                (full_fn, data) = self._extract_framework(app)
                self.frameworks_file[app] = full_fn
                self.frameworks[app] = data

        self.framework_policy_dirs = ['apparmor', 'seccomp']
        self.framework_policy_subdirs = ['templates', 'policygroups']
        (self.framework_policy, self.framework_policy_unknown) = \
            self._extract_framework_policy()
    def __init__(self, fn, overrides=None):
        peer_hooks = dict()
        my_hook = 'scope'
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = ClickReview.scope_allowed_peer_hooks
        peer_hooks[my_hook]['required'] = ['apparmor']

        ClickReview.__init__(self, fn, "scope", peer_hooks=peer_hooks,
                             overrides=overrides)

        if not self.is_click and not self.is_snap1:
            return

        self.scopes = dict()

        if self.manifest is None:
            return

        for app in self.manifest['hooks']:
            if 'scope' not in self.manifest['hooks'][app]:
                # msg("Skipped missing scope hook for '%s'" % app)
                continue
            if not isinstance(self.manifest['hooks'][app]['scope'], str):
                error("manifest malformed: hooks/%s/scope is not str" % app)
            self.scopes[app] = self._extract_scopes(app)
    def __init__(self, fn, overrides=None):
        peer_hooks = dict()
        my_hook = 'content-hub'
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = ClickReview.app_allowed_peer_hooks
        peer_hooks[my_hook]['required'] = []

        ClickReview.__init__(self,
                             fn,
                             "content_hub",
                             peer_hooks=peer_hooks,
                             overrides=overrides)
        if not self.is_click and not self.is_snap1:
            return

        self.valid_keys = ['destination', 'share', 'source']

        self.content_hub_files = dict()  # click-show-files and tests
        self.content_hub = dict()

        if self.manifest is None:
            return

        for app in self.manifest['hooks']:
            if 'content-hub' not in self.manifest['hooks'][app]:
                # msg("Skipped missing content-hub hook for '%s'" % app)
                continue
            if not isinstance(self.manifest['hooks'][app]['content-hub'], str):
                error("manifest malformed: hooks/%s/urls is not str" % app)
            (full_fn, jd) = self._extract_content_hub(app)
            self.content_hub_files[app] = full_fn
            self.content_hub[app] = jd
    def __init__(self, fn, overrides=None):
        peer_hooks = dict()
        my_hook = 'urls'
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = ClickReview.app_allowed_peer_hooks
        peer_hooks[my_hook]['required'] = []

        ClickReview.__init__(self, fn, "url_dispatcher", peer_hooks=peer_hooks,
                             overrides=overrides)

        if not self.is_click and not self.is_snap1:
            return

        self.required_keys = ['protocol']
        self.optional_keys = ['domain-suffix']

        self.url_dispatcher_files = dict()  # click-show-files and tests
        self.url_dispatcher = dict()

        if self.manifest is None:
            return

        for app in self.manifest['hooks']:
            if 'urls' not in self.manifest['hooks'][app]:
                # msg("Skipped missing urls hook for '%s'" % app)
                continue
            if not isinstance(self.manifest['hooks'][app]['urls'], str):
                error("manifest malformed: hooks/%s/urls is not str" % app)
            (full_fn, jd) = self._extract_url_dispatcher(app)
            self.url_dispatcher_files[app] = full_fn
            self.url_dispatcher[app] = jd
    def __init__(self, fn, overrides=None):
        # bin-path is ignored by snappy install so don't bother with peerhooks
        ClickReview.__init__(self, fn, "bin-path", overrides=overrides)

        self.bin_paths_files = dict()
        self.bin_paths = dict()

        if not self.is_snap1:
            return

        # snappy yaml currently only allows specifying:
        # - exec (optional)
        # - description (optional)
        self.required_keys = []
        self.optional_keys = ['description', 'exec'] + self.snappy_exe_security

        if self.is_snap1 and 'binaries' in self.pkg_yaml:
            if len(self.pkg_yaml['binaries']) == 0:
                error("package.yaml malformed: 'binaries' is empty")
            for binary in self.pkg_yaml['binaries']:
                if 'name' not in binary:
                    error("package.yaml malformed: required 'name' not found "
                          "for entry in %s" % self.pkg_yaml['binaries'])
                elif not isinstance(binary['name'], str):
                    error("package.yaml malformed: required 'name' is not str"
                          "for entry in %s" % self.pkg_yaml['binaries'])

                app = os.path.basename(binary['name'])
                if 'exec' in binary:
                    rel = binary['exec']
                else:
                    rel = binary['name']
                self.bin_paths[app] = rel
                self.bin_paths_files[app] = self._extract_bin_path(app)
    def __init__(self, fn, overrides=None):
        ClickReview.__init__(self, fn, "functional", overrides=overrides)
        if not self.is_click and not self.is_snap1:
            return

        self.qml_files = []
        for i in self.pkg_files:
            if i.endswith(".qml"):
                self.qml_files.append(i)

        self._list_all_compiled_binaries()
    def __init__(self, fn, overrides=None):
        peer_hooks = dict()
        my_hook = 'desktop'
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = ClickReview.app_allowed_peer_hooks
        peer_hooks[my_hook]['required'] = ["apparmor"]

        ClickReview.__init__(self,
                             fn,
                             "desktop",
                             peer_hooks=peer_hooks,
                             overrides=overrides)
        if not self.is_click and not self.is_snap1:
            return

        self.desktop_files = dict()  # click-show-files and a couple tests
        self.desktop_entries = dict()
        self.desktop_hook_entries = 0

        if self.manifest is None:
            return

        for app in self.manifest['hooks']:
            if 'desktop' not in self.manifest['hooks'][app]:
                # msg("Skipped missing desktop hook for '%s'" % app)
                continue
            if not isinstance(self.manifest['hooks'][app]['desktop'], str):
                error("manifest malformed: hooks/%s/desktop is not str" % app)
            self.desktop_hook_entries += 1
            (de, full_fn) = self._extract_desktop_entry(app)
            self.desktop_entries[app] = de
            self.desktop_files[app] = full_fn

        self.required_keys = [
            'Name',
            'Type',
            'Icon',
            'Exec',
            'X-Ubuntu-Touch',
        ]
        self.expected_execs = [
            'qmlscene',
            'webbrowser-app',
            'webapp-container',
            'ubuntu-html5-app-launcher',
        ]
        self.deprecated_execs = [
            'cordova-ubuntu-2.8',
        ]
        # TODO: the desktop hook will actually handle this correctly
        self.blacklisted_keys = ['Path']
Beispiel #9
0
    def __init__(self, fn, overrides=None):
        # Many test classes are for verify click hooks. 'peer_hooks' is used
        # to declare what hooks may be use with my_hook. When using this
        # mechanism, ClickReview.check_peer_hooks() is run for you.
        peer_hooks = dict()
        my_hook = 'skeleton'
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = ["desktop", "apparmor", "urls"]
        peer_hooks[my_hook]['required'] = ["desktop", "apparmor"]

        ClickReview.__init__(self, fn, "skeleton", peer_hooks=peer_hooks,
                             overrides=overrides)

        if not self.is_click and not self.is_snap1:
            return
Beispiel #10
0
    def __init__(self, fn, overrides=None):
        # systemd isn't implemented as a hook any more so don't setup peerhooks
        ClickReview.__init__(self, fn, "snappy-systemd", overrides=overrides)

        self.systemd_files = dict()  # click-show-files and tests
        self.systemd = dict()

        if not self.is_snap1:
            return

        # snappy-systemd currently only allows specifying:
        # - start (required)
        # - description (required)
        # - stop
        # - poststop
        # - stop-timeout
        # - caps (checked in in cr_security.py)
        # - security-template (checked in in cr_security.py)
        # - security-override (checked in in cr_security.py)
        # - security-policy (checked in in cr_security.py)
        self.required_keys = ['start', 'description']
        self.optional_keys = [
            'stop', 'poststop', 'stop-timeout', 'bus-name', 'listen-stream',
            'socket', 'socket-user', 'socket-group', 'ports'
        ] + self.snappy_exe_security

        if self.is_snap1 and 'services' in self.pkg_yaml:
            if len(self.pkg_yaml['services']) == 0:
                error("package.yaml malformed: 'services' is empty")
            for service in self.pkg_yaml['services']:
                if 'name' not in service:
                    error("package.yaml malformed: required 'name' not found "
                          "for entry in %s" % self.pkg_yaml['services'])
                elif not isinstance(service['name'], str):
                    error("package.yaml malformed: required 'name' is not str"
                          "for entry in %s" % self.pkg_yaml['services'])

                app = service['name']
                self.systemd[app] = copy.deepcopy(service)
                del self.systemd[app]['name']
Beispiel #11
0
    def __init__(self, fn, overrides=None):
        peer_hooks = dict()
        peer_hooks['account-application'] = dict()
        peer_hooks['account-application']['allowed'] = \
            ClickReview.app_allowed_peer_hooks + \
            ClickReview.scope_allowed_peer_hooks
        peer_hooks['account-application']['required'] = ['apparmor']

        peer_hooks['account-service'] = dict()
        peer_hooks['account-service']['required'] = [
            'account-application', 'apparmor'
        ]
        peer_hooks['account-service']['allowed'] = \
            ClickReview.app_allowed_peer_hooks + \
            ClickReview.scope_allowed_peer_hooks

        peer_hooks['accounts'] = dict()
        peer_hooks['accounts']['allowed'] = \
            [h for h in (ClickReview.app_allowed_peer_hooks +
                         ClickReview.scope_allowed_peer_hooks)
             if not h.startswith('account-')]
        peer_hooks['accounts']['required'] = ['apparmor']

        peer_hooks['account-provider'] = dict()
        peer_hooks['account-provider']['required'] = [
            'account-qml-plugin', 'apparmor'
        ]
        peer_hooks['account-provider']['allowed'] = \
            peer_hooks['account-provider']['required']

        peer_hooks['account-qml-plugin'] = dict()
        peer_hooks['account-qml-plugin']['required'] = [
            'account-provider', 'apparmor'
        ]
        peer_hooks['account-qml-plugin']['allowed'] = \
            peer_hooks['account-qml-plugin']['required']

        ClickReview.__init__(
            self,
            fn,
            "online_accounts",
            peer_hooks=peer_hooks,
            overrides=overrides,
            peer_hooks_link=
            "https://wiki.ubuntu.com/SecurityTeam/Specifications/OnlineAccountsConfinement"
        )
        if not self.is_click and not self.is_snap1:
            return

        self.accounts_files = dict()
        self.accounts = dict()

        self.account_hooks = [
            'accounts', 'account-application', 'account-provider',
            'account-qml-plugin', 'account-service'
        ]

        if self.manifest is None:
            return

        for app in self.manifest['hooks']:
            for h in self.account_hooks:
                if h not in self.manifest['hooks'][app]:
                    # msg("Skipped missing %s hook for '%s'" % (h, app))
                    continue
                if not isinstance(self.manifest['hooks'][app][h], str):
                    error("manifest malformed: hooks/%s/%s is not a str" %
                          (app, h))

                (full_fn, parsed) = self._extract_account(app, h)

                if app not in self.accounts_files:
                    self.accounts_files[app] = dict()
                self.accounts_files[app][h] = full_fn

                if app not in self.accounts:
                    self.accounts[app] = dict()
                self.accounts[app][h] = parsed

        self.required_keys = dict()
        self.allowed_keys = dict()
        self.required_keys["service"] = [
            ('provider', str),
        ]
        self.allowed_keys["service"] = [
            ('auth', dict),
            ('name', str),
            ('description', str),
        ]
        self.required_keys["plugin"] = [
            ('name', str),
            ('icon', str),
            ('qml', str),
        ]
        self.allowed_keys["plugin"] = [
            ('auth', dict),
        ]
        self.provider_re = re.compile('^[a-zA-Z0-9_.-]+$')
 def setUp(self):
     super().setUp()
     self.review = ClickReview('app.click', 'review_type')
class ClickReviewTestCase(cr_tests.TestClickReview):
    def setUp(self):
        super().setUp()
        self.review = ClickReview('app.click', 'review_type')

    def test_add_result_default_manual_review(self):
        self.review._add_result('info', 'some-check', 'OK')
        self.assertEqual(
            self.review.click_report, {
                'info': {
                    'some-check': {
                        'text': 'OK',
                        'manual_review': False,
                    }
                },
                'warn': {},
                'error': {},
            })

    def test_add_result_custom_manual_review(self):
        self.review._add_result('info', 'some-check', 'OK', manual_review=True)
        self.assertEqual(
            self.review.click_report, {
                'info': {
                    'some-check': {
                        'text': 'OK',
                        'manual_review': True,
                    }
                },
                'warn': {},
                'error': {},
            })

    def test_add_result_override_result_type_warn(self):
        self.review._add_result('warn',
                                'some-check',
                                'notok',
                                override_result_type='info')
        self.assertEqual(
            self.review.click_report, {
                'info': {
                    'some-check': {
                        'text': '[WARN] notok',
                        'manual_review': False,
                    }
                },
                'warn': {},
                'error': {},
            })

    def test_add_result_override_result_type_error(self):
        self.review._add_result('error',
                                'some-check',
                                'notok',
                                override_result_type='info')
        self.assertEqual(
            self.review.click_report, {
                'info': {
                    'some-check': {
                        'text': '[ERROR] notok',
                        'manual_review': False,
                    }
                },
                'warn': {},
                'error': {},
            })

    def test_add_result_override_result_type_info(self):
        self.review._add_result('info',
                                'some-check',
                                'ok',
                                override_result_type='warn')
        self.assertEqual(
            self.review.click_report, {
                'warn': {
                    'some-check': {
                        'text': '[INFO] ok',
                        'manual_review': False,
                    }
                },
                'info': {},
                'error': {},
            })

    def test_verify_peer_hooks_empty(self):
        '''Check verify_peer_hooks() - empty'''
        peer_hooks = dict()
        my_hook = "foo"
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = []
        peer_hooks[my_hook]['required'] = []
        self.review.peer_hooks = peer_hooks

        d = self.review._verify_peer_hooks(my_hook)
        self.assertEqual(0, len(d.keys()))

    def test_verify_peer_hooks_missing(self):
        '''Check verify_peer_hooks() - missing required'''
        peer_hooks = dict()
        my_hook = "desktop"
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = ["apparmor", "urls"]
        peer_hooks[my_hook]['required'] = ["nonexistent"]
        self.review.peer_hooks = peer_hooks

        d = self.review._verify_peer_hooks(my_hook)
        self.assertEqual(1, len(d.keys()))
        self.assertTrue('missing' in d.keys())
        self.assertTrue('nonexistent' in d['missing'][self.default_appname])

    def test_verify_peer_hooks_disallowed(self):
        '''Check verify_peer_hooks() - disallowed'''
        peer_hooks = dict()
        my_hook = "desktop"
        peer_hooks[my_hook] = dict()
        peer_hooks[my_hook]['allowed'] = ["apparmor"]
        peer_hooks[my_hook]['required'] = []
        self.review.peer_hooks = peer_hooks

        d = self.review._verify_peer_hooks(my_hook)
        self.assertEqual(1, len(d.keys()))
        self.assertTrue('disallowed' in d.keys())
        self.assertTrue('urls' in d['disallowed'][self.default_appname])

    def test_get_check_name(self):
        name = self.review._get_check_name('prefix')
        self.assertEqual(name, 'review_type:prefix')

    def test_get_check_name_with_app(self):
        name = self.review._get_check_name('prefix', app='app')
        self.assertEqual(name, 'review_type:prefix:app')

    def test_get_check_name_with_extra(self):
        name = self.review._get_check_name('prefix', extra='extra')
        self.assertEqual(name, 'review_type:prefix:extra')

    def test_get_check_name_with_app_and_extra(self):
        name = self.review._get_check_name('prefix', app='app', extra='extra')
        self.assertEqual(name, 'review_type:prefix:app:extra')

    def test_check_if_message_catalog_true(self):
        self.assertTrue(self.review._check_if_message_catalog('/a/b/foo.mo'))

    def test_check_if_message_catalog_false(self):
        self.assertFalse(self.review._check_if_message_catalog('/a/b/foo.txt'))