def scan(self, option=None): if sb_utils.os.info.is_solaris() == True: msg = "'%s' service is not part of the standard Solaris "\ "distribution." % self._svcname self.logger.notice(self.module_name, 'Not Applicable: ' + msg) raise tcs_utils.OSNotApplicable('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname=self._pkgname) if results != True: msg = "'%s' is not installed on the system" % self._pkgname self.logger.warn(self.module_name, 'Not Applicable: ' + msg) raise tcs_utils.ScanNotApplicable('%s %s' % (self.module_name, msg)) msg = "'%s' package is installed." % self._pkgname self.logger.debug(self.module_name, msg) results = sb_utils.os.service.is_enabled(svcname=self._svcname) if results == True: msg = "'%s' service is on" % self._svcname self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg elif not self.serviceExists(self._svcname): msg = "'%s' service does not exist! Manual action required to fix." % self._svcname self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg if results == None: msg = "'%s' does not appear to be a service in %s %s - nothing to disable, adminstrator should remove '%s' unless this package is required." % (self._svcname, sb_utils.os.info.getDistroName(), str(sb_utils.os.info.getDistroVersion()) , self._pkgname) self.logger.warn(self.module_name, 'Not Applicable: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) return 'Pass', ''
def apply(self, optionDict={}): results, msg, messages = self.scan(optionDict) if results == False: raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) return False, '', {}
def apply(self, optionDict=None): """Apply changes.""" action_record = '' messages = {'messages' : [] } nonRootUserInWheelGroup = False result, reason, messages = self.scan() if result == True: return False, action_record, messages # check if any users (besides root) belong to the wheel group wheelusers = grp.getgrnam('wheel').gr_mem for user in wheelusers: if user != 'root': nonRootUserInWheelGroup = True break if optionDict['requireNonRootWheelMember'] == '1' and not nonRootUserInWheelGroup: msg = "You must have at least one user in the wheel group to "\ "apply this module. Applying this module without members in "\ "the wheel group can lock you out of the system." self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) elif not nonRootUserInWheelGroup: msg = "WARNING: Applying module despite no non-root users in the wheel group. This can prevent any user from using the 'su' command." messages['messages'].append(msg) self.logger.warn(self.module_name, msg) try: linesIn = open(self.__target_file, 'r').readlines() except IOError, err: msg = "Unable to open %s file: %s" % (self.__target_file, str(err)) self.logger.info(self.module_name, 'Scan Failed: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg))
def __init__(self): """ ShellSessionTimeouts Security Module handles the guideline for default timeout values in your shell environment and access permissions on all associated files. """ self.module_name = "ShellSessionTimeouts" self.__oldfiles = [ "/etc/profile.d/sb-timeout.sh", "/etc/profile.d/sb-timeout.csh" ] self.__target_file1 = "/etc/profile.d/tmout.sh" self.__target_file2 = "/etc/profile.d/autologout.csh" self.logger = TCSLogger.TCSLogger.getInstance() self.__sh_script = "" self.__csh_script = "" # This is for bash, ksh, sh, stuff self.__sh_script = "" # This is for CSH stuff self.__csh_script = "" msg = "" if not os.path.exists('/etc/profile.d'): msg = "/etc/profile.d directory does not exist! Consider adding 'Exec shell startups in /etc/profile.d' to Profile." elif not os.path.isdir('/etc/profile.d'): msg = "/etc/profile.d is not a directory! This should be a directory. Consider adding 'Exec shell startups in /etc/profile.d' to Profile afterward." if msg: raise tcs_utils.ManualActionReqd("%s %s" % (self.module_name, msg))
def apply(self, optionDict={}): """Create and replace the /etc/hosts.allow configuration if it doesn't match.""" messages = [] retval = False self.validate_input(optionDict) missingCerts, extraCerts = self.checkCerts() messages.extend([ "Missing cryptographic certificate to provide : %s" % cert for cert in missingCerts ]) if extraCerts and self.showExtraCerts == True: messages.extend([ "Found Extra cryptographic certificate providing : %s" % cert for cert in extraCerts ]) if missingCerts: msg = "Missing %d cryptographic certificates - must be installed manually : " % len( missingCerts) msg = msg + "\n" + "\n".join(messages) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) return retval, "", {'messages': messages}
def scan(self, option=None): if sb_utils.os.suse.pam.passwdqc_configured(): msg = "It appears that pam_passwdqc is installed and configured. "\ "Presently, OS Lockdown only supports pam_cracklib." self.logger.info(self.module_name, msg) msg2 = "If wish this module to configure 'ocredit', unconfigure " \ "pam_passwdqc." self.logger.info(self.module_name, msg2) raise tcs_utils.ScanNotApplicable('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname='pam-config') if results != True: msg = "'pam-config' package is not installed on the system." self.logger.error(self.module_name, 'Scan Error: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname='cracklib') if results != True: msg = "'cracklib' package is not installed on the system." self.logger.error(self.module_name, 'Scan Error: ' + msg) raise tcs_utils.ScanError('%s %s' % (self.module_name, msg)) cracklib_settings = sb_utils.os.suse.pam.config(modName='cracklib') #------------------------------------------ # If cracklib is not being used, then fail if len(cracklib_settings) == 0: msg = "PAM cracklib is not configured." self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg #------------------------------------------ # Check cracklib settings if not cracklib_settings.has_key('password'): msg = "PAM cracklib is not configured for 'password'" self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg for pw_opt in cracklib_settings['password']: try: (pw_key, pw_val) = pw_opt.split('=') except (ValueError, IndexError): continue if pw_key == 'ocredit': msg = "PAM cracklib 'ocredit' option set to '%s' " % (pw_val) self.logger.info(self.module_name, msg) if int(pw_val) != -2: msg = "PAM cracklib 'ocredit' option is not set to '-2'" self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg else: return 'Pass', '' return 'Fail', 'ocredit parameter not set'
def undo(self, change_record=None): self.check_version() if change_record == None: msg = "Unable to perform undo operation without change record." self.logger.error(self.module_name, 'Undo Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) try: option = change_record.split('|')[1] except: msg = "Unable to perform undo operation due to invalid "\ "formatted change record" self.logger.error(self.module_name, 'Undo Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) if sb_utils.os.suse.pam.passwdqc_configured(): msg = "It appears that pam_passwdqc is installed and configured so,"\ "OS Lockdown will not edit your PAM configuration. "\ "Presently, OS Lockdown only supports pam_cracklib." self.logger.info(self.module_name, msg) return False, '', {} results = sb_utils.os.software.is_installed(pkgname='pam-config') if results != True: msg = "'pam-config' package is not installed on the system." self.logger.error(self.module_name, 'Undo Error: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname='cracklib') if results != True: msg = "'cracklib' package is not installed on the system." self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) results = sb_utils.os.suse.pam.backup() if results == False: msg = "Unable to make backup of /etc/pam.d/* files" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) # results = sb_utils.os.suse.pam.convert_to_cracklib() # if results != True: # msg = "Unable to switch from pam_pwcheck to pam_cracklib" # raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) if option == '': msg = "'ucredit' has been unset" results = sb_utils.os.suse.pam.cracklib_unset(option='ucredit') else: msg = "'ucredit' has been restored to '%s'" % option results = sb_utils.os.suse.pam.cracklib_set(option='ucredit', optValue=option) self.logger.notice(self.module_name, 'Undo Performed: ' + msg) return True
def get_shells(self): # Read /etc/shells try: shells = tcs_utils.splitNaturally(open(self.__shells).read(), wordAdditions="/-_") except Exception, err: msg = "Unable to read '/etc/shells' - may need to use 'Allowed Shells in /etc/shells' Module - %s" % str( err) self.logger.notice(self.module_name, 'Scan Failed: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg))
def apply(self, optionDict=None): # First, let's see if root's home directory is /root u_obj = pwd.getpwnam('root') if u_obj[5] != '/root': reason = "Root home directory IS NOT /root; you must manually " \ "change root's home directory or this module will continue to fail." self.logger.notice(self.module_name, 'Scan Failed: ' + reason) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, reason)) optionDict['fileList'] = u_obj[5] return GenericPerms.apply(optionDict=optionDict)
def apply(self, option=None): reason = "" messages = {'messages': []} result, reason, messages = self.scan() if result == True: return False, '', messages reason = "" msg = "Administrator must set grub password manually on each machine." raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) return False, reason, msg
def apply(self, option=None): messages = {} action_record = 'none' try: (result, reason, messages) = self.scan() if result == False: msg = "Manual Action: You must create a separate file system for %s" % self.__fsname self.logger.info(self.module_name, msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) except tcs_utils.ScanError, err: self.logger.error(self.module_name, err) raise tcs_utils.ActionError('%s %s' % (self.module_name, err))
def apply(self, option=None): """Enable password requirement for single user mode.""" result, reason, messages = self.scan() if result == True: return False, reason, messages # if we got here, we either fixed it or decided to punt because we didn't know how. Raise a ManualActionReqd # unless we have a changeRec if not self.changeRec: raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, self.problems)) else: messages['messages'] = [self.changes] open(self.__target_file,"w").writelines(self.lines) return True, self.changeRec, messages
def apply(self, option=None): messages = {} action_record = 'none' try: (result, reason, messages) = self.scan() if result == False: msg = "Manual Action: You must make any change to /etc/fstab manually." self.logger.info(self.module_name, msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) except tcs_utils.ScanError, err: self.logger.error(self.module_name, err) raise tcs_utils.ActionError('%s %s' % (self.module_name, err))
def validate_options(self, optionDict): self.__settings = {} try: items = optionDict['ldapConfs'].splitlines() for item in items: try: tag, value = item.split(None,1) self.__settings[tag] = value except Exception, err: msg = "Unable to parse line '%s' " % item self.logger.warn(self.module_name, msg) if len(self.__settings) == 0: msg = "Empty list of settings for LDAP, aborting module" raise tcs_utils.ManualActionReqd("%s %s" % (self.module_name, msg)) return
def _get_shells(self): # Read in /etc/shells and append items to the list (unique of course) default_shells = [] try: infile = open('/etc/shells', 'r') shells = infile.readlines() infile.close() for shell in shells: if os.path.isfile(shell.strip()): default_shells.append(shell.strip()) except IOError, e: msg = "Unable to read '/etc/shells' - may need to use 'Allowed Shells in /etc/shells' Module - %s" % str( e) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg))
def apply(self, optionDict=None): """Change user/group of unowned files to nobody""" reason = "" messages = {'messages':[]} result, reason, messages = self.scan(optionDict) if result == True: return False, '', messages reason = "" msg = "One or more files has the unlabeled_t SELinux security context. The Administrator should investigate and fix as required." self.logger.warning(self.module_name, msg) messages['messages'].append('Warning:%s' % msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) return False, reason, messages
class ConfigureAuditdConf: def __init__(self): self.module_name = "ConfigureAuditdConf" try: self.logger = TCSLogger.TCSLogger.getInstance(6) except TCSLogger.SingletonException: self.logger = TCSLogger.TCSLogger.getInstance() if os.path.exists("/etc/audit/auditd.conf"): self.__target_file = "/etc/audit/auditd.conf" elif os.path.exists("/etc/auditd.conf"): self.__target_file = "/etc/auditd.conf" else: self.__target_file = None self.__settings = {} ########################################################################## def validate_options(self, optionDict): self.__settings = {} if not self.__target_file: msg = "/etc/audit/auditd.conf or /etc/auditd.conf file does not exist!" self.logger.warn(self.module_name, 'Not Applicable: ' + msg) raise tcs_utils.ScanNotApplicable('%s %s' % (self.module_name, msg)) items = optionDict['auditConfs'].splitlines() regex = re.compile("(\s*)(\w+)([=\s]*)(\w*)") for item in optionDict['auditConfs'].splitlines(): if not item: continue try: match = regex.search(item) leadWhite, tag, equals, value = match.groups() self.__settings[tag] = value except Exception, err: msg = "Unable to parse line '%s' " % item self.logger.warn(self.module_name, msg) if len(self.__settings) == 0: msg = "Empty list of settings for Auditd, aborting module" raise tcs_utils.ManualActionReqd("%s %s" % (self.module_name, msg)) return
def apply(self, option=None): reason = "" messages = {'messages': []} result, reason, messages = self.scan() if result == True: return False, '', messages reason = "" msg = "This module has been retired. Please replace 'Password Protect Grub' with 'Require Grub Password' in all profiles" self.logger.warning(self.module_name, msg) messages['messages'].append('Retire:%s' % msg) msg = "Administrator must set grub password manually on each machine." messages['messages'].append('Warning:%s' % msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) return False, reason, messages
def undo(self, change_record=None): if change_record == None: msg = "Unable to perform undo operation without change record." self.logger.error(self.module_name, 'Undo Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) try: option = change_record.split('|')[1] except: msg = "Unable to perform undo operation due to invalid "\ "formatted change record" self.logger.error(self.module_name, 'Undo Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname='pam-config') if results != True: msg = "'pam-config' package is not installed on the system." self.logger.error(self.module_name, 'Undo Error: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) results = sb_utils.os.suse.pam.backup() if results == False: msg = "Unable to make backup of /etc/pam.d/* files" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) if option == '': msg = "'remember' has been unset" results = sb_utils.os.suse.pam.pwhistory_unset(option='remember') else: msg = "'remember' has been restored to '%s'" % option results = sb_utils.os.suse.pam.pwhistory_set(option='remember', optValue=option) self.logger.notice(self.module_name, 'Undo Performed: ' + msg) return True
def apply(self, option=None): messages = {} messages['messages'] = [] if platform.machine() == 'x86_64': msg = "Not applicable on Intel-based 64 bit (x86_64) systems" return False, msg, {} if platform.machine().startswith('s390'): msg = "Not applicable on S390 hardware (System z)" return False, msg, {} if sb_utils.os.info.is_solaris() == True: msg = "Not applicable in Solaris " return False, msg, {} has_support = self._hasNDorNXSupport() if has_support == True: msg = "CPU has NX and PAE support" else: msg = "CPU does not have NX and PAE support" self.logger.debug(self.module_name, msg) messages['messages'].append(msg) kernel_name = os.uname()[2] if not kernel_name.endswith('PAE'): msg = "Running kernel is not PAE enabled. (%s does not end with 'PAE')" self.logger.info(self.module_name, msg) messages['messages'].append(msg) msg = "YOU must install the 'kernel-pae' package and reboot with this kernel" self.logger.info(self.module_name, "Manual: %s" % msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) #return False, msg, messages else: msg = "Running kernel is PAE enabled. (%s ends with 'PAE')" return False, msg, messages
def scan(libraryName=None, enable=False, packageList=None, serviceList=None, option=None): if serviceList == None: (serviceList, serviceProps) = getServiceList(libraryName=libraryName) elif type(serviceList) == type(""): serviceList = [serviceList] elif type(serviceList) != type([]): msg = "Invalid service list detected" logger.error(libraryName, "Scan Error: " + msg) raise tcs_utils.ScanError('%s %s' % (libraryName, msg)) if packageList == None: packageList = getPackageList(libraryName=libraryName) elif type(packageList) == type(""): packageList = [packageList] elif type(packageList) != type([]): msg = "Invalid package list detected" logger.error(libraryName, "Scan Error: " + msg) raise tcs_utils.ScanError('%s %s' % (libraryName, msg)) # print "ServiceList",serviceList # print "PackageList",packageList if not serviceList and not packageList: msg = "No services or packages identified for this module" raise tcs_utils.OSNotApplicable('%s %s' % (libraryName, msg)) messages = {} messages['messages'] = [] # Check for each package in the list. If ONE package is missing, # report a not applicable for pkg_item in packageList: results = sb_utils.os.software.is_installed(pkgname=pkg_item) if results == False and enable == False: msg = "'%s' package is not installed" % pkg_item logger.warning(libraryName, 'Not Applicable: ' + msg) raise tcs_utils.ScanNotApplicable('%s %s' % (libraryName, msg)) elif results == False and enable == True: msg = "'%s' package is not installed" % pkg_item logger.warning(libraryName, 'Admin must install required package first: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (libraryName, msg)) else: msg = "'%s' package is installed" % pkg_item logger.info(libraryName, msg) messages['messages'].append(msg) results_flag = True for service_item in serviceList: results = sb_utils.os.service.is_enabled(svcname=service_item) if enable == False: if results == True: # should be off and is on msg = "'%s' service is enabled" % service_item logger.notice(libraryName, 'Scan Failed: ' + msg) messages['messages'].append("Fail: %s" % msg) results_flag = False else: # should be off and is off msg = "'%s' service is disabled" % service_item logger.notice(libraryName, msg) messages['messages'].append(msg) else: if results == False: # should be on and is off msg = "'%s' service is disabled" % service_item logger.notice(libraryName, 'Scan Failed: ' + msg) messages['messages'].append("Fail: %s" % msg) results_flag = False else: # should be on and is on msg = "'%s' service is enabled" % service_item logger.notice(libraryName, msg) messages['messages'].append(msg) if results_flag == False: if enable == False: results_msg = "One or more associated services are enabled" else: results_msg = "One or more associated services are disabled" else: if enable == False: results_msg = "All associated services are enabled" else: results_msg = "All associated services are disabled" return results_flag, results_msg, messages
def apply(self, optionDict=None): messages = {} messages['messages'] = [] if sb_utils.os.info.is_LikeSUSE() == True: msg = "This module is not applicable to SUSE systems" return False, msg, {} self.validate_options(optionDict) paramlist = sb_utils.os.config.get_list(configfile=self.__target_file, delim='=') SysCtl = sb_utils.os.linux.sysctl() sysdict = SysCtl.getlist() change_record = '' mem_action_record = {} file_action_record = {} if len(sysdict) == 0: msg = "Unable to get in-memory kernel setting using sysctl(8) utility" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) msg = "Checking settings in %s" % (self.__target_file) self.logger.info(self.module_name, msg) for param in self.__settings.keys(): # Verify the parameter setting actually exists in /proc/sys/kernel - if not then the feature doesn't exist and shouldn't be set # via sysconfig if not param.startswith('kernel.'): msg = "Found '%s' as the parameters, expected it to start with 'kernel.', skipping entire module..." % param raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) kernelPath = "/proc/sys/kernel/" + param[7:] if not os.path.exists(kernelPath): msg = "Did not find %s for setting %s - feature not applicable for this kernel" % ( kernelPath, param) self.logger.info(self.module_name, msg) continue if paramlist.has_key(param): if int(self.__settings[param]) == int(paramlist[param]): continue results = sb_utils.os.config.setparam( \ configfile=self.__target_file, \ param=param, value=str(self.__settings[param]), delim='=') if results == False: msg = "Unable to set %s in %s" % (param, self.__target_file) self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) else: file_action_record[param] = str(results) msg = "Apply Performed: %s set to '%s' in %s" % \ (param, self.__settings[param], self.__target_file) self.logger.notice(self.module_name, msg) messages['messages'].append(msg) ###################################################################### msg = "Checking in-memory kernel settings using sysctl(8) utility" self.logger.info(self.module_name, msg) for param in self.__settings.keys(): if sysdict.has_key(param): if int(self.__settings[param]) != int(sysdict[param]): results = SysCtl.setparam( paramname = param, paramval = self.__settings[param]) if results == True: mem_action_record[param] = str(sysdict[param]) msg = "Set '%s' to '%s' in running kernel" % (param, str(self.__settings[param])) self.logger.notice(self.module_name, 'Apply Performed: ' + msg) messages['messages'].append(msg) else: msg = "Unable to set '%s' to '%s' in running kernel" % (param, str(self.__settings[param])) self.logger.error(self.module_name, 'Apply Error: ' + msg) messages['messages'].append(msg) del paramlist del sysdict del SysCtl if mem_action_record == {} and file_action_record == {}: return False, 'empty', messages else: change_record = "mem|%s\nfile|%s" % (str(mem_action_record), str(file_action_record)) return True, change_record, messages
class DisableHPServices: def __init__(self): self.module_name = 'DisableHPServices' self.__target_file = '' self.logger = TCSLogger.TCSLogger.getInstance() # Couple of notes here - hplip appears to be the package name across the board, # but the SERVICE may or may not exist, depending on the actual OS distro and perhaps # the version os hplip - more recent OS's have the package but not the service. # Based on discussions with Greg, we'll do the following (NOTE : linux ONLY) # # SCAN - no package = N/A # SCAN - package, service disabled = PASS # SCAN - package, and service enabled= FAIL # SCAN - package, and no service = FAIL # APPLY - no package = Not required # APPLY - package, and service disabled = Not required # APPLY - package, and service enabled = disable the service, return APPLIED # APPLY - package, and no service = MANUAL ACTION REQUIRED self._pkgname = 'hplip' self._svcname = 'hplip' self._svcdesc = 'HP Printer Services' def serviceExists(self, svcname): """ See if the service even exists, needed because the hplip software has migrated away from a service (which we could disable) to simply a package that should be removed So process the chkconfig --list hplip command looking for any error string (field 2) """ cmd = "/sbin/chkconfig --list %s" % svcname results = tcs_utils.tcs_run_cmd(cmd, True) if results[2] != '': return False else: return True ########################################################################## def validate_input(self, option): if option and option != 'None': return 1 return 0 ########################################################################## def scan(self, option=None): if sb_utils.os.info.is_solaris() == True: msg = "'%s' service is not part of the standard Solaris "\ "distribution." % self._svcname self.logger.notice(self.module_name, 'Not Applicable: ' + msg) raise tcs_utils.OSNotApplicable('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname=self._pkgname) if results != True: msg = "'%s' is not installed on the system" % self._pkgname self.logger.warn(self.module_name, 'Not Applicable: ' + msg) raise tcs_utils.ScanNotApplicable('%s %s' % (self.module_name, msg)) msg = "'%s' package is installed." % self._pkgname self.logger.debug(self.module_name, msg) results = sb_utils.os.service.is_enabled(svcname=self._svcname) if results == True: msg = "'%s' service is on" % self._svcname self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg elif not self.serviceExists(self._svcname): msg = "'%s' service does not exist! Manual action required to fix." % self._svcname self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg if results == None: msg = "'%s' does not appear to be a service in %s %s - nothing to disable, adminstrator should remove '%s' unless this package is required." % (self._svcname, sb_utils.os.info.getDistroName(), str(sb_utils.os.info.getDistroVersion()) , self._pkgname) self.logger.warn(self.module_name, 'Not Applicable: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) return 'Pass', '' ########################################################################## def apply(self, option=None): try: result, reason = self.scan() if result == 'Pass': return 0, '' except tcs_utils.ScanNotApplicable, err: msg = 'module is not applicable for this system' self.logger.error(self.module_name, 'Apply Error: ' + msg) return 0, '' action_record = '' results = sb_utils.os.service.is_enabled(svcname=self._svcname) if not self.serviceExists(self._svcname): msg = "'%s' service does not exist! Manual action required to remove this package" % self._svcname raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) if results == None: msg = "Unable to determine status of the '%s' service" % self._svcname self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) if results == False: action_record = 'off' else: action_record = 'on' results = sb_utils.os.service.disable(svcname=self._svcname) if results != True: msg = 'Unable to disable: %s' % self._svcname self.logger.notice(self.module_name, 'Apply Failed: ' + msg) return 0, msg msg = '%s service is disabled.' % self._svcname self.logger.notice(self.module_name, 'Apply Performed: ' + msg) return 1, action_record
def scan(self, optionDict=None): if sb_utils.os.info.is_LikeSUSE() == True: msg = "This module is not applicable to SUSE systems" raise tcs_utils.ScanNotApplicable('%s %s' % (self.module_name, msg)) messages = {} messages['messages'] = [] self.validate_options(optionDict) paramlist = sb_utils.os.config.get_list(configfile=self.__target_file, delim='=') SysCtl = sb_utils.os.linux.sysctl() sysdict = SysCtl.getlist() if len(sysdict) == 0: msg = "Unable to get in-memory kernel setting using sysctl(8) utility" self.logger.error(self.module_name, 'Scan Error: ' + msg) raise tcs_utils.ScanError('%s %s' % (self.module_name, msg)) failure_flag = False msg = "Checking settings in %s" % (self.__target_file) self.logger.info(self.module_name, msg) for param in self.__settings.keys(): # Verify the parameter setting actually exists in /proc/sys/kernel - if not then the feature doesn't exist and shouldn't be set # via sysconfig if not param.startswith('kernel.'): msg = "Found '%s' as the parameters, expected it to start with 'kernel.', skipping entire module..." % param raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) kernelPath = "/proc/sys/kernel/" + param[7:] if not os.path.exists(kernelPath): msg = "Did not find %s for setting %s - feature not applicable for this kernel" % ( kernelPath, param) self.logger.info(self.module_name, msg) continue # Ok, got here, check for actual setting... if paramlist.has_key(param): if int(self.__settings[param]) != int(paramlist[param]): msg = "'%s' is set to '%s' in %s; exepcted it to be set to '%s'" % \ (param, paramlist[param], self.__target_file, self.__settings[param]) self.logger.notice(self.module_name, 'Scan Failed: ' + msg) failure_flag = True messages['messages'].append("Fail: %s" % msg) else: msg = "Okay: '%s' is set to '%s' in %s" % (param, self.__settings[param], self.__target_file) self.logger.info(self.module_name, msg) messages['messages'].append(msg) else: msg = "'%s' not found in %s" % (param, self.__target_file) self.logger.notice(self.module_name, 'Scan Failed: ' + msg) messages['messages'].append("Fail: %s" % msg) failure_flag = True msg = "Checking in-memory kernel settings using sysctl(8) utility" self.logger.info(self.module_name, msg) for param in self.__settings.keys(): if sysdict.has_key(param): if int(self.__settings[param]) != int(sysdict[param]): msg = "'%s' is set to '%s' in the running kernel; expected it to be set to '%s'" % \ (param, sysdict[param], self.__settings[param]) self.logger.notice(self.module_name, 'Scan Failed: ' + msg) messages['messages'].append("Fail: %s" % msg) failure_flag = True else: msg = "Okay: '%s' is set to '%s' in the running kernel" % (param, self.__settings[param]) messages['messages'].append(msg) self.logger.info(self.module_name, msg) else: msg = "'%s' not found; skipping" % param self.logger.notice(self.module_name, msg) messages['messages'].append(msg) del paramlist del sysdict del SysCtl if failure_flag == True: return False, 'Settings in sysclt are not enabled', messages else: return True, 'Settings in sysclt are enabled', messages
def apply(self, option=None): results, reason, messages = self.scan(option) if results == True: return False, '', messages action_record = '' self.check_version() messages = {'messages': []} if sb_utils.os.suse.pam.passwdqc_configured(): msg = "It appears that pam_passwdqc is installed and configured so,"\ "OS Lockdown will not edit your PAM configuration. "\ "Presently, OS Lockdown only supports pam_cracklib." self.logger.info(self.module_name, msg) return False, '', messages results = sb_utils.os.software.is_installed(pkgname='pam-config') if results != True: msg = "'pam-config' package is not installed on the system." self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname='cracklib') if results != True: msg = "'cracklib' package is not installed on the system." self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) # Backup files in /etc/pam.d/* to a tar.gz file results = sb_utils.os.suse.pam.backup() if results == False: msg = "Unable to make backup of /etc/pam.d/* files" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) settings = sb_utils.os.suse.pam.config(modName='cracklib') # cracklib is already ENABLED if len(settings) != 0: ucredit = sb_utils.os.suse.pam.cracklib_get('ucredit') if ucredit == '-1': return False, 'none', messages action_record = "cracklib|%s" % str(ucredit) results = sb_utils.os.suse.pam.cracklib_set(option='ucredit', optValue='-1') # cracklib is DISABLED else: action_record = 'cracklib|' results = sb_utils.os.suse.pam.convert_to_cracklib() if results != True: msg = "Unable to switch from pam_pwcheck to pam_cracklib" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) results = sb_utils.os.suse.pam.cracklib_set(option='ucredit', optValue='-1') if results != True: msg = "Unable to set pam_cracklib's ucredit parameter" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) msg = "pam_cracklib's ucredit parameter set to '-1'" self.logger.notice(self.module_name, 'Apply Performed: ' + msg) return True, action_record, messages
def apply(self, option=None): raise tcs_utils.ManualActionReqd( 'This module is obsolete, and has been replaced with the following modules: %s' % ', '.join(self.replacementModules.keys()))
def scan(self, optionDict=None): if self.validate_input(optionDict): msg = 'Invalid option value was supplied.' self.logger.error(self.module_name, 'Scan Error: ' + msg) raise tcs_utils.ScanError('%s %s' % (self.module_name, msg)) option = optionDict['passwordMinLength'] option = int(option) if sb_utils.os.suse.pam.passwdqc_configured(): msg = "It appears that pam_passwdqc is installed and configured. "\ "Presently, OS Lockdown only supports pam_cracklib." self.logger.info(self.module_name, msg) msg2 = "If wish this module to configure 'minlen', unconfigure " \ "pam_passwdqc." self.logger.info(self.module_name, msg2) raise tcs_utils.ScanNotApplicable('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname='pam-config') if results != True: msg = "'pam-config' package is not installed on the system." self.logger.error(self.module_name, 'Scan Error: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname='cracklib') if results != True: msg = "'cracklib' package is not installed on the system." self.logger.error(self.module_name, 'Scan Error: ' + msg) raise tcs_utils.ScanError('%s %s' % (self.module_name, msg)) cracklib_settings = sb_utils.os.suse.pam.config(modName='cracklib') #------------------------------------------ # If cracklib is not being used, check pwcheck settings if len(cracklib_settings) == 0: pwcheck_settings = sb_utils.os.suse.pam.config(modName='pwcheck') msg = "PAM cracklib is not configured; checking PAM pwcheck settings" self.logger.info(self.module_name, msg) if not pwcheck_settings.has_key('password'): msg = "PAM pwcheck is not configured either" self.logger.info(self.module_name, msg) self.logger.notice(self.module_name, 'Scan Failed.') return 'Fail', '' if len(pwcheck_settings['password']) == 0: msg = "PAM pwcheck is not set; assuming default "\ "minlen value of 5" self.logger.info(self.module_name, 'Scan Failed.') if option != 5: self.logger.notice(self.module_name, 'Scan Failed.') return 'Fail', '' else: return 'Pass', '' found_minlen = False for pw_opt in pwcheck_settings['password']: try: (pw_key, pw_val) = pw_opt.split('=') except (ValueError, IndexError): continue if pw_key == 'minlen': found_minlen = True msg = "PAM pwcheck 'minlen' option set to '%s' " % (pw_val) self.logger.info(self.module_name, msg) if option != int(pw_val): msg = "PAM pwcheck 'minlen' option is not set to '%d'" % (option) self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg if found_minlen == False: msg = "PAM pwcheck is configured but 'minlen' parameter; is not" \ " set so, assuming default minlen value of 5" self.logger.info(self.module_name, 'Scan Failed: ' + msg) if option != 5: return 'Fail', '' return 'Pass', '' #------------------------------------------ # Check cracklib settings if not cracklib_settings.has_key('password'): msg = "PAM cracklib is not configured for 'password'" self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg for pw_opt in cracklib_settings['password']: try: (pw_key, pw_val) = pw_opt.split('=') except (ValueError, IndexError): continue if pw_key == 'minlen': msg = "PAM cracklib 'minlen' option set to '%s' " % (pw_val) self.logger.info(self.module_name, msg) if option != int(pw_val): msg = "PAM cracklib 'minlen' option is not set to '%d'" % (option) self.logger.notice(self.module_name, 'Scan Failed: ' + msg) return 'Fail', msg else: return 'Pass', '' return 'Fail', 'minlen parameter not set'
def apply(self, optionDict=None): results, reason = self.scan(optionDict) if results == 'Pass': return 0, '' action_record = '' if self.validate_input(optionDict): msg = 'Invalid option value was supplied.' self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) option = optionDict['passwordMinLength'] option = int(option) if sb_utils.os.suse.pam.passwdqc_configured(): msg = "It appears that pam_passwdqc is installed and configured so,"\ "OS Lockdown will not edit your PAM configuration. "\ "Presently, OS Lockdown only supports pam_cracklib." self.logger.info(self.module_name, msg) return 0, '' results = sb_utils.os.software.is_installed(pkgname='pam-config') if results != True: msg = "'pam-config' package is not installed on the system." self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) results = sb_utils.os.software.is_installed(pkgname='cracklib') if results != True: msg = "'cracklib' package is not installed on the system." self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) # Backup files in /etc/pam.d/* to a tar.gz file results = sb_utils.os.suse.pam.backup() if results == False: msg = "Unable to make backup of /etc/pam.d/* files" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) settings = sb_utils.os.suse.pam.config(modName='cracklib') # cracklib is already ENABLED if len(settings) != 0: minlen = sb_utils.os.suse.pam.cracklib_get('minlen') action_record = "cracklib|%s" % str(minlen) results = sb_utils.os.suse.pam.cracklib_set(option='minlen', optValue=option) # cracklib is DISABLED else: settings = sb_utils.os.suse.pam.config(modName='pwcheck') results = sb_utils.os.suse.pam.pwcheck_get('minlen') if results != '': action_record = "pwcheck|%s" % str(results) else: action_record = "pwcheck|5" results = sb_utils.os.suse.pam.convert_to_cracklib() if results != True: msg = "Unable to switch from pam_pwcheck to pam_cracklib" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) results = sb_utils.os.suse.pam.cracklib_set(option='minlen', optValue=option) if results != True: msg = "Unable to set pam_cracklib's minlen parameter" self.logger.error(self.module_name, 'Apply Error: ' + msg) raise tcs_utils.ActionError('%s %s' % (self.module_name, msg)) return 1, action_record
def scan(self, option=None): msg = "This module has been retired. Please replace 'Password Protect Grub' with 'Require Grub Password' in all profiles" self.logger.warning(self.module_name, msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) return False, '', {}
def scan(self, optionDict=None): messages = {'messages': [] } if self.validate_input(optionDict): msg = 'Invalid option value was supplied.' self.logger.error(self.module_name, 'Scan Error: ' + msg) raise tcs_utils.ScanError('%s %s' % (self.module_name, msg)) option = optionDict['passwordReuse'] option = int(option) results = sb_utils.os.software.is_installed(pkgname='pam-config') if results != True: msg = "'pam-config' package is not installed on the system." self.logger.error(self.module_name, 'Scan Error: ' + msg) raise tcs_utils.ManualActionReqd('%s %s' % (self.module_name, msg)) pwhistory_settings = sb_utils.os.suse.pam.config(modName='pwhistory') #------------------------------------------ # If pwhistory is not being used, check pwcheck settings if len(pwhistory_settings) == 0: msg = "PAM pwhistory is not configured" self.logger.notice(self.module_name, 'Scan Failed:' + msg) messages['messages'].append(msg) return False, '', messages else: msg = "Okay: PAM pwhistory is configured" messages['messages'].append(msg) #------------------------------------------ # Check pwhistory settings if not pwhistory_settings.has_key('password'): msg = "PAM pwhistory is not configured for 'password'" self.logger.notice(self.module_name, 'Scan Failed: ' + msg) messages['messages'].append(msg) return False, '', messages for pw_opt in pwhistory_settings['password']: try: [pw_key, pw_val] = pw_opt.split('=') except (ValueError, IndexError): continue if pw_key == 'remember': msg = "PAM pwhistory 'remember' option set to '%s' " % (pw_val) self.logger.info(self.module_name, msg) if int(pw_val) > option: msg = "PAM pwhistory 'remember' option is currently set "\ "to '%d' which is greater than '%d' " % (int(pw_val), option) self.logger.info(self.module_name, 'Scan Passed: ' + msg) return True, '', {} elif int(pw_val) == option: msg = "PAM pwhistory 'remember' option is currently set to '%d'" % option self.logger.info(self.module_name, 'Scan Passed: ' + msg) return True, '', {} else: msg = "PAM pwhistory 'remember' option is not set to '%d' or higher." % (option) self.logger.notice(self.module_name, 'Scan Failed: ' + msg) messages['messages'].append(msg) return False, '', messages msg = 'remember parameter not set' messages['messages'].append(msg) return False, '', messages