aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbpkg/manifest.cxx57
-rw-r--r--libbpkg/manifest.hxx6
-rw-r--r--tests/manifest/testscript3
3 files changed, 62 insertions, 4 deletions
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 <libbutl/path.mxx>
#include <libbutl/base64.mxx>
#include <libbutl/utility.mxx> // casecmp(), lcase(), alpha(),
- // digit()
+ // digit(), xdigit()
#include <libbutl/manifest-parser.mxx>
#include <libbutl/manifest-serializer.mxx>
@@ -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 <typename T>
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);
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index 68c4bc7..15d19fc 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -905,6 +905,12 @@ namespace bpkg
butl::optional<std::string> description;
butl::optional<std::string> certificate;
+ // The repository fingerprint to trust. May only be present for the
+ // prerequisite or complement repository and only for repository types
+ // that support authentication (currently only pkg).
+ //
+ butl::optional<std::string> trust;
+
// The repository fragment id this repository belongs to (may only be
// present for multi-fragment repositories).
//
diff --git a/tests/manifest/testscript b/tests/manifest/testscript
index d3fe1a7..b08206a 100644
--- a/tests/manifest/testscript
+++ b/tests/manifest/testscript
@@ -199,6 +199,7 @@
:
location: http://pkg.example.org/1/bar
role: prerequisite
+ trust: 37:CE:2C:A5:1D:CF:93:81:D7:07:46:AD:66:B3:C3:90:83:B8:96:9E:34:F0:E7:B3:A2:B0:6C:EF:66:A4:BE:65
:
url: http://cppget.org
EOI
@@ -218,6 +219,8 @@
location: http://pkg.example.org/1/bar
type: pkg
role: prerequisite
+ trust: 37:CE:2C:A5:1D:CF:93:81:D7:07:46:AD:66:B3:C3:90:83:B8:96:9E:34:F0:E7:B\
+ 3:A2:B0:6C:EF:66:A4:BE:65
:
url: http://cppget.org
EOO