Esempio n. 1
0
def main(key_path, test_name):
    with subprocess.Popen(['gpg', '--no-default-keyring',
            '--keyring', key_path, '--list-key', '--with-colons'],
            stdout=subprocess.PIPE) as s:
        key_colons, _ = s.communicate()
        assert s.wait() == 0

    key_colons = key_colons.decode('ASCII')
    with io.StringIO(key_colons) as f:
        key_cls = process_gnupg_colons(f)

    assert len(key_cls) == 1
    key_cls = key_cls[0]

    results = {}
    for k, spec in SPECS.items():
        results[k] = check_key(key_cls, spec)

    print('''

class {test_name}(tests.key_base.BaseKeyTest):
    KEY_FILE = '{key_file}'

    GPG_COLONS = \'\'\'
{gpg_colons}\'\'\'

    KEY = {key_cls}

    EXPECTED_RESULTS = {expected}'''.format(
        test_name=test_name,
        key_file=os.path.relpath(key_path, 'tests'),
        gpg_colons=key_colons,
        key_cls=pretty_key(key_cls),
        expected=pretty_results(results)))
Esempio n. 2
0
    def test_key_class(self):
        """
        Test the key using predefined Key class.
        """
        keys = [self.KEY]

        with unittest.mock.patch("datetime.datetime", PatchedDateTime):
            for spec, expected in self.EXPECTED_RESULTS.items():
                with self.subTest(spec):
                    self.assertListEqual(expected,
                            list(clear_long_descs(
                                check_key(keys[0], SPECS[spec]))))
Esempio n. 3
0
    def test_colons(self):
        """
        Test the key using provided 'gpg --with-colons' output.
        """
        keys = process_gnupg_colons(io.StringIO(self.GPG_COLONS))
        assert len(keys) == 1

        with unittest.mock.patch("datetime.datetime", PatchedDateTime):
            for spec, expected in self.EXPECTED_RESULTS.items():
                with self.subTest(spec):
                    self.assertListEqual(expected,
                            list(clear_long_descs(
                                check_key(keys[0], SPECS[spec]))))
Esempio n. 4
0
    def test_integration(self):
        """
        Test the key using local installed GnuPG.
        """
        if not get_gnupg_version():
            raise unittest.SkipTest('GnuPG executable not found')

        keypath = os.path.join(os.path.dirname(__file__), self.KEY_FILE)
        with unittest.mock.patch("glep63.gnupg.subprocess.Popen", FakeTimePopen):
            keys = process_gnupg_key(keyrings=[keypath])
        assert len(keys) == 1

        with unittest.mock.patch("datetime.datetime", PatchedDateTime):
            for spec, expected in self.EXPECTED_RESULTS.items():
                with self.subTest(spec):
                    self.assertListEqual(expected,
                            list(clear_long_descs(
                                check_key(keys[0], SPECS[spec]))))
Esempio n. 5
0
def main():
    argp = argparse.ArgumentParser()
    act = argp.add_mutually_exclusive_group(required=True)
    act.add_argument('-a',
                     '--all',
                     action='store_true',
                     help='Verify all public keys in the local keyring')
    act.add_argument('-d',
                     '--developers',
                     action='store_true',
                     help='Fetch and verify keys for gentoo.git committers')
    act.add_argument('-D',
                     '--all-developers',
                     action='store_true',
                     help='Fetch and verify keys for all Gentoo developers')
    act.add_argument(
        '-G',
        '--gnupg',
        nargs='+',
        metavar='FILE',
        type=argparse.FileType('r', encoding='UTF-8'),
        help='Process "gpg --with-colons" output from FILE(s) ("-" for stdin)')
    act.add_argument(
        '-k',
        '--key-id',
        nargs='+',
        help='Check local GnuPG keys matching specified query (IDs, names)')
    act.add_argument(
        '-K',
        '--keyring',
        nargs='+',
        help='Check all keys in specified keyrings (gpg --keyring syntax)')

    argp.add_argument('-S',
                      '--spec',
                      choices=SPECS,
                      default=DEFAULT_SPEC,
                      help='Spec to verify against')
    argp.add_argument('-e',
                      '--errors-only',
                      action='store_true',
                      help='Print only errors (skip warnings)')
    argp.add_argument(
        '-i',
        '--ignore-extraneous-keys',
        action='store_true',
        help='Skip developers who have at least one good key (by UID)')
    argp.add_argument(
        '-m',
        '--machine-readable',
        action='store_true',
        help='Print only machine-readable data (skip human-readable desc)')
    argp.add_argument('-N',
                      '--no-name',
                      action='store_true',
                      help='Print only e-mail addresses as UIDs')
    argp.add_argument(
        '-w',
        '--warnings-as-errors',
        action='store_true',
        help='Treat warnings as errors (return unsucessfully if any)')

    opts = argp.parse_args()

    keys = []

    if opts.developers or opts.all_developers:
        keyring_url = ('https://qa-reports.gentoo.org/output/{}.gpg'.format(
            'committing-devs' if opts.developers else 'active-devs'))
        with urllib.request.urlopen(keyring_url) as f:
            with tempfile.NamedTemporaryFile() as tmpf:
                shutil.copyfileobj(f, tmpf)
                tmpf.flush()
                keys.extend(process_gnupg_key([tmpf.name], opts.key_id))
    elif opts.key_id is not None or opts.all or opts.keyring is not None:
        keys.extend(process_gnupg_key(opts.keyring, opts.key_id))
    elif opts.gnupg is not None:
        for f in opts.gnupg:
            keys.extend(process_gnupg_colons(f))

    out = []
    for k in keys:
        keyret = check_key(k, SPECS[opts.spec])
        if not keyret and opts.ignore_extraneous_keys:
            keyret = [GoodKey(k)]
        out.extend(keyret)

    ret = 0
    good_devs = set()
    msgs = []
    for i in out:
        # figure out a primary UID, preferring @gentoo.org
        primary_uid = i.key.uids[0].user_id
        for x in i.key.uids:
            if '@gentoo.org' in x.user_id:
                primary_uid = x.user_id
                break
        _, uid_addr = email.utils.parseaddr(primary_uid)

        if isinstance(i, GoodKey):
            good_devs.add(uid_addr)
            continue

        keyid = i.key.keyid
        if hasattr(i, 'subkey'):
            keyid += ':' + i.subkey.keyid
        elif hasattr(i, 'uid'):
            if opts.no_name:
                _, uid_fmt = email.utils.parseaddr(i.uid_user_id)
            else:
                uid_fmt = i.uid.user_id
            keyid += ':[{}]'.format(uid_fmt)

        if type(i) in FAIL:
            ret |= 1
            cls = '[E]'
        else:
            assert type(i) in WARN
            cls = '[W]'
            if opts.errors_only:
                continue
            if opts.warnings_as_errors:
                ret |= 2

        if opts.machine_readable:
            msg = [keyid, i.machine_desc]
        else:
            msg = [
                keyid,
                '[{}]'.format(uid_addr if opts.no_name else primary_uid), cls,
                i.machine_desc, i.long_desc
            ]

        msgs.append((uid_addr, msg))

    for addr, msg in msgs:
        if addr not in good_devs:
            print(' '.join(msg))

    return ret