示例#1
0
    def reportSSHFile(self, sshfile, directives):
        """
        Report configuration options of config files
        :param: sshfile - filepath string
        :param: directives - dictionary of desired directives
        :return: compliant
        :rtype: bool

        """
        compliant = True
        debug = ""
        directives = dict(directives)
        tpath = sshfile + ".tmp"

        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["PasswordAuthentication"] = "no"
                    self.server = directives
            editor = KVEditorStonix(self.statechglogger,
                                      self.logger, "conf",
                                      sshfile, tpath,
                                      directives, "present",
                                      "space")
            if not editor.report():
                self.detailedresults += "Did not find the correct " + \
                                        "contents in sshd_config\n"
                compliant = False

            # for ubuntu systems we want to make sure the following two
            # directives don't exist in the server file
            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)
                if not editor.report():
                    self.detailedresults += "didn't find the correct" + \
                            " contents in sshd_config\n"
                    self.logger.log(LogPriority.DEBUG, debug)
                    compliant = False
            if not checkPerms(sshfile, [0, 0, 0o644],
                              self.logger):
                self.detailedresults += "Incorrect permissions for " + \
                                        "file " + self.serverfile + "\n"
                compliant = False
        else:
            self.detailedresults += sshfile + " does not exist\n"
            compliant = False
        return compliant
示例#2
0
class SecureIPV4(Rule):

    def __init__(self, config, environ, logger, statechglogger):
        '''Constructor'''
        Rule.__init__(self, config, environ, logger, statechglogger)
        self.logger = logger
        self.rulenumber = 15
        self.cmdhelper = CommandHelper(self.logger)
        self.rulename = "SecureIPV4"
        self.formatDetailedResults("initialize")
        self.mandatory = True
        self.sethelptext()
        if self.environ.getostype() == "Mac OS X":
            self.networkTuning2 = self.__InitializeNetworkTuning2()
        else:
            self.networkTuning1 = self.__InitializeNetworkTuning1()
            self.networkTuning2 = self.__InitializeNetworkTuning2()
        self.guidance = ["NSA 2.5.1.1", "NSA 2.5.1.2"]
        self.applicable = {'type': 'white',
                           'family': ['linux', 'solaris', 'freebsd'],
                           'os': {'Mac OS X': ['10.15', 'r', '10.15.10']}}
        self.iditerator = 0
        self.ch = CommandHelper(self.logger)

    def __InitializeNetworkTuning1(self):
        '''Private method to initialize the configurationitem object for the
        NetworkTuning1 bool.
        @return: configurationitem object instance'''

        datatype = 'bool'
        key = "NETWORKTUNING1"
        instructions = "Network Parameter Tuning. You should not need " + \
            "to override this under normal circumstances."
        default = True
        ci = self.initCi(datatype, key, instructions, default)
        return ci

    def __InitializeNetworkTuning2(self):
        '''Private method to initialize the configurationitem object for the
        NetworkTuning2 bool.
        @return: configurationitem object instance'''

        key = "NETWORKTUNING2"
        instructions = "Additional network parameters. Set this to False " + \
            "if you are running a router or a bridge. Also, in rare " + \
            "cases, you may need to set this to False for VMware (if you " + \
            "are using normal VMware routing, True should be fine)."
        default = True
        datatype = "bool"
        ci = self.initCi(datatype, key, instructions, default)
        return ci

    def report(self):
        '''Main parent report method that calls the sub report methods


        :returns: bool

        '''
        try:
            self.detailedresults = ""
            if self.environ.getosfamily() == "linux":
                self.path = "/etc/sysctl.conf"
                self.tmpPath = "/etc/sysctl.conf.tmp"
                self.original = readFile(self.path, self.logger)
                rep1success = self.reportLinux1()
                rep2success = self.reportLinux2()
            elif self.environ.getosfamily() == "freebsd":
                self.path = "/etc/sysctl.conf"
                self.tmpPath = "/etc/sysctl.conf.tmp"
                self.original = readFile(self.path, self.logger)
                rep1success = self.reportFreebsd1()
                rep2success = self.reportFreebsd2()
            elif self.environ.getostype() == "Mac OS X":
                self.path = "/private/etc/sysctl.conf"
                self.tmpPath = "/private/etc/sysctl.conf.tmp"
                rep1success = True
                rep2success = self.reportMac()
            if rep1success and rep2success:
                self.compliant = True
            else:
                self.compliant = False
        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("report", self.compliant,
                                   self.detailedresults)
        self.logdispatch.log(LogPriority.INFO, self.detailedresults)
        return self.compliant
        return self.rulesuccess

    def reportLinux1(self):
        '''Linux specific report method that ensures the items in fileContents
        exist in /etc/sysctl.conf.  Sets self.compliant to True if all items
        exist in the file.  Returns True if successful in updating the file


        :returns: bool

        '''
        compliant = True
        if not os.path.exists(self.path):
            self.detailedresults += self.path + " does not exist\n"
            compliant = False
        else:
            lfc = {"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"}
            editor = KVEditorStonix(self.statechglogger, self.logger,
                                    "conf", self.path, self.tmpPath, lfc,
                                    "present", "openeq")
            if not editor.report():
                self.detailedresults += self.path + " is not configured " + \
                    "correctly for configuration item 1\n"
                compliant = False
            if not checkPerms(self.path, [0, 0, 0o644], self.logger):
                self.detailedresults += "Permissions are incorrect on " + \
                    self.path + "\n"
                compliant = False
        for key in lfc:
            self.ch.executeCommand("/sbin/sysctl " + key)
            retcode = self.ch.getReturnCode()

            if retcode != 0:
                self.detailedresults += "Failed to get value of core dumps configuration with sysctl command\n"
                errmsg = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG, errmsg)
                compliant = False
            else:
                output = self.ch.getOutputString()
                if output.strip() != key + " = " + lfc[key]:
                    compliant = False
                    self.detailedresults += "sysctl output has incorrect value: " + \
                        output + "\n"
        return compliant

    def reportLinux2(self):
        '''Linux specific report method2 that ensures the items in fileContents
        exist in /etc/sysctl.conf.  Sets self.compliant to True if all items
        exist in the file.  Returns True if successful in updating the file


        :returns: bool

        '''
        compliant = True
        if not os.path.exists(self.path):
            compliant = False
        else:
            lfc = {"net.ipv4.conf.default.send_redirects": "0",
                   "net.ipv4.conf.all.send_redirects": "0",
                   "net.ipv4.ip_forward": "0"}
            editor = KVEditorStonix(self.statechglogger, self.logger,
                                    "conf", self.path, self.tmpPath,
                                    lfc, "present", "openeq")
            if not editor.report():
                self.detailedresults += self.path + " is not configured " + \
                    "correctly for configuration item 2\n"
                compliant = False

        for key in lfc:
            self.ch.executeCommand("/sbin/sysctl " + key)
            retcode = self.ch.getReturnCode()

            if retcode != 0:
                self.detailedresults += "Failed to get value of core dumps configuration with sysctl command\n"
                errmsg = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG, errmsg)
                compliant = False
            else:
                output = self.ch.getOutputString()
                if output.strip() != key + " = " + lfc[key]:
                    compliant = False
                    self.detailedresults += "sysctl output has incorrect value: " + \
                        output + "\n"
        return compliant

    def reportMac(self):
        '''Mac specific report method1 that ensures the items in fileContents
        exist in /etc/sysctl.conf.  Sets self.compliant to True if all items
        exist in the file.


        :returns: compliant

        :rtype: bool
@author: dwalker
@change: Breen Malmberg - 1/10/2017 - minor doc string adjustments; fixed
        permissions on file /etc/sysctl.conf (needs to be 0o600; was 0o644);
        try/except

        '''

        compliant = True

        try:
            self.editor = None

            if not os.path.exists(self.path):
                self.detailedresults += self.path + " does not exist\n"
                compliant = False
            else:
                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.detailedresults += self.path + " is not " + \
                        "configured correctly\n"
                    compliant = False
                else:
                    self.detailedresults += self.path + " is " + \
                        "configured correctly\n"
                if not checkPerms(self.path, [0, 0, 0o600], self.logger):
                    self.detailedresults += "Permissions are incorrect on " + \
                        self.path + ": Expected 644, found " + \
                        str(getOctalPerms(self.path)) + "\n"
                    compliant = False

        except Exception:
            raise

        return compliant

    def reportFreebsd1(self):
        '''Freebsd specific report method1 that ensures the items in the file
        exist in /etc/sysctl.conf.  Sets self.compliant to True if all items
        exist in the file.  Returns True if successful in updating the file


        :returns: bool

        '''
        compliant = True
        if not os.path.exists(self.path):
            self.detailedresults += self.path + " does not exist\n"
            compliant = False
        else:
            ffc = {"net.inet.icmp.bmcastecho": "0",
                   "net.inet.ip.redirect": "0",
                   "net.inet.icmp.maskrepl": "0",
                   "net.inet.ip.sourceroute": "0",
                   "net.inet.ip.accept_sourceroute": "0",
                   "net.inet.tcp.syncookies": "1"}
            kvtype = "conf"
            intent = "present"
            self.editor = KVEditorStonix(self.statechglogger, self.logger,
                                         kvtype, self.path, self.tmpPath, ffc,
                                         intent, "openeq")
            if not self.editor.report():
                compliant = False
            if not checkPerms(self.path, [0, 0, 0o644], self.logger):
                self.detailedresults += "Permissions are incorrect on " + \
                    self.path + ": Expected 644, found " + \
                    str(getOctalPerms(self.path)) + "\n"
                compliant = False
        return compliant

    def reportFreebsd2(self):
        '''Freebsd specific report method1 that ensures the items in
        fileContents exist in /etc/sysctl.conf. Sets self.compliant to True
        if all items exist in the file. Returns True if successful in updating
        the file


        :returns: bool

        '''
        compliant = True
        if not os.path.exists(self.path):
            self.detailedresults += self.path + " does not exist\n"
            compliant = False
        else:
            ffc = {"net.inet.ip.forwarding": "0",
                   "net.inet.ip.fastforwarding": "0"}
            if not self.networkTuning1.getcurrvalue():
                kvtype = "conf"
                intent = "present"
                self.editor = KVEditorStonix(self.statechglogger, self.logger,
                                             kvtype, self.path, self.tmpPath,
                                             ffc, intent, "closedeq")
            else:
                self.editor.setData(ffc)
            if not self.editor.report():
                compliant = False
            if not checkPerms(self.path, [0, 0, 0o644], self.logger):
                self.detailedresults += "Permissions are incorrect on " + \
                    self.path + ": Expected 644, found " + \
                    str(getOctalPerms(self.path)) + "\n"
                compliant = False
        return compliant

    def fix(self):
        '''Main parent fix method that calls the sub fix methods


        :returns: bool

        '''
        try:
            self.detailedresults = ""
            success = True
            self.iditerator = 0
            eventlist = self.statechglogger.findrulechanges(self.rulenumber)
            for event in eventlist:
                self.statechglogger.deleteentry(event)

            if self.environ.getosfamily() == "linux":
                if self.networkTuning1 and self.networkTuning2:
                    success = self.fixLinux()
                else:
                    self.detailedresults += "Required CI has not been initialized."
                    success = False
            elif self.environ.getosfamily() == "freebsd":
                if self.networkTuning1 and self.networkTuning2:
                    success = self.fixFreebsd()
                else:
                    self.detailedresults += "Required CI has not been initialized."
                    success = False
            elif self.environ.getosfamily() == "darwin":
                if self.networkTuning2:
                    success = self.fixMac()
                else:
                    self.detailedresults += "Required CI has not been initialized."
                    success = False
        except (KeyboardInterrupt, SystemExit):
            raise
        except Exception:
            self.detailedresults += "\n" + traceback.format_exc()
            self.logdispatch.log(LogPriority.ERROR, self.detailedresults)
            success = False
        self.formatDetailedResults("fix", success, self.detailedresults)
        self.logdispatch.log(LogPriority.INFO, self.detailedresults)

        self.rulesuccess = success
        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 fixFreebsd(self):
        if not checkPerms(self.path, [0, 0, 0o644], self.logger):
            self.iditerator += 1
            myid = iterate(self.iditerator, self.rulenumber)
            if not setPerms(self.path, [0, 0, 0o644], self.logger,
                            self.statechglogger, myid):
                return False
        if self.networkTuning1.getcurrvalue() or \
                self.networkTuning2.getcurrvalue():
            if self.editor.fixables:
                self.iditerator += 1
                myid = iterate(self.iditerator, self.rulenumber)
                self.editor.setEventID(myid)
                if not self.editor.fix():
                    return False
                elif not self.editor.commit():
                    return False
                os.chown(self.path, 0, 0)
                os.chmod(self.path, 0o644)
                resetsecon(self.path)
                cmd = ["/usr/sbin/service", "sysctl", "restart"]
                self.ch.executeCommand(cmd)
                if self.ch.getReturnCode() != 0:
                    self.detailedresults = "Unable to restart sysctl\n"
                    self.logger.log(LogPriority.DEBUG, self.detailedresults)
                    return False
                else:
                    return True
            else:
                return True
示例#3
0
    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
示例#4
0
class SecureCUPS(Rule):
    '''With this rule, you can:
        Disable the CUPS service
        Configure CUPS service
        Disable Printer Browsing
        Limit Printer Browsing
        Disable Print Server Capabilities
        Set the Default Auth Type
        Setup default set of policy blocks for CUPS
    '''
    def __init__(self, config, environ, logger, statechglogger):
        '''
        Constructor
        '''

        Rule.__init__(self, config, environ, logger, statechglogger)
        self.config = config
        self.environ = environ
        self.logger = logger
        self.statechglogger = statechglogger
        self.rulenumber = 128
        self.rulename = 'SecureCUPS'
        self.rulesuccess = True
        self.formatDetailedResults("initialize")
        self.mandatory = True
        self.sethelptext()
        self.rootrequired = True
        self.guidance = ['CCE 4420-6', 'CCE 4407-3']
        self.applicable = {
            'type': 'white',
            'os': {
                'Mac OS X': ['10.15', 'r', '10.15.10']
            },
            'family': ['linux']
        }

        # init CIs
        datatype1 = 'bool'
        key1 = 'SECURECUPS'
        instructions1 = 'To prevent to STONIX from securing the CUPS service, set the value of ' + \
        'SecureCUPS to False.'
        default1 = True
        self.SecureCUPS = self.initCi(datatype1, key1, instructions1, default1)

        datatype2 = 'bool'
        key2 = 'DISABLECUPS'
        instructions2 = 'To have STONIX completely disable the CUPS service on this system, set ' + \
        'the value of DisableCUPS to True.'
        default2 = False
        self.DisableCUPS = self.initCi(datatype2, key2, instructions2,
                                       default2)

        datatype3 = 'bool'
        key3 = 'DISABLEPRINTBROWSING'
        instructions3 = 'If this machine is to be used as a print server and you wish to enable automatic client discovery of ' \
                        'its shared printers/print resources, then set the value of DISABLEPRINTBROWSING TO False'
        default3 = True
        self.DisablePrintBrowsing = self.initCi(datatype3, key3, instructions3,
                                                default3)

        datatype4 = 'string'
        key4 = 'PRINTBROWSESUBNET'
        instructions4 = 'If this machine is to be used as a print server and you wish to enable automatic client discovery of ' \
                        'its shared printers/print resources, you may wish to limit that discovery to clients only on a certain subnet. ' \
                        'Please customize the value of PRINTBROWSESUBNET to match your networks requirements. Ex: 192.168.0.0/16'
        default4 = ''
        self.PrintBrowseSubnet = self.initCi(datatype4, key4, instructions4,
                                             default4)

        datatype5 = 'bool'
        key5 = 'DISABLEGENERICPORT'
        instructions5 = 'To prevent remote users from potentially connecting ' + \
        'to and using locally configured printers by disabling the CUPS print ' + \
        'server sharing capabilities, set the value of DisableGenericPort to ' + \
        'True.'
        default5 = False
        self.DisableGenericPort = self.initCi(datatype5, key5, instructions5,
                                              default5)

        datatype6 = 'bool'
        key6 = 'SETDEFAULTAUTHTYPE'
        instructions6 = 'To prevent the defaultauthtype for cups from being ' + \
        'set to Digest, set the value of SetDefaultAuthType to False.'
        default6 = True
        self.SetDefaultAuthType = self.initCi(datatype6, key6, instructions6,
                                              default6)

        datatype7 = 'bool'
        key7 = 'SETUPDEFAULTPOLICYBLOCKS'
        instructions7 = "To prevent default policy blocks for cups from " + \
        "being defined in the cups config file, set the value of " + \
        "SetupDefaultPolicyBlocks to False. Note that if you choose to setup " + \
        "the default set of policy blocks you can (and probably should) edit " + \
        "them in the cups config file afterward to customize these policies to " + \
        "your site's particular needs."
        default7 = False
        self.SetupDefaultPolicyBlocks = self.initCi(datatype7, key7,
                                                    instructions7, default7)

        self.localize()

    def localize(self):
        '''set various settings and variables and objects based on
        which OS is currently running


        :returns: void
        @author: Breen Malmberg

        '''

        self.linux = False
        self.darwin = False

        if self.environ.getosfamily() == 'darwin':
            self.darwin = True
        if self.environ.getosfamily() == 'linux':
            self.linux = True

        self.initObjs()
        self.setVars()

    def initObjs(self):
        '''initialize all required class objects


        :returns: void
        @author: Breen Malmberg

        '''

        if self.linux:
            self.ph = Pkghelper(self.logger, self.environ)
        if self.darwin:
            pass
        self.sh = ServiceHelper(self.environ, self.logger)
        self.serviceTarget = ""
        self.ch = CommandHelper(self.logger)

    def setVars(self):
        '''set all class variables depending on which
        OS is currently running


        :returns: void
        @author: Breen Malmberg
        @change: Breen Malmberg - 2/8/2017 - fixed a typo with the var name of the dict
                for cupsd conf options;

        '''

        try:

            # linux config
            if self.linux:
                self.configfileperms = '0640'
                errorlog = "/var/log/cups/error_log"
                logfileperms = '0644'
                self.pkgname = "cups"
                self.svcname = "cups"
                accesslog = "/var/log/cups/access_log"

            self.cupsfilesopts = {}
            self.cupsfilesconf = ""
            self.cupsdconf = ""
            self.cupsdconfremopts = {}

            # darwin config
            if self.darwin:
                accesslog = "/private/var/log/cups/access_log"
                # a value of 'strict' causes issues connecting to printers on some mac systems
                self.configfileperms = '0644'
                logfileperms = '0644'
                errorlog = "/private/var/log/cups/error_log"
                self.svclongname = "/System/Library/LaunchDaemons/org.cups.cupsd.plist"
                self.svcname = "org.cups.cupsd"

# common config
            cupsdconflocs = [
                '/etc/cups/cupsd.conf', '/private/etc/cups/cupsd.conf'
            ]
            for loc in cupsdconflocs:
                if os.path.exists(loc):
                    self.cupsdconf = loc
            self.tmpcupsdconf = self.cupsdconf + ".stonixtmp"

            cupsfileslocs = [
                '/etc/cups/cups-files.conf',
                '/private/etc/cups/cups-files.conf'
            ]
            for loc in cupsfileslocs:
                if os.path.exists(loc):
                    self.cupsfilesconf = loc
            self.tmpcupsfilesconf = self.cupsfilesconf + ".stonixtmp"

            # options for cups-files.conf
            self.cupsfilesopts["ConfigFilePerm"] = self.configfileperms
            self.cupsfilesopts["ErrorLog"] = errorlog
            self.cupsfilesopts["LogFilePerm"] = logfileperms

            # cupsd conf default configuration options
            loglevel = "warn"
            self.cupsdconfopts = {"LogLevel": loglevel}
            self.cupsdconfopts["AccessLog"] = accesslog
            self.cupsdconfopts["AccessLogLevel"] = "config"

            # cupsd conf remove these options
            if self.DisableGenericPort.getcurrvalue():
                self.cupsdconfremopts = {"Port": "631"}

            # this line added to prevent kvaconf trying to load files
            # it can't access during __init__, if the program is being
            # run in user mode
            if self.environ.geteuid() == 0:

                ## create kveditor objects
                if os.path.exists(self.cupsfilesconf):
                    kvtype1 = "conf"
                    path1 = self.cupsfilesconf
                    tmpPath1 = path1 + ".stonixtmp"
                    data1 = self.cupsfilesopts
                    intent1 = "present"
                    configType1 = "space"
                    self.KVcupsfiles = KVEditorStonix(self.statechglogger,
                                                      self.logger, kvtype1,
                                                      path1, tmpPath1, data1,
                                                      intent1, configType1)

                if os.path.exists(self.cupsdconf):
                    kvtype2 = "conf"
                    path2 = self.cupsdconf
                    tmpPath2 = path2 + ".stonixtmp"
                    data2 = self.cupsdconfopts
                    intent2 = "present"
                    configType2 = "space"
                    self.KVcupsd = KVEditorStonix(self.statechglogger,
                                                  self.logger, kvtype2, path2,
                                                  tmpPath2, data2, intent2,
                                                  configType2)

            # policy blocks
            self.serveraccess = """# Restrict access to the server...
<Location />
  Encryption Required
  Order allow,deny
</Location>"""
            self.adminpagesaccess = """# Restrict access to the admin pages...
<Location /admin>
  Encryption Required
  Order allow,deny
</Location>"""
            self.configfilesaccess = """# Restrict access to configuration files...
<Location /admin/conf>
  AuthType Default
  Encryption IfRequested
  Require user @SYSTEM
  Order allow,deny
</Location>"""
            self.logfileaccess = """# Restrict access to log files...
<Location /admin/log>
  AuthType Default
  Encryption IfRequested
  Require user @SYSTEM
  Order allow,deny
</Location>"""
            self.defaultprinterpolicies = """# Set the default printer/job policies...
<Policy default>
  # Job-related operations must be done by the owner or an administrator...
  <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job CUPS-Move-Job>
    Require user @OWNER @SYSTEM
    Order deny,allow
  </Limit>

  # All administration operations require an administrator to authenticate...
  <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
    AuthType Default
    Require user @SYSTEM
    Order deny,allow
  </Limit>

  # All printer operations require a printer operator to authenticate...
  <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After CUPS-Accept-Jobs CUPS-Reject-Jobs>
    AuthType Default
    Require user @SYSTEM
    Order deny,allow
  </Limit>

  # Only the owner or an administrator can cancel or authenticate a job...
  <Limit Cancel-Job CUPS-Authenticate-Job>
    Require user @OWNER @SYSTEM
    Order deny,allow
  </Limit>

  <Limit All>
    Order deny,allow
  </Limit>
</Policy>"""

        except Exception:
            raise

    def sanityCheck(self):
        '''perform sanity check on the cups configuration files


        :returns: sane

        :rtype: bool
@author: Breen Malmberg

        '''

        sane = True

        sanitycheck = "/usr/sbin/cupsd -t"

        try:

            self.ch.executeCommand(sanitycheck)
            retcode = self.ch.getReturnCode()
            output = self.ch.getOutput()
            if retcode != 0:
                sane = False
                self.detailedresults += "\nError while running command: " + str(
                    sanitycheck)
            for line in output:
                if re.search("Bad|Missing|Incorrect|Error|Wrong", line,
                             re.IGNORECASE):
                    sane = False
                    self.detailedresults += "\n" + line

        except Exception:
            raise
        return sane

    def updateOpts(self):
        '''update the kveditor values for the different CIs
        based on their current user-specified values


        :returns: void
        @author: Breen Malmberg
        @change: Breen Malmberg - 2/8/2017 - KVcupsdrem will now only be processed if
                self.DisableGenericPort CI is True

        '''

        try:

            if self.DisableCUPS.getcurrvalue():
                self.PrintBrowseSubnet.updatecurrvalue(False)

            if self.DisablePrintBrowsing.getcurrvalue():
                self.cupsdconfopts["Browsing"] = "Off"
                self.cupsdconfopts["BrowseAllow"] = "none"
                self.cupsdconfopts["BrowseWebIF"] = "No"

            if self.PrintBrowseSubnet.getcurrvalue():
                self.cupsdconfopts["Browsing"] = "On"
                self.cupsdconfopts["BrowseOrder"] = "allow,deny"
                self.cupsdconfopts["BrowseDeny"] = "all"
                self.cupsdconfopts[
                    "BrowseAllow"] = self.PrintBrowseSubnet.getcurrvalue()

            if self.DisableGenericPort.getcurrvalue():
                self.cupsdconfremopts["Port"] = "631"
            if self.SetDefaultAuthType.getcurrvalue():
                self.cupsdconfopts["DefaultAuthType"] = "Negotiate"

            # don't try to create, or update, the kv object,
            # if the file it's based on doesn't exist.
            # this would cause tracebacks in kveditor
            if os.path.exists(self.cupsfilesconf):
                kvtype1 = "conf"
                path1 = self.cupsfilesconf
                tmpPath1 = path1 + ".stonixtmp"
                data1 = self.cupsfilesopts
                intent1 = "present"
                configType1 = "space"
                self.KVcupsfiles = KVEditorStonix(self.statechglogger,
                                                  self.logger, kvtype1, path1,
                                                  tmpPath1, data1, intent1,
                                                  configType1)
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Location of required configuration file cups-files.conf could not be determined"
                )
            if os.path.exists(self.cupsdconf):
                kvtype2 = "conf"
                path2 = self.cupsdconf
                tmpPath2 = path2 + ".stonixtmp"
                data2 = self.cupsdconfopts
                intent2 = "present"
                configType2 = "space"
                self.KVcupsd = KVEditorStonix(self.statechglogger, self.logger,
                                              kvtype2, path2, tmpPath2, data2,
                                              intent2, configType2)
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Location of required configuration file cupsd.conf could not be determined"
                )

        except Exception:
            raise

    def report(self):
        '''run report methods/actions appropriate for the current
        OS and return compliancy status


        :returns: self.compliant

        :rtype: bool
@author: Breen Malmberg

        '''

        self.logger.log(LogPriority.DEBUG, "\n\nREPORT()\n\n")

        # DEFAULTS
        self.detailedresults = ""
        self.compliant = True
        badopts = [
            "^HostNameLookups\s+Double", "^Sandboxing\s+strict",
            "^FatalErrors\s+config"
        ]
        badoptsfiles = [self.cupsdconf, self.cupsfilesconf]

        try:

            # check for bad config options in files
            for f in badoptsfiles:
                if os.path.exists(f):
                    fh = open(f, 'r')
                    contentlines = fh.readlines()
                    fh.close()
                    for line in contentlines:
                        for opt in badopts:
                            if re.search(opt, line, re.IGNORECASE):
                                self.compliant = False
            # if these opts exist, then we don't want to do anything else
            ## except just remove them
            if not self.compliant:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Bad configuration options found in cups config files. Will now remove them."
                )
                self.formatDetailedResults('report', self.compliant,
                                           self.detailedresults)
                return self.compliant

            if self.linux:
                if not self.ph.check(self.pkgname):
                    self.detailedresults += "\nCUPS not installed on this system. Nothing to secure."
                    self.formatDetailedResults('report', self.compliant,
                                               self.detailedresults)
                    return self.compliant

            # update kv objects with any new
            # user-specified information
            self.updateOpts()

            if self.SecureCUPS.getcurrvalue():
                # is cups secured?
                if not self.reportSecure():
                    self.compliant = False
                # make sure config syntax is correct
                if not self.sanityCheck():
                    self.compliant = False

            if self.DisableCUPS.getcurrvalue():
                # is cups disabled?
                if not self.reportDisabled():
                    self.compliant = False

        except (KeyboardInterrupt, SystemExit):
            raise
        except Exception:
            self.rulesuccess = False
            self.detailedresults += traceback.format_exc()
            self.logger.log(LogPriority.ERROR, self.detailedresults)
        self.formatDetailedResults('report', self.compliant,
                                   self.detailedresults)
        return self.compliant

    def reportDisabled(self):
        '''return True if cups is disabled
        return False if cups is enabled


        :returns: retval

        :rtype: bool
@author: Breen Malmberg

        '''

        retval = True

        try:

            if self.linux:
                if self.sh.auditService(self.svcname,
                                        serviceTarget=self.serviceTarget):
                    retval = False
                    self.detailedresults += "\nThe " + str(
                        self.svcname) + " service is still configured to run"
            elif self.darwin:
                if self.sh.auditService(self.svclongname,
                                        serviceTarget=self.svcname):
                    retval = False
                    self.detailedresults += "\nThe " + str(
                        self.svcname) + " service is still configured to run"

        except Exception:
            raise
        return retval

    def checkPolicyBlocks(self):
        '''report on whether default policy blocks are currently set up
        in cups configuration. Note that if these already exist, we
        do not want to overwrite them as the local admin may have
        them customised to their specific environment.


        :returns: retval

        :rtype: bool
@author: Breen Malmberg

        '''

        self.logger.log(LogPriority.DEBUG, "\n\nCHECKPOLICYBLOCKS()\n\n")

        retval = True
        rootfound = False
        adminfound = False
        adminconffound = False
        defpolicyfound = False

        try:

            if os.path.exists(self.cupsdconf):
                self.logger.log(
                    LogPriority.DEBUG,
                    "\n\nCUPSD CONF EXISTS. OPENING FILE AND READING CONTENTS...\n\n"
                )
                f = open(self.cupsdconf, 'r')
                contentlines = f.readlines()
                f.close()

                self.logger.log(
                    LogPriority.DEBUG,
                    "\n\nCONTENTS READ. CHECKING FOR POLICY BLOCKS...\n\n")
                for line in contentlines:
                    if re.search('\<Location \/\>', line, re.IGNORECASE):
                        rootfound = True
                    if re.search('\<Location \/admin\>', line, re.IGNORECASE):
                        adminfound = True
                    if re.search('\<Location \/admin\/conf\>', line,
                                 re.IGNORECASE):
                        adminconffound = True
                    if re.search('\<Policy default\>', line, re.IGNORECASE):
                        defpolicyfound = True
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "\n\ncupsd.conf file does not exist. Nothing to check...\n\n"
                )
                return retval

            if not rootfound:
                retval = False
                self.detailedresults += "\nCUPS Root location policy not defined"
            if not adminfound:
                retval = False
                self.detailedresults += "\nCUPS admin location policy not defined"
            if not adminconffound:
                retval = False
                self.detailedresults += "\nCUPS admin/conf location policy not defined"
            if not defpolicyfound:
                retval = False
                self.detailedresults += "\nCUPS Default Policy block not defined"

            if retval:
                self.logger.log(LogPriority.DEBUG,
                                "\n\nALL POLICY BLOCKS OK\n\n")

        except Exception:
            raise
        return retval

    def reportSecure(self):
        '''run report actions common to all platforms


        :returns: retval

        :rtype: bool
@author: Breen Malmberg
@change: Breen Malmberg - 2/8/2017 - KVcupsdrem will now only be run if
        self.DisableGenericPort CI is True

        '''

        self.logger.log(LogPriority.DEBUG, "\n\nREPORTSECURE()\n\n")

        retval = True

        try:

            if self.SecureCUPS.getcurrvalue():

                if os.path.exists(self.cupsdconf):
                    # Report on cupsd.conf change/add options
                    self.KVcupsd.setData(self.cupsdconfopts)
                    self.KVcupsd.setIntent("present")
                    self.KVcupsd.report()

                    # Report on cupsd.conf remove options
                    self.KVcupsd.setData(self.cupsdconfremopts)
                    self.KVcupsd.setIntent("notpresent")
                    self.KVcupsd.report()

                    if self.KVcupsd.fixables:
                        retval = False
                        self.detailedresults += "\nThe following configuration options, in " + str(
                            self.cupsdconf) + ", are incorrect:\n" + "\n".join(
                                self.KVcupsd.fixables)

                    if not self.checkPolicyBlocks():
                        retval = False
                else:
                    pass

                if os.path.exists(self.cupsfilesconf):
                    self.KVcupsfiles.report()
                    if self.KVcupsfiles.fixables:
                        retval = False
                        self.detailedresults += "\nThe following configuration options, in " + str(
                            self.cupsfilesconf
                        ) + ", are incorrect:\n" + "\n".join(
                            self.KVcupsfiles.fixables)
                else:
                    pass

            else:
                self.detailedresults += "\nNeither SecureCUPS nor DisableCUPS CI's was enabled. Nothing was done."

        except Exception:
            raise
        return retval

    def fix(self):
        '''run fix methods/actions appropriate for the current
        OS and return success status of fix


        :returns: success

        :rtype: bool
@author: Breen Malmberg

        '''

        # DEFAULTS
        self.detailedresults = ""
        success = True
        self.iditerator = 0
        badopts = [
            "^HostNameLookups\s+Double", "^Sandboxing\s+strict",
            "^FatalErrors\s+config"
        ]
        badoptsfiles = [self.cupsdconf, self.cupsfilesconf]
        foundbadopts = False

        try:

            # fix bad opts; do not record state change,
            ## so that a possible revert, afterward, will
            ## not revert back to the bad state
            ## this code is a one-off for a hotfix and
            ## should probably be discontinued in some future
            ## release at some point
            for f in badoptsfiles:
                contentlines = []
                if os.path.exists(f):
                    fh = open(f, 'r')
                    contentlines = fh.readlines()
                    fh.close()
                    for line in contentlines:
                        for opt in badopts:
                            if re.search(opt, line, re.IGNORECASE):
                                foundbadopts = True
                                contentlines = [
                                    c.replace(line, '\n') for c in contentlines
                                ]
                    # finished building new contentlines; now write them for each file
                    fn = open(f, 'w')
                    fn.writelines(contentlines)
                    fn.close()
                    os.chmod(f, 0o644)
            if foundbadopts:
                # do not continue with rest of fix because that would save state for this fix run
                self.logger.log(
                    LogPriority.DEBUG,
                    "Reloading cups service to read configuration changes...")
                if self.darwin:
                    self.sh.reloadService(self.svclongname,
                                          serviceTarget=self.svcname)
                else:
                    self.sh.reloadService(self.svcname,
                                          serviceTarget=self.serviceTarget)
                self.logger.log(
                    LogPriority.DEBUG,
                    "Removed bad configuration options from cups config files. Exiting..."
                )
                self.formatDetailedResults('fix', success,
                                           self.detailedresults)
                return success

            # Are any of the CIs enabled?
            # If not, then exit, returning True
            if not self.SecureCUPS.getcurrvalue() and \
            not self.DisableCUPS.getcurrvalue():
                self.detailedresults += "\nNo CI was enabled, so nothing was done."
                self.logger.log(
                    LogPriority.DEBUG,
                    "SecureCUPS rule was run, but neither SecureCUPS, nor DisableCUPS CI's were enabled so nothing was done!"
                )
                self.formatDetailedResults('fix', success,
                                           self.detailedresults)
                return success

            if self.linux and not self.ph.check("cups"):
                self.detailedresults += "\nCUPS is not installed. Nothing to do."
                self.formatDetailedResults('fix', success,
                                           self.detailedresults)
                return success

            if self.SecureCUPS.getcurrvalue():
                if not self.fixSecure():
                    success = False

            if self.DisableCUPS.getcurrvalue():
                if not self.disableCUPS():
                    success = False

        except (KeyboardInterrupt, SystemExit):
            raise
        except Exception:
            self.rulesuccess = False
            self.detailedresults += traceback.format_exc()
            self.logger.log(LogPriority.ERROR, self.detailedresults)
        self.formatDetailedResults('fix', success, self.detailedresults)
        return success

    def fixSecure(self):
        '''run fix actions common to all platforms


        :returns: retval

        :rtype: bool
@author: Breen Malmberg
@change: Breen Malmberg - 2/8/2017 - added inline comments; changed the way KVCupsdrem
        was being handled (will not be run if there are no options to remove; aka if
        self.DisableGenericPort CI is False)

        '''

        retval = True
        pdefaultfound = False
        serveraccessfound = False
        adminaccessfound = False
        configaccessfound = False
        logfileaccessfound = False

        try:

            if os.path.exists(self.cupsdconf):
                # Fix cupsd.conf add/change/remove options
                self.iditerator += 1
                myid = iterate(self.iditerator, self.rulenumber)
                self.KVcupsd.setEventID(myid)
                if self.KVcupsd.fix():
                    if not self.KVcupsd.commit():
                        self.detailedresults += "\nCommit failed for cupsd.conf"
                        self.logger.log(LogPriority.DEBUG,
                                        "Commit failed for KVcupsd")
                        retval = False

            # cups-files conf add/change options
            if os.path.exists(self.cupsfilesconf):
                self.iditerator += 1
                myid = iterate(self.iditerator, self.rulenumber)
                self.KVcupsfiles.setEventID(myid)
                if self.KVcupsfiles.fix():
                    if not self.KVcupsfiles.commit():
                        self.detailedresults += "\nCommit failed for cups-files.conf"
                        self.logger.log(LogPriority.DEBUG,
                                        "Commit failed for KVcupsfiles")
                        retval = False

# cupsdconf default policy blocks
# this portion cannot be handled by kveditor because of its
# xml style formatting
            if os.path.exists(self.cupsdconf):
                if self.SetupDefaultPolicyBlocks.getcurrvalue():
                    f = open(self.cupsdconf, 'r')
                    contentlines = f.readlines()
                    f.close()
                    for line in contentlines:
                        if re.search("\<Location \/\>", line, re.IGNORECASE):
                            serveraccessfound = True
                    for line in contentlines:
                        if re.search("\<Location \/admin\>", line,
                                     re.IGNORECASE):
                            adminaccessfound = True
                    for line in contentlines:
                        if re.search("\<Location \/admin\/conf\>", line,
                                     re.IGNORECASE):
                            configaccessfound = True
                    for line in contentlines:
                        if re.search("\<Location \/admin\/log\>", line,
                                     re.IGNORECASE):
                            logfileaccessfound = True
                    for line in contentlines:
                        if re.search("\<Policy default\>", line,
                                     re.IGNORECASE):
                            pdefaultfound = True

                    if not serveraccessfound:
                        contentlines.append("\n" + self.serveraccess + "\n")
                        self.logger.log(
                            LogPriority.DEBUG,
                            "\n\nroot access policy block not found. adding it...\n\n"
                        )

                    if not adminaccessfound:
                        contentlines.append("\n" + self.adminpagesaccess +
                                            "\n")
                        self.logger.log(
                            LogPriority.DEBUG,
                            "\n\nadmin access policy block not found. adding it...\n\n"
                        )

                    if not configaccessfound:
                        contentlines.append("\n" + self.configfilesaccess +
                                            "\n")
                        self.logger.log(
                            LogPriority.DEBUG,
                            "\n\nconfig access policy block not found. adding it...\n\n"
                        )

                    if not logfileaccessfound:
                        contentlines.append("\n" + self.logfileaccess + "\n")
                        self.logger.log(
                            LogPriority.DEBUG,
                            "\n\nlog file access policy block not found. adding it...\n\n"
                        )

                    if not pdefaultfound:
                        contentlines.append("\n" +
                                            self.defaultprinterpolicies + "\n")
                        self.logger.log(
                            LogPriority.DEBUG,
                            "\n\ndefault policy block not found. adding it...\n\n"
                        )

                    tf = open(self.tmpcupsdconf, 'w')
                    tf.writelines(contentlines)
                    tf.close()

                    self.iditerator += 1
                    myid = iterate(self.iditerator, self.rulenumber)
                    event = {"eventtype": "conf", "filename": self.cupsdconf}

                    self.statechglogger.recordfilechange(
                        self.cupsdconf, self.tmpcupsdconf, myid)
                    self.statechglogger.recordchgevent(myid, event)
                    self.logger.log(
                        LogPriority.DEBUG, "\n\nwriting changes to " +
                        str(self.cupsdconf) + " file...\n\n")
                    os.rename(self.tmpcupsdconf, self.cupsdconf)
                    self.logger.log(
                        LogPriority.DEBUG,
                        "\n\nsetting permissions and ownership for " +
                        str(self.cupsdconf) + " file...\n\n")
                    os.chown(self.cupsdconf, 0, 0)
                    if self.linux:
                        os.chmod(self.cupsdconf, 0o640)
                    elif self.darwin:
                        os.chmod(self.cupsdconf, 0o644)

            if not self.reloadCUPS():
                retval = False

        except Exception:
            raise
        return retval

    def reloadCUPS(self):
        '''reload the cups service to read the new configurations


        :returns: retval

        :rtype: bool
@author: Breen Malmberg

        '''

        retval = True

        try:

            # do not attempt to reload the service
            # if the rule is set to disable it
            if self.DisableCUPS.getcurrvalue():
                return retval

            if self.linux:
                if not self.sh.reloadService(self.svcname,
                                             serviceTarget=self.serviceTarget):
                    retval = False
                    self.detailedresults += "|nThere was a problem reloading the " + str(
                        self.svcname) + " service"
            elif self.darwin:
                if not self.sh.reloadService(self.svclongname,
                                             serviceTarget=self.svcname):
                    retval = False
                    self.detailedresults += "|nThere was a problem reloading the " + str(
                        self.svcname) + " service"

        except Exception:
            raise
        return retval

    def disableCUPS(self):
        '''disable the cups service


        :returns: retval

        :rtype: bool
@author: Breen Malmberg

        '''

        retval = True

        try:

            if self.linux:

                if not self.sh.disableService(
                        self.svcname, serviceTarget=self.serviceTarget):
                    retval = False
                    self.detailedresults += "\nThere was a problem disabling the " + str(
                        self.svcname) + " service"

            elif self.darwin:

                if not self.sh.disableService(self.svclongname,
                                              serviceTarget=self.svcname):
                    retval = False
                    self.detailedresults += "\nThere was a problem disabling the " + str(
                        self.svcname) + " service"

        except Exception:
            raise
        return retval