Exemple #1
0
    def action_dm(self, fingerprint, section, session):
        cnf = Config()

        if 'Command::DM::AdminKeyrings' not in cnf \
                or 'Command::DM::ACL' not in cnf \
                or 'Command::DM::Keyrings' not in cnf:
            raise CommandError('DM command is not configured for this archive.')

        allowed_keyrings = cnf.value_list('Command::DM::AdminKeyrings')
        if fingerprint.keyring.keyring_name not in allowed_keyrings:
            raise CommandError('Key {0} is not allowed to set DM'.format(fingerprint.fingerprint))

        acl_name = cnf.get('Command::DM::ACL', 'dm')
        acl = session.query(ACL).filter_by(name=acl_name).one()

        fpr_hash = section['Fingerprint'].translate(None, ' ')
        fpr = session.query(Fingerprint).filter_by(fingerprint=fpr_hash).first()
        if fpr is None:
            raise CommandError('Unknown fingerprint {0}'.format(fpr_hash))
        if fpr.keyring is None or fpr.keyring.keyring_name not in cnf.value_list('Command::DM::Keyrings'):
            raise CommandError('Key {0} is not in DM keyring.'.format(fpr.fingerprint))
        addresses = gpg_get_key_addresses(fpr.fingerprint)
        if len(addresses) > 0:
            self.cc.append(addresses[0])

        self.log.log(['dm', 'fingerprint', fpr.fingerprint])
        self.result.append('Fingerprint: {0}'.format(fpr.fingerprint))
        if len(addresses) > 0:
            self.log.log(['dm', 'uid', addresses[0]])
            self.result.append('Uid: {0}'.format(addresses[0]))

        for source in self._split_packages(section.get('Allow', '')):
            # Check for existance of source package to catch typos
            if session.query(DBSource).filter_by(source=source).first() is None:
                raise CommandError('Tried to grant permissions for unknown source package: {0}'.format(source))

            if session.query(ACLPerSource).filter_by(acl=acl, fingerprint=fpr, source=source).first() is None:
                aps = ACLPerSource()
                aps.acl = acl
                aps.fingerprint = fpr
                aps.source = source
                aps.created_by = fingerprint
                aps.reason = section.get('Reason')
                session.add(aps)
                self.log.log(['dm', 'allow', fpr.fingerprint, source])
                self.result.append('Allowed: {0}'.format(source))
            else:
                self.result.append('Already-Allowed: {0}'.format(source))

        session.flush()

        for source in self._split_packages(section.get('Deny', '')):
            count = session.query(ACLPerSource).filter_by(acl=acl, fingerprint=fpr, source=source).delete()
            if count == 0:
                raise CommandError('Tried to remove upload permissions for package {0}, '
                                   'but no upload permissions were granted before.'.format(source))

            self.log.log(['dm', 'deny', fpr.fingerprint, source])
            self.result.append('Denied: {0}'.format(source))

        session.commit()
Exemple #2
0
    def evaluate(self):
        """evaluate commands file

        @rtype:   bool
        @returns: C{True} if the file was processed sucessfully,
                  C{False} otherwise
        """
        result = True

        session = DBConn().session()

        keyrings = session.query(Keyring).filter_by(active=True).order_by(Keyring.priority)
        keyring_files = [ k.keyring_name for k in keyrings ]

        signed_file = SignedFile(self.data, keyring_files)
        if not signed_file.valid:
            self.log.log(['invalid signature', self.filename])
            return False

        self.fingerprint = session.query(Fingerprint).filter_by(fingerprint=signed_file.primary_fingerprint).one()
        if self.fingerprint.keyring is None:
            self.log.log(['singed by key in unknown keyring', self.filename])
            return False
        assert self.fingerprint.keyring.active

        self.log.log(['processing', self.filename, 'signed-by={0}'.format(self.fingerprint.fingerprint)])

        with tempfile.TemporaryFile() as fh:
            fh.write(signed_file.contents)
            fh.seek(0)
            sections = apt_pkg.TagFile(fh)

        self.uploader = None
        addresses = gpg_get_key_addresses(self.fingerprint.fingerprint)
        if len(addresses) > 0:
            self.uploader = addresses[0]

        try:
            sections.next()
            section = sections.section
            if 'Uploader' in section:
                self.uploader = section['Uploader']
            # TODO: Verify first section has valid Archive field
            if 'Archive' not in section:
                raise CommandError('No Archive field in first section.')

            # TODO: send mail when we detected a replay.
            # sync actions can happen multiple times, so we won't keep a history
            if not self._has_only_sync_actions(sections):
                self._check_replay(signed_file, session)

            self._evaluate_sections(sections, session)
            self.result.append('')
        except Exception as e:
            self.log.log(['ERROR', e])
            self.result.append("There was an error processing this section. No changes were committed.\nDetails:\n{0}".format(e))
            result = False

        self._notify_uploader()

        session.close()

        return result
Exemple #3
0
    def evaluate(self):
        """evaluate commands file

        @rtype:   bool
        @returns: C{True} if the file was processed sucessfully,
                  C{False} otherwise
        """
        result = True

        session = DBConn().session()

        keyrings = session.query(Keyring).filter_by(active=True).order_by(
            Keyring.priority)
        keyring_files = [k.keyring_name for k in keyrings]

        signed_file = SignedFile(self.data, keyring_files)
        if not signed_file.valid:
            self.log.log(['invalid signature', self.filename])
            return False

        self.fingerprint = session.query(Fingerprint).filter_by(
            fingerprint=signed_file.primary_fingerprint).one()
        if self.fingerprint.keyring is None:
            self.log.log(['singed by key in unknown keyring', self.filename])
            return False
        assert self.fingerprint.keyring.active

        self.log.log([
            'processing', self.filename,
            'signed-by={0}'.format(self.fingerprint.fingerprint)
        ])

        with tempfile.TemporaryFile() as fh:
            fh.write(signed_file.contents)
            fh.seek(0)
            sections = apt_pkg.TagFile(fh)

        self.uploader = None
        addresses = gpg_get_key_addresses(self.fingerprint.fingerprint)
        if len(addresses) > 0:
            self.uploader = addresses[0]

        try:
            sections.next()
            section = sections.section
            if 'Uploader' in section:
                self.uploader = section['Uploader']
            if 'Cc' in section:
                self.cc.append(section['Cc'])
            # TODO: Verify first section has valid Archive field
            if 'Archive' not in section:
                raise CommandError('No Archive field in first section.')

            # TODO: send mail when we detected a replay.
            # sync actions can happen multiple times, so we won't keep a history
            if not self._has_only_sync_actions(sections):
                self._check_replay(signed_file, session)

            self._evaluate_sections(sections, session)
            self.result.append('')
        except Exception as e:
            self.log.log(['ERROR', e])
            self.result.append(
                "There was an error processing this section. No changes were committed.\nDetails:\n{0}"
                .format(e))
            result = False

        self._notify_uploader()

        session.close()

        return result
Exemple #4
0
    def action_dm(self, fingerprint, section, session):
        cnf = Config()

        if 'Command::DM::AdminKeyrings' not in cnf \
                or 'Command::DM::ACL' not in cnf \
                or 'Command::DM::Keyrings' not in cnf:
            raise CommandError(
                'DM command is not configured for this archive.')

        allowed_keyrings = cnf.value_list('Command::DM::AdminKeyrings')
        if fingerprint.keyring.keyring_name not in allowed_keyrings:
            raise CommandError('Key {0} is not allowed to set DM'.format(
                fingerprint.fingerprint))

        acl_name = cnf.get('Command::DM::ACL', 'dm')
        acl = session.query(ACL).filter_by(name=acl_name).one()

        fpr_hash = section['Fingerprint'].translate(None, ' ')
        fpr = session.query(Fingerprint).filter_by(
            fingerprint=fpr_hash).first()
        if fpr is None:
            raise CommandError('Unknown fingerprint {0}'.format(fpr_hash))
        if fpr.keyring is None or fpr.keyring.keyring_name not in cnf.value_list(
                'Command::DM::Keyrings'):
            raise CommandError('Key {0} is not in DM keyring.'.format(
                fpr.fingerprint))
        addresses = gpg_get_key_addresses(fpr.fingerprint)
        if len(addresses) > 0:
            self.cc.append(addresses[0])

        self.log.log(['dm', 'fingerprint', fpr.fingerprint])
        self.result.append('Fingerprint: {0}'.format(fpr.fingerprint))
        if len(addresses) > 0:
            self.log.log(['dm', 'uid', addresses[0]])
            self.result.append('Uid: {0}'.format(addresses[0]))

        for source in self._split_packages(section.get('Allow', '')):
            # Check for existance of source package to catch typos
            if session.query(DBSource).filter_by(
                    source=source).first() is None:
                raise CommandError(
                    'Tried to grant permissions for unknown source package: {0}'
                    .format(source))

            if session.query(ACLPerSource).filter_by(
                    acl=acl, fingerprint=fpr, source=source).first() is None:
                aps = ACLPerSource()
                aps.acl = acl
                aps.fingerprint = fpr
                aps.source = source
                aps.created_by = fingerprint
                aps.reason = section.get('Reason')
                session.add(aps)
                self.log.log(['dm', 'allow', fpr.fingerprint, source])
                self.result.append('Allowed: {0}'.format(source))
            else:
                self.result.append('Already-Allowed: {0}'.format(source))

        session.flush()

        for source in self._split_packages(section.get('Deny', '')):
            count = session.query(ACLPerSource).filter_by(
                acl=acl, fingerprint=fpr, source=source).delete()
            if count == 0:
                raise CommandError(
                    'Tried to remove upload permissions for package {0}, '
                    'but no upload permissions were granted before.'.format(
                        source))

            self.log.log(['dm', 'deny', fpr.fingerprint, source])
            self.result.append('Denied: {0}'.format(source))

        session.commit()
Exemple #5
0
    def action_dm(self, fingerprint, section, session):
        cnf = Config()

        if (
            "Command::DM::AdminKeyrings" not in cnf
            or "Command::DM::ACL" not in cnf
            or "Command::DM::Keyrings" not in cnf
        ):
            raise CommandError("DM command is not configured for this archive.")

        allowed_keyrings = cnf.value_list("Command::DM::AdminKeyrings")
        if fingerprint.keyring.keyring_name not in allowed_keyrings:
            raise CommandError("Key {0} is not allowed to set DM".format(fingerprint.fingerprint))

        acl_name = cnf.get("Command::DM::ACL", "dm")
        acl = session.query(ACL).filter_by(name=acl_name).one()

        fpr_hash = section["Fingerprint"].translate(None, " ")
        fpr = session.query(Fingerprint).filter_by(fingerprint=fpr_hash).first()
        if fpr is None:
            raise CommandError("Unknown fingerprint {0}".format(fpr_hash))
        if fpr.keyring is None or fpr.keyring.keyring_name not in cnf.value_list("Command::DM::Keyrings"):
            raise CommandError("Key {0} is not in DM keyring.".format(fpr.fingerprint))
        addresses = gpg_get_key_addresses(fpr.fingerprint)
        if len(addresses) > 0:
            self.cc.append(addresses[0])

        self.log.log(["dm", "fingerprint", fpr.fingerprint])
        self.result.append("Fingerprint: {0}".format(fpr.fingerprint))
        if len(addresses) > 0:
            self.log.log(["dm", "uid", addresses[0]])
            self.result.append("Uid: {0}".format(addresses[0]))

        for source in self._split_packages(section.get("Allow", "")):
            # Check for existance of source package to catch typos
            if session.query(DBSource).filter_by(source=source).first() is None:
                raise CommandError("Tried to grant permissions for unknown source package: {0}".format(source))

            if session.query(ACLPerSource).filter_by(acl=acl, fingerprint=fpr, source=source).first() is None:
                aps = ACLPerSource()
                aps.acl = acl
                aps.fingerprint = fpr
                aps.source = source
                aps.created_by = fingerprint
                aps.reason = section.get("Reason")
                session.add(aps)
                self.log.log(["dm", "allow", fpr.fingerprint, source])
                self.result.append("Allowed: {0}".format(source))
            else:
                self.result.append("Already-Allowed: {0}".format(source))

        session.flush()

        for source in self._split_packages(section.get("Deny", "")):
            count = session.query(ACLPerSource).filter_by(acl=acl, fingerprint=fpr, source=source).delete()
            if count == 0:
                raise CommandError(
                    "Tried to remove upload permissions for package {0}, "
                    "but no upload permissions were granted before.".format(source)
                )

            self.log.log(["dm", "deny", fpr.fingerprint, source])
            self.result.append("Denied: {0}".format(source))

        session.commit()