Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-patatt for openSUSE:Factory checked in at 2022-09-08 14:22:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-patatt (Old) and /work/SRC/openSUSE:Factory/.python-patatt.new.2083 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-patatt" Thu Sep 8 14:22:29 2022 rev:6 rq:1001696 version:0.6.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-patatt/python-patatt.changes 2022-08-12 16:07:21.115597791 +0200 +++ /work/SRC/openSUSE:Factory/.python-patatt.new.2083/python-patatt.changes 2022-09-08 14:23:11.470604861 +0200 @@ -1,0 +2,9 @@ +Wed Sep 7 10:36:48 UTC 2022 - Jiri Slaby <jsl...@suse.cz> + +- update to 0.6.2 + * Better fix for non-writable GNUPGHOME + * Use NamedTemporaryFile for gpg keyring creation + * Call git-mailinfo with line endings normalized to LF + * Make patatt more python API friendly + +------------------------------------------------------------------- Old: ---- patatt-0.5.0.tar.asc patatt-0.5.0.tar.gz New: ---- patatt-0.6.2.tar.asc patatt-0.6.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-patatt.spec ++++++ --- /var/tmp/diff_new_pack.nJ5mmI/_old 2022-09-08 14:23:12.010606107 +0200 +++ /var/tmp/diff_new_pack.nJ5mmI/_new 2022-09-08 14:23:12.018606126 +0200 @@ -19,7 +19,7 @@ %define skip_python2 1 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-patatt -Version: 0.5.0 +Version: 0.6.2 Release: 0 Summary: Cryptographic patch attestation for the masses License: MIT-0 ++++++ patatt-0.5.0.tar.gz -> patatt-0.6.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patatt-0.5.0/man/patatt.5 new/patatt-0.6.2/man/patatt.5 --- old/patatt-0.5.0/man/patatt.5 2022-06-17 18:36:51.000000000 +0200 +++ new/patatt-0.6.2/man/patatt.5 2022-08-25 22:41:52.000000000 +0200 @@ -27,7 +27,7 @@ .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "PATATT" 5 "2022-10-17" "0.5.0" "" +.TH "PATATT" 5 "2022-08-22" "0.6.0" "" .SH NAME PATATT \- DKIM-like cryptographic patch attestation .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patatt-0.5.0/man/patatt.5.rst new/patatt-0.6.2/man/patatt.5.rst --- old/patatt-0.5.0/man/patatt.5.rst 2022-06-17 18:36:51.000000000 +0200 +++ new/patatt-0.6.2/man/patatt.5.rst 2022-08-25 22:41:52.000000000 +0200 @@ -5,10 +5,10 @@ ----------------------------------------- :Author: mri...@kernel.org -:Date: 2022-10-17 +:Date: 2022-08-22 :Copyright: The Linux Foundation and contributors :License: MIT-0 -:Version: 0.5.0 +:Version: 0.6.0 :Manual section: 5 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patatt-0.5.0/patatt/__init__.py new/patatt-0.6.2/patatt/__init__.py --- old/patatt-0.5.0/patatt/__init__.py 2022-06-17 18:36:51.000000000 +0200 +++ new/patatt-0.6.2/patatt/__init__.py 2022-08-25 22:41:52.000000000 +0200 @@ -47,9 +47,11 @@ # Quick cache for key info KEYCACHE = dict() +# Quick cache for config settings +CONFIGCACHE = dict() # My version -__VERSION__ = '0.5.0' +__VERSION__ = '0.6.2' MAX_SUPPORTED_FORMAT_VERSION = 1 @@ -337,7 +339,7 @@ @staticmethod def _validate_openssh(sigdata: bytes, payload: bytes, keydata: bytes) -> None: - with tempfile.TemporaryDirectory(suffix='.patch-attest-poc') as td: + with tempfile.TemporaryDirectory(suffix='.patatt.ssh') as td: # Start by making a signers file fpath = os.path.join(td, 'signers') spath = os.path.join(td, 'sigdata') @@ -392,11 +394,12 @@ bsigdata = base64.b64decode(sigdata) vrfyargs = ['--verify', '--output', '-', '--status-fd=2'] if pubkey: - with tempfile.TemporaryFile(suffix='.patch-attest-poc') as temp_keyring: - keyringargs = ['--no-default-keyring', f'--keyring={temp_keyring.name}'] + with tempfile.TemporaryDirectory(suffix='.patatt.gnupg') as td: + keyringargs = ['--homedir', td, '--no-default-keyring', '--keyring', 'pub'] if pubkey in KEYCACHE: logger.debug('Reusing cached keyring') - temp_keyring.write(KEYCACHE[pubkey]) + with open(os.path.join(td, 'pub'), 'wb') as kfh: + kfh.write(KEYCACHE[pubkey]) else: logger.debug('Importing into new keyring') gpgargs = keyringargs + ['--status-fd=1', '--import'] @@ -404,7 +407,8 @@ # look for IMPORT_OK if out.find(b'[GNUPG:] IMPORT_OK') < 0: raise ValidationError('Could not import GnuPG public key') - KEYCACHE[pubkey] = temp_keyring.read() + with open(os.path.join(td, 'pub'), 'rb') as kfh: + KEYCACHE[pubkey] = kfh.read() gpgargs = keyringargs + vrfyargs ecode, out, err = gpg_run_command(gpgargs, stdin=bsigdata) @@ -676,7 +680,9 @@ mf = os.path.join(td, 'm') pf = os.path.join(td, 'p') cmdargs = ['git', 'mailinfo', '--encoding=utf-8', '--no-scissors', mf, pf] - ecode, i, err = _run_command(cmdargs, stdin=payload) + # normalize line endings in payload to single lf for consistent results + # from git-mailinfo. + ecode, i, err = _run_command(cmdargs, stdin=payload.replace(b'\r\n', b'\n')) if ecode > 0: logger.debug('FAILED : Failed running git-mailinfo:') logger.debug(err.decode()) @@ -925,12 +931,17 @@ SSHKBIN = 'ssh-keygen' -def cmd_sign(cmdargs, config: dict) -> None: +def get_algo_keydata(config: dict) -> Tuple[str, str]: + global KEYCACHE # Do we have the signingkey defined? usercfg = get_config_from_git(r'user\..*') if not config.get('identity') and usercfg.get('email'): # Use user.email config['identity'] = usercfg.get('email') + # Do we have this already looked up? + if config['identity'] in KEYCACHE: + return KEYCACHE[config['identity']] + if not config.get('signingkey'): if usercfg.get('signingkey'): logger.info('N: Using pgp key %s defined by user.signingkey', usercfg.get('signingkey')) @@ -939,13 +950,7 @@ else: logger.critical('E: patatt.signingkey is not set') logger.critical('E: Perhaps you need to run genkey first?') - sys.exit(1) - - try: - messages = _load_messages(cmdargs) - except IOError as ex: - logger.critical('E: %s', ex) - sys.exit(1) + raise NoKeyError('patatt.signingkey is not set') sk = config.get('signingkey') if sk.startswith('ed25519:'): @@ -969,8 +974,7 @@ keysrc = skey if not keysrc: - logger.critical('E: Could not find the key matching %s', identifier) - sys.exit(1) + raise ConfigurationError('Could not find the key matching %s' % identifier) logger.info('N: Using ed25519 key: %s', keysrc) with open(keysrc, 'r') as fh: @@ -984,22 +988,62 @@ keydata = sk[8:] else: logger.critical('E: Unknown key type: %s', sk) + raise ConfigurationError('Unknown key type: %s' % sk) + + KEYCACHE[config['identity']] = (algo, keydata) + return algo, keydata + + +def rfc2822_sign(message: bytes, config: Optional[dict] = None) -> bytes: + if config is None: + config = get_main_config() + algo, keydata = get_algo_keydata(config) + pm = PatattMessage(message) + pm.sign(algo, keydata, identity=config.get('identity'), selector=config.get('selector')) + logger.debug('--- SIGNED MESSAGE STARTS ---') + logger.debug(pm.as_string()) + return pm.as_bytes() + + +def get_main_config(section: Optional[str] = None) -> dict: + global CONFIGCACHE + if section in CONFIGCACHE: + return CONFIGCACHE[section] + config = get_config_from_git(r'patatt\..*', section=section, multivals=['keyringsrc']) + # Append some extra keyring locations + if 'keyringsrc' not in config: + config['keyringsrc'] = list() + config['keyringsrc'] += ['ref:::.keys', 'ref:::.local-keys', 'ref::refs/meta/keyring:'] + set_bin_paths(config) + logger.debug('config: %s', config) + CONFIGCACHE[section] = config + return config + + +def cmd_sign(cmdargs, config: dict) -> None: + try: + messages = _load_messages(cmdargs) + except IOError as ex: + logger.critical('E: %s', ex) sys.exit(1) for fn, msgdata in messages.items(): try: - pm = PatattMessage(msgdata) - pm.sign(algo, keydata, identity=config.get('identity'), selector=config.get('selector')) + signed = rfc2822_sign(msgdata, config) logger.debug('--- SIGNED MESSAGE STARTS ---') - logger.debug(pm.as_string()) + logger.debug(signed.decode()) if fn == '-': - sys.stdout.buffer.write(pm.as_bytes()) + sys.stdout.buffer.write(signed) else: with open(fn, 'wb') as fh: - fh.write(pm.as_bytes()) + fh.write(signed) logger.critical('SIGN | %s', os.path.basename(fn)) + except (ConfigurationError, NoKeyError) as ex: + logger.debug('Exiting due to %s', ex) + sys.exit(1) + except SigningError as ex: logger.critical('E: %s', ex) sys.exit(1) @@ -1292,13 +1336,7 @@ ch.setLevel(logging.CRITICAL) logger.addHandler(ch) - config = get_config_from_git(r'patatt\..*', section=_args.section, multivals=['keyringsrc']) - # Append some extra keyring locations - if 'keyringsrc' not in config: - config['keyringsrc'] = list() - config['keyringsrc'] += ['ref:::.keys', 'ref:::.local-keys', 'ref::refs/meta/keyring:'] - set_bin_paths(config) - logger.debug('config: %s', config) + config = get_main_config(section=_args.section) if 'func' not in _args: parser.print_help()