feature(keyringctl): support passing fingerprint as source
This helps make the CLI more useful by listing, exporting or inspecting a specific fingerprint.
This commit is contained in:
parent
6d336828e1
commit
5249453726
18
README.md
18
README.md
@ -56,14 +56,9 @@ Export the whole keyring including main and packager to stdout
|
|||||||
./keyringctl export
|
./keyringctl export
|
||||||
```
|
```
|
||||||
|
|
||||||
Limit to specific usernames using an output file
|
Limit to specific certs using an output file
|
||||||
```bash
|
```bash
|
||||||
./keyringctl export <usernames...> --output <filename>
|
./keyringctl export <username_or_fingerprint_or_directory...> --output <filename>
|
||||||
```
|
|
||||||
|
|
||||||
Only export specific certificate directories in [keyring](keyring)
|
|
||||||
```bash
|
|
||||||
./keyringctl export <directory...>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### List
|
### List
|
||||||
@ -75,7 +70,7 @@ List all certificates in the keyring
|
|||||||
|
|
||||||
Only show a specific main key
|
Only show a specific main key
|
||||||
```bash
|
```bash
|
||||||
./keyringctl list --main <usernames...>
|
./keyringctl list --main <username_or_fingerprint...>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Inspect
|
### Inspect
|
||||||
@ -87,12 +82,7 @@ Inspect all certificates in the keyring
|
|||||||
|
|
||||||
Only inspect a specific main key
|
Only inspect a specific main key
|
||||||
```bash
|
```bash
|
||||||
./keyringctl inspect --main <usernames...>
|
./keyringctl inspect --main <username_or_fingerprint_or_directory...>
|
||||||
```
|
|
||||||
|
|
||||||
Specify directories to inspect a single fingerprint
|
|
||||||
```bash
|
|
||||||
./keyringctl inspect <directories...>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
60
keyringctl
60
keyringctl
@ -16,6 +16,7 @@ from os import chdir
|
|||||||
from os import getcwd
|
from os import getcwd
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from re import escape
|
from re import escape
|
||||||
|
from re import match
|
||||||
from re import split
|
from re import split
|
||||||
from re import sub
|
from re import sub
|
||||||
from shutil import copytree
|
from shutil import copytree
|
||||||
@ -128,6 +129,22 @@ def system(cmd: List[str], exit_on_error: bool = False) -> str:
|
|||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
|
def is_pgp_fingerprint(string: str) -> bool:
|
||||||
|
"""Returns whether the passed string looks like a PGP (long) fingerprint
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
string: Input to consider as a fingerprint
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
RWhether string is a fingerprint
|
||||||
|
"""
|
||||||
|
if len(string) not in [16, 40]:
|
||||||
|
return False
|
||||||
|
return match("^[A-F0-9]+$", string) is not None
|
||||||
|
|
||||||
|
|
||||||
def get_cert_paths(paths: Iterable[Path]) -> Set[Path]:
|
def get_cert_paths(paths: Iterable[Path]) -> Set[Path]:
|
||||||
"""Walks a list of paths and resolves all discovered certificate paths
|
"""Walks a list of paths and resolves all discovered certificate paths
|
||||||
|
|
||||||
@ -1018,7 +1035,8 @@ def export(
|
|||||||
----------
|
----------
|
||||||
working_dir: A directory to use for temporary files
|
working_dir: A directory to use for temporary files
|
||||||
keyring_root: The keyring root directory to look up username shorthand sources
|
keyring_root: The keyring root directory to look up username shorthand sources
|
||||||
sources: A list of directories or files from which to read PGP packet information (defaults to `keyring_root`)
|
sources: A list of username, fingerprint or directories from which to read PGP packet information
|
||||||
|
(defaults to `keyring_root`)
|
||||||
output: An output file that all PGP packet data is written to, return the result instead if None
|
output: An output file that all PGP packet data is written to, return the result instead if None
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@ -1031,9 +1049,17 @@ def export(
|
|||||||
|
|
||||||
# resolve shorthand username exports for packager keys
|
# resolve shorthand username exports for packager keys
|
||||||
for index, source in enumerate(sources):
|
for index, source in enumerate(sources):
|
||||||
|
if source.exists():
|
||||||
|
continue
|
||||||
packager_source = keyring_root / "packager" / source.name
|
packager_source = keyring_root / "packager" / source.name
|
||||||
if not source.exists() and packager_source.exists():
|
if packager_source.exists():
|
||||||
sources[index] = packager_source
|
sources[index] = packager_source
|
||||||
|
continue
|
||||||
|
if is_pgp_fingerprint(source.name):
|
||||||
|
fingerprint_paths = list(keyring_root.glob(f"*/*/*{source.name}"))
|
||||||
|
if fingerprint_paths:
|
||||||
|
sources[index] = fingerprint_paths[0]
|
||||||
|
continue
|
||||||
|
|
||||||
temp_dir = Path(mkdtemp(dir=working_dir, prefix="arch-keyringctl-export-join-")).absolute()
|
temp_dir = Path(mkdtemp(dir=working_dir, prefix="arch-keyringctl-export-join-")).absolute()
|
||||||
cert_paths: Set[Path] = get_cert_paths(sources)
|
cert_paths: Set[Path] = get_cert_paths(sources)
|
||||||
@ -1090,7 +1116,7 @@ def list_keyring(keyring_root: Path, sources: Optional[List[Path]] = None, main_
|
|||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
keyring_root: Path The keyring root directory to look up username shorthand sources
|
keyring_root: Path The keyring root directory to look up username shorthand sources
|
||||||
sources: A list of username or files/directories from which to read PGP packet information
|
sources: A list of username, fingerprint or directories from which to read PGP packet information
|
||||||
(defaults to `keyring_root`)
|
(defaults to `keyring_root`)
|
||||||
main_keys: List main keys instead of packager keys (defaults to False)
|
main_keys: List main keys instead of packager keys (defaults to False)
|
||||||
"""
|
"""
|
||||||
@ -1102,9 +1128,17 @@ def list_keyring(keyring_root: Path, sources: Optional[List[Path]] = None, main_
|
|||||||
|
|
||||||
# resolve shorthand username exports for packager keys
|
# resolve shorthand username exports for packager keys
|
||||||
for index, source in enumerate(sources):
|
for index, source in enumerate(sources):
|
||||||
|
if source.exists():
|
||||||
|
continue
|
||||||
packager_source = keyring_dir / source.name
|
packager_source = keyring_dir / source.name
|
||||||
if not source.exists() and packager_source.exists():
|
if packager_source.exists():
|
||||||
sources[index] = packager_source
|
sources[index] = packager_source
|
||||||
|
continue
|
||||||
|
if is_pgp_fingerprint(source.name):
|
||||||
|
fingerprint_paths = list(keyring_root.glob(f"*/*/*{source.name}"))
|
||||||
|
if fingerprint_paths:
|
||||||
|
sources[index] = fingerprint_paths[0].parent
|
||||||
|
continue
|
||||||
|
|
||||||
username_length = max([len(source.name) for source in sources])
|
username_length = max([len(source.name) for source in sources])
|
||||||
|
|
||||||
@ -1122,7 +1156,7 @@ def inspect_keyring(working_dir: Path, keyring_root: Path, sources: Optional[Lis
|
|||||||
----------
|
----------
|
||||||
working_dir: A directory to use for temporary files
|
working_dir: A directory to use for temporary files
|
||||||
keyring_root: The keyring root directory to look up username shorthand sources
|
keyring_root: The keyring root directory to look up username shorthand sources
|
||||||
sources: A list of username or files/directories from which to read PGP packet information
|
sources: A list of username, fingerprint or directories from which to read PGP packet information
|
||||||
(defaults to `keyring_root`)
|
(defaults to `keyring_root`)
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@ -1135,9 +1169,17 @@ def inspect_keyring(working_dir: Path, keyring_root: Path, sources: Optional[Lis
|
|||||||
|
|
||||||
# resolve shorthand username exports for packager keys
|
# resolve shorthand username exports for packager keys
|
||||||
for index, source in enumerate(sources):
|
for index, source in enumerate(sources):
|
||||||
|
if source.exists():
|
||||||
|
continue
|
||||||
packager_source = keyring_root / "packager" / source.name
|
packager_source = keyring_root / "packager" / source.name
|
||||||
if not source.exists() and packager_source.exists():
|
if packager_source.exists():
|
||||||
sources[index] = packager_source
|
sources[index] = packager_source
|
||||||
|
continue
|
||||||
|
if is_pgp_fingerprint(source.name):
|
||||||
|
fingerprint_paths = list(keyring_root.glob(f"*/*/*{source.name}"))
|
||||||
|
if fingerprint_paths:
|
||||||
|
sources[index] = fingerprint_paths[0]
|
||||||
|
continue
|
||||||
|
|
||||||
keyring = Path(mkstemp(dir=working_dir, prefix="packet-", suffix=".asc")[1]).absolute()
|
keyring = Path(mkstemp(dir=working_dir, prefix="packet-", suffix=".asc")[1]).absolute()
|
||||||
export(working_dir=working_dir, keyring_root=keyring_root, sources=sources, output=keyring)
|
export(working_dir=working_dir, keyring_root=keyring_root, sources=sources, output=keyring)
|
||||||
@ -1213,7 +1255,7 @@ if __name__ == "__main__":
|
|||||||
export_parser.add_argument(
|
export_parser.add_argument(
|
||||||
"source",
|
"source",
|
||||||
nargs="*",
|
nargs="*",
|
||||||
help="username or files/directories containing PGP packet data (can be provided multiple times)",
|
help="username, fingerprint or directories containing certificates",
|
||||||
type=absolute_path,
|
type=absolute_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1230,7 +1272,7 @@ if __name__ == "__main__":
|
|||||||
list_parser.add_argument(
|
list_parser.add_argument(
|
||||||
"source",
|
"source",
|
||||||
nargs="*",
|
nargs="*",
|
||||||
help="username or files/directories containing certificates (can be provided multiple times)",
|
help="username, fingerprint or directories containing certificates",
|
||||||
type=absolute_path,
|
type=absolute_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1241,7 +1283,7 @@ if __name__ == "__main__":
|
|||||||
inspect_parser.add_argument(
|
inspect_parser.add_argument(
|
||||||
"source",
|
"source",
|
||||||
nargs="*",
|
nargs="*",
|
||||||
help="username or directories containing certificates",
|
help="username, fingerprint or directories containing certificates",
|
||||||
type=absolute_path,
|
type=absolute_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user