From d3e5ca3472472d1d6f218f6dc88371a79557880e Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 3 May 2018 01:19:59 +0300 Subject: Add support for dependent repository trust --- libbpkg/manifest.cxx | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) (limited to 'libbpkg/manifest.cxx') diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index 78e3f2e..d14437b 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -17,7 +17,7 @@ #include #include #include // casecmp(), lcase(), alpha(), - // digit() + // digit(), xdigit() #include #include @@ -55,7 +55,7 @@ namespace bpkg if (s.size () != 64) return false; - for (const auto& c: s) + for (const char& c: s) { if ((c < 'a' || c > 'f' ) && !digit (c)) return false; @@ -64,6 +64,28 @@ namespace bpkg return true; } + inline static bool + valid_fingerprint (const string& s) noexcept + { + size_t n (s.size ()); + if (n != 32 * 3 - 1) + return false; + + for (size_t i (0); i != n; ++i) + { + char c (s[i]); + if ((i + 1) % 3 == 0) // Must be the colon, + { + if (c != ':') + return false; + } + else if (!xdigit (c)) // Must be a hex digit. + return false; + } + + return true; + } + template static string concatenate (const T& s, const char* delim = ", ") @@ -2610,6 +2632,16 @@ namespace bpkg r.certificate = move (v); } + else if (n == "trust") + { + if (r.trust) + bad_name ("trust redefinition"); + + if (!valid_fingerprint (v)) + bad_value ("invalid fingerprint"); + + r.trust = move (v); + } else if (n == "fragment") { if (r.fragment) @@ -2662,15 +2694,22 @@ namespace bpkg bad_value (e.what ()); } - // Verify that all non-optional values were specified. + // Verify that all non-optional values were specified and the optional ones + // are allowed. // // - location can be omitted // - role can be omitted + // - trust, url, email, summary, description and certificate are allowed // if (r.role && r.location.empty () != (*r.role == repository_role::base)) bad_value ("invalid role"); - if (r.effective_role () != repository_role::base) + bool base (r.effective_role () == repository_role::base); + + if (r.trust && (base || r.location.type () != repository_type::pkg)) + bad_value ("trust not allowed"); + + if (!base) { if (r.url) bad_value ("url not allowed"); @@ -2773,6 +2812,16 @@ namespace bpkg s.next ("certificate", *certificate); } + if (trust) + { + assert (b || !location.empty ()); + + if (b || location.type () != repository_type::pkg) + bad_value ("trust not allowed"); + + s.next ("trust", *trust); + } + if (fragment) s.next ("fragment", *fragment); -- cgit v1.1