1c1ed15f1Sopenharmony_ci#!/usr/bin/env python
2c1ed15f1Sopenharmony_ci# coding: utf-8
3c1ed15f1Sopenharmony_ci
4c1ed15f1Sopenharmony_ci"""
5c1ed15f1Sopenharmony_ciCopyright (c) 2024 Huawei Device Co., Ltd.
6c1ed15f1Sopenharmony_ciLicensed under the Apache License, Version 2.0 (the "License");
7c1ed15f1Sopenharmony_ciyou may not use this file except in compliance with the License.
8c1ed15f1Sopenharmony_ciYou may obtain a copy of the License at
9c1ed15f1Sopenharmony_ci
10c1ed15f1Sopenharmony_ci    http://www.apache.org/licenses/LICENSE-2.0
11c1ed15f1Sopenharmony_ci
12c1ed15f1Sopenharmony_ciUnless required by applicable law or agreed to in writing, software
13c1ed15f1Sopenharmony_cidistributed under the License is distributed on an "AS IS" BASIS,
14c1ed15f1Sopenharmony_ciWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15c1ed15f1Sopenharmony_ciSee the License for the specific language governing permissions and
16c1ed15f1Sopenharmony_cilimitations under the License.
17c1ed15f1Sopenharmony_ci
18c1ed15f1Sopenharmony_ci"""
19c1ed15f1Sopenharmony_ci
20c1ed15f1Sopenharmony_ciimport argparse
21c1ed15f1Sopenharmony_ciimport os
22c1ed15f1Sopenharmony_cifrom check_common import read_json_file, traverse_file_in_each_type
23c1ed15f1Sopenharmony_ci
24c1ed15f1Sopenharmony_ciWHITELIST_FILE_NAME = "permissive_whitelist.json"
25c1ed15f1Sopenharmony_ci
26c1ed15f1Sopenharmony_ci
27c1ed15f1Sopenharmony_cidef simplify_string(string):
28c1ed15f1Sopenharmony_ci    return string.strip().replace('(', '').replace(')', '')
29c1ed15f1Sopenharmony_ci
30c1ed15f1Sopenharmony_ci
31c1ed15f1Sopenharmony_cidef deal_with_allow(cil_file, allow_set):
32c1ed15f1Sopenharmony_ci    with open(cil_file, 'r', encoding='utf-8') as cil_read:
33c1ed15f1Sopenharmony_ci        for line in cil_read:
34c1ed15f1Sopenharmony_ci            if not line.startswith('(typepermissive '):
35c1ed15f1Sopenharmony_ci                continue
36c1ed15f1Sopenharmony_ci            sub_string = simplify_string(line)
37c1ed15f1Sopenharmony_ci            elem_list = sub_string.split(' ')
38c1ed15f1Sopenharmony_ci            # (typepermissive xx)
39c1ed15f1Sopenharmony_ci            if len(elem_list) < 2:
40c1ed15f1Sopenharmony_ci                continue
41c1ed15f1Sopenharmony_ci            split_attribute(elem_list, allow_set)
42c1ed15f1Sopenharmony_ci
43c1ed15f1Sopenharmony_ci
44c1ed15f1Sopenharmony_cidef split_attribute(elem_list, allow_set):
45c1ed15f1Sopenharmony_ci    rulename = elem_list[0]
46c1ed15f1Sopenharmony_ci    scontext = elem_list[1]
47c1ed15f1Sopenharmony_ci    if rulename == 'typepermissive' :
48c1ed15f1Sopenharmony_ci        allow_set.add(scontext)
49c1ed15f1Sopenharmony_ci
50c1ed15f1Sopenharmony_ci
51c1ed15f1Sopenharmony_cidef get_permissive_set(args, with_developer):
52c1ed15f1Sopenharmony_ci    allow_set = set()
53c1ed15f1Sopenharmony_ci    if with_developer:
54c1ed15f1Sopenharmony_ci        deal_with_allow(args.developer_cil_file, allow_set)
55c1ed15f1Sopenharmony_ci    else:
56c1ed15f1Sopenharmony_ci        deal_with_allow(args.cil_file, allow_set)
57c1ed15f1Sopenharmony_ci    return allow_set
58c1ed15f1Sopenharmony_ci
59c1ed15f1Sopenharmony_ci
60c1ed15f1Sopenharmony_cidef get_whitelist(args, with_developer):
61c1ed15f1Sopenharmony_ci    whitelist_file_list = traverse_file_in_each_type(args.policy_dir_list, WHITELIST_FILE_NAME)
62c1ed15f1Sopenharmony_ci    contexts_list = []
63c1ed15f1Sopenharmony_ci    for path in whitelist_file_list:
64c1ed15f1Sopenharmony_ci        white_list = read_json_file(path).get('whitelist')
65c1ed15f1Sopenharmony_ci        contexts_list.extend(white_list.get('user'))
66c1ed15f1Sopenharmony_ci        if with_developer:
67c1ed15f1Sopenharmony_ci            contexts_list.extend(white_list.get('developer'))
68c1ed15f1Sopenharmony_ci    return contexts_list
69c1ed15f1Sopenharmony_ci
70c1ed15f1Sopenharmony_ci
71c1ed15f1Sopenharmony_cidef check(args, with_developer):
72c1ed15f1Sopenharmony_ci    permissive_set = get_permissive_set(args, with_developer)
73c1ed15f1Sopenharmony_ci    contexts_list = get_whitelist(args, with_developer)
74c1ed15f1Sopenharmony_ci    notallow = permissive_set - set(contexts_list)
75c1ed15f1Sopenharmony_ci    if len(notallow) > 0 :
76c1ed15f1Sopenharmony_ci        print('check permissive rule in {} mode failed.'.format("developer" if with_developer else "user"))
77c1ed15f1Sopenharmony_ci        print('violation list (scontext):')
78c1ed15f1Sopenharmony_ci        for diff in sorted(list(notallow)):
79c1ed15f1Sopenharmony_ci            print('\t{}'.format(diff))
80c1ed15f1Sopenharmony_ci        print('There are two solutions:\n',
81c1ed15f1Sopenharmony_ci              '\t1. Add the above list to whitelist file \'{}\' under \'{}\' in \'{}\' mode.\n'.format(
82c1ed15f1Sopenharmony_ci                    WHITELIST_FILE_NAME, args.policy_dir_list, "developer" if with_developer else "user"),
83c1ed15f1Sopenharmony_ci              '\t2. Change the policy to avoid violating rule.')
84c1ed15f1Sopenharmony_ci    return len(notallow) > 0
85c1ed15f1Sopenharmony_ci
86c1ed15f1Sopenharmony_ci
87c1ed15f1Sopenharmony_cidef parse_args():
88c1ed15f1Sopenharmony_ci    parser = argparse.ArgumentParser()
89c1ed15f1Sopenharmony_ci    parser.add_argument('--cil_file', help='the cil file path', required=True)
90c1ed15f1Sopenharmony_ci    parser.add_argument('--developer_cil_file', help='the developer cil file path', required=True)
91c1ed15f1Sopenharmony_ci    parser.add_argument('--policy-dir-list', help='policy dirs need to be included', required=True)
92c1ed15f1Sopenharmony_ci
93c1ed15f1Sopenharmony_ci    return parser.parse_args()
94c1ed15f1Sopenharmony_ci
95c1ed15f1Sopenharmony_ci
96c1ed15f1Sopenharmony_ciif __name__ == '__main__':
97c1ed15f1Sopenharmony_ci    input_args = parse_args()
98c1ed15f1Sopenharmony_ci    print("check permissive input_args: {}".format(input_args))
99c1ed15f1Sopenharmony_ci    result = check(input_args, False)
100c1ed15f1Sopenharmony_ci    if result:
101c1ed15f1Sopenharmony_ci        raise Exception(-1)
102c1ed15f1Sopenharmony_ci    result = check(input_args, True)
103c1ed15f1Sopenharmony_ci    if result:
104c1ed15f1Sopenharmony_ci        raise Exception(-1)
105c1ed15f1Sopenharmony_ci
106