stages,sources/dnf: allow passing certificate data

Add support for dnf's sslcacert, sslclientcert, and sslclientkey
options. The latter two are passed as secrets (clientcert as well
because it might be a pem file that also includes the private key).

Sources run on the host, so their options may contain paths to the host
file system. Make use of that by accepting only paths in those options,
because it allows using tools to deal with certificate files.

Also make sure that the dnf source only returns options it knows about.
This commit is contained in:
Lars Karlitski 2020-01-06 23:49:14 +01:00 committed by Tom Gundersen
parent 12b5c6aaa4
commit 59ffebaff0
2 changed files with 37 additions and 8 deletions

View file

@ -4,20 +4,42 @@ import json
import sys
def main(options, sources):
def main(options, sources, secrets):
repos = options.get("repos", {})
repo_secrets = secrets.get("repos", {})
reply = []
for s in sources:
for checksum in sources:
try:
repo = {
"checksum": s,
**repos[s]
}
source_repo = repos[checksum]
source_repo_secrets = repo_secrets.get(checksum, {})
except KeyError:
json.dump({"error": f"source unknown: {s}"}, sys.stdout)
json.dump({"error": f"source unknown: {checksum}"}, sys.stdout)
return 1
repo = {"checksum": checksum}
if "baseurl" in source_repo:
repo["baseurl"] = source_repo["baseurl"]
elif "mirrorlist" in source_repo:
repo["mirrorlist"] = source_repo["mirrorlist"]
elif "metalink" in source_repo:
repo["metalink"] = source_repo["metalink"]
else:
json.dump({"error": f"repo {checksum} is missing baseurl, mirrorlist, or metalink key"}, sys.stdout)
if "sslcacert" in source_repo:
repo["sslcacert"] = source_repo["sslcacert"]
if "gpgkey" in source_repo:
repo["gpgkey"] = source_repo["gpgkey"]
if "sslclientcert" in source_repo_secrets:
repo["sslclientcert"] = source_repo_secrets["sslclientcert"]
if "sslclientkey" in source_repo_secrets:
repo["sslclientkey"] = source_repo_secrets["sslclientkey"]
reply.append(repo)
json.dump(reply, sys.stdout)
@ -26,5 +48,5 @@ def main(options, sources):
if __name__ == '__main__':
args = json.load(sys.stdin)
r = main(args["options"], args["checksums"])
r = main(args["options"], args["checksums"], args.get("secrets", {}))
sys.exit(r)

View file

@ -165,6 +165,13 @@ def write_repofile(f, repoid, repo, keydir):
if value:
write_option(key, value)
for cert in ("sslcacert", "sslclientcert", "sslclientkey"):
if cert in repo:
path = f"{keydir}/{cert}.pem"
with open(path, "w") as certfile:
certfile.write(repo[cert])
write_option(cert, path)
if "gpgkey" in repo:
keyfile = f"{keydir}/{repoid}.asc"
with open(keyfile, "w") as key: