lol

libxcrypt: Add check for enabledCryptSchemeIds

+80 -3
+70
pkgs/development/libraries/libxcrypt/check_passthru_matches.py
··· 1 + import tarfile 2 + import sys 3 + 4 + 5 + def process_columns(line: list[str]) -> tuple[str, list[str]]: 6 + match line: 7 + case [name, h_prefix, nrbytes, flags]: 8 + return (h_prefix, flags.lower().split(",")) 9 + case other: 10 + raise Exception("Unsupported hashes.conf line format", other) 11 + 12 + 13 + def find_tar_file(tar: tarfile.TarFile, requested_name: str): 14 + """Attempts to find a single file with given name in tarball.""" 15 + all_names = tar.getnames() 16 + 17 + if requested_name in all_names: 18 + return requested_name 19 + 20 + requested_suffix = f"/{requested_name}" 21 + candidate_names = [name for name in all_names if name.endswith(requested_suffix)] 22 + match candidate_names: 23 + case [real_name]: 24 + return real_name 25 + case other: 26 + raise KeyError( 27 + f"Could not locate a single {requested_name} in the contents of the tarball." 28 + ) 29 + 30 + 31 + hashes_path = "lib/hashes.conf" 32 + 33 + 34 + def main() -> None: 35 + match sys.argv: 36 + case [_name, src, enable_hashes, "--", *enabled_crypt_scheme_ids]: 37 + pass 38 + case other: 39 + raise Exception( 40 + "Incorrect number of arguments. Usage: check_passthru_matches.py <src> <enable_hashes> -- <enabled_crypt_scheme_ids...>" 41 + ) 42 + 43 + with tarfile.open(src, "r") as tar: 44 + real_hashes_path = find_tar_file(tar, hashes_path) 45 + config = tar.extractfile(real_hashes_path).read().decode("utf-8") 46 + 47 + formats = [ 48 + process_columns(columns) 49 + for line in config.splitlines() 50 + if not line.startswith("#") and len(columns := line.split()) > 0 51 + ] 52 + expected_supported_formats = set( 53 + prefix 54 + for (prefix, flags) in formats 55 + if enable_hashes in flags or enable_hashes == "all" 56 + ) 57 + passthru_supported_schemes = set( 58 + f"${scheme}$" for scheme in enabled_crypt_scheme_ids 59 + ) 60 + 61 + assert ( 62 + len(expected_supported_formats - passthru_supported_schemes) == 0 63 + ), f"libxcrypt package enables the following crypt schemes that are not listed in passthru.enabledCryptSchemeIds: {expected_supported_formats - passthru_supported_schemes}" 64 + assert ( 65 + len(passthru_supported_schemes - expected_supported_formats) == 0 66 + ), f"libxcrypt package lists the following crypt schemes in passthru.enabledCryptSchemeIds that are not supported: {passthru_supported_schemes - expected_supported_formats}" 67 + 68 + 69 + if __name__ == "__main__": 70 + main()
+10 -3
pkgs/development/libraries/libxcrypt/default.nix
··· 2 2 # Update the enabled crypt scheme ids in passthru when the enabled hashes change 3 3 , enableHashes ? "strong" 4 4 , nixosTests 5 + , runCommand 6 + , python3 5 7 }: 6 8 7 - stdenv.mkDerivation rec { 9 + stdenv.mkDerivation (finalAttrs: { 8 10 pname = "libxcrypt"; 9 11 version = "4.4.33"; 10 12 11 13 src = fetchurl { 12 - url = "https://github.com/besser82/libxcrypt/releases/download/v${version}/libxcrypt-${version}.tar.xz"; 14 + url = "https://github.com/besser82/libxcrypt/releases/download/v${finalAttrs.version}/libxcrypt-${finalAttrs.version}.tar.xz"; 13 15 hash = "sha256-6HrPnGUsVzpHE9VYIVn5jzBdVu1fdUzmT1fUGU1rOm8="; 14 16 }; 15 17 ··· 37 39 passthru = { 38 40 tests = { 39 41 inherit (nixosTests) login shadow; 42 + 43 + passthruMatches = runCommand "libxcrypt-test-passthru-matches" { } '' 44 + ${python3.interpreter} "${./check_passthru_matches.py}" ${lib.escapeShellArgs ([ finalAttrs.src enableHashes "--" ] ++ finalAttrs.passthru.enabledCryptSchemeIds)} 45 + touch "$out" 46 + ''; 40 47 }; 41 48 enabledCryptSchemeIds = [ 42 49 # https://github.com/besser82/libxcrypt/blob/v4.4.33/lib/hashes.conf ··· 57 64 maintainers = with maintainers; [ dottedmag hexa ]; 58 65 license = licenses.lgpl21Plus; 59 66 }; 60 - } 67 + })