summaryrefslogtreecommitdiff
path: root/apt-pkg/deb/debmetaindex.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-06-24 19:31:22 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-08-10 17:25:26 +0200
commitb0d408547734100bf86781615f546487ecf390d9 (patch)
tree8e88e2394ce15a4ac5a070b59a0cf4b74d748859 /apt-pkg/deb/debmetaindex.cc
parent0741daeb7ab870b4dd62a93fa12a1cf6330f9a72 (diff)
implement Signed-By option for sources.list
Limits which key(s) can be used to sign a repository. Not immensely useful from a security perspective all by itself, but if the user has additional measures in place to confine a repository (like pinning) an attacker who gets the key for such a repository is limited to its potential and can't use the key to sign its attacks for an other (maybe less limited) repository… (yes, this is as weak as it sounds, but having the capability might come in handy for implementing other stuff later).
Diffstat (limited to 'apt-pkg/deb/debmetaindex.cc')
-rw-r--r--apt-pkg/deb/debmetaindex.cc35
1 files changed, 35 insertions, 0 deletions
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index 5d7e539c7..4bb03a942 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -462,6 +462,29 @@ bool debReleaseIndex::SetValidUntilMax(time_t const Valid)
return _error->Error(_("Conflicting values set for option %s concerning source %s %s"), "Max-ValidTime", URI.c_str(), Dist.c_str());
return true;
}
+bool debReleaseIndex::SetSignedBy(std::string const &pSignedBy)
+{
+ if (SignedBy.empty() == true && pSignedBy.empty() == false)
+ {
+ if (pSignedBy[0] == '/') // no check for existence as we could be chrooting later or such things
+ ; // absolute path to a keyring file
+ else
+ {
+ // we could go all fancy and allow short/long/string matches as gpgv/apt-key does,
+ // but fingerprints are harder to fake than the others and this option is set once,
+ // not interactively all the time so easy to type is not really a concern.
+ std::string finger = pSignedBy;
+ finger.erase(std::remove(finger.begin(), finger.end(), ' '), finger.end());
+ std::transform(finger.begin(), finger.end(), finger.begin(), ::toupper);
+ if (finger.length() != 40 || finger.find_first_not_of("0123456789ABCDEF") != std::string::npos)
+ return _error->Error(_("Invalid value set for option %s concerning source %s %s (%s)"), "Signed-By", URI.c_str(), Dist.c_str(), "not a fingerprint");
+ }
+ SignedBy = pSignedBy;
+ }
+ else if (SignedBy != pSignedBy)
+ return _error->Error(_("Conflicting values set for option %s concerning source %s %s"), "Signed-By", URI.c_str(), Dist.c_str());
+ return true;
+}
/*}}}*/
// ReleaseIndex::IsTrusted /*{{{*/
bool debReleaseIndex::IsTrusted() const
@@ -706,6 +729,18 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/
Deb->SetValidUntilMin(GetTimeOption(Options, "valid-until-min")) == false)
return false;
+ std::map<std::string, std::string>::const_iterator const signedby = Options.find("signed-by");
+ if (signedby == Options.end())
+ {
+ if (Deb->SetSignedBy("") == false)
+ return false;
+ }
+ else
+ {
+ if (Deb->SetSignedBy(signedby->second) == false)
+ return false;
+ }
+
return true;
}