• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#coding=utf-8
3
4#
5# Copyright (c) 2023 Huawei Device Co., Ltd.
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19import os
20import json
21
22from .base_rule import BaseRule
23
24class cmdRule(BaseRule):
25    RULE_NAME = "NO-Config-Cmds-In-Init"
26
27    def __init__(self, mgr, args):
28        super().__init__(mgr, args)
29        self._cmds = {}
30        self._start_modes = {}
31        self._boot_list = {}
32        self._condition_list = {}
33        self._start_cmd_list = {}
34
35    def _get_json_service(self):
36        for i in range(len(self._start_modes)):
37            if self._start_modes[i]["start-mode"] == "boot":
38                self._boot_list = self._start_modes[i]["service"]
39            elif self._start_modes[i]["start-mode"] == "condition":
40                self._condition_list = self._start_modes[i]["service"]
41        pass
42
43    def _get_start_cmds(self, parser):
44        list = {}
45        for cmd in parser._cmds:
46            if cmd["name"] == "start":
47                list[cmd["content"]] = cmd["fileId"]
48                pass
49        return list
50
51    def _parse_while_list(self):
52        white_lists =self.get_white_lists()[0]
53        for key, item in white_lists.items():
54            if key == "cmds":
55                self._cmds = item
56            if key == "start-modes":
57                self._start_modes = item
58            if key == "start-cmd":
59                self._start_cmd_list = item
60
61    def _check_condition_start_mode(self, cmd_list, service_name, passed):
62        if service_name in self._condition_list and service_name in cmd_list:
63            pass
64        else:
65            self.warn("\'%s\' cannot be started in conditional mode" % service_name)
66        return passed
67
68
69    def _check_service(self, parser):
70        boot_passed = True
71        condition_passed = True
72        start_cmd_list = self._get_start_cmds(parser).keys()
73        for key, item in parser._services.items():
74            if item.get("start_mode") == "boot":
75                if key not in self._boot_list:
76                    self.warn("\'%s\' cannot be started in boot mode" % key)
77            elif item.get("on_demand") is not True and item.get("start_mode") == "condition":
78                condition_passed = self._check_condition_start_mode(start_cmd_list, key, condition_passed)
79        return boot_passed and condition_passed
80
81    def _check_file_id_in_cmds(self, cmdlist, cmdline):
82        file_id_list = set()
83        # print(cmdlist)
84        for i in range(len(cmdlist)):
85            if cmdline == cmdlist[i]["name"]:
86                file_id_list.add(cmdlist[i]["fileId"])
87                pass
88        return file_id_list
89
90    def _check_cmdline_in_parser(self, parser):
91        passed = True
92        cmdline = []
93        file_id_list = set()
94        parser_cmds = parser._cmds
95
96        for cmd in self._cmds:
97            cmdline = cmd["cmd"]
98            file_id_list = self._check_file_id_in_cmds(parser_cmds, cmdline)
99            file_lists = cmd["location"]
100            for key, item in parser._files.items():
101                if item["fileId"] in file_id_list and key not in file_lists:
102                    output = "\'" + cmd["cmd"] + "\' is timeout command, in "+  key
103                    self.error("%s" % str(output))
104                    passed = False
105            file_id_list.clear()
106        return passed
107
108    def _check_selinux(self, parser):
109        if parser._selinux != 'enforcing':
110            self.warn("selinux status is %s" %parser._selinux)
111            return True
112
113        passed = True
114        for key, item in parser._services.items():
115            if item.get("secon") == "":
116                output_str = "%s \'secon\' is empty" % key
117                self.error("%s" % str(output_str))
118                passed = False
119        return passed
120
121    def _check_start_cmd(self, parser):
122        passed = True
123        start_cmd_list = self._get_start_cmds(parser)
124        for cmd, file_id in start_cmd_list.items():
125            if cmd in list(self._start_cmd_list):
126                pass
127            else:
128                for key, item in parser._files.items():
129                    if item["fileId"] == file_id:
130                        log_str = cmd + " is not in start cmd list. " + " path:" + item["file_name"]
131                        self.warn("%s" % log_str)
132                        passed = False
133                    pass
134        return passed
135
136    def check_config_cmd(self):
137        passed = True
138        self._parse_while_list()
139        cfg_parser = self.get_mgr().get_parser_by_name('cmd_whitelist')
140        self._get_json_service()
141
142        start_passed = self._check_start_cmd(cfg_parser)
143        secon_passed = self._check_selinux(cfg_parser)
144        cmd_passed = self._check_cmdline_in_parser(cfg_parser)
145        start_mode_passed = self._check_service(cfg_parser)
146        passed = start_passed and secon_passed and cmd_passed and start_mode_passed
147        return passed
148
149    def __check__(self):
150        return self.check_config_cmd()
151