Example #1
0
    def get_image_policies(self, image):
        # load default and image override policies, merge (if new
        # checks are in default), and save (if there is a diff after
        # the merge)

        try:
            policy = anchore_policy.read_policy(name='default',
                                                file=self.default_gatepol)
            policy_data = policy['default']
        except Exception as err:
            policy_data = []
        default_policies = anchore_policy.structure_policy(policy_data)

        policy_data = self.anchoreDB.load_gate_policy(image.meta['imageId'])
        image_policies = anchore_policy.structure_policy(policy_data)

        if image_policies and default_policies:
            policies = self.merge_policies(image_policies, default_policies)
            if policies != image_policies:
                self.save_policy(image.meta['imageId'], policies)
        else:
            policies = default_policies
            self.save_policy(image.meta['imageId'], policies)

        return (policies)
Example #2
0
    def edit_policy_file(self, editpolicy=False, whitelist=False):
        ret = True

        if not editpolicy and not whitelist:
            # nothing to do
            return(ret)

        for imageId in self.images:
            if editpolicy:
                data = self.anchoreDB.load_gate_policy(imageId)
            else:
                data = self.anchoreDB.load_gate_whitelist(imageId)

            if not data:
                self._logger.info("Cannot find existing data to edit, skipping: " + str(imageId))
            else:
                tmpdir = anchore_utils.make_anchoretmpdir("/tmp")
                try:
                    thefile = os.path.join(tmpdir, "anchorepol."+imageId)
                    anchore_utils.write_plainfile_fromlist(thefile, data)
                    if "EDITOR" in os.environ:
                        cmd = os.environ["EDITOR"].split()
                        cmd.append(thefile)
                        try:
                            subprocess.check_output(cmd, shell=False)
                        except:
                            ret = False
                    elif os.path.exists("/bin/vi"):
                        try:
                            rc = os.system("/bin/vi " + thefile)
                            if rc:
                                ret = False
                        except:
                            ret = False
                    else:
                        self._logger.info("Cannot find editor to use: please set the EDITOR environment variable and try again")
                        break

                    #newdata = anchore_utils.read_plainfile_tolist(thefile)
                    try:
                        policy = anchore_policy.read_policy(name='default', file=thefile)
                        newdata = policy['default']
                    except Exception as err:
                        newdata = []

                    if editpolicy:
                        self.anchoreDB.save_gate_policy(imageId, newdata)
                    else:
                        self.anchoreDB.save_gate_whitelist(imageId, newdata)
                except Exception as err:
                    pass
                finally:
                    if tmpdir:
                        shutil.rmtree(tmpdir)

        return(ret)
Example #3
0
    def load_policies(self, image):
        policies = {}
        if self.policy_override:
            try:
                policy = anchore_policy.read_policy(name='default', file=self.policy_override)
                policy_data = policy['default']
                
            except Exception as err:
                policy_data = []

            policies = anchore_policy.structure_policy(policy_data)
        else:
            policies = self.get_image_policies(image)

        return(policies)
Example #4
0
    def load_policies(self, image):
        policies = {}
        if self.policy_override:
            try:
                policy = anchore_policy.read_policy(name='default',
                                                    file=self.policy_override)
                policy_data = policy['default']

            except Exception as err:
                policy_data = []

            policies = anchore_policy.structure_policy(policy_data)
        else:
            policies = self.get_image_policies(image)

        return (policies)
Example #5
0
    def updatepolicy(self, newpolicyfile):
        #policy_data = anchore_utils.read_plainfile_tolist(newpolicyfile)
        try:
            policy = anchore_policy.read_policy(name='default', file=newpolicyfile)
            policy_data = policy['default']
        except Exception as err:
            policy_data = []

        newpol = anchore_policy.structure_policy(policy_data)
        for imageId in self.images:
            if imageId in self.allimages:
                try:
                    self.save_policy(imageId, newpol)
                except Exception as err:
                    self._logger.error("failed to update policy for image ("+imageId+"). bailing out: " + str(err))
                    return(False)
        return(True)
Example #6
0
    def updatepolicy(self, newpolicyfile):
        #policy_data = anchore_utils.read_plainfile_tolist(newpolicyfile)
        try:
            policy = anchore_policy.read_policy(name='default',
                                                file=newpolicyfile)
            policy_data = policy['default']
        except Exception as err:
            policy_data = []

        newpol = anchore_policy.structure_policy(policy_data)
        for imageId in self.images:
            if imageId in self.allimages:
                try:
                    self.save_policy(imageId, newpol)
                except Exception as err:
                    self._logger.error("failed to update policy for image (" +
                                       imageId + "). bailing out: " + str(err))
                    return (False)
        return (True)
Example #7
0
    def get_image_policies(self, image):
        # load default and image override policies, merge (if new
        # checks are in default), and save (if there is a diff after
        # the merge)

        try:
            policy = anchore_policy.read_policy(name='default', file=self.default_gatepol)
            policy_data = policy['default']
        except Exception as err:
            policy_data = []
        default_policies = anchore_policy.structure_policy(policy_data)

        policy_data = self.anchoreDB.load_gate_policy(image.meta['imageId'])
        image_policies = anchore_policy.structure_policy(policy_data)

        if image_policies and default_policies:
            policies = self.merge_policies(image_policies, default_policies)
            if policies != image_policies:
                self.save_policy(image.meta['imageId'], policies)
        else:
            policies = default_policies
            self.save_policy(image.meta['imageId'], policies)

        return(policies)
Example #8
0
    def edit_policy_file(self, editpolicy=False, whitelist=False):
        ret = True

        if not editpolicy and not whitelist:
            # nothing to do
            return (ret)

        for imageId in self.images:
            if editpolicy:
                data = self.anchoreDB.load_gate_policy(imageId)
            else:
                data = self.anchoreDB.load_gate_whitelist(imageId)

            if not data:
                self._logger.info(
                    "Cannot find existing data to edit, skipping: " +
                    str(imageId))
            else:
                tmpdir = anchore_utils.make_anchoretmpdir("/tmp")
                try:
                    thefile = os.path.join(tmpdir, "anchorepol." + imageId)
                    anchore_utils.write_plainfile_fromlist(thefile, data)
                    if "EDITOR" in os.environ:
                        cmd = os.environ["EDITOR"].split()
                        cmd.append(thefile)
                        try:
                            subprocess.check_output(cmd, shell=False)
                        except:
                            ret = False
                    elif os.path.exists("/bin/vi"):
                        try:
                            rc = os.system("/bin/vi " + thefile)
                            if rc:
                                ret = False
                        except:
                            ret = False
                    else:
                        self._logger.info(
                            "Cannot find editor to use: please set the EDITOR environment variable and try again"
                        )
                        break

                    #newdata = anchore_utils.read_plainfile_tolist(thefile)
                    try:
                        policy = anchore_policy.read_policy(name='default',
                                                            file=thefile)
                        newdata = policy['default']
                    except Exception as err:
                        newdata = []

                    if editpolicy:
                        self.anchoreDB.save_gate_policy(imageId, newdata)
                    else:
                        self.anchoreDB.save_gate_whitelist(imageId, newdata)
                except Exception as err:
                    pass
                finally:
                    if tmpdir:
                        shutil.rmtree(tmpdir)

        return (ret)
Example #9
0
    def execute_gates(self, image, refresh=True):
        self._logger.debug("gate policy evaluation for image " +
                           str(image.meta['imagename']) + ": begin")
        success = True

        imagename = image.meta['imageId']
        gatesdir = '/'.join([self.config["scripts_dir"], "gates"])
        workingdir = '/'.join([self.config['anchore_data_dir'], 'querytmp'])
        outputdir = workingdir

        self._logger.info(image.meta['shortId'] + ": evaluating policies ...")

        for d in [outputdir, workingdir]:
            if not os.path.exists(d):
                os.makedirs(d)

        imgfile = '/'.join(
            [workingdir, "queryimages." + str(random.randint(0, 99999999))])
        anchore_utils.write_plainfile_fromstr(imgfile, image.meta['imageId'])

        if self.policy_override:
            #policy_data = anchore_utils.read_plainfile_tolist(self.policy_override)
            try:
                policy = anchore_policy.read_policy(name='default',
                                                    file=self.policy_override)
                policy_data = policy['default']
            except Exception as err:
                policy_data = []
            policies = anchore_policy.structure_policy(policy_data)
        else:
            policies = self.get_image_policies(image)

        try:
            gmanifest, failedgates = anchore_utils.generate_gates_manifest()
            if failedgates:
                self._logger.error(
                    "some gates failed to run - check the gate(s) modules for errors: "
                    + str(','.join(failedgates)))
                success = False
            else:
                success = True
                for gatecheck in policies.keys():
                    # get all commands that match the gatecheck
                    gcommands = []
                    for gkey in gmanifest.keys():
                        if gmanifest[gkey]['gatename'] == gatecheck:
                            gcommands.append(gkey)

                    # assemble the params from the input policy for this gatecheck
                    params = []
                    for trigger in policies[gatecheck].keys():
                        if 'params' in policies[gatecheck][
                                trigger] and policies[gatecheck][trigger][
                                    'params']:
                            params.append(
                                policies[gatecheck][trigger]['params'])

                    if not params:
                        params = ['all']

                    if gcommands:
                        for command in gcommands:
                            cmd = [command] + [
                                imgfile, self.config['image_data_store'],
                                outputdir
                            ] + params
                            self._logger.debug("running gate command: " +
                                               str(' '.join(cmd)))

                            (rc, sout,
                             cmdstring) = anchore_utils.run_command(cmd)
                            if rc:
                                self._logger.error("FAILED")
                                self._logger.error("\tCMD: " + str(cmdstring))
                                self._logger.error("\tEXITCODE: " + str(rc))
                                self._logger.error("\tOUTPUT: " + str(sout))
                                success = False
                            else:
                                self._logger.debug("")
                                self._logger.debug("\tCMD: " + str(cmdstring))
                                self._logger.debug("\tEXITCODE: " + str(rc))
                                self._logger.debug("\tOUTPUT: " + str(sout))
                                self._logger.debug("")
                    else:
                        self._logger.warn(
                            "WARNING: gatecheck (" + str(gatecheck) +
                            ") line in policy, but no gates were found that match this gatecheck"
                        )
        except Exception as err:
            self._logger.error("gate evaluation failed - exception: " +
                               str(err))
        finally:
            if imgfile and os.path.exists(imgfile):
                try:
                    os.remove(imgfile)
                except:
                    self._logger.error("could not remove tempfile: " +
                                       str(imgfile))

        if success:
            report = self.generate_gates_report(image)
            self.anchoreDB.save_gates_report(image.meta['imageId'], report)
            self._logger.info(image.meta['shortId'] + ": evaluated.")

        self._logger.debug("gate policy evaluation for image " +
                           str(image.meta['imagename']) + ": end")
        return (success)
Example #10
0
    def evaluate_gates_results(self, image):
        ret = list()
        fullret = list()
        final_gate_action = 'GO'

        policies_whitelist = self.load_whitelist(image)
        global_whitelist = self.load_global_whitelist()

        if self.policy_override:
            #policy_data = anchore_utils.read_plainfile_tolist(self.policy_override)
            try:
                policy = anchore_policy.read_policy(name='default',
                                                    file=self.policy_override)
                policy_data = policy['default']
            except Exception as err:
                policy_data = []

            policies = anchore_policy.structure_policy(policy_data)
        else:
            policies = self.get_image_policies(image)

        for m in policies.keys():
            gdata = self.anchoreDB.load_gate_output(image.meta['imageId'], m)
            for l in gdata:
                (k, v) = re.match('(\S*)\s*(.*)', l).group(1, 2)
                imageId = image.meta['imageId']
                check = m
                trigger = k
                output = v
                triggerId = hashlib.md5(''.join([check, trigger,
                                                 output])).hexdigest()

                # if the output is structured (i.e. decoded as an
                # anchore compatible json string) then extract the
                # elements for display
                try:
                    json_output = json.loads(output)
                    if 'id' in json_output:
                        triggerId = str(json_output['id'])
                    if 'desc' in json_output:
                        output = str(json_output['desc'])
                except:
                    pass

                if k in policies[m]:
                    trigger = k
                    action = policies[check][trigger]['action']

                    r = {
                        'imageId': imageId,
                        'check': check,
                        'triggerId': triggerId,
                        'trigger': trigger,
                        'output': output,
                        'action': action
                    }
                    # this is where whitelist check should go
                    whitelisted = False
                    whitelist_type = "none"

                    if [m, triggerId] in global_whitelist:
                        whitelisted = True
                        whitelist_type = "global"
                    elif r in policies_whitelist['ignore']:
                        whitelisted = True
                        whitelist_type = "image"
                    else:
                        # look for prefix wildcards
                        try:
                            for [gmod, gtriggerId] in global_whitelist:
                                if gmod == m:
                                    # special case for backward compat
                                    try:
                                        if gmod == 'ANCHORESEC' and not re.match(
                                                ".*\*.*",
                                                gtriggerId) and re.match(
                                                    "^CVE.*|^RHSA.*",
                                                    gtriggerId):
                                            gtriggerId = gtriggerId + "*"
                                    except Exception as err:
                                        self._logger.warn(
                                            "problem with backward compat modification of whitelist trigger - exception: "
                                            + str(err))

                                    matchtoks = []
                                    for tok in gtriggerId.split("*"):
                                        matchtoks.append(re.escape(tok))
                                    rematch = "^" + '(.*)'.join(
                                        matchtoks) + "$"
                                    self._logger.debug(
                                        "checking regexp wl<->triggerId for match: "
                                        + str(rematch) + " : " +
                                        str(triggerId))
                                    if re.match(rematch, triggerId):
                                        self._logger.debug(
                                            "found wildcard whitelist match")
                                        whitelisted = True
                                        whitelist_type = "global"
                                        break

                        except Exception as err:
                            self._logger.warn(
                                "problem with prefix wildcard match routine - exception: "
                                + str(err))

                    fullr = {}
                    fullr.update(r)
                    fullr['whitelisted'] = whitelisted
                    fullr['whitelist_type'] = whitelist_type
                    fullret.append(fullr)

                    if not whitelisted:
                        if policies[m][k]['action'] == 'STOP':
                            final_gate_action = 'STOP'
                        elif final_gate_action != 'STOP' and policies[m][k][
                                'action'] == 'WARN':
                            final_gate_action = 'WARN'
                        ret.append(r)
                    else:
                        # whitelisted, skip evaluation
                        pass

        self.save_whitelist(image, policies_whitelist, ret)

        ret.append({
            'imageId': image.meta['imageId'],
            'check': 'FINAL',
            'trigger': 'FINAL',
            'output': "",
            'action': final_gate_action
        })
        fullret.append({
            'imageId': image.meta['imageId'],
            'check': 'FINAL',
            'trigger': 'FINAL',
            'output': "",
            'action': final_gate_action,
            'whitelisted': False,
            'whitelist_type': "none",
            'triggerId': "N/A"
        })
        for i in ret:
            self.anchoreDB.del_gate_eval_output(image.meta['imageId'],
                                                i['check'])

        evals = {}
        for i in ret:
            if i['check'] not in evals:
                evals[i['check']] = list()
            evals[i['check']].append(' '.join([i['trigger'], i['action']]))

        for i in evals.keys():
            self.anchoreDB.save_gate_eval_output(image.meta['imageId'], i,
                                                 evals[i])

        self.anchoreDB.save_gates_eval_report(image.meta['imageId'], ret)
        return (ret, fullret)