Example #1
0
        def _install(jobList):
            self.cfg.flavor = []
            openpgpkey.getKeyCache().setPublicPath(
                                     self.cfg.root + '/root/.gnupg/pubring.gpg')
            openpgpkey.getKeyCache().setPrivatePath(
                                self.cfg.root + '/root/.gnupg/secring.gpg')
            self.cfg.pubRing = [self.cfg.root + '/root/.gnupg/pubring.gpg']
            client = conaryclient.ConaryClient(self.cfg)
            client.setUpdateCallback(self.callback)
            if self.csCache:
                changeSetList = self.csCache.getChangeSets(client.getRepos(),
                                                           jobList,
                                                           callback=self.callback)
            else:
                changeSetList = []

            updJob = client.newUpdateJob()
            try:
                client.prepareUpdateJob(updJob,
                    jobList, keepExisting=False, resolveDeps=False,
                    recurse=False, checkPathConflicts=False,
                    fromChangesets=changeSetList,
                    migrate=True)
            except conaryclient.update.NoNewTrovesError:
                # since we're migrating, this simply means there were no
                # operations to be performed
                pass
            else:
                util.mkdirChain(self.cfg.root + '/root')
                client.applyUpdate(updJob, replaceFiles=True,
                                   tagScript=self.cfg.root + '/root/tagscripts')
Example #2
0
        def _install(jobList):
            self.cfg.flavor = []
            openpgpkey.getKeyCache().setPublicPath(self.cfg.root +
                                                   '/root/.gnupg/pubring.gpg')
            openpgpkey.getKeyCache().setPrivatePath(self.cfg.root +
                                                    '/root/.gnupg/secring.gpg')
            self.cfg.pubRing = [self.cfg.root + '/root/.gnupg/pubring.gpg']
            client = conaryclient.ConaryClient(self.cfg)
            client.setUpdateCallback(self.callback)
            if self.csCache:
                changeSetList = self.csCache.getChangeSets(
                    client.getRepos(), jobList, callback=self.callback)
            else:
                changeSetList = []

            updJob = client.newUpdateJob()
            try:
                client.prepareUpdateJob(updJob,
                                        jobList,
                                        keepExisting=False,
                                        resolveDeps=False,
                                        recurse=False,
                                        checkPathConflicts=False,
                                        fromChangesets=changeSetList,
                                        migrate=True)
            except conaryclient.update.NoNewTrovesError:
                # since we're migrating, this simply means there were no
                # operations to be performed
                pass
            else:
                util.mkdirChain(self.cfg.root + '/root')
                client.applyUpdate(updJob,
                                   replaceFiles=True,
                                   tagScript=self.cfg.root +
                                   '/root/tagscripts')
Example #3
0
    def testInstallSignedTrove(self):
        # CNY-2555
        fingerprint = '95B457D16843B21EA3FC73BBC7C32FC1F94E405E'
        self.addComponent('test:run',
                          '1',
                          fileContents=[('/usr/share/foo1', 'blah')])
        self.addCollection('test', '1', [':run'])

        self.cfg.signatureKey = fingerprint
        self.cfg.quiet = True
        signtrove.signTroves(self.cfg, ["test"])

        # Install, have a non-existant keyring
        self.cfg.pubRing = "/some/keyring"
        openpgpkey.getKeyCache().reset()
        openpgpkey.getKeyCache().setPublicPath(self.cfg.pubRing)

        # This should change to an error when RMK-791 (related to CNY-2555) is
        # fixed
        self.logFilter.add()
        self.updatePkg("test")
        self.logFilter.remove()

        self.logFilter.compare(
            "error: While caching PGP key: Permission denied: /some")
Example #4
0
    def testUnknownSig(self):
        # the repository shouldn't blow up on this commit unless it's bene
        # run w/ requireSigs = True
        self.stopRepository(0)
        sigRepos = self.openRepository(0, requireSigs=True)

        fingerprint = 'F7440D78FE813C882212C2BF8AC2828190B1E477'
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')
        os.chdir(self.workDir)
        self.newpkg('testcase')
        os.chdir('testcase')
        self.writeFile('testcase.recipe', testRecipe)
        self.addfile('testcase.recipe')

        repos = self.openRepository()

        self.cfg.signatureKey = fingerprint

        try:
            checkin.commit(repos, self.cfg, 'testcase', None)
            self.fail("Repository should have required a signature")
        except DigitalSignatureVerificationError:
            pass

        self.stopRepository(0)
        repos = self.openRepository(0)
        checkin.commit(repos, self.cfg, 'testcase', None)

        self.cfg.signatureKey = None
Example #5
0
    def testTroveDisplaySigs(self):
        # go through a lot of trouble to sign this trove.
        # copied from sigtest.
        self.addComponent('foo:runtime', '1.0')
        from conary.lib import openpgpfile, openpgpkey
        from conary.build import signtrove
        fingerprint = 'F7440D78FE813C882212C2BF8AC2828190B1E477'
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')
        keyRing = open(resources.get_archive() + '/pubring.gpg')
        keyData = openpgpfile.exportKey(fingerprint, keyRing)
        keyData.seek(0)
        keyData = keyData.read()

        # upload the public key
        repos = self.openRepository()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        self.cfg.signatureKey = fingerprint
        self.cfg.quiet = True
        signtrove.signTroves(self.cfg, [ "foo:runtime"])

        rs, txt = self.captureOutput(queryrep.displayTroves, self.cfg, 
                                     ['foo:runtime'],
                                     digSigs=True)
        assert(txt.startswith('''\
foo:runtime=1.0-1-1
  Digital Signature:
      F7440D78FE813C882212C2BF8AC2828190B1E477:'''))
Example #6
0
    def testUpdateMissingKey(self):
        fingerprint = '95B457D16843B21EA3FC73BBC7C32FC1F94E405E'
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')

        self.cfg.signatureKey = fingerprint
        self.addQuickTestComponent("test:doc", "1.0-1-1")

        signtrove.signTroves(self.cfg, ["test:doc"])

        repos = self.openRepository()

        # utterly prevent the keycache from knowing about the key,
        # but give it a place to store a keyserver retrieved key.
        newKeyCache = openpgpkey.OpenPGPKeyFileCache()
        tmpPath = mkdtemp()
        pubRing = self.cfg.pubRing
        self.cfg.pubRing = [tmpPath + '/pubring.gpg']
        newKeyCache.publicPaths = self.cfg.pubRing
        keyCacheCallback = openpgpkey.KeyCacheCallback(repos, self.cfg)
        newKeyCache.setCallback(keyCacheCallback)

        openpgpkey.setKeyCache(newKeyCache)

        try:
            self.updatePkg(self.rootDir, "test:doc")
            newKeyCache.getPublicKey(fingerprint)
        finally:
            self.cfg.pubRing = pubRing
            openpgpkey.setKeyCache(keyCache)
        util.rmtree(tmpPath)
Example #7
0
    def testChangeKeyOwner(self):
        fingerprint = 'F7440D78FE813C882212C2BF8AC2828190B1E477'
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')

        self.addQuickTestComponent("test:source", "1.0-1-1")

        self.cfg.signatureKey = fingerprint
        self.cfg.quiet = True

        repos = self.openRepository()
        anotherRepos = self.setupUser(repos, self.cfg.buildLabel, 'another',
                                      'anotherpass', None, None)

        # put the public key into the repo
        keyRing = open(
            resources.get_path('conary_test', 'archive', 'pubring.gpg'))
        keyData = openpgpfile.exportKey(fingerprint, keyRing)
        keyData.seek(0)
        keyData = keyData.read()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        repos.changePGPKeyOwner(self.cfg.buildLabel, 'another', fingerprint)

        assert (repos.listUsersMainKeys(self.cfg.buildLabel,
                                        'another')[0] == fingerprint)
Example #8
0
    def testTroveDisplaySigs(self):
        # go through a lot of trouble to sign this trove.
        # copied from sigtest.
        self.addComponent('foo:runtime', '1.0')
        from conary.lib import openpgpfile, openpgpkey
        from conary.build import signtrove
        fingerprint = 'F7440D78FE813C882212C2BF8AC2828190B1E477'
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')
        keyRing = open(resources.get_archive() + '/pubring.gpg')
        keyData = openpgpfile.exportKey(fingerprint, keyRing)
        keyData.seek(0)
        keyData = keyData.read()

        # upload the public key
        repos = self.openRepository()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        self.cfg.signatureKey = fingerprint
        self.cfg.quiet = True
        signtrove.signTroves(self.cfg, ["foo:runtime"])

        rs, txt = self.captureOutput(queryrep.displayTroves,
                                     self.cfg, ['foo:runtime'],
                                     digSigs=True)
        assert (txt.startswith('''\
foo:runtime=1.0-1-1
  Digital Signature:
      F7440D78FE813C882212C2BF8AC2828190B1E477:'''))
Example #9
0
    def testNonRecursiveGroupSigs(self):
        fingerprint = '95B457D16843B21EA3FC73BBC7C32FC1F94E405E'
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')
        # make all components before assigning a key, so all start out blank
        self.addQuickTestComponent("test:doc", "1.0-1-1")

        self.makeSourceTrove('testcase', testRecipe)

        repos = self.openRepository()
        built = self.cookItem(repos, self.cfg, 'testcase', ignoreDeps=True)
        group = self.build(testGroup, "GroupTest")
        group = self.build(outerGroup, "OuterGroup")

        signatureKey = self.cfg.signatureKey
        self.cfg.signatureKey = fingerprint
        self.cfg.quiet = True

        v = versions.VersionFromString('/localhost@rpl:linux/1.0-1-1')
        f = deps.parseFlavor('')

        try:
            # first sign the outer group trove
            #signtrove.signTroves(self.cfg, [ "group-outer" ])
            cvccmd.sourceCommand(self.cfg, ["sign", "group-outer"], {})

            try:
                t = repos.getTrove('group-outer', v, f)
                self._checkDigitalSig(t, fingerprint)
            except openpgpfile.KeyNotFound:
                self.fail('Group signing failed to cover %s' % t)

            # check the sig on each trove in the group, since group signing
            # should be recursive
            for trvName in ('group-test', 'test:doc', 'testcase',
                            'testcase:runtime'):
                try:
                    t = repos.getTrove(trvName, v, f)
                    t.getDigitalSignature(fingerprint)
                    self.fail('Group signing inadvenderntly signed %s' %
                              trvName)
                except openpgpfile.KeyNotFound:
                    pass
            # then check that the source trove wasn't signed... it wasn't
            # explicitly part of the group
            v = versions.VersionFromString('/localhost@rpl:linux/1.0-1')
            f = deps.parseFlavor('')
            t = repos.getTrove('testcase:source', v, f)
            try:
                signature = t.getDigitalSignature(fingerprint)
                self._checkDigitalSig(t, fingerprint)
                self.fail('signing group inadvendently signed source trove')
            except openpgpfile.KeyNotFound:
                pass

        finally:
            self.cfg.signatureKey = signatureKey
Example #10
0
    def runCommand(self, thisCommand, cfg, argSet, args, debugAll=False):
        client = conaryclient.ConaryClient(cfg)
        repos = client.getRepos()
        callback = commit.CheckinCallback(cfg)

        if not cfg.buildLabel and cfg.installLabelPath:
            cfg.buildLabel = cfg.installLabelPath[0]

        sys.excepthook = util.genExcepthook(debug=cfg.debugExceptions,
                                            debugCtrlC=debugAll)

        if cfg.installLabelPath:
            cfg.installLabel = cfg.installLabelPath[0]
        else:
            cfg.installLabel = None

        cfg.initializeFlavors()
        log.setMinVerbosity(log.INFO)
        log.resetErrorOccurred()

        # set the build flavor here, just to set architecture information
        # which is used when initializing a recipe class
        use.setBuildFlagsFromFlavor(None, cfg.buildFlavor, error=False)

        profile = False
        if argSet.has_key('lsprof'):
            import cProfile
            prof = cProfile.Profile()
            prof.enable()
            profile = 'lsprof'
            del argSet['lsprof']

        keyCache = openpgpkey.getKeyCache()
        keyCache.setPublicPath(cfg.pubRing)
        repos = conaryclient.ConaryClient(cfg).getRepos()
        keyCacheCallback = openpgpkey.KeyCacheCallback(repos, cfg)
        keyCache.setCallback(keyCacheCallback)

        try:
            rv = options.MainHandler.runCommand(self,
                                                thisCommand,
                                                cfg,
                                                argSet,
                                                args,
                                                callback=callback,
                                                repos=client.getRepos(),
                                                profile=profile)
        finally:
            if profile == 'lsprof':
                prof.disable()
                prof.dump_stats('cvc.lsprof')
                prof.print_stats()
            elif profile:
                prof.stop()

        if log.errorOccurred():
            sys.exit(2)
        return rv
Example #11
0
    def runCommand(self, thisCommand, cfg, argSet, args, debugAll=False):
        client = conaryclient.ConaryClient(cfg)
        repos = client.getRepos()
        callback = commit.CheckinCallback(cfg)

        if not cfg.buildLabel and cfg.installLabelPath:
            cfg.buildLabel = cfg.installLabelPath[0]

        sys.excepthook = util.genExcepthook(debug=cfg.debugExceptions,
                                            debugCtrlC=debugAll)

        if cfg.installLabelPath:
            cfg.installLabel = cfg.installLabelPath[0]
        else:
            cfg.installLabel = None

        cfg.initializeFlavors()
        log.setMinVerbosity(log.INFO)
        log.resetErrorOccurred()

        # set the build flavor here, just to set architecture information
        # which is used when initializing a recipe class
        use.setBuildFlagsFromFlavor(None, cfg.buildFlavor, error=False)

        profile = False
        if argSet.has_key('lsprof'):
            import cProfile
            prof = cProfile.Profile()
            prof.enable()
            profile = 'lsprof'
            del argSet['lsprof']

        keyCache = openpgpkey.getKeyCache()
        keyCache.setPublicPath(cfg.pubRing)
        repos = conaryclient.ConaryClient(cfg).getRepos()
        keyCacheCallback = openpgpkey.KeyCacheCallback(repos,
                                                       cfg)
        keyCache.setCallback(keyCacheCallback)

        try:
            rv = options.MainHandler.runCommand(self, thisCommand,
                                                cfg, argSet, args,
                                                callback=callback,
                                                repos=client.getRepos(),
                                                profile=profile)
        finally:
            if profile == 'lsprof':
                prof.disable()
                prof.dump_stats('cvc.lsprof')
                prof.print_stats()
            elif profile:
                prof.stop()

        if log.errorOccurred():
            sys.exit(2)
        return rv
Example #12
0
    def testMirror(self):
        sourceRepos, targetRepos = self.createRepositories()
        mirrorFile = self.createConfigurationFile()
        # this is really ugly, but needed to ensure test consistency
        db = self.servers.getServer(0).reposDB.connect()
        cu = db.cursor()

        # test simple trove mirroring
        self.createTroves(sourceRepos, 1, 2, "1.0")
        self.createTroves(sourceRepos, 1, 2, "2.0")
        self.sleep(1.2)
        self.createTroves(sourceRepos, 1, 2, "3.0")
        # the following is just to get the trigger to fire
        cu.execute("update Instances set changed=1")
        db.commit()
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)

        # simulate multiple trove versions with the same mark
        self.createTroves(sourceRepos, 10, 2, "1.0", "~foo")
        self.createTroves(sourceRepos, 10, 2, "1.0", "~!foo")
        self.createTroves(sourceRepos, 10, 2, "1.1")
        # the following is just to get the trigger to fire
        cu.execute("update Instances set changed=1")
        db.commit()
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)

        # test mirroring of ascii keys
        sourceRepos.addNewAsciiPGPKey(self.cfg.buildLabel, 'test',
                                      sigtest.unexpiredKey)
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)

        # test mirroring of new trove signatures
        self.createTroves(sourceRepos, 20, 2)
        self.cfg.signatureKey = '7CCD34B5C5D9CD1F637F6743D4F8F127C267B79D'
        signtrove.signTroves(self.cfg, ["test10:runtime", "test20:runtime"])
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)

        fprint = 'F7440D78FE813C882212C2BF8AC2828190B1E477'
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fprint, '111111')
        self.cfg.signatureKey = fprint

        keyRing = open(resources.get_archive() + '/pubring.gpg')
        keyData = openpgpfile.exportKey(fprint, keyRing)
        keyData.seek(0)
        keyData = keyData.read()
        sourceRepos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        signtrove.signTroves(self.cfg, ["test11:runtime", "test21:runtime"])
        self.createTroves(sourceRepos, 30, 2)
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)
Example #13
0
    def testMirror(self):
        sourceRepos, targetRepos = self.createRepositories()
        mirrorFile = self.createConfigurationFile()
        # this is really ugly, but needed to ensure test consistency
        db = self.servers.getServer(0).reposDB.connect()
        cu = db.cursor()

        # test simple trove mirroring
        self.createTroves(sourceRepos, 1, 2, "1.0")
        self.createTroves(sourceRepos, 1, 2, "2.0")
        self.sleep(1.2)
        self.createTroves(sourceRepos, 1, 2, "3.0")
        # the following is just to get the trigger to fire
        cu.execute("update Instances set changed=1")
        db.commit()
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)

        # simulate multiple trove versions with the same mark
        self.createTroves(sourceRepos, 10, 2, "1.0", "~foo")
        self.createTroves(sourceRepos, 10, 2, "1.0", "~!foo")
        self.createTroves(sourceRepos, 10, 2, "1.1")
        # the following is just to get the trigger to fire
        cu.execute("update Instances set changed=1")
        db.commit()
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)

        # test mirroring of ascii keys
        sourceRepos.addNewAsciiPGPKey(self.cfg.buildLabel, 'test', sigtest.unexpiredKey)
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)

        # test mirroring of new trove signatures
        self.createTroves(sourceRepos, 20, 2)
        self.cfg.signatureKey = '7CCD34B5C5D9CD1F637F6743D4F8F127C267B79D'
        signtrove.signTroves(self.cfg, [ "test10:runtime", "test20:runtime" ])
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)

        fprint='F7440D78FE813C882212C2BF8AC2828190B1E477'
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fprint, '111111')
        self.cfg.signatureKey = fprint

        keyRing = open(resources.get_archive() + '/pubring.gpg')
        keyData = openpgpfile.exportKey(fprint, keyRing)
        keyData.seek(0)
        keyData = keyData.read()
        sourceRepos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        signtrove.signTroves(self.cfg, [ "test11:runtime", "test21:runtime" ])
        self.createTroves(sourceRepos, 30, 2)
        self.runMirror(mirrorFile)
        self.compareRepositories(sourceRepos, targetRepos)
Example #14
0
    def testFileUpdateMissingKey(self):
        fingerprint = '95B457D16843B21EA3FC73BBC7C32FC1F94E405E'

        # make a changeset with useful stuff that could be installed
        cs = changeset.ChangeSet()
        flavor = deps.parseFlavor('')
        v = versions.VersionFromString('/%s/1.0-1-1' %
                                       self.cfg.buildLabel.asString()).copy()
        v.resetTimeStamps()
        t = trove.Trove('test:test', v, flavor, None)

        path = self.workDir + '/blah'
        f = open(path, 'w')
        f.write('hello, world!\n')
        f.close()
        pathId = sha1helper.md5String('/blah')
        f = files.FileFromFilesystem(path, pathId)

        fileId = f.fileId()
        t.addFile(pathId, '/blah', v, fileId)
        cs.addFile(None, fileId, f.freeze())
        cs.addFileContents(pathId, fileId, changeset.ChangedFileTypes.file,
                           filecontents.FromFilesystem(path),
                           f.flags.isConfig())
        diff = t.diff(None, absolute=1)[0]
        cs.newTrove(diff)
        cs.addPrimaryTrove('test:test', v, flavor)

        # sign the changeset
        csPath = os.path.join(self.workDir, 'test-1.0-1.ccs')
        cs = cook.signAbsoluteChangeset(cs, fingerprint)
        cs.writeToFile(csPath)

        tmpPath = mkdtemp()

        keyCache = openpgpkey.getKeyCache()
        newKeyCache = openpgpkey.OpenPGPKeyFileCache()

        pubRing = self.cfg.pubRing

        self.cfg.pubRing = [tmpPath + '/pubring.gpg']
        keyCacheCallback = openpgpkey.KeyCacheCallback(None, self.cfg)
        newKeyCache.setCallback(keyCacheCallback)

        openpgpkey.setKeyCache(newKeyCache)

        try:
            self.updatePkg(self.rootDir, csPath)
        finally:
            self.cfg.pubRing = pubRing
            openpgpkey.setKeyCache(keyCache)
Example #15
0
    def _setupSignature(self, repos, fingerprint):
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')

        # get the public key
        keyRing = open(resources.get_archive('pubring.gpg'))
        if hasattr(openpgpfile, 'readKeyData'):
            keyData = openpgpfile.readKeyData(keyRing, fingerprint)
        else:
            keyData = openpgpfile.exportKey(fingerprint, keyRing)
            keyData.seek(0)
            keyData = keyData.read()

        # upload the public key
        repos = self.openRepository()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        self.buildCfg.signatureKey = fingerprint
Example #16
0
    def _setupSignature(self, repos, fingerprint):
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')

        # get the public key
        keyRing = open(resources.get_archive('pubring.gpg'))
        if hasattr(openpgpfile, 'readKeyData'):
            keyData = openpgpfile.readKeyData(keyRing, fingerprint)
        else:
            keyData = openpgpfile.exportKey(fingerprint, keyRing)
            keyData.seek(0)
            keyData = keyData.read()

        # upload the public key
        repos = self.openRepository()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        self.buildCfg.signatureKey = fingerprint
Example #17
0
    def testSignedCheckout(self):
        fingerprint = 'F7440D78FE813C882212C2BF8AC2828190B1E477'
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')

        self.addQuickTestComponent("test:source", "1.0-1-1")

        self.cfg.signatureKey = fingerprint
        self.cfg.quiet = True

        # put the public key into the repo
        keyRing = open(
            resources.get_path('conary_test', 'archive', 'pubring.gpg'))
        keyData = openpgpfile.exportKey(fingerprint, keyRing)
        keyData.seek(0)
        keyData = keyData.read()
        repos = self.openRepository()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        signtrove.signTroves(self.cfg, ["test:source"])

        # alter key's trust value and determine that the doUpdate
        # code properly verifies trust thresholds
        pubKey = keyCache.getPublicKey(fingerprint)
        pubKey.trustLevel = openpgpfile.TRUST_UNTRUSTED
        keyCache.publicDict[fingerprint] = pubKey
        self.cfg.trustThreshold = openpgpfile.TRUST_ULTIMATE
        self.logFilter.add()
        try:
            checkout(repos, self.cfg, self.workDir, ["test"])
            self.fail("checkin.checkout did not properly verify trust levels")
        except DigitalSignatureVerificationError:
            self.logFilter.compare([
                'warning: The trove test:source has '
                'signatures generated with untrusted keys. You can either '
                'resign the trove with a key that you trust, or add one of the '
                'keys to the list of trusted keys (the trustedKeys '
                'configuration option). The keys that were not trusted are: '
                '90B1E477'
            ])
Example #18
0
    def __init__(self, cfg = None, passwordPrompter = None,
                 resolverClass=resolve.DependencySolver, updateCallback=None,
                 repos=None, modelFile=None):
        """
        @param cfg: a custom L{conarycfg.ConaryConfiguration} object.
                    If None, the standard Conary configuration is loaded
                    from /etc/conaryrc, ~/.conaryrc, and ./conaryrc.
        @type cfg: L{conarycfg.ConaryConfiguration}
        """

        ClientUpdate.__init__(self, callback=updateCallback)

        if cfg == None:
            cfg = conarycfg.ConaryConfiguration()
            cfg.initializeFlavors()
        self.repos = None

        self.cfg = cfg
        self.db = database.Database(cfg.root, cfg.dbPath, cfg.modelPath,
                                    modelFile=modelFile)
        if repos:
            self.repos = repos
        else:
            self.repos = self.createRepos(self.db, cfg,
                                          passwordPrompter = passwordPrompter)

        log.openSysLog(self.cfg.root, self.cfg.logFile)

        if not resolverClass:
            resolverClass = resolve.DependencySolver

        self.resolver = resolverClass(self, cfg, self.db)

        # Set up the callbacks for the PGP key cache
        keyCache = openpgpkey.getKeyCache()
        keyCache.setPublicPath(cfg.pubRing)
        keyCacheCallback = openpgpkey.KeyCacheCallback(self.repos,
                                                       cfg)
        keyCache.setCallback(keyCacheCallback)
Example #19
0
    def checkTroveSignatures(self, trv, callback):
        assert(hasattr(callback, 'verifyTroveSignatures'))
        if callback.keyCache is None:
            callback.keyCache = openpgpkey.getKeyCache()
        for fingerprint, timestamp, sig in trv.troveInfo.sigs.digitalSigs.iter():
            try:
                pubKey = callback.keyCache.getPublicKey(fingerprint)
                if pubKey.isRevoked():
                    raise openpgpfile.IncompatibleKey('Key %s is revoked'
                                                      %pubKey.getFingerprint())
                expirationTime = pubKey.getTimestamp()
                if expirationTime and expirationTime < timestamp:
                    raise openpgpfile.IncompatibleKey('Key %s is expired'
                                                      %pubKey.getFingerprint())
            except openpgpfile.KeyNotFound:
                # missing keys could be okay; that depends on the threshold
                # we've set. it's the callbacks problem in any case.
                pass

        res = ChangeSetJob.checkTroveSignatures(self, trv, callback)
        if len(res[1]) and self.requireSigs:
            raise openpgpfile.KeyNotFound('Repository does not recognize '
                                          'key: %s'% res[1][0])
Example #20
0
    def testSignTrove(self):
        fingerprint = 'F7440D78FE813C882212C2BF8AC2828190B1E477'
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')

        self.addQuickTestComponent("test:doc", "1.0-1-1")
        self.cfg.signatureKey = fingerprint
        self.cfg.quiet = True

        self.assertRaises(errors.DigitalSignatureError, signtrove.signTroves,
                          self.cfg, ["test:doc"])

        # get the public key
        keyRing = open(
            resources.get_path('conary_test', 'archive', 'pubring.gpg'))
        keyData = openpgpfile.exportKey(fingerprint, keyRing)
        keyData.seek(0)
        keyData = keyData.read()

        # upload the public key
        repos = self.openRepository()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        signtrove.signTroves(self.cfg, ["test:doc"])

        # get the signed trove from the repository, verify that
        # everything is correct
        v = versions.VersionFromString('/localhost@rpl:linux/1.0-1-1')
        f = deps.parseFlavor('')
        t = repos.getTrove('test:doc', v, f)
        self._checkDigitalSig(t, fingerprint)
        self.assertEqual(t.verifyDigitalSignatures(),
                         (openpgpfile.TRUST_TRUSTED, [], set()))

        # add another signature.  This exercises code such as the
        # change set cache invalidation
        fingerprint2 = '95B457D16843B21EA3FC73BBC7C32FC1F94E405E'
        keyCache.getPrivateKey(fingerprint2, '111111')

        # upload the public key
        keyRing = open(
            resources.get_path('conary_test', 'archive', 'pubring.gpg'))
        keyData = openpgpfile.exportKey(fingerprint2, keyRing)
        keyData.seek(0)
        keyData = keyData.read()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)

        # sign with the second private key
        self.cfg.signatureKey = fingerprint2
        self.cfg.quiet = True
        signtrove.signTroves(self.cfg, ["test:doc"])

        # iterate over the signatures, making sure each signature version has
        # two sigs associated with it
        t = repos.getTrove('test:doc', v, f)
        self._checkDigitalSig(t, fingerprint)
        self._checkDigitalSig(t, fingerprint2)
        self.assertEqual(t.verifyDigitalSignatures(),
                         (openpgpfile.TRUST_TRUSTED, [], set()))

        # attempt signing again with a key that already signed the trove
        self.assertRaises(errors.DigitalSignatureError, signtrove.signTroves,
                          self.cfg, ["test:doc"])
Example #21
0
    def testReposRequireSigs(self):
        fingerprint = '95B457D16843B21EA3FC73BBC7C32FC1F94E405E'
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')

        callback = checkin.CheckinCallback()
        # make sure there's not a cached repo index 1
        self.stopRepository(1)
        sigRepos = self.openRepository(1, requireSigs=True)
        ascKey = open(resources.get_path('conary_test', 'archive',
                                         'key.asc')).read()
        buildLabel = self.cfg.buildLabel
        signatureKey = self.cfg.signatureKey
        signatureKeyMap = self.cfg.signatureKeyMap
        # try block protects test suite from the alteration of self.cfg
        # or most especially, the effects of leaving a requireSigs repo around
        try:
            self.cfg.signatureKey = None
            self.cfg.signatureKeyMap = None
            self.cfg.buildLabel = versions.Label('localhost1@rpl:linux')
            sigRepos.addNewAsciiPGPKey(self.cfg.buildLabel, 'test', ascKey)
            try:
                self.addQuickTestComponent("test:doc",
                                           "/localhost1@rpl:devel/1.0-1-1")
                self.fail("Repository should have required a signature")
            except DigitalSignatureVerificationError:
                pass

            name = 'testcase'
            fullName = name + '=/localhost1@rpl:linux'
            # test commit codepath.
            origDir = os.getcwd()
            try:
                os.chdir(self.workDir)
                self.newpkg(name)
                os.chdir(name)
                self.writeFile(name + '.recipe', testRecipe)
                self.addfile(name + '.recipe')
                try:
                    checkin.commit(sigRepos, self.cfg, 'foobar', callback)
                    self.fail("Repository should have rejected  commit")
                except DigitalSignatureVerificationError:
                    pass
                # but we really need a source trove for the rest of the paths
                self.cfg.signatureKey = fingerprint
                checkin.commit(sigRepos, self.cfg, fullName, None)
                self.cfg.signatureKey = None
            finally:
                os.chdir(origDir)

        # test cook codepath
            try:
                self.cookItem(sigRepos,
                              self.cfg,
                              fullName,
                              callback=callback,
                              ignoreDeps=True)
                self.fail("Repository should have rejected cook")
            except DigitalSignatureVerificationError:
                pass
            self.cfg.signatureKey = fingerprint
            self.cookItem(sigRepos,
                          self.cfg,
                          fullName,
                          callback=callback,
                          ignoreDeps=True)
            self.cfg.signatureKey = None

            # test clone codepath
            try:
                self.clone('/localhost1@rpl:shadow',
                           'testcase:source=/localhost1@rpl:linux')
                self.fail("Repository should have rejected clone")
            except DigitalSignatureVerificationError:
                pass

            # test branch codepath
            try:
                self.mkbranch("1.0-1",
                              "localhost1@rpl:shadow",
                              "testcase:source",
                              shadow=False)
                self.fail("Repository should have rejected branch")
            except DigitalSignatureVerificationError:
                pass

            # test shadow codepath
            try:
                self.mkbranch("1.0-1",
                              "localhost1@rpl:shadow",
                              "testcase:source",
                              shadow=True)
                self.fail("Repository should have rejected shadow")
            except DigitalSignatureVerificationError:
                pass

        finally:
            self.cfg.buildLabel = buildLabel
            self.cfg.signatureKey = signatureKey
            self.cfg.signatureKeyMap = signatureKeyMap
            # this repo MUST be destroyed, other tests will fail against it.
            self.stopRepository(1)
            sigRepos = self.openRepository(1)
        self.addQuickTestComponent("test:doc", "/localhost1@rpl:devel/1.0-1-1")
Example #22
0
    def testSignedUpdate(self):
        fingerprint = '95B457D16843B21EA3FC73BBC7C32FC1F94E405E'
        # supply the pass phrase for our private key
        keyCache = openpgpkey.getKeyCache()
        keyCache.getPrivateKey(fingerprint, '111111')

        self.addQuickTestComponent("test:doc", "1.0-1-1")

        self.cfg.signatureKey = fingerprint
        self.cfg.quiet = True

        # put the public key into the repo
        keyRing = open(
            resources.get_path('conary_test', 'archive', 'pubring.gpg'))
        keyData = openpgpfile.exportKey(fingerprint, keyRing)
        keyData.seek(0)
        keyData = keyData.read()
        repos = self.openRepository()
        repos.addNewPGPKey(self.cfg.buildLabel, 'test', keyData)
        signtrove.signTroves(self.cfg, ["test:doc"])

        # alter key's trust value and determine that the doUpdate
        # code properly verifies trust thresholds
        pubKey = keyCache.getPublicKey(fingerprint)
        pubKey.trustLevel = openpgpfile.TRUST_UNTRUSTED
        keyCache.publicDict[fingerprint] = pubKey
        self.cfg.trustThreshold = openpgpfile.TRUST_ULTIMATE
        self.logFilter.add()
        try:
            self.discardOutput(doUpdate, self.cfg, 'test:doc')
            self.fail("updatecmd.doUpdate did not properly check trust levels")
        except DigitalSignatureVerificationError:
            self.logFilter.compare([
                'warning: The trove test:doc has '
                'signatures generated with untrusted keys. You can either '
                'resign the trove with a key that you trust, or add one of the '
                'keys to the list of trusted keys (the trustedKeys '
                'configuration option). The keys that were not trusted are: '
                'F94E405E'
            ])

        # An example how one can catch the digital signature verification
        # error for each unsigned trove (and display some message in a GUI
        # maybe). In this case we just raise a different exception.
        class MyException(Exception):
            errorIsUncatchable = True

        class C_(callbacks.UpdateCallback):
            def verifyTroveSignatures(self, trv):
                try:
                    return callbacks.UpdateCallback.verifyTroveSignatures(
                        self, trv)
                except DigitalSignatureVerificationError:
                    raise MyException("Error in trove %s" % trv.getName())

        callback = C_(trustThreshold=self.cfg.trustThreshold)
        # We should catch our own exception now
        self.discardOutput(self.assertRaises,
                           MyException,
                           doUpdate,
                           self.cfg,
                           "test:doc",
                           callback=callback)
Example #23
0
    def addNewKey(self, userId, pgpKeyData):
        # this ignore duplicate keys
        cu = self.db.cursor()

        stream = util.ExtendedStringIO(pgpKeyData)
        if openpgpfile.countKeys(stream) != 1:
            raise openpgpfile.IncompatibleKey( \
                'Submit only one key at a time.')

        inKey = openpgpfile.newKeyFromStream(stream)

        # make sure it's a public key
        if not isinstance(inKey, openpgpfile.PGP_PublicKey):
            raise openpgpfile.IncompatibleKey('Key must be a public key')

        inKey.verifySelfSignatures()

        mainFingerprint = inKey.getKeyFingerprint()

        # if key already exists we need to ensure it's safe to overwrite
        # the old one, and then just do it.
        r = cu.execute('SELECT KeyId, pgpKey FROM PGPKeys WHERE fingerprint=?',
                       mainFingerprint)
        for (keyId, keyBlob) in cu.fetchall():
            origKey = cu.frombinary(keyBlob)
            origKey = openpgpfile.newKeyFromString(origKey)

            modified = origKey.merge(inKey)
            if not modified:
                # Nothing to do here, the key in our DB is already a superset
                # of the incoming key
                break
            # origKey now is a superset of both the old key and the incoming
            # key. we can't allow the repo to let go of subkeys or
            # revocations.
            sio = StringIO()
            origKey.writeAll(sio)
            keyData = sio.getvalue()

            #reset the key cache so the changed key shows up
            keyCache = openpgpkey.getKeyCache()
            keyCache.remove(keyId)
            cu.execute('UPDATE PGPKeys set pgpKey=? where keyId=?',
                       cu.binary(keyData), keyId)
            break
        else:  #for
            cu.execute(
                'INSERT INTO PGPKeys (userId, fingerprint, pgpKey) '
                'VALUES (?, ?, ?)',
                (userId, mainFingerprint, cu.binary(pgpKeyData)))
            keyId = cu.lastrowid

        keyFingerprints = [mainFingerprint]
        keyFingerprints.extend(x.getKeyFingerprint()
                               for x in inKey.iterSubKeys())

        for fingerprint in keyFingerprints:
            cu.execute(
                "SELECT COUNT(*) FROM PGPFingerprints "
                "WHERE keyId = ? and fingerprint = ?", (keyId, fingerprint))
            if cu.fetchall()[0][0] > 0:
                continue
            cu.execute(
                'INSERT INTO PGPFingerprints (keyId, fingerprint) '
                'VALUES(?, ?)', (keyId, fingerprint))
        self.db.commit()
Example #24
0
    def addNewKey(self, userId, pgpKeyData):
        # this ignore duplicate keys
        cu = self.db.cursor()

        stream = util.ExtendedStringIO(pgpKeyData)
        if openpgpfile.countKeys(stream) != 1:
            raise openpgpfile.IncompatibleKey( \
                'Submit only one key at a time.')

        inKey = openpgpfile.newKeyFromStream(stream)

        # make sure it's a public key
        if not isinstance(inKey, openpgpfile.PGP_PublicKey):
            raise openpgpfile.IncompatibleKey('Key must be a public key')

        inKey.verifySelfSignatures()

        mainFingerprint = inKey.getKeyFingerprint()

        # if key already exists we need to ensure it's safe to overwrite
        # the old one, and then just do it.
        r = cu.execute('SELECT KeyId, pgpKey FROM PGPKeys WHERE fingerprint=?',
                       mainFingerprint)
        for (keyId, keyBlob) in cu.fetchall():
            origKey = cu.frombinary(keyBlob)
            origKey = openpgpfile.newKeyFromString(origKey)

            modified = origKey.merge(inKey)
            if not modified:
                # Nothing to do here, the key in our DB is already a superset
                # of the incoming key
                break
            # origKey now is a superset of both the old key and the incoming
            # key. we can't allow the repo to let go of subkeys or
            # revocations.
            sio = StringIO()
            origKey.writeAll(sio)
            keyData = sio.getvalue()

            #reset the key cache so the changed key shows up
            keyCache = openpgpkey.getKeyCache()
            keyCache.remove(keyId)
            cu.execute('UPDATE PGPKeys set pgpKey=? where keyId=?',
                       cu.binary(keyData), keyId)
            break
        else: #for
            cu.execute('INSERT INTO PGPKeys (userId, fingerprint, pgpKey) '
                       'VALUES (?, ?, ?)',
                       (userId, mainFingerprint, cu.binary(pgpKeyData)))
            keyId = cu.lastrowid

        keyFingerprints = [ mainFingerprint ]
        keyFingerprints.extend(x.getKeyFingerprint() for x in inKey.iterSubKeys())

        for fingerprint in keyFingerprints:
            cu.execute("SELECT COUNT(*) FROM PGPFingerprints "
                       "WHERE keyId = ? and fingerprint = ?",
                       (keyId, fingerprint))
            if cu.fetchall()[0][0] > 0:
                continue
            cu.execute('INSERT INTO PGPFingerprints (keyId, fingerprint) '
                       'VALUES(?, ?)', (keyId, fingerprint))
        self.db.commit()