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 for i in range(len(cmdlist)): 84 if cmdline == cmdlist[i]["name"]: 85 file_id_list.add(cmdlist[i]["fileId"]) 86 pass 87 return file_id_list 88 89 def _check_cmdline_in_parser(self, parser): 90 passed = True 91 cmdline = [] 92 file_id_list = set() 93 parser_cmds = parser._cmds 94 95 for cmd in self._cmds: 96 cmdline = cmd["cmd"] 97 file_id_list = self._check_file_id_in_cmds(parser_cmds, cmdline) 98 file_lists = cmd["location"] 99 for key, item in parser._files.items(): 100 if item["fileId"] in file_id_list and key not in file_lists: 101 output = "\'{}\' is timeout command, in {}".format(cmd["cmd"], key) 102 self.error("%s" % str(output)) 103 passed = False 104 file_id_list.clear() 105 return passed 106 107 def _check_selinux(self, parser): 108 if parser._selinux != 'enforcing': 109 self.warn("selinux status is %s" %parser._selinux) 110 return True 111 112 passed = True 113 for key, item in parser._services.items(): 114 if item.get("secon") == "": 115 output_str = "%s \'secon\' is empty" % key 116 self.error("%s" % str(output_str)) 117 passed = False 118 return passed 119 120 def _check_start_cmd(self, parser): 121 passed = True 122 start_cmd_list = self._get_start_cmds(parser) 123 for cmd, file_id in start_cmd_list.items(): 124 if cmd in list(self._start_cmd_list): 125 pass 126 else: 127 for key, item in parser._files.items(): 128 if item["fileId"] == file_id: 129 log_str = "{} is not in start cmd list. path:{}".format(cmd, item["file_name"]) 130 self.warn("%s" % log_str) 131 passed = False 132 pass 133 return passed 134 135 def check_config_cmd(self): 136 passed = True 137 self._parse_while_list() 138 cfg_parser = self.get_mgr().get_parser_by_name('cmd_whitelist') 139 self._get_json_service() 140 141 start_passed = self._check_start_cmd(cfg_parser) 142 secon_passed = self._check_selinux(cfg_parser) 143 cmd_passed = self._check_cmdline_in_parser(cfg_parser) 144 start_mode_passed = self._check_service(cfg_parser) 145 passed = start_passed and secon_passed and cmd_passed and start_mode_passed 146 return passed 147 148 def __check__(self): 149 return self.check_config_cmd() 150