Example #1
0
def test_simple():
    cfg = ConfigParser.RawConfigParser()
    cfg.readfp(StringIO("""\
[access *]
users = @bar xyzzy

[group bar]
users = quux thud
"""))
    got = decide_recipients.decide_recipients(cfg, 'some/path')
    eq(sorted(got), sorted(['quux', 'thud', 'xyzzy']))
Example #2
0
def verify(cfg, path):
    """
    Generates a list of problems, each item a `VerifyResult`; empty
    list means everything is good.
    """
    for relpath, path in walk.walk(cfg=cfg, path=path):
            log.debug('Verifying file: %s', relpath)
            ok = True
            result = VerifyResult(
                path=relpath,
                extra=set(),
                missing=set(),
                unknown_keys=set(),
                unknown_fingerprints=set(),
                )
            want = decide_recipients.decide_recipients(
                cfg=cfg,
                path=relpath,
                )
            want = set(want)
            log.debug('Expecting recipients: %s', ' '.join(sorted(want)))

            keyids = extract_recipients.extract_recipients(path)
            keyids = set(keyids)
            log.debug('Got recipient keyids: %s', ' '.join(keyids))

            # Keyids can collide; that means a message may (to us)
            # look like it's encrypted to Bob, but in reality it's
            # encrypted to Mallory. This attack requires tricking the
            # person encrypting it to choosing the wrong key; if you
            # use "sekrit set", the recipient will be chosen by
            # fingerprint, and thus this attack is most likely
            # infeasible. Hence, we will just assume the keyids
            # extracted above map simply to our known
            # fingerprints/users.
            fprs = set()
            for keyid in keyids:
                fpr = keyid_to_fingerprint.keyid_to_fingerprint(keyid)
                if fpr is None:
                    log.critical(
                        '%s: Unexpected recipient keyid: %r',
                        relpath,
                        keyid,
                        )
                    result.unknown_keys.add(keyid)
                    ok = False
                else:
                    fprs.add(fpr)
            log.debug('Got recipient fingerprints: %s', ' '.join(fprs))

            got_users = set()
            for fpr in fprs:
                user = map_fpr_to_user.map_fpr_to_user(cfg, fpr)
                if user is None:
                    log.critical(
                        '%s: Unknown recipient fingerprint: %r',
                        relpath,
                        fpr,
                        )
                    result.unknown_fingerprints.add(fpr)
                    ok = False
                else:
                    got_users.add(user)

            log.debug('Got recipients: %s', ' '.join(sorted(got_users)))

            extra = got_users - want
            if extra:
                log.critical(
                    '%s: Unexpected recipients: %s',
                    relpath,
                    ' '.join(sorted(extra)),
                    )
                result.extra.update(extra)
                ok = False

            missing = want - got_users
            if missing:
                log.error(
                    '%s: Missing recipients: %s',
                    relpath,
                    ' '.join(sorted(missing)),
                    )
                result.missing.update(missing)
                ok = False

            if ok:
                log.info('%s: ok: %s', relpath, ' '.join(sorted(got_users)))
            else:
                log.error('%s: bad', relpath)
                yield result
Example #3
0
def set_secret(cfg, path):
    users = decide_recipients.decide_recipients(cfg, path)
    users = list(users)
    if not users:
        raise RuntimeError('Nobody to encrypt to: %s', path)

    fingerprints = [
        user_to_fpr.user_to_fpr(cfg=cfg, user=user)
        for user in users
        ]
    if not fingerprints:
        raise RuntimeError('No fingerprints found for users: %s', ' '.join(users))

    gpg = GnuPGInterface.GnuPG()
    gpg.options.armor = 1
    gpg.options.meta_interactive = 0
    gpg.options.recipients = fingerprints

    if not os.isatty(sys.stdin.fileno()):
        # redirected from file / pipe, read passphrase from there
        secret1 = sys.stdin.readline()
        secret1 = secret1.rstrip('\n')
    else:
        secret1 = prompt(message='Passphrase for %s' % path)
        secret2 = prompt(message='Repeat pass for %s' % path)

        if secret1 != secret2:
            del secret1
            del secret2
            print >>sys.stderr, '%s: Passphrases do not match.' % sys.argv[0]
            sys.exit(1)

        del secret2

    tmp = '{path}.{pid}.tmp'.format(
        path=path,
        pid=os.getpid(),
        )
    with file(tmp, 'w') as fp:
        try:
            proc = gpg.run(
                [
                    '--encrypt',
                    '--for-your-eyes-only',
                    '--trust-mode=always',
                    ],
                create_fhs=['stdin'],
                attach_fhs=dict(
                    stdout=fp,
                    logger=sys.stderr,
                    ),
                )

            proc.handles['stdin'].write(secret1)
            del secret1
            proc.handles['stdin'].close()

            try:
                proc.wait()
            except IOError, e:
                print >>sys.stderr, '%s: gnupg: %s' % (sys.argv[0], e)
                sys.exit(1)
        except:
            try:
                os.unlink(tmp)
            except:
                pass
            raise

    os.rename(tmp, path)

    print 'Encrypted to:'
    for uid in users:
        print '\t%s' % uid