def fix(self): try: if not self.ci.getcurrvalue(): return success = True self.detailedresults = "" self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) if os.path.exists(self.path): sttyText = readFile(self.path, self.logger) newSttyText = [] for line in sttyText: # Check for both serial connections and the old style of # virtual connections if re.search(self.serialRE, line) or \ re.search(r"^vc/\d", line): line = "#" + line newSttyText.append(line) newSttyString = "".join(newSttyText) tmpfile = self.path + ".tmp" if writeFile(tmpfile, newSttyString, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": self.path} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange( self.path, tmpfile, myid) os.rename(tmpfile, self.path) perms = self.perms setPerms(self.path, perms, self.logger, self.statechglogger, myid) resetsecon(self.path) else: success = False self.detailedresults += "Problem writing new " + \ "contents to temporary file" self.rulesuccess = success except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fixShadow(self): success = True if not os.path.exists(self.shadowfile): self.detailedresults += self.shadowfile + "does not exist. \ Will not perform fix on shadow file\n" return False if self.fixusers: contents = readFile(self.shadowfile, self.logger) if self.ph.manager == "apt-get": perms = [0, 42, 0o640] else: perms = [0, 0, 0o400] if not checkPerms(self.shadowfile, perms, self.logger) and \ not checkPerms(self.shadowfile, [0, 0, 0], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) setPerms(self.shadowfile, perms, self.logger, self.statechglogger, myid) tmpdate = strftime("%Y%m%d") tmpdate = list(tmpdate) date = tmpdate[0] + tmpdate[1] + tmpdate[2] + tmpdate[3] + "-" + \ tmpdate[4] + tmpdate[5] + "-" + tmpdate[6] + tmpdate[7] for user in self.fixusers: cmd = ["chage", "-d", date, "-m", "1", "-M", "180", "-W", "28", "-I", "35", user] self.ch.executeCommand(cmd) # We have to do some gymnastics here, because chage writes directly # to /etc/shadow, but statechglogger expects the new contents to # be in a temp file. newContents = readFile(self.shadowfile, self.logger) shadowTmp = "/tmp/shadow.stonixtmp" createFile(shadowTmp, self.logger) writeFile(shadowTmp, "".join(newContents) + "\n", self.logger) writeFile(self.shadowfile, "".join(contents) + "\n", self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {'eventtype': 'conf', 'filepath': self.shadowfile} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(self.shadowfile, shadowTmp, myid) shutil.move(shadowTmp, self.shadowfile) os.chmod(self.shadowfile, perms[2]) os.chown(self.shadowfile, perms[0], perms[1]) resetsecon(self.shadowfile) return success
def fixFreebsd(self): if not checkPerms(self.path, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.path, [0, 0, 0o644], self.logger, self.statechglogger, myid): return False if self.networkTuning1.getcurrvalue() or \ self.networkTuning2.getcurrvalue(): if self.editor.fixables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if not self.editor.fix(): return False elif not self.editor.commit(): return False os.chown(self.path, 0, 0) os.chmod(self.path, 0o644) resetsecon(self.path) cmd = ["/usr/sbin/service", "sysctl", "restart"] self.ch.executeCommand(cmd) if self.ch.getReturnCode() != 0: self.detailedresults = "Unable to restart sysctl\n" self.logger.log(LogPriority.DEBUG, self.detailedresults) return False else: return True else: return True
def fixsolaris(self): '''because solaris has to be different @author bemalmbe ''' if not checkPerms(self.editor.getPath(), [0, 3, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.editor.getPath(), [0, 3, 420], self.logger, self.statechglogger, myid): self.rulesuccess = False if self.editor.fixables or self.editor.removeables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if not self.editor.fix(): self.detailedresults += "Unable to run fix for kveditor\n" self.rulesuccess = False return False elif not self.editor.commit(): self.detailedresults += "Unable to run commit for kveditor\n" self.rulesuccess = False return False return True
def fixMain(self, command): '''Entries that are found with an empty password field (2nd field) should have the blank field replaced with an ! @author: dwalker :param command: ''' success = True if os.path.exists(self.shadow): if self.empty: for user in self.empty: try: retval = call(command + user, stdout=None, shell=True) if retval != 0: self.detailedresults += "not able to lock the \ following account: " + user + "\n" success = False except OSError: success = False self.detailedresults += traceback.format_exc() + "\n" self.detailedresults += " unable to run the account \ lock command\n" if self.ph: if self.ph.manager == "apt-get": retval = getUserGroupName("/etc/shadow") if retval[0] != "root" or retval[1] != "shadow": uid = pwd.getpwnam("root").pw_uid gid = grp.getgrnam("shadow").gr_gid setPerms("/etc/shadow", [uid, gid, 416], self.logger) else: if not checkPerms(self.shadow, [0, 0, 256], self.logger) \ and not checkPerms(self.shadow, [0, 0, 0], self.logger): if not setPerms(self.shadow, [0, 0, 256], self.logger): success = False else: if not checkPerms(self.shadow, [0, 0, 256], self.logger) and \ not checkPerms(self.shadow, [0, 0, 0], self.logger): if not setPerms(self.shadow, [0, 0, 256], self.logger): success = False return success else: self.detailedresults += "/etc/shadow file or /etc/master.passwd \ file not present, cannot perform fix\n" return False
def fixLogDef(self, specs): success = True debug = "" if not os.path.exists(self.logdeffile): if createFile(self.logdeffile, self.logger): self.logindefcreate = True setPerms(self.logdeffile, [0, 0, 0o644], self.logger) tmpfile = self.logdeffile + ".tmp" self.editor1 = KVEditorStonix(self.statechglogger, self.logger, "conf", self.logdeffile, tmpfile, specs, "present", "space") else: self.detailedresults += "Was not able to create " + \ self.logdeffile + " file\n" success = False if self.logindefcreate: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.logdeffile} self.statechglogger.recordchgevent(myid, event) elif not checkPerms(self.logdeffile, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.logdeffile, [0, 0, 0o644], self.logger, self.statechglogger, myid): debug += "permissions not correct on: " + \ self.logdeffile + "\n" success = False if self.editor1.fixables or self.editor1.removeables: if not self.logindefcreate: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor1.setEventID(myid) if not self.editor1.fix(): debug += "fixLogDef editor.fix did not complete successfully\n" success = False elif not self.editor1.commit(): debug += "fixLogDef editor.commit did not complete successfully\n" success = False os.chown(self.logdeffile, 0, 0) os.chmod(self.logdeffile, 0o644) resetsecon(self.logdeffile) if debug: self.logger.log(LogPriority.DEBUG, debug) return success
def setaccountlockout(self, regex): """ configure the account lockout time in pam :param regex: string; regular expression :return: success :rtype: bool """ success = True pamfiles = [] if self.ph.manager in ("yum", "dnf"): pamfiles.append(self.pamauthfile) pamfiles.append(self.pampassfile) writecontents = self.auth + "\n" + self.acct + "\n" + \ self.password + "\n" + self.session else: pamfiles.append(self.pamauthfile) writecontents = self.auth for pamfile in pamfiles: if not os.path.exists(pamfile): self.detailedresults += pamfile + " doesn't exist.\n" + \ "Stonix will not attempt to create this file " + \ "and the fix for the this rule will not continue\n" return False # """Check permissions on pam file(s)""" for pamfile in pamfiles: if not checkPerms(pamfile, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(pamfile, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to set " + \ "correct permissions on " + pamfile + "\n" contents = readFile(pamfile, self.logger) found = False for line in contents: if re.search(regex, line.strip()): found = True if not found: tmpfile = pamfile + ".stonixtmp" if writeFile(tmpfile, writecontents, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {'eventtype': 'conf', 'filepath': pamfile} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(pamfile, tmpfile, myid) os.rename(tmpfile, pamfile) os.chown(pamfile, 0, 0) os.chmod(pamfile, 0o644) resetsecon(pamfile) else: self.detailedresults += "Unable to write to " + pamfile + "\n" success = False return success
def fix(self): try: if not self.ci.getcurrvalue(): return results = "" success = True # Clear out event history so only the latest fix is recorded self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) if os.path.exists(self.path): if not checkPerms(self.path, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.path, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False results += "Could not set permissions on " + \ self.path + "\n" if self.editor.fixables or self.editor.removeables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if not self.editor.fix(): debug = "kveditor fix did not run successfully\n" self.logger.log(LogPriority.DEBUG, debug) success = False elif not self.editor.commit(): debug = "kveditor commit did not run successfully\n" self.logger.log(LogPriority.DEBUG, debug) success = False os.chown(self.path, 0, 0) os.chmod(self.path, 0o644) resetsecon(self.path) else: success = False results += "Could not find path to sshd_config\n" self.detailedresults = results self.rulesuccess = success except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False success = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", success, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def setlogindefs(self): """ configure login.defs options :return: success :rtype: bool """ success = True if not checkPerms(self.logindefs, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.logindefs, [0, 0, 0o644], self.logger, self.statechglogger, myid): self.detailedresults += "Unable to set permissions on " + self.logindefs + " file\n" success = False if self.editor2: if self.editor2.fixables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor2.setEventID(myid) if self.editor2.fix(): if self.editor2.commit(): debug = "/etc/login.defs file has been corrected\n" self.logger.log(LogPriority.DEBUG, debug) os.chown(self.logindefs, 0, 0) os.chmod(self.logindefs, 0o644) resetsecon(self.logindefs) else: debug = "Unable to correct the contents of /etc/login.defs\n" self.detailedresults += "Unable to correct the contents of /etc/login.defs\n" self.logger.log(LogPriority.DEBUG, debug) success = False else: self.detailedresults += "Unable to correct the contents of /etc/login.defs\n" debug = "Unable to correct the contents of /etc/login.defs\n" self.logger.log(LogPriority.DEBUG, debug) success = False return success
def fixLinux(self): ''' @change: dkennel removed extraneous arg from setperms call on 864 ''' universal = "#The following lines were added by stonix\n" debug = "" success = True ifacefile = "" netwrkfile = "" sysctl = "/etc/sysctl.conf" blacklistfile = "/etc/modprobe.d/stonix-blacklist.conf" # STIG portion, correct netconfig file if self.ph.manager == "apt-get": nfspkg = "nfs-common" else: nfspkg = "nfs-utils.x86_64" # if package not installed, no need to configure it if self.ph.check(nfspkg): if os.path.exists("/etc/netconfig"): filestring = "" # we want to make sure the following two lines don't # appear in the netconfig file item1 = "udp6 tpi_clts v inet6 udp - -" item2 = "tcp6 tpi_cots_ord v inet6 tcp - -" contents = readFile("/etc/netconfig", self.logger) for line in contents: templine = re.sub("\s+", " ", line.strip()) # if we find the lines, skip them thus leaving them out of # of the rewrite if re.search(item1, templine) or re.search( item2, templine): continue else: filestring += line tmpfile = "/etc/netconfig.tmp" if not writeFile(tmpfile, filestring, self.logger): success = False else: # record event, rename file, set perms self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": "/etc/netconfig"} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange( "/etc/netconfig", tmpfile, myid) os.rename(tmpfile, "/etc/netconfig") os.chown("/etc/netconfig", 0, 0) os.chmod("/etc/netconfig", 420) resetsecon("/etc/netconfig") # remove any ipv6 addresses from /etc/hosts file if os.path.exists("/etc/hosts"): contents = readFile("/etc/hosts", self.logger) tempstring = "" tmpfile = "/etc/hosts.tmp" for line in contents: if re.search("^#", line) or re.match("^\s*$", line): tempstring += line continue elif re.search(":", line): tempstring += "#" + line else: tempstring += line if writeFile(tmpfile, tempstring, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": "/etc/hosts"} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange("/etc/hosts", tmpfile, myid) os.rename(tmpfile, "/etc/hosts") os.chown("/etc/hosts", 0, 0) os.chmod("/etc/hosts", 420) resetsecon("/etc/hosts") else: success = False debug = "Unable to write to file /etc/hosts\n" self.logger.log(LogPriority.DEBUG, debug) # fix sysctl / tuning kernel parameters # manually write key value pairs to /etc/sysctl.conf created = False if not os.path.exists(sysctl): if createFile(sysctl, self.logger): created = True setPerms(sysctl, [0, 0, 0o644], self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": sysctl} self.statechglogger.recordchgevent(myid, event) else: success = False debug = "Unable to create " + sysctl + "\n" self.logger.log(LogPriority.DEBUG, debug) if os.path.exists(sysctl): if not checkPerms(sysctl, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(sysctl, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False tmpfile = sysctl + ".tmp" self.editor1 = KVEditorStonix(self.statechglogger, self.logger, "conf", sysctl, tmpfile, self.sysctls, "present", "openeq") if not self.editor1.report(): if self.editor1.fixables: # If we did not create the file, set an event ID for the # KVEditor's undo event if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor1.setEventID(myid) if not self.editor1.fix(): success = False debug = "Unable to complete kveditor fix method" + \ "for /etc/sysctl.conf file\n" self.logger.log(LogPriority.DEBUG, debug) elif not self.editor1.commit(): success = False debug = "Unable to complete kveditor commit " + \ "method for /etc/sysctl.conf file\n" self.logger.log(LogPriority.DEBUG, debug) if not checkPerms(sysctl, [0, 0, 0o644], self.logger): if not setPerms(self.path, [0, 0, 0o644], self.logger): self.detailedresults += "Could not set permissions on " + \ self.path + "\n" success = False resetsecon(sysctl) # here we also check the output of the sysctl command for each key # to cover all bases for key in self.sysctls: if self.ch.executeCommand("/sbin/sysctl " + key): output = self.ch.getOutputString().strip() errmsg = output + self.ch.getErrorString() if re.search("unknown key", errmsg): continue if not re.search(self.sysctls[key] + "$", output): undovalue = output[-1] self.ch.executeCommand("/sbin/sysctl -q -e -w " + key + "=" + self.sysctls[key]) retcode = self.ch.getReturnCode() if retcode != 0: success = False self.detailedresults += "Failed to set " + key + " = " + self.sysctls[ key] + "\n" errmsg = self.ch.getErrorString() self.logger.log(LogPriority.DEBUG, errmsg) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) command = "/sbin/sysctl -q -e -w " + key + "=" + undovalue event = { "eventtype": "commandstring", "command": command } self.statechglogger.recordchgevent(myid, event) else: self.detailedresults += "Unable to get value for " + key + "\n" success = False # at the end do a print and ignore any key errors to ensure # the new values are read into the kernel self.ch.executeCommand("/sbin/sysctl -q -e -p") retcode2 = self.ch.getReturnCode() if retcode2 != 0: success = False self.detailedresults += "Failed to load new sysctl configuration from config file\n" errmsg2 = self.ch.getErrorString() self.logger.log(LogPriority.DEBUG, errmsg2) # We never found the correct contents in any of the modprobe.d files # so we're going to created the stonix-blacklist file # this file is used in other rules if not self.modprobeOK: created = False tmpfile = blacklistfile + ".tmp" modprobekveditor = KVEditorStonix(self.statechglogger, self.logger, "conf", blacklistfile, tmpfile, self.modprobes, "notpresent", "space") if not os.path.exists(blacklistfile): # create the file and record the event as file creation if createFile(blacklistfile, self.logger): created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = { "eventtype": "creation", "filepath": blacklistfile } self.statechglogger.recordchgevent(myid, event) if os.path.exists(blacklistfile): if not modprobekveditor.report(): if not modprobekveditor.fix(): success = False self.detailedresults += "Unable to correct contents in " + \ blacklistfile + "\n" else: # if the file was created, then we already recorded an event # for that, so this step would get skipped if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) modprobekveditor.setEventID(myid) if not modprobekveditor.commit(): success = False self.detailedresults += "Unable to correct contents in " + \ blacklistfile + "\n" # fix ifcfg (interface) files if self.ph.manager == "yum": ifacefile = "/etc/sysconfig/network-scripts/" netwrkfile = "/etc/sysconfig/network" elif self.ph.manager == "zypper": ifacefile = "/etc/sysconfig/network/" if ifacefile: if os.path.exists(ifacefile): dirs = glob.glob(ifacefile + "*") if dirs: for loc in dirs: interface = {"IPV6INIT": "no", "NETWORKING_IPV6": "no"} interface2 = { "IPV6INIT": "no", "NETWORKING_IPV6": "no" } found = False tempstring = "" if re.search('^' + ifacefile + 'ifcfg', loc): filename = loc tmpfile = filename + ".tmp" contents = readFile(filename, self.logger) if not checkPerms(filename, [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(filename, [0, 0, 420], self.logger, self.statechglogger, myid): debug = "Unable to set permissions on " + \ filename + "\n" self.logger.log(LogPriority.DEBUG, debug) success = False for key in interface: found = False for line in contents: if re.search("^#", line) or \ re.match("^\s*$", line): continue if re.search("^" + key, line): if re.search("=", line): temp = line.split("=") if temp[1].strip( ) == interface[key]: if found: continue found = True else: contents.remove(line) if found: del interface2[key] for line in contents: tempstring += line tempstring += universal for key in interface2: tempstring += key + "=" + interface2[key] + \ "\n" if not writeFile(tmpfile, tempstring, self.logger): success = False debug = "Unable to write to file " + loc + "\n" self.logger.log(LogPriority.DEBUG, debug) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {'eventtype': 'conf', 'filepath': filename} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange( filename, tmpfile, myid) os.rename(tmpfile, filename) os.chown(filename, 0, 0) os.chmod(filename, 420) resetsecon(filename) elif not os.path.exists(ifacefile) and ifacefile != "": # will not attempt to create the interface files debug = "interface directory which holds interface \ files, doesn't exist, stonix will not attempt to make this \ directory or the files contained therein" success = False self.logger.log(LogPriority.DEBUG, debug) # fix network file if it exists if netwrkfile: if not os.path.exists(netwrkfile): if not createFile(netwrkfile, self.logger): debug = "Unable to create " + netwrkfile + "file\n" self.logger.log(LogPriority.DEBUG, debug) success = False else: if not checkPerms(netwrkfile, [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(netwrkfile, [0, 0, 420], self.logger, self.statechglogger, myid): debug = "Unable to set permissions on " + \ netwrkfile + "\n" self.logger.log(LogPriority.DEBUG, debug) success = False tmpfile = netwrkfile + ".tmp" self.editor2 = KVEditorStonix(self.statechglogger, self.logger, "conf", netwrkfile, tmpfile, self.interface, "present", "closedeq") if not self.editor2.report(): self.detailedresults += netwrkfile + " doesn't contain \ the correct contents\n" if self.editor2: if self.editor2.fixables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor2.setEventID(myid) if not self.editor2.fix(): success = False debug = "Unable to complete kveditor fix method" + \ "for " + netwrkfile + "\n" self.logger.log(LogPriority.DEBUG, debug) elif not self.editor2.commit(): success = False debug = "Unable to complete kveditor commit " + \ "method for " + netwrkfile + "\n" self.logger.log(LogPriority.DEBUG, debug) os.chown(netwrkfile, 0, 0) os.chmod(netwrkfile, 420) resetsecon(netwrkfile) # fix sshd_config file for apt-get systems if ssh is installed if self.ph.manager == "apt-get": if not os.path.exists("/etc/ssh/sshd_config"): msg = "/etc/ssh/ssd_config doesn\'t exist. This could mean ssh \ is not installed or the file has been inadvertantly deleted. Due to the \ complexity of this file stonix will not attempt to create this file" self.logger.log(LogPriority.DEBUG, msg) success = False else: if not checkPerms("/etc/ssh/sshd_config", [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms("/etc/ssh/sshd_config", [0, 0, 420], self.logger, self.statechglogger, myid): success = False debug = "Unable to set permissions on " + \ "/etc/ssh/sshd_config\n" self.logger.log(LogPriority.DEBUG, debug) if self.editor3: if self.editor3.fixables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor3.setEventID(myid) if not self.editor3.fix(): success = False debug = "Unable to complete kveditor fix method" + \ "for /etc/ssh/sshd_config file\n" self.logger.log(LogPriority.DEBUG, debug) elif not self.editor3.commit(): success = False debug = "Unable to complete kveditor commit " + \ "method for /etc/ssh/sshd_config file\n" self.logger.log(LogPriority.DEBUG, debug) os.chown("/etc/ssh/sshd_config", 0, 0) os.chmod("/etc/ssh/sshd_config", 420) resetsecon("/etc/ssh/sshd_config") return success
def fix(self): '''The fix method will apply the required settings to the system. self.rulesuccess will be updated if the rule does not succeed. @author: Breen Malmberg @change: dwalker - added statechglogger findrulechanges and deleteentry @changed: Breen Malmberg - 12/05/2017 - removed unnecessary servicetarget ''' try: self.rulesuccess = True self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) self.detailedresults = "" # if this system is a mac, run fixmac() if self.ismac: self.rulesuccess = self.fixmac() # if not mac os x, run this portion else: # if DisableAvahi CI is enabled, disable the avahi service # and remove the package if self.DisableAvahi.getcurrvalue(): avahi = self.package avahid = 'avahi-daemon' if self.sh.auditService(avahid): debug = "Disabling " + avahid + " service" self.logger.log(LogPriority.DEBUG, debug) self.sh.disableService(avahid) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = { "eventtype": "servicehelper", "servicename": avahid, "startstate": "enabled", "endstate": "disabled" } self.statechglogger.recordchgevent(myid, event) if self.environ.getosfamily() == 'linux' and \ self.pkghelper.check(avahi): if self.numdependencies <= 3: self.pkghelper.remove(avahi) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = { "eventtype": "pkghelper", "pkgname": avahi, "startstate": "installed", "endstate": "removed" } self.statechglogger.recordchgevent(myid, event) else: debug += 'Avahi package has too many dependent ' \ + 'packages. Will not attempt to remove.\n' self.logger.log(LogPriority.DEBUG, debug) if self.pkghelper.determineMgr() == 'yum' or \ self.pkghelper.determineMgr() == 'dnf': path = self.path if not os.path.exists(path): if createFile(path, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = { "eventtype": "creation", "filepath": path } self.statechglogger.recordchgevent(myid, event) else: self.rulesuccess = False self.detailedresults += "Failed to create " + \ "file: " + path + ".\n" if self.editor is None: tmppath = path + ".tmp" data = {"NOZEROCONF": "yes"} self.editor = KVEditorStonix( self.statechglogger, self.logger, "conf", path, tmppath, data, "present", "closedeq") if not self.editor.report(): if self.editor.fix(): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if not self.editor.commit(): self.rulesuccess = False self.detailedresults += "Could not " + \ "commit changes to " + path + ".\n" else: self.rulesuccess = False self.detailedresults += "Could not fix " + \ "file " + path + ".\n" # if SecureMDNS CI is enabled, configure avahi-daemon.conf if self.SecureMDNS.getcurrvalue(): # if config file is present, proceed avahiconf = '/etc/avahi/avahi-daemon.conf' if os.path.exists(avahiconf): if self.avahiconfeditor.fixables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.avahiconfeditor.setEventID(myid) if not self.avahiconfeditor.fix(): self.rulesuccess = False debug = "KVEditor fix for " + avahiconf + \ "failed" self.logger.log(LogPriority.DEBUG, debug) elif not self.avahiconfeditor.commit(): self.rulesuccess = False debug = "KVEditor commit for " + avahiconf + \ "failed" self.logger.log(LogPriority.DEBUG, debug) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) setPerms(avahiconf, [0, 0, 0o644], self.logger, self.statechglogger, myid) resetsecon(avahiconf) # if config file is not present and avahi not installed, # then we can't configure it else: if not self.pkghelper.check(avahi): debug = 'Avahi Daemon not installed. ' + \ 'Cannot configure it.' self.logger.log(LogPriority.DEBUG, debug) else: self.detailedresults += 'Avahi daemon ' + \ 'installed, but could not locate the ' + \ 'configuration file for it.\n' self.rulesuccess = False except IOError: self.detailedresults += '\n' + traceback.format_exc() self.logger.log(LogPriority.DEBUG, self.detailedresults) except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fix(self): '''will check if the shadow, passwd, or group file is present and if so remove the plus(+) account located in the file ''' try: if not self.ci.getcurrvalue(): return self.detailedresults = "" #clear out event history so only the latest fix is recorded self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) for path in self.badfiles: path = path.strip() if os.path.exists(path): tempstring = "" contents = readFile(path, self.logger) if not contents: continue for line in contents: if not re.search('^\+', line.strip()): tempstring += line if path == "/etc/master.passwd": if not checkPerms(path, [0, 0, 384], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) setPerms(path, [0, 0, 384], self.logger, self.statechglogger, myid) elif path == "/etc/shadow": #put in code to handle apt-get systems /etc/shadow file later #for this file, the owner is root, but the group is shadow #by default this group is 42 but may not always be that if self.ph.manager == "apt-get": retval = getUserGroupName("/etc/shadow") if retval[0] != "root" or retval[1] != "shadow": uid = pwd.getpwnam("root").pw_uid gid = grp.getgrnam("shadow").gr_gid self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) setPerms(path, [uid, gid, 420], self.logger, self.statechglogger, myid) else: if not checkPerms(path, [0, 0, 256], self.logger) and \ not checkPerms(path, [0, 0, 0], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) setPerms(path, [0, 0, 256], self.logger, self.statechglogger, myid) else: if not checkPerms(path, [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) setPerms(path, [0, 0, 420], self.logger, self.statechglogger, myid) tmpfile = path + ".tmp" if not writeFile(tmpfile, tempstring, self.logger): self.rulesuccess = False return self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {'eventtype': 'conf', 'filepath': path} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(path, tmpfile, myid) os.rename(tmpfile, path) if path == "/etc/master.passwd": os.chown(path, 0, 0) os.chmod(path, 384) elif path == "/etc/shadow": if self.ph.manager == "apt-get": os.chown(path, uid, gid) os.chmod(path, 420) else: os.chown(path, 0, 0) os.chmod(path, 256) else: os.chmod(path, 420) resetsecon(path) except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fix(self): try: if not self.ci.getcurrvalue(): self.detailedresults += "CI not enabled\n" else: success = True self.detailedresults = "" self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) if not os.path.exists(self.path1): createFile(self.path1, self.logger) self.created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.path1} self.statechglogger.recordchgevent(myid, event) self.tmppath = self.path1 + ".tmp" self.editor1 = KVEditorStonix(self.statechglogger, self.logger, "conf", self.path1, self.tmppath, self.data1, "present", "closedeq") self.editor1.report() self.editor2 = KVEditorStonix(self.statechglogger, self.logger, "conf", self.path1, self.tmppath, self.data2, "present", "space") self.editor2.report() if self.editor1.fixables or self.editor2.fixables: if self.editor1.fix(): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor1.setEventID(myid) if self.editor1.commit(): debug = self.path1 + "'s contents have been " + \ "corrected\n" self.logger.log(LogPriority.DEBUG, debug) resetsecon(self.path1) else: debug = "kveditor commit not successful\n" self.logger.log(LogPriority.DEBUG, debug) success = False self.detailedresults += self.path1 + \ " properties could not be set\n" else: debug = "kveditor fix not successful\n" self.logger.log(LogPriority.DEBUG, debug) success = False self.detailedresults += self.path1 + \ " properties could not be set\n" if self.editor2.fix(): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor2.setEventID(myid) if self.editor2.commit(): debug = self.path1 + "'s contents have been " + \ "corrected\n" self.logger.log(LogPriority.DEBUG, debug) resetsecon(self.path1) else: debug = "kveditor commit not successful\n" self.logger.log(LogPriority.DEBUG, debug) success = False self.detailedresults += self.path1 + \ " properties could not be set\n" else: debug = "kveditor fix not successful\n" self.logger.log(LogPriority.DEBUG, debug) success = False self.detailedresults += self.path1 + \ " properties could not be set\n" if not checkPerms(self.path1, [0, 0, 0o755], self.logger) and \ not checkPerms(self.path1, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.path1, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Could not set permissions " + \ "for " + self.path1 + "\n" if not os.path.exists(self.path2): createFile(self.path2, self.logger) self.created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.path2} self.statechglogger.recordchgevent(myid, event) writeFile(self.path2, self.cshData, self.logger) if not checkPerms(self.path2, [0, 0, 0o755], self.logger) and \ not checkPerms(self.path2, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.path2, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Could not set permissions " + \ "for " + self.path2 + "\n" self.rulesuccess = success except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fix(self): ''' ''' try: if not self.ci.getcurrvalue(): return self.detailedresults = "" success = True created = False self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) if self.installed: if not os.path.exists(self.squidfile): if not createFile(self.squidfile, self.logger): success = False else: created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.squidfile} self.statechglogger.recordchgevent(myid, event) if not checkPerms(self.squidfile, [0, 0, 420], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.squidfile, [0, 0, 420], self.logger, self.statechglogger, myid): success = False else: if not setPerms(self.squidfile, [0, 0, 420], self.logger): success = False tempstring = "" contents = readFile(self.squidfile, self.logger) newcontents = [] if contents: '''Remove any undesired acl lines''' for line in contents: if re.match('^#', line) or re.match(r'^\s*$', line): newcontents.append(line) elif re.search("^acl Safe_ports port ", line.strip()): m = re.search("acl Safe_ports port ([0-9]+).*", line) if m.group(1): item = "acl Safe_ports port " + m.group(1) if item in self.denied: continue else: newcontents.append(line) else: newcontents.append(line) '''removeables list holds key vals we find in the file that we can remove from self.data''' removeables = [] '''deleteables list holds key vals we can delete from newcontents list if it's incorrect.''' deleteables = {} for key in self.data1: found = False for line in reversed(newcontents): if re.match('^#', line) or re.match(r'^\s*$', line): continue elif re.search("^" + key + " ", line) or re.search("^" + key, line): temp = line.strip() temp = re.sub("\s+", " ", temp) temp = temp.split(" ") if len(temp) >= 3: joinlist = [temp[1], temp[2]] joinstring = " ".join(joinlist) if self.data1[key] == joinstring: '''We already found this line and value No need for duplicates''' if found: newcontents.remove(line) continue removeables.append(key) found = True else: try: deleteables[line] = "" except Exception: continue continue elif len(temp) == 2: if self.data1[key] == temp[1]: '''We already found this line and value No need for duplicates''' if found: newcontents.remove(line) continue removeables.append(key) found = True else: try: deleteables[line] = "" except Exception: continue continue elif len(temp) == 1: try: deleteables[line] = "" except Exception: continue continue if deleteables: for item in deleteables: newcontents.remove(item) '''anything in removeables we found in the file so we will remove from the self.data1 dictionary''' if removeables: for item in removeables: del(self.data1[item]) '''now check if there is anything left over in self.data1 if there is we need to add that to newcontents list''' if self.data1: for item in self.data1: line = item + " " + self.data1[item] + "\n" newcontents.append(line) for line in newcontents: found = False if re.search("^http_access", line.strip()): temp = line.strip() temp = re.sub("\s+", " ", temp) temp = re.sub("http_access\s+", "", temp) if re.search("^deny to_localhost", temp): found = True break if not found: newcontents.append("http_access deny to_localhost\n") for item in newcontents: tempstring += item tmpfile = self.squidfile + ".tmp" if not writeFile(tmpfile, tempstring, self.logger): success = False else: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": self.squidfile} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(self.squidfile, tmpfile, myid) os.rename(tmpfile, self.squidfile) os.chown(self.squidfile, 0, 0) os.chmod(self.squidfile, 420) resetsecon(self.squidfile) else: tempstring = "" for item in self.data1: tempstring += item + " " + self.data1[item] + "\n" for item in self.data2: tempstring += item + " " + self.data2[item] + "\n" tmpfile = self.squidfile + ".tmp" if not writeFile(tmpfile, tempstring, self.logger): success = False else: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": self.squidfile} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(self.squidfile, tmpfile, myid) os.rename(tmpfile, self.squidfile) os.chown(self.squidfile, 0, 0) os.chmod(self.squidfile, 420) resetsecon(self.squidfile) self.rulesuccess = success except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception as err: self.rulesuccess = False self.detailedresults = self.detailedresults + "\n" + str(err) + \ " - " + str(traceback.format_exc()) self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fix(self): try: if not self.ci.getcurrvalue(): return self.iditerator = 0 # clear out event history so only the latest fix is recorded eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) success = True index = { "/etc/X11/gdm/gdm.conf": "command = /usr/X11R6/bin/X -nolisten tcp", "/usr/share/gdm/defaults.conf": "DisallowTCP = true", "/etc/gdm/custom.conf": "DisallowTCP = true", "/etc/X11/xinit/xserverrc": "exec /usr/X11R6/bin/X -nolisten tcp", "/etc/kde/kdm/kdmrc": "ServerArgsLocal = -nolisten tcp", "/etc/kde4/kdm/kdmrc": "ServerArgsLocal = -nolisten tcp", "/usr/share/config/kdm/kdmrc": "ServerArgsLocal = -nolisten tcp", "/etc/sysconfig/displaymanager": 'DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN=NO', "/etc/dt/config/Xservers": ":0 Local local_uid@console root /usr/X11/bin/Xserver :0 -nobanner -nolisten tcp", "/usr/dt/config/Xservers": ":0 Local local_uid@console root /usr/X11/bin/Xserver :0 -nobanner -nolisten tcp" } for item in self.fp1: if os.path.exists(item[1]): if item[1] == "/etc/X11/xdm/Xservers" or \ item[1] == "/usr/X11R6/lib/X11/xdm/Xservers": if not checkPerms(item[1], [0, 0, 292], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(item[1], [0, 0, 292], self.logger, self.statechglogger, myid): success = False else: if not checkPerms(item[1], [0, 3, 292], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(item[1], [0, 3, 292], self.logger, self.statechglogger, myid): success = False for item in self.fp2: if os.path.exists(item[1]): if item[1] == "/etc/X11/xinit/xserverrc": if not checkPerms(item[1], [0, 0, 493], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(item[1], [0, 0, 493], self.logger, self.statechglogger, myid): success = False elif not checkPerms(item[1], [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(item[1], [0, 0, 420], self.logger, self.statechglogger, myid): success = False for item in self.fixables1: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if self.writeConfig(item[1], myid, item[0], item[2]): os.chown(item[1], 0, 0) os.chmod(item[1], 292) resetsecon(item[1]) else: success = False for item in self.fixables2: for item2 in index: if item[1] == item2: item[0] = index[item2] self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if self.writeConfig(item[1], myid, item[0], item[2]): if item[1] == "/etc/X11/xinit/xserverrc": os.chmod(item[1], 493) else: os.chmod(item[1], 420) os.chown(item[1], 0, 0) resetsecon(item[1]) else: success = False if self.environ.getosfamily() == "solaris": fp3 = "/etc/X11/gdm/gdm.conf" if self.editor.fixables(): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if self.editor.fix(): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if self.editor.commit(): self.detailedresults += "/etc/X11/gdm/gdm.conf \ file has been fixed\n" os.chown(fp3, 0, 0) os.chmod(fp3, 292) resetsecon(fp3) else: debug = "kveditor commit did not run successfully, must return" self.logger.log(LogPriority.DEBUG, debug) success = False else: debug = "kveditor fix did not run successfully, must return" self.logger.log(LogPriority.DEBUG, debug) success = False self.rulesuccess = success except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fix(self): try: if not self.ci.getcurrvalue(): return success = True # Clean out old undo events self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) self.detailedresults = "" if not os.path.exists(self.path): createFile(self.path, self.logger) self.created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.path} self.statechglogger.recordchgevent(myid, event) self.editor = KVEditorStonix(self.statechglogger, self.logger, "conf", self.path, self.tmppath, self.data1, "present", "space") self.editor.report() tempstring = "" tmpfile = self.path + ".tmp" contents = readFile(self.path, self.logger) changes = False for line in contents: found = False if re.match('^#', line) or re.match(r'^\s*$', line): tempstring += line continue if re.search("^option", line): temp = line.split() if len(temp) >= 2: for item in self.data2: if re.search(item, temp[1]): found = True changes = True break if found: continue else: tempstring += line else: tempstring += line if changes: debug = "Writing changes to " + tmpfile self.logger.log(LogPriority.DEBUG, debug) if not writeFile(tmpfile, tempstring, self.logger): debug = "Unable to write changes to " + tmpfile self.detailedresults += debug self.logger.log(LogPriority.DEBUG, debug) success = False else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": self.path} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange( self.path, tmpfile, myid) os.rename(tmpfile, self.path) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) setPerms(self.path, [0, 0, 0o644], self.logger, self.statechglogger, myid) resetsecon(self.path) if self.editor.fixables: if not self.created: if not checkPerms(self.path, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.path, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if self.editor.fix(): if self.editor.commit(): debug = self.path + "'s contents have been " + \ "corrected\n" self.logger.log(LogPriority.DEBUG, debug) os.chown(self.path, 0, 0) os.chmod(self.path, 0o644) resetsecon(self.path) else: debug = "kveditor commit not successful\n" self.logger.log(LogPriority.DEBUG, debug) success = False else: debug = "kveditor fix not successful\n" self.logger.log(LogPriority.DEBUG, debug) success = False self.rulesuccess = success except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fix_security_limits(self): '''ensure the limits.conf file contains the configuration setting * hard core 0 :returns: succcess :rtype: bool @author: ??? ''' success = True path1 = "/etc/security/limits.conf" lookfor1 = "(^\*)\s+hard\s+core\s+0?" created = False if not os.path.exists(path1): if not createFile(path1, self.logger): success = False self.detailedresults += "Unable to create " + path1 + " file\n" else: created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": "path1"} self.statechglogger.recordchgevent(myid, event) if os.path.exists(path1): if not checkPerms(path1, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(path1, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to correct permissions on " + path1 + "\n" contents = readFile(path1, self.logger) found = False tempstring = "" if contents: for line in contents: if re.search(lookfor1, line.strip()): found = True else: tempstring += line else: found = False if not found: tempstring += "* hard core 0\n" tempfile = path1 + ".stonixtmp" if not writeFile(tempfile, tempstring, self.logger): success = False self.detailedresults += "Unable to write contents to " + path1 + "\n" else: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": path1} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange( path1, tempfile, myid) os.rename(tempfile, path1) setPerms(path1, [0, 0, 0o644], self.logger) resetsecon(path1) return success
def fix(self): '''Enable the firewall services and establish basic rules if needed. @author: D. Kennel ''' try: if not self.clfci.getcurrvalue(): return self.iditerator = 0 self.detailedresults = "" success = True # delete past state change records from previous fix eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) #firewall-cmd portion if self.checkFirewalld(): if self.servicehelper.enableService('firewalld.service', serviceTarget=self.serviceTarget): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) cmd = "/usr/bin/systemctl disable firewalld.service" event = {"eventtype": "commandstring", "command": cmd} self.statechglogger.recordchgevent(myid, event) self.detailedresults += "Firewall configured.\n " else: success = False self.detailedresults += "Unable to enable firewall\n" debug = "Unable to enable firewall\n" self.logger.log(LogPriority.DEBUG, debug) #ufw command portion elif self.checkUFW(): self.logger.log(LogPriority.DEBUG, "System uses ufw. Running ufw commands...") cmdufw = '/usr/sbin/ufw status' if not self.cmdhelper.executeCommand(cmdufw): self.detailedresults += "Unable to run " + \ "ufw status command\n" success = False else: outputufw = self.cmdhelper.getOutputString() if re.search('Status: inactive', outputufw): ufwcmd = '/usr/sbin/ufw --force enable' if not self.cmdhelper.executeCommand(ufwcmd): self.detailedresults += "Unable to run " + \ "ufw enable command\n" success = False else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) undocmd = "/usr/sbin/ufw --force disable" event = {"eventtype": "commandstring", "command": undocmd} self.statechglogger.recordchgevent(myid, event) cmdufw = "/usr/sbin/ufw status verbose" if not self.cmdhelper.executeCommand(cmdufw): self.detailedresults += "Unable to retrieve firewall rules\n" success = False else: outputfw = self.cmdhelper.getOutputString() if not re.search("Default\:\ deny\ \(incoming\)", outputfw): ufwcmd = "/usr/sbin/ufw default deny incoming" if not self.cmdhelper.executeCommand(ufwcmd): self.detailedresults += "Unable to set default " + \ "rule for incoming unspecified packets\n" success = False else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) undocmd = "/usr/sbin/ufw default allow incoming" event = {"eventtype": "commandstring", "command": undocmd} self.statechglogger.recordchgevent(myid, event) elif re.search('Status: active', outputufw): cmdufw = "/usr/sbin/ufw status verbose" if not self.cmdhelper.executeCommand(cmdufw): self.detailedresults += "Cannot retrieve firewall rules\n" success = False else: outputufw = self.cmdhelper.getOutputString() if not re.search("Default\:\ deny\ \(incoming\)", outputufw): ufwcmd = "/usr/sbin/ufw default deny incoming" if not self.cmdhelper.executeCommand(ufwcmd): self.detailedresults += "Unable to set default " + \ "rule for incoming unspecified packets\n" success = False else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) undocmd = "/usr/sbin/ufw default allow incoming" event = {"eventtype": "commandstring", "command": undocmd} self.statechglogger.recordchgevent(myid, event) else: #following portion is mainly for debian and opensuse systems only if os.path.exists("/etc/network/if-pre-up.d"): self.iptScriptPath = "/etc/network/if-pre-up.d/iptables" self.scriptType = "debian" servicename = "networking" elif os.path.exists("/etc/sysconfig/scripts"): self.iptScriptPath = "/etc/sysconfig/scripts/SuSEfirewall2-custom" self.scriptType = "suse" servicename = "network" #this script will ensure that iptables gets configured #each time the network restarts iptables = self.getScriptValues("iptables") ip6tables = self.getScriptValues("ip6tables") iptScript = "" created = False if self.iptScriptPath: if self.scriptType == "debian": if self.iprestore and self.ip6restore: iptScript = '#!/bin/bash\n' + self.iprestore + \ ' <<< "' + iptables + '"\n' + self.ip6restore + \ ' <<< "' + ip6tables + '"' else: iptScript = self.getScriptValues("iptscript") if iptScript: if not os.path.exists(self.iptScriptPath): if not createFile(self.iptScriptPath, self.logger): success = False self.detailedresults += "Unable to create file " + self.iptScriptPath + "\n" else: created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.iptScriptPath} self.statechglogger.recordchgevent(myid, event) if os.path.exists(self.iptScriptPath): if not checkPerms(self.iptScriptPath, [0, 0, 0o755], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.iptScriptPath, [0, 0, 0o755], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to set permissions on " + self.iptScriptPath + "\n" contents = readFile(self.iptScriptPath, self.logger) if contents != iptScript: tempfile = self.iptScriptPath + ".tmp" if not writeFile(tempfile, iptScript, self.logger): success = False self.detailedresults += "Unable to write contents to " + self.iptScriptPath + "\n" else: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": self.iptScriptPath} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(self.iptScriptPath, tempfile, myid) os.rename(tempfile, self.iptScriptPath) os.chown(self.iptScriptPath, 0, 0) os.chmod(self.iptScriptPath, 0o755) resetsecon(self.iptScriptPath) stonixfilepath = "/var/db/stonix/" savecmd = "/sbin/iptables-save > " + stonixfilepath + "user-firewall-pre-stonix" if not self.cmdhelper.executeCommand(savecmd): success = False self.detailedresults += "Unable to save current ipv4 " + \ "firewall rules for revert\n" debug = "Unable to save current ipv4 " + \ "firewall rules for revert\n" self.logger.log(LogPriority.DEBUG, debug) save6cmd = "/sbin/ip6tables-save > " + stonixfilepath + "user-firewall6-pre-stonix" if not self.cmdhelper.executeCommand(save6cmd): success = False self.detailedresults += "Unable to save current ipv6 " + \ "firewall rules for revert\n" debug = "Unable to save current ipv6 " + \ "firewall rules for revert\n" self.logger.log(LogPriority.DEBUG, debug) self.servicehelper.stopService(servicename) if not self.servicehelper.startService(servicename): success = False self.detailedresults += "Unable to restart networking\n" debug = "Unable to restart networking\n" self.logger.log(LogPriority.DEBUG, debug) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) cmd = "/sbin/iptables-restore < " + stonixfilepath + "user-firewall-pre-stonix" event = {"eventtype": "commandstring", "command": cmd} self.statechglogger.recordchgevent(myid, event) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) cmd = "/sbin/ip6tables-restore < " + stonixfilepath + "user-firewall6-pre-stonix" event = {"eventtype": "commandstring", "command": cmd} self.statechglogger.recordchgevent(myid, event) else: success = False self.detailedresults += "There is no iptables startup script\n" debug = "There is no iptables startup script\n" self.logger.log(LogPriority.DEBUG, debug) #this portion mostly applies to RHEL6 and Centos6 if os.path.exists('/usr/bin/system-config-firewall') or \ os.path.exists('/usr/bin/system-config-firewall-tui'): systemconfigfirewall = self.getScriptValues("systemconfigfirewall") sysconfigiptables = self.getScriptValues("sysconfigiptables") sysconfigip6tables = self.getScriptValues("sysconfigip6tables") fwpath = '/etc/sysconfig/system-config-firewall' iptpath = '/etc/sysconfig/iptables' ip6tpath = '/etc/sysconfig/ip6tables' #portion to handle the system-config-firewall file created = False if not os.path.exists(fwpath): if not createFile(fwpath, self.logger): success = False self.detailedresults += "Unable to create file " + fwpath + "\n" else: created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": fwpath} self.statechglogger.recordchgevent(myid, event) if os.path.exists(fwpath): if not checkPerms(fwpath, [0, 0, 0o600], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(fwpath, [0, 0, 0o600], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to set permissions on " + fwpath + "\n" contents = readFile(fwpath, self.logger) if contents != systemconfigfirewall: print("contents don't equal systemconfigurefirewall contents\n") tempfile = fwpath + ".tmp" if not writeFile(tempfile, systemconfigfirewall, self.logger): success = False self.detailedresults += "Unable to write contents to " + fwpath + "\n" else: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": fwpath} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(fwpath, tempfile, myid) os.rename(tempfile, fwpath) os.chown(fwpath, 0, 0) os.chmod(fwpath, 0o600) resetsecon(fwpath) created = False #portion to handle the iptables rules file if not os.path.exists(iptpath): if not createFile(iptpath, self.logger): success = False self.detailedresults += "Unable to create file " + iptpath + "\n" else: created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": iptpath} self.statechglogger.recordchgevent(myid, event) if os.path.exists(iptpath): if not checkPerms(iptpath, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(iptpath, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to set permissions on " + iptpath + "\n" contents = readFile(iptpath, self.logger) if contents != sysconfigiptables: tempfile = iptpath + ".tmp" if not writeFile(tempfile, sysconfigiptables, self.logger): success = False self.detailedresults += "Unable to write contents to " + iptpath + "\n" else: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": iptpath} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(iptpath, tempfile, myid) os.rename(tempfile, iptpath) os.chown(iptpath, 0, 0) os.chmod(iptpath, 0o644) resetsecon(iptpath) created = False #portion to handle ip6tables rules file if not os.path.exists(ip6tpath): if not createFile(ip6tpath, self.logger): success = False self.detailedresults += "Unable to create file " + ip6tpath + "\n" else: created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": ip6tpath} self.statechglogger.recordchgevent(myid, event) if os.path.exists(ip6tpath): if not checkPerms(ip6tpath, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(ip6tpath, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to set permissions on " + ip6tpath + "\n" contents = readFile(ip6tpath, self.logger) if contents != sysconfigip6tables: tempfile = ip6tpath + ".tmp" if not writeFile(tempfile, sysconfigip6tables, self.logger): success = False self.detailedresults += "Unable to write contents to " + ip6tpath + "\n" else: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": ip6tpath} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(ip6tpath, tempfile, myid) os.rename(tempfile, ip6tpath) os.chown(ip6tpath, 0, 0) os.chmod(ip6tpath, 0o644) resetsecon(ip6tpath) # check if iptables is enabled to run at start if not self.servicehelper.auditService('iptables'): # enable service to run at start if not if not self.servicehelper.enableService('iptables'): self.detailedresults += "Unable to enable iptables service\n" debug = "Unable to enable iptables service\n" self.logger.log(LogPriority.DEBUG, debug) success = False else: # record event if successful self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) cmd = self.servicehelper.getDisableCommand('iptables') event = {"eventtype": "commandstring", "command": cmd} self.statechglogger.recordchgevent(myid, event) self.servicehelper.stopService('iptables') # start iptables if not if not self.servicehelper.startService('iptables'): self.detailedresults += "Unable to start iptables service\n" debug = "Unable to start iptables service\n" self.logger.log(LogPriority.DEBUG, debug) success = False else: stonixfilepath = "/var/db/stonix/" savecmd = "/sbin/iptables-save > " + stonixfilepath + "user-firewall-pre-stonix" if not self.cmdhelper.executeCommand(savecmd): success = False self.detailedresults += "Unable to save current ipv4 " + \ "firewall rules for revert\n" debug = "Unable to save current ipv4 " + \ "firewall rules for revert\n" self.logger.log(LogPriority.DEBUG, debug) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) cmd = "/sbin/iptables-restore < " + stonixfilepath + "user-firewall-pre-stonix" event = {"eventtype": "commandstring", "command": cmd} self.statechglogger.recordchgevent(myid, event) savecmd = "/sbin/ip6tables-save > " + stonixfilepath + "user-firewall6-pre-stonix" if not self.cmdhelper.executeCommand(savecmd): success = False self.detailedresults += "Unable to save current ipv6 " + \ "firewall rules for revert\n" debug = "Unable to save current ipv6 " + \ "firewall rules for revert\n" self.logger.log(LogPriority.DEBUG, debug) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) cmd = "/sbin/ip6tables-restore < " + stonixfilepath + "user-firewall6-pre-stonix" event = {"eventtype": "commandstring", "command": cmd} self.statechglogger.recordchgevent(myid, event) # check if ip6tables is enabled to run at start if not self.servicehelper.auditService('ip6tables'): # enable service to run at start if not if not self.servicehelper.enableService('ip6tables'): self.detailedresults += "Unable to enable ip6tables service\n" debug = "Unable to enable ip6tables service\n" self.logger.log(LogPriority.DEBUG, debug) success = False else: # record event if successful self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) cmd = self.servicehelper.getDisableCommand('ip6tables') event = {"eventtype": "commandstring", "command": cmd} self.statechglogger.recordchgevent(myid, event) self.servicehelper.stopService('ip6tables') # start ip6tables if not if not self.servicehelper.startService('ip6tables'): self.detailedresults += "Unable to start ip6tables service\n" debug = "Unable to start ip6tables service\n" self.logger.log(LogPriority.DEBUG, debug) success = False # Sleep for a bit to let the restarts occur time.sleep(10) self.rulesuccess = success except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def afterfix(self): for path in self.permsdict: setPerms(path, self.permsdict[path], self.logdispatch, self.statechglogger)
def fixMac(self): '''run fix actions for mac systems :returns: success :rtype: bool @author: dwalker @change: Breen Malmberg - 1/10/2017 - added doc string; try/except; fixed perms for file sysctl.conf (should be 0o600; was 0o644) ''' success = True try: if not os.path.exists(self.path): if createFile(self.path, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.path} self.statechglogger.recordchgevent(myid, event) else: return False if self.networkTuning2.getcurrvalue(): if not self.editor: mfc = {"net.inet.ip.forwarding": "0", "net.inet.ip.redirect": "0"} kvtype = "conf" intent = "present" self.editor = KVEditorStonix(self.statechglogger, self.logger, kvtype, self.path, self.tmpPath, mfc, intent, "closedeq") if not self.editor.report(): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if self.editor.fix(): if not self.editor.commit(): success = False self.detailedresults += "KVEditor commit to " + \ self.path + " was not successful\n" else: success = False self.detailedresults += "KVEditor fix of " + self.path + \ " was not successful\n" resetsecon(self.path) if not checkPerms(self.path, [0, 0, 0o600], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.path, [0, 0, 0o600], self.logger, self.statechglogger, myid): self.detailedresults += "Could not set permissions on " + \ self.path + "\n" success = False except Exception: raise return success
def fixLinux(self): success = True created = False debug = "" sysctl = "/etc/sysctl.conf" tmpfile = sysctl + ".tmp" if not os.path.exists(sysctl): if createFile(sysctl, self.logger): created = True setPerms(sysctl, [0, 0, 0o644], self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": sysctl} self.statechglogger.recordchgevent(myid, event) else: self.detailedresults += "Could not create file " + self.path + \ "\n" self.formatDetailedResults("fix", False, self.detailedresults) if not checkPerms(sysctl, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(sysctl, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False lfc = {} if self.networkTuning1 and self.networkTuning1.getcurrvalue(): lfc.update({"net.ipv4.conf.all.secure_redirects": "0", "net.ipv4.conf.all.accept_redirects": "0", "net.ipv4.conf.all.rp_filter": "1", "net.ipv4.conf.all.log_martians": "1", "net.ipv4.conf.all.accept_source_route": "0", "net.ipv4.conf.default.accept_redirects": "0", "net.ipv4.conf.default.secure_redirects": "0", "net.ipv4.conf.default.rp_filter": "1", "net.ipv4.conf.default.accept_source_route": "0", "net.ipv4.tcp_syncookies": "1", "net.ipv4.icmp_echo_ignore_broadcasts": "1", "net.ipv4.tcp_max_syn_backlog": "4096"}) if self.networkTuning2 and self.networkTuning2.getcurrvalue(): lfc.update({"net.ipv4.conf.default.send_redirects": "0", "net.ipv4.conf.all.send_redirects": "0", "net.ipv4.ip_forward": "0"}) self.editor = KVEditorStonix(self.statechglogger, self.logger, "conf", sysctl, tmpfile, lfc, "present", "openeq") if not self.editor.report(): if self.editor.fixables: # If we did not create the file, set an event ID for the # KVEditor's undo event to record the file write if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if not self.editor.fix(): success = False debug = "KVEditor fix of " + self.path + \ " was not successful\n" self.logger.log(LogPriority.DEBUG, debug) elif not self.editor.commit(): success = False debug = "KVEditor commit to " + \ self.path + " was not successful\n" self.logger.log(LogPriority.DEBUG, debug) # permissions on file are incorrect if not checkPerms(self.path, [0, 0, 0o644], self.logger): if not setPerms(self.path, [0, 0, 0o644], self.logger): self.detailedresults += "Could not set permissions on " + \ self.path + "\n" success = False resetsecon(self.path) # here we also check the output of the sysctl command for each key # to cover all bases for key in lfc: if self.ch.executeCommand("/sbin/sysctl " + key): output = self.ch.getOutputString().strip() if not re.search(lfc[key] + "$", output): undovalue = output[-1] self.ch.executeCommand("/sbin/sysctl -w " + key + "=" + lfc[key]) retcode = self.ch.getReturnCode() if retcode != 0: success = False self.detailedresults += "Failed to set " + key + " = " + lfc[key] + "\n" errmsg = self.ch.getErrorString() self.logger.log(LogPriority.DEBUG, errmsg) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) command = "/sbin/sysctl -w " + key + "=" + undovalue event = {"eventtype": "commandstring", "command": command} self.statechglogger.recordchgevent(myid, event) else: self.detailedresults += "Unable to get value for " + key + "\n" success = False # at the end do a print and ignore any key errors to ensure # the new values are read into the kernel self.ch.executeCommand("/sbin/sysctl -q -e -p") retcode2 = self.ch.getReturnCode() if retcode2 != 0: success = False self.detailedresults += "Failed to load new sysctl configuration from config file\n" errmsg2 = self.ch.getErrorString() self.logger.log(LogPriority.DEBUG, errmsg2) return success
def fixLinux(self): '''sub method for linux portion of compliance fixing @author: dwalker :returns: success :rtype: boolean ''' success = True created1, created2 = False, False changed = False tempstring = "" grubfilefound = False for grub in self.grubfiles: if os.path.exists(grub): grubfilefound = True if self.grubperms: if not checkPerms(grub, self.grubperms, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(grub, self.grubperms, self.logger, self.statechglogger, myid): success = False contents = readFile(grub, self.logger) kernellinefound = False if contents: for line in contents: if re.search("^kernel", line.strip()) or re.search("^linux", line.strip()) \ or re.search("^linux16", line.strip()): kernellinefound = True if not re.search("\s+nousb\s*", line): changed = True tempstring += line.strip() + " nousb" if not re.search( "\s+usbcore\.authorized_default=0\s+", line): changed = True tempstring += line.strip( ) + " usbcore.authorized_default=0" tempstring += "\n" elif re.search("^set default_kernelopts", line.strip()): # Fedora 31 has changed it's kernel option line format kernellinefound = True kernelline = line.strip() if not re.search("\s+nousb\s*", kernelline): changed = True kernelline = re.sub("\"$", " nousb\"", kernelline) if not re.search( "\s+usbcore\.authorized_default=0\s+", kernelline): changed = True kernelline = re.sub( "\"$", " usbcore.authorized_default=0\"", kernelline) tempstring += kernelline + "\n" else: tempstring += line if not kernellinefound: changed = False self.detailedresults += "The grub file doesn't contain kernel line\n" + \ "Unable to fully implement fixes in this rule\n" success = False if changed: tmpfile = grub + ".tmp" if writeFile(tmpfile, tempstring, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": grub} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange( grub, tmpfile, myid) os.rename(tmpfile, grub) if not setPerms(grub, self.grubperms, self.logger): success = False self.detailedresults += "Unable to set permissions on " + \ grub + " file\n" else: success = False if not grubfilefound: self.detailedresults += "No grub configuration file found\n" + \ "Unable to fully fix system for this rule\n" success = False blacklistf = "/etc/modprobe.d/stonix-blacklist.conf" tempstring = "" # Check if self.blacklist still contains values, if it # does, then we didn't find all the blacklist values # in report if self.blacklist: # didn't find one or more directives in the files # inside modprobe.d so we now check an alternate file # we create stonixblacklist file if it doesn't # exist and put remaining unfound blacklist # items there if not os.path.exists(blacklistf): created1 = True createFile(blacklistf, self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": blacklistf} self.statechglogger.recordchgevent(myid, event) # file was already present and we need contents already # inside file to remain in newly written file if not created1: contents = readFile(blacklistf, self.logger) for item in contents: tempstring += item for item in self.blacklist: tempstring += item + "\n" tmpfile = blacklistf + ".tmp" if writeFile(tmpfile, tempstring, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": blacklistf} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(blacklistf, tmpfile, myid) os.rename(tmpfile, blacklistf) os.chown(blacklistf, 0, 0) os.chmod(blacklistf, 420) resetsecon(blacklistf) if not checkPerms(blacklistf, [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(blacklistf, [0, 0, 420], self.logger, self.statechglogger, myid): success = False if self.ph.manager == "apt-get": cmd = ["/usr/sbin/update-initramfs", "-u"] if not self.ch.executeCommand(cmd): success = False self.detailedresults += "Unable to run update-initramfs command\n" for item in self.pcmcialist: if self.ph.check(item): self.ph.remove(item) self.pkgremovedlist.append(item) if not os.path.exists(self.udevfile): if not createFile(self.udevfile, self.logger): self.detailedresults += "Unable to create " + \ self.udevfile + " file\n" success = False else: created2 = True if os.path.exists(self.udevfile): if not checkPerms(self.udevfile, [0, 0, 0o644], self.logger): if created2: if not setPerms(self.udevfile, [0, 0, 0o644], self.logger): success = False self.detailedresults += "Unable to set " + \ "permissions on " + self.udevfile + "\n" else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.udevfile, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to set " + \ "permissions on " + self.udevfile + "\n" found = False contents = readFile(self.udevfile, self.logger) tempstring = "" for line in contents: if re.search( "ACTION==\"add\"\, SUBSYSTEMS==\"usb\"\, RUN+=\"/bin/sh -c \'for host in /sys/bus/usb/devices/usb\*\; do echo 0 > \$host/authorized_default; done\'\"", line.strip()): found = True tempstring += line if not found: tempstring += "ACTION==\"add\", SUBSYSTEMS==\"usb\", RUN+=\"/bin/sh -c \'for host in /sys/bus/usb/devices/usb*; do echo 0 > $host/authorized_default; done\'\"" tmpfile = self.udevfile + ".tmp" if writeFile(tmpfile, tempstring, self.logger): if not created2: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = { "eventtype": "conf", "filepath": self.udevfile } self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange( self.udevfile, tmpfile, myid) os.rename(tmpfile, self.udevfile) os.chown(self.udevfile, 0, 0) os.chmod(self.udevfile, 0o644) resetsecon(self.udevfile) else: success = False self.detailedresults += "Unable to write changes " + \ "to " + self.udevfile + "\n" return success
def setpasswordsetup(self, regex1, pkglist = None): """ configure password requirements in pam, install necessary packages :param regex1: string; regular expression :param pkglist: list; string names of packages to install :return: success :rtype: bool """ regex2 = "^password[ \t]+sufficient[ \t]+pam_unix.so sha512 shadow " + \ "try_first_pass use_authtok remember=10" success = True pamfiles = [] installed = False if pkglist: for pkg in pkglist: if self.ph.check(pkg): installed = True break else: installed = True if not installed: for pkg in pkglist: if self.ph.checkAvailable(pkg): if not self.ph.install(pkg): self.detailedresults += "Unable to install pkg " + pkg + "\n" return False else: installed = True if self.usingpwquality: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) comm = self.ph.getRemove() + pkg event = {"eventtype": "commandstring", "command": comm} self.statechglogger.recordchgevent(myid, event) pwqfile = "/etc/security/pwquality.conf" tmpfile = pwqfile + ".stonixtmp" if self.environ.getsystemfismacat() == "high": data = {"difok": "7", "minlen": "14", "dcredit": "0", "ucredit": "0", "lcredit": "0", "ocredit": "0", "maxrepeat": "3", "minclass": "4"} else: data = {"difok": "7", "minlen": "8", "dcredit": "0", "ucredit": "0", "lcredit": "0", "ocredit": "0", "maxrepeat": "3", "minclass": "3"} self.pwqeditor = KVEditorStonix(self.statechglogger, self.logger, "conf", pwqfile, tmpfile, data, "present", "openeq") self.pwqeditor.report() break if not installed: self.detailedresults += "No password checking program available\n" return False if self.usingpwquality: if not self.setpwquality(): success = False if self.ph.manager in ("yum", "dnf"): writecontents = self.auth + "\n" + self.acct + "\n" + \ self.password + "\n" + self.session pamfiles.append(self.pamauthfile) pamfiles.append(self.pampassfile) else: writecontents = self.password pamfiles.append(self.pampassfile) for pamfile in pamfiles: if not os.path.exists(pamfile): self.detailedresults += pamfile + " doesn't exist.\n" + \ "Stonix will not attempt to create this file " + \ "and the fix for the this rule will not continue\n" return False # """Check permissions on pam file(s)""" for pamfile in pamfiles: if not checkPerms(pamfile, [0, 0, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(pamfile, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to set correct permissions on " + pamfile + "\n" contents = readFile(pamfile, self.logger) found1, found2 = False, False for line in contents: if re.search(regex1, line.strip()): found1 = True if re.search(regex2, line.strip()): found2 = True if not found1 or not found2: tmpfile = pamfile + ".stonixtmp" if writeFile(tmpfile, writecontents, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {'eventtype': 'conf', 'filepath': pamfile} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(pamfile, tmpfile, myid) os.rename(tmpfile, pamfile) os.chown(pamfile, 0, 0) os.chmod(pamfile, 0o644) resetsecon(pamfile) else: self.detailedresults += "Unable to write to " + pamfile + "\n" success = False return success
def setlibuser(self): """Method to check if libuser is installed and the contents of libuser file. @author: Derek Walker :return: bool """ created = False success = True data = {"defaults": {"crypt_style": "sha512"}} # """check if installed""" if not self.ph.check("libuser"): # """if not installed, check if available""" if self.ph.checkAvailable("libuser"): # """if available, install it""" if not self.ph.install("libuser"): self.detailedresults += "Unable to install libuser\n" return False else: # """since we're just now installing it we know we now # need to create the kveditor""" self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) comm = self.ph.getRemove() + "libuser" event = {"eventtype": "commandstring", "command": comm} self.statechglogger.recordchgevent(myid, event) datatype = "tagconf" intent = "present" tmppath = self.libuserfile + ".stonixtmp" self.editor1 = KVEditorStonix(self.statechglogger, self.logger, datatype, self.libuserfile, tmppath, data, intent, "openeq") self.editor1.report() else: return True if not os.path.exists(self.libuserfile): if not createFile(self.libuserfile, self.logger): self.detailedresults += "Unable to create libuser file\n" debug = "Unable to create the libuser file\n" self.logger.log(LogPriority.DEBUG, debug) return False created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.libuserfile} self.statechglogger.recordchgevent(myid, event) tmppath = self.libuserfile + ".stonixtmp" self.editor1 = KVEditorStonix(self.statechglogger, self.logger, "tagconf", self.libuserfile, tmppath, data, "present", "openeq") self.editor1.report() if not checkPerms(self.libuserfile, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.libuserfile, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to set the permissions on " + self.libuserfile + "\n" elif not setPerms(self.libuserfile, [0, 0, 0o644], self.logger): success = False self.detailedresults += "Unable to set the permissions on " + self.libuserfile + "\n" if self.editor1.fixables: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor1.setEventID(myid) if self.editor1.fix(): if self.editor1.commit(): debug = "/etc/libuser.conf has been corrected\n" self.logger.log(LogPriority.DEBUG, debug) os.chown(self.libuserfile, 0, 0) os.chmod(self.libuserfile, 0o644) resetsecon(self.libuserfile) else: self.detailedresults += "/etc/libuser.conf couldn't be corrected\n" success = False else: self.detailedresults += "/etc/libuser.conf couldn't be corrected\n" success = False return success
def fix(self): '''DisableWeakAuthentication.fix() Public method to fix any issues that were found in the report method. @author: dwalker :returns: bool - False if the method died during execution ''' try: self.detailedresults = "" if not self.ci.getcurrvalue(): return success = True for item in self.rsh: if self.helper.check(item): if not self.helper.remove(item): success = False if self.incorrects: for item in self.incorrects: tempstring = "" contents = readFile(item, self.logger) if not contents: continue for line in contents: if re.match('^#', line) or re.match(r'^\s*$', line): tempstring += line elif re.search("pam_rhosts", line): continue else: tempstring += line if not checkPerms(item, [0, 0, 420], self.logger): if not setPerms(item, [0, 0, 420], self.logger): success = False tmpfile = item + ".tmp" if writeFile(tmpfile, tempstring, self.logger): os.rename(tmpfile, item) os.chown(item, 0, 0) os.chmod(item, 420) resetsecon(item) else: success = False for item in self.pams: if os.path.exists(item): if not checkPerms(item, [0, 0, 420], self.logger): if not setPerms(item, [0, 0, 420], self.logger): success = False if os.path.exists("/etc/pam.d/"): fileItems = glob.glob("/etc/pam.d/*") for item in fileItems: if not checkPerms(item, [0, 0, 420], self.logger): if not setPerms(item, [0, 0, 420], self.logger): success = False return success except (KeyboardInterrupt, SystemExit): raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fixOther(self): config = "" success = True permswrong = False debug = "" if not os.path.exists(self.shadow): debug += "shadow or master.passwd file not present, \ cannot perform fix" self.logger.log(LogPriority.DEBUG, debug) return False statdata = os.stat(self.shadow) owner = statdata.st_uid group = statdata.st_gid mode = stat.S_IMODE(statdata.st_mode) if not checkPerms(self.shadow, [0, 0, 256], self.logger) or \ not checkPerms(self.shadow, [0, 0, 0], self.logger): permswrong = True if not setPerms(self.shadow, [0, 0, 256], self.logger): success = False contents = readFile(self.shadow, self.logger) if not contents: return False if self.empty: try: for line in contents: for user in self.empty: if re.search(":", line): temp = line.split(':') if temp[0] == user: tempstring = "" if temp[1].strip() == "": temp[1] = "!" tempstring = ":".join(temp) config += tempstring break else: config += line else: config += line continue except IndexError: raise except Exception: self.detailedresults += traceback.format_exc() + "\n" self.detailedresults += "Index out of range\n, stonix will \ not continue to complete fix" self.logger.log(LogPriority.DEBUG, self.detailedresults) return False tempfile = self.shadow + ".tmp" if not writeFile(tempfile, config, self.logger): success = False os.rename(tempfile, self.shadow) if permswrong: os.chown(self.shadow, 0, 0) os.chmod(self.shadow, 256) else: os.chown(self.shadow, owner, group) os.chmod(self.shadow, mode) return success
def fix_sysctl(self): '''set the systemd configuration setting fs.suid_dumpable to 0 :returns: success :rtype: bool @author: ??? ''' success = True # manually writing key and value to /etc/sysctl.conf sysctl = "/etc/sysctl.conf" created = False if not os.path.exists(sysctl): if createFile(sysctl, self.logger): created = True setPerms(sysctl, [0, 0, 0o644], self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": sysctl} self.statechglogger.recordchgevent(myid, event) else: success = False debug = "Unable to create " + sysctl + "\n" self.logger.log(LogPriority.DEBUG, debug) if os.path.exists(sysctl): if not checkPerms(sysctl, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(sysctl, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False tmpfile = sysctl + ".tmp" editor = KVEditorStonix(self.statechglogger, self.logger, "conf", sysctl, tmpfile, {"fs.suid_dumpable": "0"}, "present", "openeq") if not editor.report(): if editor.fixables: # If we did not create the file, set an event ID for the # KVEditor's undo event if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) editor.setEventID(myid) if not editor.fix(): success = False debug = "Unable to complete kveditor fix method" + \ "for /etc/sysctl.conf file\n" self.logger.log(LogPriority.DEBUG, debug) elif not editor.commit(): success = False debug = "Unable to complete kveditor commit " + \ "method for /etc/sysctl.conf file\n" self.logger.log(LogPriority.DEBUG, debug) if not checkPerms(sysctl, [0, 0, 0o644], self.logger): if not setPerms(sysctl, [0, 0, 0o644], self.logger): self.detailedresults += "Could not set permissions on " + \ self.path + "\n" success = False resetsecon(sysctl) # using sysctl -w command self.logger.log(LogPriority.DEBUG, "Configuring /etc/sysctl fs.suid_dumpable directive") self.ch.executeCommand("/sbin/sysctl -w fs.suid_dumpable=0") retcode = self.ch.getReturnCode() if retcode != 0: success = False self.detailedresults += "Failed to set core dumps variable suid_dumpable to 0\n" errmsg = self.ch.getErrorString() self.logger.log(LogPriority.DEBUG, errmsg) else: self.logger.log(LogPriority.DEBUG, "Re-reading sysctl configuration from files") self.ch.executeCommand("/sbin/sysctl -q -e -p") retcode2 = self.ch.getReturnCode() if retcode2 != 0: success = False self.detailedresults += "Failed to load new sysctl configuration from config file\n" errmsg2 = self.ch.getErrorString() self.logger.log(LogPriority.DEBUG, errmsg2) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) command = "/sbin/sysctl -w fs.suid_dumpable=1" event = {"eventtype": "commandstring", "command": command} self.statechglogger.recordchgevent(myid, event) return success
def fixFree(self): # debug messages are used for developers, self.detailedresults # are used for the users information path1 = "/etc/rc.conf" path2 = "/etc/sysctl.conf" success = True debug = "" if os.path.exists(path1): if not checkPerms(path1, [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.path, [0, 0, 420], self.logger, self.statechglogger, myid): success = False if self.editor1: if self.editor1.fixables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor1.setEventID(myid) if not self.editor1.fix(): debug += "Kveditor unable to correct file: " + \ path1 + "\n" self.detailedresults += "Unable to correct " + path1 + \ "\n" success = False elif not self.editor1.commit(): self.detailedresults += "Unable to correct " + path1 + \ "\n" debug += "commit for kveditor1 was not successful\n" success = False else: debug += "Editor2 was never created so path didn't exist \ and/or wasn't able to be created\n" success = False else: self.detailedresults += path1 + " doesn't exist!\n" debug += path1 + " doesn't exist, unble to fix file\n" success = False if os.path.exists(path2): # check permissions on /etc/sysctl.conf if not checkPerms(path2, [0, 0, 384], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) # set permissions if wrong if not setPerms(self.path, [0, 0, 384, self.logger], self.statechglogger, myid): success = False # check if editor is present if self.editor2: if self.editor2.fixables(): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor2.setEventID(myid) if not self.editor2.fix(): debug += "Kveditor unable to correct file: " + \ path2 + "\n" self.detailedresults += "Unable to correct " + path2 + \ "\n" success = False elif not self.editor2.commit(): self.detailedresults += "Unable to correct " + path2 + \ "\n" debug += "commit for kveditor2 was not successful\n" success = False else: debug += "Editor2 was never created so path didn't exist \ and/or wasn't able to be created\n" success = False else: self.detailedresults += path2 + " doesn't exist!\n" debug += path2 + " doesn't exist, unble to fix file\n" success = False # restart the network ch = CommandHelper(self.logger) cmd = ["/etc/rc.d/netif", "restart"] if not ch.executeCommand(cmd): self.detaileresults += "Unable to restart network\n" success = False return success
def fix(self): '''The fix method will apply the required settings to the system. self.rulesuccess will be updated if the rule does not succeed. Search for the /etc/sysconfig/init configuration file and set the PROMPT setting to PROMPT=no @author bemalmbe @change: dwalker 4/8/2014 implementing KVEditorStonix ''' try: if not self.ci.getcurrvalue(): return self.detailedresults = "" # clear out event history so only the latest fix is recorded self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) if os.path.exists(self.filepath): if not checkPerms(self.filepath, self.perms, self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.filepath, self.perms, self.logger, self.statechglogger, myid): self.rulesuccess = False if self.editor.fixables: if not self.created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if self.editor.fix(): self.detailedresults += "kveditor fix ran successfully\n" if self.editor.commit(): self.detailedresults += "kveditor commit ran " + \ "successfully\n" else: self.detailedresults += "kveditor commit did not " + \ "run successfully\n" self.rulesuccess = False else: self.detailedresults += "kveditor fix did not run " + \ "successfully\n" self.rulesuccess = False os.chown(self.filepath, self.perms[0], self.perms[1]) os.chmod(self.filepath, self.perms[2]) resetsecon(self.filepath) if self.restart: self.ch.executeCommand(self.restart) if self.ch.getReturnCode() != 0: self.detailedresults += "Unable to restart Grub with " + \ "new changes\n" self.rulesuccess = False except (KeyboardInterrupt, SystemExit): raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess
def fix(self): '''The report method examines the current configuration and determines whether or not it is correct. If the config is correct then the self.compliant, self.detailedresults and self.currstate properties are updated to reflect the system status. self.rulesuccess will be updated if the rule does not succeed. :returns: self.rulesuccess :rtype: bool @author bgonz12 ''' try: self.iditerator = 0 self.detailedresults = "" if not self.ci.getcurrvalue(): return success = True if not os.path.exists(self.securettypath): if not createFile(self.securettypath, self.logger): success = False self.detailedresults += "Unable to create " + \ self.securettypath + "\n" else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.securettypath} self.statechglogger.recordchgevent(myid, event) if not setPerms(self.securettypath, [0, 0, 0o600], self.logger): success = False self.detailedresults += "Unable to correct permissions on " + \ self.securettypath + "\n" elif not self.isblank: tempfile = self.securettypath + ".tmp" if not checkPerms(self.securettypath, [0, 0, 0o600], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.securettypath, [0, 0, 0o600], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to correct permissions on " + \ self.securettypath + "\n" if not writeFile(tempfile, "", self.logger): success = False self.detailedresults += "Unable to write blank contents " + \ "to " + self.securettypath + "\n" else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": self.securettypath} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(self.securettypath, tempfile, myid) os.rename(tempfile, self.securettypath) os.chmod(self.securettypath, 0o600) os.chown(self.securettypath, 0, 0) resetsecon(self.securettypath) else: if not checkPerms(self.securettypath, [0, 0, 0o600], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(self.securettypath, [0, 0, 0o600], self.logger, self.statechglogger, myid): success = False self.detailedresults += "Unable to correct permissions on " + \ self.securettypath + "\n" self.rulesuccess = success except (KeyboardInterrupt, SystemExit): # User initiated exit raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.rulesuccess