def fixLockdownX(self): success = True if self.sh.disableService("xfs", _="_"): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "servicehelper", "servicename": "xfs", "startstate": "enabled", "endstate": "disabled"} self.statechglogger.recordchgevent(myid, event) else: success = False self.detailedresults += "STONIX was unable to disable the " + \ "xfs service\n" if not self.xservSecure: serverrcString = "exec X :0 -nolisten tcp $@" if not os.path.exists(self.serverrc): createFile(self.serverrc, self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.serverrc} self.statechglogger.recordchgevent(myid, event) writeFile(self.serverrc, serverrcString, self.logger) else: open(self.serverrc, "a").write(serverrcString) return success
def setpwquality(self): """ :return: """ success = True created = False pwqfile = "/etc/security/pwquality.conf" if not os.path.exists(pwqfile): createFile(pwqfile, self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {'eventtype': 'creation', 'filepath': pwqfile} self.statechglogger.recordchgevent(myid, event) created = True 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() if self.pwqeditor.fixables: if self.pwqeditor.fix(): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.pwqeditor.setEventID(myid) if not self.pwqeditor.commit(): success = False self.detailedresults += "Unable to correct " + pwqfile + "\n" else: success = False self.detailedresults += "Unable to correct " + pwqfile + "\n" return success
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 report(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. Perform a check to see if PROMPT has been set to 'no' or not :returns: bool @author bemalmbe @change: dwalker ''' try: self.detailedresults = "" compliant = True self.perms = [0, 0, 420] self.helper = Pkghelper(self.logger, self.environ) if self.helper.manager == "portage": self.filepath = "/etc/conf.d/rc" keyval = {"RC_INTERACTIVE": "no"} elif self.helper.manager == "zypper": self.filepath = "/etc/sysconfig/boot" keyval = {"PROMPT_FOR_CONFIRM": "no"} elif self.helper.manager == "apt-get": self.filepath = "/etc/default/grub" keyval = {"GRUB_DISABLE_RECOVERY": '"true"'} self.restart = "/usr/sbin/update-grub" elif self.helper.manager == "yum" or self.helper.manager == "dnf": self.filepath = "/etc/sysconfig/init" keyval = {"PROMPT": "no"} tmpPath = self.filepath + ".tmp" if not os.path.exists(self.filepath): if createFile(self.filepath, self.logger): self.created = True if not checkPerms(self.filepath, self.perms, self.logger): compliant = False self.detailedresults += "Permissions are not correct on " + \ self.filepath + "\n" self.editor = KVEditorStonix(self.statechglogger, self.logger, "conf", self.filepath, tmpPath, keyval, "present", "closedeq") if os.path.exists(self.filepath): if not self.editor.report(): self.detailedresults += "Configuration for " + \ self.filepath + " is incorrect via kveditor report\n" compliant = False self.compliant = compliant except (KeyboardInterrupt, SystemExit): raise except Exception: self.rulesuccess = False self.detailedresults += "\n" + traceback.format_exc() self.logdispatch.log(LogPriority.ERROR, self.detailedresults) self.formatDetailedResults("report", self.compliant, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return self.compliant
def fix(self): try: if not self.ci.getcurrvalue(): return success = True self.detailedresults = "" protocols = self.ci2.getcurrvalue() mpdir = "/etc/modprobe.d/" protoconf = mpdir + "stonix-protocols.conf" self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) if not os.path.exists(protoconf): createFile(protoconf, self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": protoconf} self.statechglogger.recordchgevent(myid, event) for proto in protocols: cmd = ["grep", "-R", proto, mpdir] self.ch.executeCommand(cmd) if not re.search(":install " + proto + " /bin/true", self.ch.getOutputString()): open(protoconf, "a").write("install " + proto + " /bin/true\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 correctFile(self, kfile, user): '''separate method to find the correct contents of each file passed in as a parameter. @author: dwalker :param filehandle: string :param kfile: :param user: :returns: bool ''' created = False success = True self.editor = "" debug = "" if not os.path.exists(kfile): if not createFile(kfile, self.logger): self.detailedresults += "Unable to create " + kfile + \ " file for the user\n" self.logger.log(LogPriority.DEBUG, self.detailedresults) return False created = True if self.environ.geteuid() == 0: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": kfile} self.statechglogger.recordchgevent(myid, event) if not self.searchFile(kfile): if self.editor.fixables: if self.environ.geteuid() == 0 and not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor.setEventID(myid) if not self.editor.fix(): debug = "Kveditor fix is failing for file " + \ kfile + "\n" self.logger.log(LogPriority.DEBUG, debug) self.detailedresults += "Unable to correct contents for " + \ kfile + "\n" return False elif not self.editor.commit(): debug = "Kveditor commit is failing for file " + \ kfile + "\n" self.logger.log(LogPriority.DEBUG, debug) self.detailedresults += "Unable to correct contents for " + \ kfile + "\n" return False uid = getpwnam(user)[2] gid = getpwnam(user)[3] os.chmod(kfile, 0o600) os.chown(kfile, uid, gid) resetsecon(kfile) return success
def correctFile(self, kfile, user): """separate method to find the correct contents of each file passed in as a parameter. @author: dwalker :param kfile: :param user: :returns: bool """ success = True if not os.path.exists(kfile): if not createFile(kfile, self.logger): self.detailedresults += "Unable to create " + kfile + \ " file for the user\n" self.logger.log(LogPriority.DEBUG, self.detailedresults) return False if not self.searchFile(kfile): if self.editor.fixables: if not self.editor.fix(): debug = "Kveditor fix is failing for file " + \ kfile + "\n" self.logger.log(LogPriority.DEBUG, debug) self.detailedresults += "Unable to correct contents for " + \ kfile + "\n" return False elif not self.editor.commit(): debug = "Kveditor commit is failing for file " + \ kfile + "\n" self.logger.log(LogPriority.DEBUG, debug) self.detailedresults += "Unable to correct contents for " + \ kfile + "\n" return False uid = getpwnam(user)[2] gid = getpwnam(user)[3] if uid != "" and gid != "": os.chmod(kfile, 0o600) os.chown(kfile, uid, gid) resetsecon(kfile) else: success = False self.detailedresults += "Unable to obtain uid and gid of " + user + "\n" self.logger.log(LogPriority.DEBUG, self.detailedresults) return success
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 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): ''' ''' 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(): 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 fixGnome(self): """ensures gnome is configured to automatically screen lock after 15 minutes of inactivity, if gnome is installed @author: dwalker :param self: essential if you override this definition :returns: bool - True if gnome is successfully configured, False if it isn't """ info = "" success = True gconf = "/usr/bin/gconftool-2" gsettings = "/usr/bin/gsettings" if os.path.exists(gconf): #variable self.setcmds still has items left in its dictionary #which was set in the reportGnome method, meaning some values #either were incorrect or didn't have values. Go through and #set each remaining value that isn't correct cmd = "" if self.setcmds: for item in self.setcmds: if item == "/apps/gnome-screensaver/idle_activation_enabled": cmd = gconf + " --type bool --set /apps/gnome-screensaver/idle_activation_enabled true" elif item == "/apps/gnome-screensaver/lock_enabled": cmd = gconf + " --type bool --set /apps/gnome-screensaver/lock_enabled true" elif item == "/apps/gnome-screensaver/mode": cmd = gconf + ' --type string --set /apps/gnome-screensaver/mode "blank-only"' elif item == "/desktop/gnome/session/idle_delay": if self.gconfidletime: cmd = gconf + " --type int --set /desktop/gnome/session/idle_delay " + \ self.gconfidletime else: cmd = gconf + " --type int --set /desktop/gnome/session/idle_delay 15" if self.cmdhelper.executeCommand(cmd): if self.cmdhelper.getReturnCode() != 0: info += "Unable to set value for " + cmd + "\n" success = False else: info += "Unable to set value for " + cmd + "\n" success = False if os.path.exists(gsettings): setcmds = [ "org.gnome.desktop.screensaver idle-activation-enabled true", "org.gnome.desktop.screensaver lock-enabled true", "org.gnome.desktop.screensaver lock-delay 0", "org.gnome.desktop.screensaver picture-opacity 100", "org.gnome.desktop.screensaver picture-uri ''", "org.gnome.desktop.session idle-delay 900" ] # " set org.gnome.desktop.session idle-delay " + self.gsettingsidletime] for cmd in setcmds: cmd2 = gsettings + " set " + cmd self.cmdhelper.executeCommand(cmd2) if self.cmdhelper.getReturnCode() != 0: success = False info += "Unable to set value for " + cmd + \ " using gsettings\n" # Set gsettings with dconf # Unlock dconf settings # Create dconf settings lock file if self.environ.geteuid() == 0: if not os.path.exists(self.dconfsettingslock): if not createFile(self.dconfsettingslock, self.logger): self.rulesuccess = False self.detailedresults += "Unable to create stonix-settings file\n" self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) return False #write correct contents to dconf lock file if os.path.exists(self.dconfsettingslock): # Write to the lock file if self.dconflockdata: contents = "" tmpfile = self.dconfsettingslock + ".tmp" for line in self.dconflockdata: contents += line + "\n" if not writeFile(tmpfile, contents, self.logger): self.rulesuccess = False self.detailedresults += "Unable to write contents to " + \ "stonix-settings file\n" else: os.rename(tmpfile, self.dconfsettingslock) os.chown(self.dconfsettingslock, 0, 0) os.chmod(self.dconfsettingslock, 0o644) resetsecon(self.dconfsettingslock) # Create dconf user profile file if not os.path.exists(self.dconfuserprofile): if not createFile(self.dconfuserprofile, self.logger): self.rulesuccess = False self.detailedresults += "Unable to create dconf " + \ "user profile file\n" self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) return False # Write dconf user profile if os.path.exists(self.dconfuserprofile): tmpfile = self.dconfuserprofile + ".tmp" if not writeFile(tmpfile, self.userprofilecontent, self.logger): self.rulesuccess = False self.detailedresults += "Unabled to write to dconf user" + \ " profile file\n" self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) return False else: os.rename(tmpfile, self.dconfuserprofile) os.chown(self.dconfuserprofile, 0, 0) os.chmod(self.dconfuserprofile, 0o644) resetsecon(self.dconfuserprofile) # Fix dconf settings if not os.path.exists(self.dconfsettings): if not createFile(self.dconfsettings, self.logger): self.rulesuccess = False self.detailedresults += "Unable to create " + self.dconfsettings + " file \n" self.formatDetailedResults("fix", self.rulesuccess, self.detailedresults) return False self.dconfdata = { "org/gnome/desktop/screensaver": { "idle-activation-enabled": "true", "lock-enabled": "true", "lock-delay": "0", "picture-opacity": "100", "picture-uri": "\'\'" }, "org/gnome/desktop/session": { "idle-delay": "uint32 900" } } self.kveditordconf = KVEditorStonix( self.statechglogger, self.logger, "tagconf", self.dconfsettings, self.dconfsettings + ".tmp", self.dconfdata, "present", "closedeq") self.kveditordconf.report() if self.kveditordconf.fixables: if not self.kveditordconf.fix(): success = False self.detailedresults += "Unable to put correct settings inside " + \ self.dconfsettings + "\n" elif not self.kveditordconf.commit(): success = False self.detailedresults += "Unable to put correct settings inside " + \ self.dconfsettings + "\n" #run dconf update command to make dconf changes take effect if os.path.exists("/bin/dconf"): cmd = "/bin/dconf update" self.cmdhelper.executeCommand(cmd) elif os.path.exists("/usr/bin/dconf"): cmd = "/usr/bin/dconf update" self.cmdhelper.executeCommand(cmd) self.detailedresults += info return success
def fixMac(self): '''use the sysctl command to write directives create the sysctl.conf file if needed set permissions and ownership of sysctl.conf file to 0o600 and 0,0 :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 420) ''' success = True created = False try: if self.fixables: sysctl = "/usr/sbin/sysctl" for directive in self.fixables: cmd = [sysctl, "-w", directive + "=" + self.fixables[directive]] if not self.cmdhelper.executeCommand(cmd): error = self.cmdhelper.getErrorString() self.detailedresults += "There was an error running " + \ "the command " + cmd + "\n" self.logger.log(LogPriority.DEBUG, error) success = False if not os.path.exists(self.path): if createFile(self.path, self.logger): created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": self.path} self.statechglogger.recordchgevent(myid, event) else: return False if not self.editor: self.editor = KVEditorStonix(self.statechglogger, self.logger, "conf", self.path, self.tmpPath, self.directives, "present", "closedeq") if not self.editor.report(): 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" else: 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" if not checkPerms(self.path, [0, 0, 0o600], self.logger): if not created: 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 else: if not setPerms(self.path, [0, 0, 0o600], self.logger): self.detailedresults += "Could not set permissions" + \ " on " + self.path + "\n" success = False except Exception: raise 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): try: if not self.ci.getcurrvalue(): return success = True path = self.path tmppath = path + ".tmp" prelinkCache = "/etc/prelink.cache" self.detailedresults = "" self.iditerator = 0 eventlist = self.statechglogger.findrulechanges(self.rulenumber) for event in eventlist: self.statechglogger.deleteentry(event) 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: success = False self.detailedresults += "Failed to create file: " + \ path + "\n" if writeFile(tmppath, "PRELINKING=no", self.logger): os.rename(tmppath, path) resetsecon(path) else: success = False self.detailedresults += "Failed to write settings " + \ "to file: " + path + "\n" elif not self.editor.report(): if self.editor.fix(): if self.editor.commit(): self.detailedresults += "Changes successfully " + \ "committed to " + path + "\n" else: success = False self.detailedresults += "Changes could not be " + \ "committed to " + path + "\n" else: success = False self.detailedresults += "Could not fix file " + path + "\n" # Although the guidance and documentation recommends using "prelink # -ua" command, testing has shown this command to be completely # unreliable. Instead, the prelink cache will be removed entirely. if os.path.exists(prelinkCache): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.statechglogger.recordfiledelete(prelinkCache, myid) os.remove(prelinkCache) 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): '''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 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 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 fixLinux(self): """ Linux specific submethod to correct linux distributions. If your system is portage based, i.e. gentoo, you will need to do a manual fix for everything except the login.defs file @author: Derek Walker :return: success :rtype: bool """ success = True try: if self.ph.manager == "dnf": if not self.ph.check("authconfig"): self.ph.install("authconfig") # this is needed by fedora to continue except: pass # """create backups of pamfiles""" if os.path.exists(self.pampassfile): createFile(self.pampassfile + ".backup", self.logger) if os.path.exists(self.pamauthfile): createFile(self.pamauthfile + ".backup", self.logger) if self.ci2.getcurrvalue(): if not self.ci2comp: # configure regex for pwquality if self.usingpwquality: self.password = re.sub("pam_cracklib\.so", "pam_pwquality.so", self.password) if self.environ.getsystemfismacat() == "high": self.password = re.sub("minlen=8", "minlen=14", self.password) self.password = re.sub("minclass=3", "minclass=4", self.password) regex = PWQUALITY_HIGH_REGEX else: regex = PWQUALITY_REGEX if self.pwqinstalled: if not self.setpasswordsetup(regex): success = False else: if not self.setpasswordsetup(regex, self.pwqualitypkgs): success = False # configure regex for cracklib elif self.usingcracklib: self.password = re.sub("pam_pwquality\.so", "pam_cracklib.so", self.password) if self.environ.getsystemfismacat() == "high": self.password = re.sub("minlen=8", "minlen=14", self.password) self.password = re.sub("minclass=3", "minclass=4", self.password) regex = CRACKLIB_HIGH_REGEX else: regex = CRACKLIB_REGEX if self.clinstalled: if not self.setpasswordsetup(regex): success = False else: if not self.setpasswordsetup(regex, self.cracklibpkgs): success = False else: error = "Could not find pwquality/cracklib pam module. Fix failed." self.logger.log(LogPriority.ERROR, error) self.detailedresults += error + "\n" return False if self.ci3.getcurrvalue(): if not self.ci3comp: if self.usingpamfail: regex = PAMFAIL_REGEX if not self.setaccountlockout(regex): success = False self.detailedresults += "Unable to configure pam for faillock\n" elif self.usingpamtally2: regex = PAMTALLY_REGEX if not self.setaccountlockout(regex): success = False self.detailedresults += "Unable to configure pam for pam_tally2\n" else: self.detailedresults += "There is no account lockout program available for this system\n" success = False if self.ci4.getcurrvalue(): if not self.ci4comp: if not self.checklibuser(): if not self.setlibuser(): debug = "setlibuser() failed\n" self.detailedresults += "Unable to configure /etc/libuser.conf\n" self.logger.log(LogPriority.DEBUG, debug) success = False if not self.checklogindefs(): if not self.setlogindefs(): debug = "setdefpasshash() failed\n" self.logger.log(LogPriority.DEBUG, debug) self.detailedresults += "Unable to configure /etc/login.defs file\n" success = False if not self.set_showfailed_logins(): success = False 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 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(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
def fixBootMode(self): success = True if self.initver == "systemd": cmd = ["/bin/systemctl", "set-default", "multi-user.target"] if not self.ch.executeCommand(cmd): success = False self.detailedresults += '"systemctl set-default ' \ + 'multi-user.target" did not succeed\n' else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) commandstring = "/bin/systemctl set-default " + \ "graphical.target" event = {"eventtype": "commandstring", "command": commandstring} self.statechglogger.recordchgevent(myid, event) elif self.initver == "debian": dmlist = ["gdm", "gdm3", "lightdm", "xdm", "kdm"] for dm in dmlist: cmd = ["update-rc.d", "-f", dm, "disable"] if not self.ch.executeCommand(cmd): self.detailedresults += "Failed to disable desktop " + \ "manager " + dm else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "servicehelper", "servicename": dm, "startstate": "enabled", "endstate": "disabled"} self.statechglogger.recordchgevent(myid, event) elif self.initver == "ubuntu": ldmover = "/etc/init/lightdm.override" tmpfile = ldmover + ".tmp" created = False if not os.path.exists(ldmover): createFile(ldmover, self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": ldmover} self.statechglogger.recordchgevent(myid, event) created = True writeFile(tmpfile, "manual\n", self.logger) if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": ldmover} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(ldmover, tmpfile, myid) os.rename(tmpfile, ldmover) resetsecon(ldmover) grub = "/etc/default/grub" if not os.path.exists(grub): createFile(grub, self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": grub} self.statechglogger.recordchgevent(myid, event) tmppath = grub + ".tmp" data = {"GRUB_CMDLINE_LINUX_DEFAULT": '"quiet"'} editor = KVEditorStonix(self.statechglogger, self.logger, "conf", grub, tmppath, data, "present", "closedeq") editor.report() if editor.fixables: if editor.fix(): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) editor.setEventID(myid) debug = "kveditor fix ran successfully\n" self.logger.log(LogPriority.DEBUG, debug) if editor.commit(): debug = "kveditor commit ran successfully\n" self.logger.log(LogPriority.DEBUG, debug) else: error = "kveditor commit did not run " + \ "successfully\n" self.logger.log(LogPriority.ERROR, error) success = False else: error = "kveditor fix did not run successfully\n" self.logger.log(LogPriority.ERROR, error) success = False cmd = "update-grub" self.ch.executeCommand(cmd) else: inittab = "/etc/inittab" tmpfile = inittab + ".tmp" if os.path.exists(inittab): initText = open(inittab, "r").read() initre = r"id:\d:initdefault:" if re.search(initre, initText): initText = re.sub(initre, "id:3:initdefault:", initText) writeFile(tmpfile, initText, self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": inittab} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(inittab, tmpfile, myid) os.rename(tmpfile, inittab) resetsecon(inittab) else: initText += "\nid:3:initdefault:\n" writeFile(tmpfile, initText, self.logger) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "conf", "filepath": inittab} self.statechglogger.recordchgevent(myid, event) self.statechglogger.recordfilechange(inittab, tmpfile, myid) os.rename(tmpfile, inittab) resetsecon(inittab) else: self.detailedresults += inittab + " not found, no other " + \ "init system found. If you are using a supported " + \ "Linux OS, please report this as a bug\n" return success
def fixLinux(self): universal = "#The following lines were added by stonix\n" debug = "" success = True ifacefile = "" netwrkfile = "" sysctl = "/etc/sysctl.conf" interface = {"IPV6_AUTOCONF": "no"} interface2 = {"IPV6_PRIVACY": "rfc3041"} # "IPV6_DEFAULTGW": self.gateway, # "IPV6ADDR":self.ipaddr} if self.ph.manager == "yum": ifacefile = "/etc/sysconfig/network-scripts/" netwrkfile = "/etc/sysconfig/network" elif self.ph.manager == "zypper": ifacefile = "/etc/sysconfig/network/" created = False # fix sysctl / tuning kernel parameters # manually write key value pairs to /etc/sysctl.conf 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 " + sysctl + \ "\n" success = False 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 to record the file write 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) # permissions on file are incorrect 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 " + \ sysctl + "\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) # correct the network file if it exists if netwrkfile: created = False if not os.path.exists(netwrkfile): if not createFile(netwrkfile, self.logger): success = False debug = "Unable to create " + netwrkfile + " file\n" self.logger.log(LogPriority.DEBUG, debug) else: created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": netwrkfile} self.statechglogger.recordchgevent(myid, event) tmpfile = netwrkfile + ".tmp" self.editor2 = KVEditorStonix(self.statechglogger, self.logger, "conf", netwrkfile, tmpfile, self.interface1, "present", "closedeq") self.editor2.report() if os.path.exists(netwrkfile): if not checkPerms(netwrkfile, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(netwrkfile, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False 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 elif not self.editor2.commit(): success = False os.chown(netwrkfile, 0, 0) os.chmod(netwrkfile, 0o644) resetsecon(netwrkfile) if ifacefile: if os.path.exists(ifacefile): dirs = glob.glob(ifacefile + "*") if dirs: for loc in dirs: interface2 = {"IPV6_PRIVACY": "rfc3041"} # "IPV6_DEFAULTGW": self.gateway, # "IPV6ADDR":self.ipaddr} interface3 = {"IPV6_PRIVACY": "rfc3041"} # "IPV6_DEFAULTGW": self.gateway, # "IPV6ADDR":self.ipaddr} 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, 0o644], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(filename, [0, 0, 0o644], self.logger, self.statechglogger, myid): return False for key in interface2: 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() == \ interface2[key]: if found: continue found = True else: contents.remove(line) if found: del interface3[key] for line in contents: tempstring += line tempstring += universal for key in interface3: tempstring += key + "=" + interface3[key] + \ "\n" if not writeFile(tmpfile, tempstring, self.logger): return False 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, 0o644) resetsecon(filename) elif not os.path.exists(ifacefile) and ifacefile != "": # will not attempt to create the interface files self.detailedresults += "Interface directory which holds interface \ files, doesn't exist. Stonix will not attempt to make this \ directory or the files contained therein." success = False return success
def fix(self): """ Run fix actions for SecureNFS :return: self.rulesuccess :rtype: bool @author: dwalker @change: Breen Malmberg - 4/26/2016 - changed location of defaults variables in method; added detailedresults message if fix run while CI disabled; added formatdetailedresults update if fix called when CI disabled; changed return value to always be self.rulesuccess; updated self.rulesuccess based on success variable as well @change: Breen Malmberg - 7/11/2017 - added another service check on mac os x; no files will be created on mac if the service is not enabled """ self.logdispatch.log(LogPriority.DEBUG, "Entering SecureNFS.fix()...") success = True changed1, changed2 = False, False installed = False self.detailedresults = "" try: if not self.ci.getcurrvalue(): self.detailedresults += "\nThe CI for this rule was not enabled. Nothing has been done." success = True self.formatDetailedResults("fix", success, self.detailedresults) self.logdispatch.log(LogPriority.DEBUG, "Exiting SecureNFS.fix()...") return success # 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 self.environ.getostype() == "Mac OS X": nfsservice = "nfsd" nfsfile = "/etc/nfs.conf" data1 = { "nfs.lockd.port": "", "nfs.lockd.tcp": "1", "nfs.lockd.udp": "1" } elif self.ph.manager in ("yum", "zypper", "dnf"): nfsfile = "/etc/sysconfig/nfs" data1 = { "LOCKD_TCPPORT": "32803", "LOCKD_UDPPORT": "32769", "MOUNTD_PORT": "892", "RQUOTAD_PORT": "875", "STATD_PORT": "662", "STATD_OUTGOING_PORT": "2020" } nfsservice = "nfs" if self.ph.manager == "zypper": nfspackage = "nfs-kernel-server" elif self.ph.manager == "yum" or self.ph.manager == "dnf": nfspackage = "nfs-utils" elif self.ph.manager == "apt-get": nfsservice = "nfs-kernel-server" nfspackage = "nfs-kernel-server" nfsfile = "/etc/services" data1 = { "rpc.lockd": ["32803/tcp", "32769/udp"], "rpc.mountd": ["892/tcp", "892/udp"], "rpc.quotad": ["875/tcp", "875/udp"], "rpc.statd": ["662/tcp", "662/udp"], "rpc.statd-bc": ["2020/tcp", "2020/udp"] } if self.environ.getostype() != "Mac OS X": if self.ph.manager in ("apt-get", "zypper"): if not self.ph.check(nfspackage): success = True self.formatDetailedResults("fix", success, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return success if not os.path.exists(nfsfile): if createFile(nfsfile, self.logger): nfstemp = nfsfile + ".stonixtmp" if self.environ.getostype() == "Mac OS X": if not self.sh.auditService( '/System/Library/LaunchDaemons/com.apple.nfsd.plist', serviceTarget='com.apple.nfsd'): success = True self.formatDetailedResults("fix", success, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return success self.editor1 = KVEditorStonix(self.statechglogger, self.logger, "conf", nfsfile, nfstemp, data1, "present", "openeq") elif self.ph.manager in ("yum", "zypper", "dnf"): self.editor1 = KVEditorStonix(self.statechglogger, self.logger, "conf", nfsfile, nfstemp, data1, "present", "closedeq") elif self.ph.manager == "apt-get": self.editor1 = KVEditorStonix(self.statechglogger, self.logger, "conf", nfsfile, nfstemp, data1, "present", "space") if not self.editor1.report(): if not self.editor1.fix(): success = False debug = "fix for editor1 failed" self.logger.log(LogPriority.DEBUG, debug) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor1.setEventID(myid) if not self.editor1.commit(): success = False debug = "commit for editor1 failed" self.logger.log(LogPriority.DEBUG, debug) else: changed1 = True if not checkPerms(nfsfile, [0, 0, 420], self.logger): if not setPerms(nfsfile, [0, 0, 420], self.logger, self.statechglogger): success = False debug = "Unable to set permissions on " + nfsfile self.logger.log(LogPriority.DEBUG, debug) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": nfsfile} self.statechglogger.recordchgevent(myid, event) else: success = False debug = "Unable to create " + nfsfile + " file" self.logger.log(LogPriority.DEBUG, debug) else: if self.editor1.fixables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor1.setEventID(myid) if not self.editor1.fix(): success = False debug = "editor1 fix failed" self.logger.log(LogPriority.DEBUG, debug) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor1.setEventID(myid) if not self.editor1.commit(): success = False debug = "editor1 commit failed" self.logger.log(LogPriority.DEBUG, debug) else: changed1 = True if not checkPerms(nfsfile, [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(nfsfile, [0, 0, 420], self.logger, self.statechglogger, myid): debug = "Unable to set permissions on " + nfsfile self.logger.log(LogPriority.DEBUG, debug) export = "/etc/exports" if not os.path.exists(export): # mac os x will automatically enable the nfs # service and related ports if the file /etc/exports # is created if self.environ.getostype() == "Mac OS X": if not self.sh.auditService( '/System/Library/LaunchDaemons/com.apple.nfsd.plist', serviceTarget='com.apple.nfsd'): success = True self.formatDetailedResults("fix", success, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return success if createFile(export, self.logger): extemp = export + ".stonixtmp" data2 = { "all_squash": "", "no_root_squash": "", "insecure_locks": "" } self.editor2 = KVEditorStonix(self.statechglogger, self.logger, "conf", export, extemp, data2, "notpresent", "space") if not self.editor2.report(): if not self.editor2.fix(): success = False debug = "fix for editor2 failed" self.logger.log(LogPriority.DEBUG, debug) else: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor2.setEventID(myid) if not self.editor2.commit(): success = False debug = "commit for editor2 failed" self.logger.log(LogPriority.DEBUG, debug) else: changed2 = True if not checkPerms(export, [0, 0, 420], self.logger): if not setPerms(export, [0, 0, 420], self.logger, self.statechglogger): success = False debug = "Unable to set permissions on " + export self.logger.log(LogPriority.DEBUG, debug) self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": export} self.statechglogger.recordchgevent(myid, event) else: if installed: extemp = export + ".stonixtmp" data2 = { "all_squash": "", "no_root_squash": "", "insecure_locks": "" } self.editor2 = KVEditorStonix(self.statechglogger, self.logger, "conf", export, extemp, data2, "notpresent", "space") self.editor2.report() if self.editor2.removeables: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) self.editor2.setEventID(myid) if not self.editor2.fix(): success = False debug = "editor2 fix failed" self.logger.log(LogPriority.DEBUG, debug) else: if not self.editor2.commit(): success = False debug = "editor2 commit failed" self.logger.log(LogPriority.DEBUG, debug) else: changed2 = True if not checkPerms(export, [0, 0, 420], self.logger): self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(export, [0, 0, 420], self.logger, self.statechglogger, myid): success = False debug = "Unable to set permissions on " + export self.logger.log(LogPriority.DEBUG, debug) if changed1 or changed2: ## CHANGE (Breen Malmberg) 1/23/2017 # The self.sh.reloadservice() call, for SHlaunchd, will start # the service even if it is not already running. # We don't want to start THIS service if it is not # already running/enabled! # We also don't want to change this functionality at the # SHlaunchd class-level, because there may be other # instances in which we want it to do a stop and start # (aka a full reload), so this decision should be made at # the rule-level. ## if self.sh.isRunning(nfsservice, serviceTarget=nfsservice): self.sh.reloadService(nfsservice, serviceTarget=nfsservice) self.logdispatch.log(LogPriority.DEBUG, "Exiting SecureNFS.fix()...") 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", success, self.detailedresults) self.logdispatch.log(LogPriority.INFO, self.detailedresults) return success
def reportFree(self): compliant = True self.editor1, self.editor2 = "", "" directives1 = { "ipv6_network_interfaces": "none", "ipv6_activate_all_interfaces": "NO", "ip6addrctl_enable": "NO", "ip6addrctl_policy": "NO" } directives2 = { "net.ipv6.conf.all.disable_ipv6": "1", "net.ipv6.conf.default.disable_ipv6": "1", "net.ipv6.conf.lo.disable_ipv6": "1" } path1 = "/etc/rc.conf" path2 = "/etc/sysctl.conf" tmpfile1 = "/etc/rc.conf.tmp" tmpfile2 = "/etc/sysctl.conf.tmp" # try and create /etc/rc.conf if doesn't exist if not os.path.exists(path1): if not createFile(path1, self.logger): compliant = False self.detailedresults += "Unable to create the file: " + \ path1 + ", so this file will not be configured, " + \ "resulting in failed compliance\n" if os.path.exists(path1): if not checkPerms(path1, [0, 0, 420], self.logger): compliant = False self.editor1 = KVEditorStonix(self.statechglogger, self.logger, "conf", path1, tmpfile1, directives1, "present", "closedeq") if not self.editor1.report(): compliant = False # try and create /etc/sysctl.conf if doesn't exist if not os.path.exists(path2): if not createFile(path2, self.logger): compliant = False self.detailedresults += "Unable to create the file: " + \ path2 + " so this file will not be configured " + \ "resulting in failed compliance\n" if os.path.exists(path2): if not checkPerms(path2, [0, 0, 384], self.logger): compliant = False self.editor2 = KVEditorStonix(self.statechglogger, self.logger, "conf", path2, tmpfile2, directives2, "present", "closedeq") if not self.editor2.report(): compliant = False else: compliant = False cmdhelper = CommandHelper(self.logger) cmd = ["/sbin/ifconfig", "-a"] if not cmdhelper.executeCommand(cmd): return False output = cmdhelper.getOutput() for line in output: line = line.strip() if re.search("^nd6", line): if not re.search("(.)*IFDISABLED(.)*", line): compliant = False return compliant
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 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 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 fixSSHFile(self, sshfile, directives): """ apply configuration options to config files :param: sshfile - filepath string :param: directives - dictionary of desired directives :return: compliant :rtype: bool """ success = True debug = "" directives = dict(directives) tpath = sshfile + ".tmp" created = False if not os.path.exists(sshfile): createFile(sshfile, self.logger) created = True self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) event = {"eventtype": "creation", "filepath": sshfile} self.statechglogger.recordchgevent(myid, event) if os.path.exists(sshfile): if re.search("Ubuntu", self.environ.getostype()): if sshfile == "/etc/ssh/sshd_config": del (directives["GSSAPIAuthentication"]) del (directives["KerberosAuthentication"]) elif sshfile == "/etc/ssh/ssh_config": del (directives["GSSAPIAuthentication"]) elif self.environ.getostype() == "Mac OS X" and self.mac_piv_auth_CI.getcurrvalue(): if sshfile == "/private/etc/ssh/sshd_config": directives["ChallengeResponseAuthentication"] = "no" directives["PasswordAuthentication"] = "no" editor = KVEditorStonix(self.statechglogger, self.logger, "conf", sshfile, tpath, directives, "present", "space") editor.report() if re.search("Ubuntu", self.environ.getostype()): if sshfile == "/etc/ssh/sshd_config": directives = {"GSSAPIAuthentication": "", "KerberosAuthentication": ""} elif sshfile == "/etc/ssh/ssh_config": directives = {"GSSAPIAuthentication": ""} editor.setIntent("notpresent") editor.setData(directives) editor.report() if not checkPerms(sshfile, [0, 0, 0o644], self.logger): if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) if not setPerms(sshfile, [0, 0, 0o644], self.logger, self.statechglogger, myid): success = False else: if not setPerms(sshfile, [0, 0, 0o644], self.logger): success = False if editor.fixables or editor.removeables: if not created: self.iditerator += 1 myid = iterate(self.iditerator, self.rulenumber) editor.setEventID(myid) if editor.fix(): if editor.commit(): os.chown(sshfile, 0, 0) os.chmod(sshfile, 0o644) resetsecon(sshfile) else: self.detailedresults += "Unable to correct contents " + \ "in " + sshfile + "\n" debug = "kveditor1 commit did not run successfully" self.logger.log(LogPriority.DEBUG, debug) success = False else: self.detailedresults += "Unable to correct contents " + \ "in " + sshfile + "\n" debug = "kveditor1 fix did not run successfully" self.logger.log(LogPriority.DEBUG, debug) success = False return success