e55042e45b
This moves all verify code to an own module and adds support to check all packet files in the structure for integrity. This is done by parsing assumptions like packet kind, type, issuer and location etc.
208 lines
7.1 KiB
Python
208 lines
7.1 KiB
Python
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from argparse import ArgumentParser
|
|
from logging import DEBUG
|
|
from logging import basicConfig
|
|
from logging import debug
|
|
from pathlib import Path
|
|
from tempfile import TemporaryDirectory
|
|
from tempfile import mkdtemp
|
|
|
|
from .ci import ci
|
|
from .keyring import Username
|
|
from .keyring import build
|
|
from .keyring import convert
|
|
from .keyring import export
|
|
from .keyring import inspect_keyring
|
|
from .keyring import list_keyring
|
|
from .util import absolute_path
|
|
from .util import cwd
|
|
from .verify import verify
|
|
|
|
parser = ArgumentParser()
|
|
parser.add_argument(
|
|
"-v", "--verbose", action="store_true", help="Causes to print debugging messages about the progress"
|
|
)
|
|
parser.add_argument("--wait", action="store_true", help="Block before cleaning up the temp directory")
|
|
parser.add_argument(
|
|
"-f",
|
|
"--force",
|
|
action="store_true",
|
|
default=False,
|
|
help="force the execution of subcommands (e.g. overwriting of files)",
|
|
)
|
|
subcommands = parser.add_subparsers(dest="subcommand")
|
|
|
|
convert_parser = subcommands.add_parser(
|
|
"convert",
|
|
help="convert one or multiple PGP public keys to a decomposed directory structure",
|
|
)
|
|
convert_parser.add_argument("source", type=absolute_path, nargs="+", help="Files or directorie to convert")
|
|
convert_parser.add_argument("--target", type=absolute_path, help="Target directory instead of a random tmpdir")
|
|
convert_parser.add_argument(
|
|
"--name",
|
|
type=Username,
|
|
default=None,
|
|
help="override the username to use (only useful when using a single file as source)",
|
|
)
|
|
|
|
import_parser = subcommands.add_parser(
|
|
"import",
|
|
help="import one or several PGP keys to the keyring directory structure",
|
|
)
|
|
import_parser.add_argument("source", type=absolute_path, nargs="+", help="Files or directories to import")
|
|
import_parser.add_argument(
|
|
"--name",
|
|
type=Username,
|
|
default=None,
|
|
help="override the username to use (only useful when using a single file as source)",
|
|
)
|
|
import_parser.add_argument("--main", action="store_true", help="Import a main signing key into the keyring")
|
|
|
|
export_parser = subcommands.add_parser(
|
|
"export",
|
|
help="export a directory structure of PGP packet data to a combined file",
|
|
)
|
|
export_parser.add_argument("-o", "--output", type=absolute_path, help="file to write PGP packet data to")
|
|
export_parser.add_argument(
|
|
"source",
|
|
nargs="*",
|
|
help="username, fingerprint or directories containing certificates",
|
|
type=absolute_path,
|
|
)
|
|
|
|
build_parser = subcommands.add_parser(
|
|
"build",
|
|
help="build keyring PGP artifacts alongside ownertrust and revoked status files",
|
|
)
|
|
|
|
list_parser = subcommands.add_parser(
|
|
"list",
|
|
help="list the certificates in the keyring",
|
|
)
|
|
list_parser.add_argument("--main", action="store_true", help="List main signing keys instead of packager keys")
|
|
list_parser.add_argument(
|
|
"source",
|
|
nargs="*",
|
|
help="username, fingerprint or directories containing certificates",
|
|
type=absolute_path,
|
|
)
|
|
|
|
inspect_parser = subcommands.add_parser(
|
|
"inspect",
|
|
help="inspect certificates in the keyring and pretty print the data",
|
|
)
|
|
inspect_parser.add_argument(
|
|
"source",
|
|
nargs="*",
|
|
help="username, fingerprint or directories containing certificates",
|
|
type=absolute_path,
|
|
)
|
|
|
|
verify_parser = subcommands.add_parser(
|
|
"verify",
|
|
help="verify certificates against modern expectations",
|
|
)
|
|
verify_parser.add_argument(
|
|
"source",
|
|
nargs="*",
|
|
help="username, fingerprint or directories containing certificates",
|
|
type=absolute_path,
|
|
)
|
|
verify_parser.add_argument("--no-lint-hokey", dest="lint_hokey", action="store_false", help="Do not run hokey lint")
|
|
verify_parser.add_argument(
|
|
"--no-lint-sq-keyring", dest="lint_sq_keyring", action="store_false", help="Do not run sq-keyring-linter"
|
|
)
|
|
verify_parser.set_defaults(lint_hokey=True, lint_sq_keyring=True)
|
|
|
|
ci_parser = subcommands.add_parser(
|
|
"ci",
|
|
help="ci command to verify certain aspects and expectations in pipelines",
|
|
)
|
|
|
|
|
|
def main() -> None: # noqa: ignore=C901
|
|
args = parser.parse_args()
|
|
|
|
if args.verbose:
|
|
basicConfig(level=DEBUG)
|
|
|
|
# temporary working directory that gets auto cleaned
|
|
with TemporaryDirectory(prefix="arch-keyringctl-") as tempdir:
|
|
project_root = Path(".").absolute()
|
|
keyring_root = Path("keyring").absolute()
|
|
working_dir = Path(tempdir)
|
|
debug(f"Working directory: {working_dir}")
|
|
with cwd(working_dir):
|
|
if "convert" == args.subcommand:
|
|
target_dir = args.target or Path(mkdtemp(prefix="arch-keyringctl-")).absolute()
|
|
print(
|
|
convert(
|
|
working_dir=working_dir,
|
|
keyring_root=keyring_root,
|
|
sources=args.source,
|
|
target_dir=target_dir,
|
|
name_override=args.name,
|
|
)
|
|
)
|
|
elif "import" == args.subcommand:
|
|
target_dir = "main" if args.main else "packager"
|
|
print(
|
|
convert(
|
|
working_dir=working_dir,
|
|
keyring_root=keyring_root,
|
|
sources=args.source,
|
|
target_dir=keyring_root / target_dir,
|
|
name_override=args.name,
|
|
)
|
|
)
|
|
elif "export" == args.subcommand:
|
|
result = export(
|
|
working_dir=working_dir,
|
|
keyring_root=keyring_root,
|
|
sources=args.source,
|
|
output=args.output,
|
|
)
|
|
if result:
|
|
print(
|
|
result,
|
|
end="",
|
|
)
|
|
elif "build" == args.subcommand:
|
|
build(
|
|
working_dir=working_dir,
|
|
keyring_root=keyring_root,
|
|
target_dir=keyring_root.parent / "build",
|
|
)
|
|
elif "list" == args.subcommand:
|
|
list_keyring(
|
|
keyring_root=keyring_root,
|
|
sources=args.source,
|
|
main_keys=args.main,
|
|
)
|
|
elif "inspect" == args.subcommand:
|
|
print(
|
|
inspect_keyring(
|
|
working_dir=working_dir,
|
|
keyring_root=keyring_root,
|
|
sources=args.source,
|
|
),
|
|
end="",
|
|
)
|
|
elif "verify" == args.subcommand:
|
|
verify(
|
|
working_dir=working_dir,
|
|
keyring_root=keyring_root,
|
|
sources=args.source,
|
|
lint_hokey=args.lint_hokey,
|
|
lint_sq_keyring=args.lint_sq_keyring,
|
|
)
|
|
elif "ci" == args.subcommand:
|
|
ci(working_dir=working_dir, keyring_root=keyring_root, project_root=project_root)
|
|
else:
|
|
parser.print_help()
|
|
|
|
if args.wait:
|
|
print("Press [ENTER] to continue")
|
|
input()
|