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