def _run_test(self, params, expected):
        logfile = '%s.in' % params
        profile_dummy_file = 'AATest_does_exist'

        # we need to find out the profile name and aamode (complain vs. enforce mode) so that the test can access the correct place in storage
        parser = ReadLog('', '', '', '')
        parsed_event = parser.parse_event(read_file(logfile))

        if not parsed_event:  # AA_RECORD_INVALID
            return

        if params.split('/')[-1] in log_to_profile_skip:
            return

        aamode = parsed_event['aamode']

        if aamode in [
                'AUDIT', 'STATUS', 'HINT'
        ]:  # ignore some event types  # XXX maybe we shouldn't ignore AUDIT events?
            return

        if aamode not in ['PERMITTING', 'REJECTING']:
            raise Exception('Unexpected aamode %s' % parsed_event['aamode'])

        # cleanup apparmor.aa storage
        apparmor.aa.log = dict()
        apparmor.aa.aa = apparmor.aa.hasher()
        apparmor.aa.prelog = apparmor.aa.hasher()

        profile = parsed_event['profile']
        hat = profile
        if '//' in profile:
            profile, hat = profile.split('//')

        apparmor.aa.existing_profiles = {profile: profile_dummy_file}

        log_reader = ReadLog(dict(), logfile, apparmor.aa.existing_profiles,
                             '')
        log = log_reader.read_log('')

        for root in log:
            apparmor.aa.handle_children('', '',
                                        root)  # interactive for exec events!

        log_dict = apparmor.aa.collapse_log()

        apparmor.aa.filelist = apparmor.aa.hasher()
        apparmor.aa.filelist[profile_dummy_file]['profiles'][profile] = True

        new_profile = apparmor.aa.serialize_profile(log_dict[aamode][profile],
                                                    profile, None)

        expected_profile = read_file('%s.profile' % params)

        if params.split('/')[-1] in log_to_profile_known_failures:
            self.assertNotEqual(new_profile, expected_profile)  # known failure
        else:
            self.assertEqual(new_profile, expected_profile)
Exemple #2
0
def logfile_to_profile(logfile):
    profile_dummy_file = 'AATest_does_exist'

    # we need to find out the profile name and aamode (complain vs. enforce mode) so that the test can access the correct place in storage
    parser = ReadLog('', '', '')
    parsed_event = parser.parse_event(read_file(logfile))

    if not parsed_event:  # AA_RECORD_INVALID
        return None, 'INVALID'

    aamode = parsed_event['aamode']

    if aamode in [
            'AUDIT', 'STATUS', 'HINT'
    ]:  # ignore some event types  # XXX maybe we shouldn't ignore AUDIT events?
        return None, aamode

    if aamode not in ['PERMITTING', 'REJECTING']:
        raise Exception('Unexpected aamode %s' % parsed_event['aamode'])

    # cleanup apparmor.aa storage
    apparmor.aa.log = dict()
    apparmor.aa.aa = apparmor.aa.hasher()

    profile, hat = split_name(parsed_event['profile'])

    apparmor.aa.active_profiles = ProfileList()

    # optional for now, might be needed one day
    # if profile.startswith('/'):
    #     apparmor.aa.active_profiles.add_profile(profile_dummy_file, profile, profile)
    # else:
    apparmor.aa.active_profiles.add_profile(profile_dummy_file, profile, '')

    log_reader = ReadLog(logfile, apparmor.aa.active_profiles, '')
    hashlog = log_reader.read_log('')

    apparmor.aa.ask_exec(hashlog)
    apparmor.aa.ask_addhat(hashlog)

    log_dict = apparmor.aa.collapse_log(hashlog, ignore_null_profiles=False)

    if profile != hat:
        # log event for a child profile means log_dict only contains the child profile
        # initialize parent profile in log_dict as ProfileStorage to ensure writing the profile doesn't fail
        # (in "normal" usage outside of this test, log_dict will not be handed over to serialize_profile())

        if log_dict[aamode][profile][profile] != {}:
            raise Exception(
                'event for child profile, but parent profile was initialized nevertheless. Logfile: %s'
                % logfile)

        log_dict[aamode][profile][profile] = apparmor.aa.ProfileStorage(
            'TEST DUMMY for empty parent profile', profile_dummy_file,
            'logfile_to_profile()')

    log_is_empty = True

    for tmpaamode in hashlog:
        for tmpprofile in hashlog[tmpaamode]:
            for tmpruletype in hashlog[tmpaamode][tmpprofile]:
                if tmpruletype == 'final_name' and hashlog[tmpaamode][
                        tmpprofile]['final_name'] == tmpprofile:
                    continue  # final_name is a copy of the profile name (may be changed by ask_exec(), but that won't happen in this test)
                if hashlog[tmpaamode][tmpprofile][tmpruletype]:
                    log_is_empty = False

    if logfile.split('/')[-1][:-3] in log_to_profile_known_empty_log:
        # unfortunately this function might be called outside Unittest.TestCase, therefore we can't use assertEqual / assertNotEqual
        if log_is_empty == False:
            raise Exception(
                'got non-empty log for logfile in log_to_profile_known_empty_log: %s %s'
                % (logfile, hashlog))
    else:
        if log_is_empty == True:
            raise Exception(
                'got empty log for logfile not in log_to_profile_known_empty_log: %s %s'
                % (logfile, hashlog))

    new_profile = apparmor.aa.serialize_profile(log_dict[aamode][profile],
                                                profile, {})

    return profile, new_profile