From c65a594d3bff70d0a78e88d673e94b3c03276d51 Mon Sep 17 00:00:00 2001 From: Jonathan Cross Date: Mon, 9 Dec 2019 22:31:57 +0100 Subject: [PATCH] verify-merge.py : detailed file path / folder name checking. --- verify-merge.py | 60 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/verify-merge.py b/verify-merge.py index 4f67f3d..4ad5449 100755 --- a/verify-merge.py +++ b/verify-merge.py @@ -15,8 +15,13 @@ def verify(): import_gpg_keys() if args.refresh_keys: refresh_gpg_keys() - assert_files = get_assert_file_list() - verify_gpg_sigs(assert_files) + # Shell glob pattern for specific version or all builds: + ver_pattern = args.version if args.version else 'v0*' + sig_file_paths = set(glob.glob(ver_pattern + '-*/*/*.assert.sig')) + assert_files = get_assert_file_list(ver_pattern) + user_names = get_user_names_from_keys() + verify_file_path_naming(assert_files, sig_file_paths, user_names) + verify_gpg_sigs(sig_file_paths) verify_checksums(assert_files) print('All checks passed.') os.chdir(workdir) @@ -68,33 +73,31 @@ def refresh_gpg_keys(): def import_gpg_keys(): os.chdir(GITIAN_PUBKEYS_DIR) print('Importing gpg pubkeys...') - keys = [f for f in glob.glob('*.asc', recursive=False)] + keys = glob.glob('*.asc') for key in keys: subprocess.check_call([GPG, '--import', key]) os.chdir('../') -def get_assert_file_list(): - global args - # Shell glob pattern for specific version or all builds: - ver_pattern = args.version if args.version else 'v0*' +def get_assert_file_list(ver_pattern): assert_files = [] for assert_file in sorted(glob.glob(ver_pattern + '-*/*/*.assert')): pieces = assert_file.split('/') release_full = pieces[0] # eg v0.15.0.1-linux release_num, platform = release_full.split('-') + version_major = release_num.split('.')[1] assert_files.append({ 'release_full': release_full, 'release_num': release_num, 'platform': platform, 'path': assert_file, - 'user': pieces[1]}) + 'user': pieces[1], + 'version_major': version_major}) return assert_files -def verify_gpg_sigs(assert_files): +def verify_gpg_sigs(sig_file_paths): print('Verifying signatures:') is_verification_error = False - for assert_file in assert_files: - sig_file = assert_file['path'] + '.sig' + for sig_file in sig_file_paths: print(' - ' + '{message: <{fill}}'.format(message=sig_file, fill='72'), end='') result = verify_gpg_sig(sig_file) if result.returncode != 0: @@ -108,7 +111,42 @@ def verify_gpg_sigs(assert_files): exit(1) print('All signatures verified correctly.\n') +def verify_file_path_naming(assert_files, sig_file_paths, user_names): + path_pattern = '{release_num}-{platform}/{user}/monero-{platform}-0.{version_major}-build.assert' + print('Verifying file path naming...') + # Check that every sig has an assert: + if len(sig_file_paths) > len(assert_files): + sys.stderr.write("ERROR: One or more sig files doesn't have a matching assert file:\n") + assert_file_paths = [a['path'] for a in assert_files] + extra_sigs = [s for s in sig_file_paths if os.path.splitext(s)[0] not in assert_file_paths] + for extra_sig in extra_sigs: + sys.stderr.write(" - {0}\n".format(extra_sig)) + exit(1) + for assert_file in assert_files: + # Check assert file has a sig file: + if (assert_file['path'] + '.sig') not in sig_file_paths: + sys.stderr.write('ERROR: Assert file found without corresponding sig file:\n' + assert_file['path'] + '\n') + exit(1) + # Check assert user corresponds with a known GPG pubkey: + if assert_file['user'] not in user_names: + sys.stderr.write("ERROR: User '{user}' doesn't have a matching PGP key. Expected {folder}/{user}.asc\n".format(user=assert_file['user'], folder=GITIAN_PUBKEYS_DIR)) + sys.stderr.write(" * Found in path: {path}\n".format(path=assert_file['path'])) + exit(1) + # Check overall format of path (version num, platform, folder and file names): + expected_path = path_pattern.format(**assert_file) + if expected_path != assert_file['path']: + sys.stderr.write('ERROR: File path appears to be incorrect:\n{actual}\nExpected:\n{expected}\n'.format(actual=assert_file['path'], expected=expected_path)) + exit(1) + print('All file paths seem to be correct.\n') + +def get_user_names_from_keys(): + os.chdir(GITIAN_PUBKEYS_DIR) + user_names = [os.path.splitext(key)[0] for key in glob.glob('*.asc')] + os.chdir('../') + return user_names + def verify_gpg_sig(sig_file): + # TODO: Verify correct user created the signature. return subprocess.run([GPG, '--verify', sig_file], capture_output=True, encoding='utf-8') def verify_checksums(assert_files):