From 59ffebaff027c787e398f99da1bf9de33bd0678b Mon Sep 17 00:00:00 2001 From: Lars Karlitski Date: Mon, 6 Jan 2020 23:49:14 +0100 Subject: [PATCH] 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. --- sources/org.osbuild.dnf | 38 ++++++++++++++++++++++++++++++-------- stages/org.osbuild.dnf | 7 +++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/sources/org.osbuild.dnf b/sources/org.osbuild.dnf index ed060d31..d67e4dbb 100755 --- a/sources/org.osbuild.dnf +++ b/sources/org.osbuild.dnf @@ -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) diff --git a/stages/org.osbuild.dnf b/stages/org.osbuild.dnf index 64a7a921..092a097b 100755 --- a/stages/org.osbuild.dnf +++ b/stages/org.osbuild.dnf @@ -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: