From 23e64f6d0facf9610c1042326ad9850e071e8349 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 4 Nov 2015 14:48:36 +0100 Subject: allow acquire method specific options via Binary scope Allows users who know what they are getting themselves into with this trick to e.g. disable privilege dropping for e.g. file:// until they can fix up the permissions on those repositories. It helps also the test framework and people with a similar setup (= me) to run in less modified environments. --- methods/aptmethod.h | 51 +++++++++++++++++++++++++--------------------- methods/ftp.cc | 9 +++----- methods/ftp.h | 3 ++- methods/gpgv.cc | 16 +++------------ methods/gzip.cc | 31 ++++++++-------------------- methods/http.h | 2 +- methods/https.h | 2 +- methods/rred.cc | 15 +++----------- methods/rsh.cc | 18 +++++++--------- methods/rsh.h | 6 ++++-- methods/server.cc | 15 ++------------ methods/server.h | 6 +++--- test/integration/framework | 14 ++++++------- 13 files changed, 72 insertions(+), 116 deletions(-) diff --git a/methods/aptmethod.h b/methods/aptmethod.h index 61d7b78f1..7f7f31dba 100644 --- a/methods/aptmethod.h +++ b/methods/aptmethod.h @@ -2,36 +2,41 @@ #define APT_APTMETHOD_H #include +#include #include class aptMethod : public pkgAcqMethod { char const * const Binary; - public: - virtual bool Configuration(std::string Message) APT_OVERRIDE; - bool CalculateHashes(FetchItem const * const Itm, FetchResult &Res) const; - - aptMethod(char const * const Binary, char const * const Ver, unsigned long const Flags) : pkgAcqMethod(Ver, Flags), Binary(Binary) {}; +public: + virtual bool Configuration(std::string Message) APT_OVERRIDE + { + if (pkgAcqMethod::Configuration(Message) == false) + return false; + + std::string const conf = std::string("Binary::") + Binary; + _config->MoveSubTree(conf.c_str(), NULL); + + DropPrivsOrDie(); + + return true; + } + + bool CalculateHashes(FetchItem const * const Itm, FetchResult &Res) const + { + Hashes Hash(Itm->ExpectedHashes); + FileFd Fd; + if (Fd.Open(Res.Filename, FileFd::ReadOnly) == false || Hash.AddFD(Fd) == false) + return false; + Res.TakeHashes(Hash); + return true; + } + + aptMethod(char const * const Binary, char const * const Ver, unsigned long const Flags) : + pkgAcqMethod(Ver, Flags), Binary(Binary) + {} }; -bool aptMethod::Configuration(std::string Message) -{ - if (pkgAcqMethod::Configuration(Message) == false) - return false; - - DropPrivsOrDie(); - - return true; -} -bool aptMethod::CalculateHashes(FetchItem const * const Itm, FetchResult &Res) const -{ - Hashes Hash(Itm->ExpectedHashes); - FileFd Fd; - if (Fd.Open(Res.Filename, FileFd::ReadOnly) == false || Hash.AddFD(Fd) == false) - return false; - Res.TakeHashes(Hash); - return true; -} #endif diff --git a/methods/ftp.cc b/methods/ftp.cc index 360333107..a8bc95938 100644 --- a/methods/ftp.cc +++ b/methods/ftp.cc @@ -950,7 +950,7 @@ bool FTPConn::Get(const char *Path,FileFd &To,unsigned long long Resume, // FtpMethod::FtpMethod - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -FtpMethod::FtpMethod() : pkgAcqMethod("1.0",SendConfig) +FtpMethod::FtpMethod() : aptMethod("ftp","1.0",SendConfig) { signal(SIGTERM,SigTerm); signal(SIGINT,SigTerm); @@ -985,13 +985,10 @@ void FtpMethod::SigTerm(int) /* We stash the desired pipeline depth */ bool FtpMethod::Configuration(string Message) { - if (pkgAcqMethod::Configuration(Message) == false) + if (aptMethod::Configuration(Message) == false) return false; - - TimeOut = _config->FindI("Acquire::Ftp::Timeout",TimeOut); - // no more active ftp, sorry - DropPrivsOrDie(); + TimeOut = _config->FindI("Acquire::Ftp::Timeout",TimeOut); return true; } diff --git a/methods/ftp.h b/methods/ftp.h index 2c4e9f57a..c5165782d 100644 --- a/methods/ftp.h +++ b/methods/ftp.h @@ -12,6 +12,7 @@ #include #include +#include "aptmethod.h" #include #include @@ -71,7 +72,7 @@ class FTPConn ~FTPConn(); }; -class FtpMethod : public pkgAcqMethod +class FtpMethod : public aptMethod { virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE; virtual bool Configuration(std::string Message) APT_OVERRIDE; diff --git a/methods/gpgv.cc b/methods/gpgv.cc index 490833d8c..f17990245 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -6,6 +6,7 @@ #include #include #include +#include "aptmethod.h" #include #include @@ -35,7 +36,7 @@ using std::vector; #define GNUPGREVKEYSIG "[GNUPG:] REVKEYSIG" #define GNUPGNODATA "[GNUPG:] NODATA" -class GPGVMethod : public pkgAcqMethod +class GPGVMethod : public aptMethod { private: string VerifyGetSigners(const char *file, const char *outfile, @@ -47,22 +48,11 @@ class GPGVMethod : public pkgAcqMethod protected: virtual bool URIAcquire(std::string const &Message, FetchItem *Itm) APT_OVERRIDE; - virtual bool Configuration(string Message) APT_OVERRIDE; public: - GPGVMethod() : pkgAcqMethod("1.0",SingleInstance | SendConfig) {}; + GPGVMethod() : aptMethod("gpgv","1.0",SingleInstance | SendConfig) {}; }; -bool GPGVMethod::Configuration(string Message) -{ - if (pkgAcqMethod::Configuration(Message) == false) - return false; - - DropPrivsOrDie(); - - return true; -} - string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, std::string const &key, vector &GoodSigners, diff --git a/methods/gzip.cc b/methods/gzip.cc index 2429069e5..fbfd3bbac 100644 --- a/methods/gzip.cc +++ b/methods/gzip.cc @@ -18,6 +18,7 @@ #include #include #include +#include "aptmethod.h" #include #include @@ -28,27 +29,15 @@ #include /*}}}*/ -const char *Prog; - -class GzipMethod : public pkgAcqMethod +class GzipMethod : public aptMethod { + std::string const Prog; virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE; - virtual bool Configuration(std::string Message) APT_OVERRIDE; - - public: - - GzipMethod() : pkgAcqMethod("1.1",SingleInstance | SendConfig) {}; -}; - -bool GzipMethod::Configuration(std::string Message) -{ - if (pkgAcqMethod::Configuration(Message) == false) - return false; - DropPrivsOrDie(); + public: - return true; -} + GzipMethod(std::string const &pProg) : aptMethod(pProg.c_str(),"1.1",SingleInstance | SendConfig), Prog(pProg) {}; +}; // GzipMethod::Fetch - Decompress the passed URI /*{{{*/ // --------------------------------------------------------------------- @@ -68,7 +57,7 @@ bool GzipMethod::Fetch(FetchItem *Itm) if (compressor->Name == Prog) break; if (compressor == compressors.end()) - return _error->Error("Extraction of file %s requires unknown compressor %s", Path.c_str(), Prog); + return _error->Error("Extraction of file %s requires unknown compressor %s", Path.c_str(), Prog.c_str()); // Open the source and destination files FileFd From; @@ -157,10 +146,6 @@ int main(int, char *argv[]) { setlocale(LC_ALL, ""); - Prog = strrchr(argv[0],'/'); - ++Prog; - - GzipMethod Mth; - + GzipMethod Mth(flNotDir(argv[0])); return Mth.Run(); } diff --git a/methods/http.h b/methods/http.h index e06a046ef..7b7e78b64 100644 --- a/methods/http.h +++ b/methods/http.h @@ -137,7 +137,7 @@ class HttpMethod : public ServerMethod public: friend struct HttpServerState; - HttpMethod() : ServerMethod("1.2",Pipeline | SendConfig) + HttpMethod() : ServerMethod("http", "1.2",Pipeline | SendConfig) { File = 0; Server = 0; diff --git a/methods/https.h b/methods/https.h index 167107ad6..0147f96a0 100644 --- a/methods/https.h +++ b/methods/https.h @@ -82,7 +82,7 @@ class HttpsMethod : public ServerMethod using pkgAcqMethod::FetchResult; using pkgAcqMethod::FetchItem; - HttpsMethod() : ServerMethod("1.2",Pipeline | SendConfig), File(NULL) + HttpsMethod() : ServerMethod("https","1.2",Pipeline | SendConfig), File(NULL) { curl = curl_easy_init(); }; diff --git a/methods/rred.cc b/methods/rred.cc index d2cefc943..b379d384d 100644 --- a/methods/rred.cc +++ b/methods/rred.cc @@ -13,6 +13,7 @@ #include #include #include +#include "aptmethod.h" #include #include @@ -532,7 +533,7 @@ class Patch { } }; -class RredMethod : public pkgAcqMethod { +class RredMethod : public aptMethod { private: bool Debug; @@ -680,18 +681,8 @@ class RredMethod : public pkgAcqMethod { return true; } - bool Configuration(std::string Message) APT_OVERRIDE - { - if (pkgAcqMethod::Configuration(Message) == false) - return false; - - DropPrivsOrDie(); - - return true; - } - public: - RredMethod() : pkgAcqMethod("2.0",SingleInstance | SendConfig), Debug(false) {} + RredMethod() : aptMethod("rred", "2.0",SingleInstance | SendConfig), Debug(false) {} }; int main(int argc, char **argv) diff --git a/methods/rsh.cc b/methods/rsh.cc index 44aa7084d..bcd688833 100644 --- a/methods/rsh.cc +++ b/methods/rsh.cc @@ -387,7 +387,7 @@ bool RSHConn::Get(const char *Path,FileFd &To,unsigned long long Resume, // RSHMethod::RSHMethod - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -RSHMethod::RSHMethod() : pkgAcqMethod("1.0",SendConfig) +RSHMethod::RSHMethod(std::string const &pProg) : aptMethod(pProg.c_str(),"1.0",SendConfig), Prog(pProg) { signal(SIGTERM,SigTerm); signal(SIGINT,SigTerm); @@ -399,15 +399,13 @@ RSHMethod::RSHMethod() : pkgAcqMethod("1.0",SendConfig) // --------------------------------------------------------------------- bool RSHMethod::Configuration(std::string Message) { - char ProgStr[100]; - - if (pkgAcqMethod::Configuration(Message) == false) + if (aptMethod::Configuration(Message) == false) return false; - snprintf(ProgStr, sizeof ProgStr, "Acquire::%s::Timeout", Prog); - TimeOut = _config->FindI(ProgStr,TimeOut); - snprintf(ProgStr, sizeof ProgStr, "Acquire::%s::Options", Prog); - RshOptions = _config->Tree(ProgStr); + std::string const timeconf = std::string("Acquire::") + Prog + "::Timeout"; + TimeOut = _config->FindI(timeconf, TimeOut); + std::string const optsconf = std::string("Acquire::") + Prog + "::Options"; + RshOptions = _config->Tree(optsconf.c_str()); return true; } @@ -548,8 +546,6 @@ int main(int, const char *argv[]) { setlocale(LC_ALL, ""); - RSHMethod Mth; - Prog = strrchr(argv[0],'/'); - Prog++; + RSHMethod Mth(flNotDir(argv[0])); return Mth.Run(); } diff --git a/methods/rsh.h b/methods/rsh.h index e6839711b..9ca14425f 100644 --- a/methods/rsh.h +++ b/methods/rsh.h @@ -54,9 +54,11 @@ class RSHConn }; #include +#include "aptmethod.h" -class RSHMethod : public pkgAcqMethod +class RSHMethod : public aptMethod { + std::string const Prog; virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE; virtual bool Configuration(std::string Message) APT_OVERRIDE; @@ -69,7 +71,7 @@ class RSHMethod : public pkgAcqMethod public: - RSHMethod(); + RSHMethod(std::string const &Prog); }; #endif diff --git a/methods/server.cc b/methods/server.cc index 650a4aeb8..e89af2dfe 100644 --- a/methods/server.cc +++ b/methods/server.cc @@ -252,17 +252,6 @@ bool ServerState::AddPartialFileToHashes(FileFd &File) /*{{{*/ } /*}}}*/ -bool ServerMethod::Configuration(string Message) /*{{{*/ -{ - if (pkgAcqMethod::Configuration(Message) == false) - return false; - - DropPrivsOrDie(); - - return true; -} - /*}}}*/ - // ServerMethod::DealWithHeaders - Handle the retrieved header data /*{{{*/ // --------------------------------------------------------------------- /* We look at the header data we got back from the server and decide what @@ -753,8 +742,8 @@ unsigned long long ServerMethod::FindMaximumObjectSizeInQueue() const /*{{{*/ return MaxSizeInQueue; } /*}}}*/ -ServerMethod::ServerMethod(const char *Ver,unsigned long Flags) : /*{{{*/ - pkgAcqMethod(Ver, Flags), Server(nullptr), File(NULL), PipelineDepth(10), +ServerMethod::ServerMethod(char const * const Binary, char const * const Ver,unsigned long const Flags) :/*{{{*/ + aptMethod(Binary, Ver, Flags), Server(nullptr), File(NULL), PipelineDepth(10), AllowRedirect(false), Debug(false) { } diff --git a/methods/server.h b/methods/server.h index 5de7686d9..365bc0879 100644 --- a/methods/server.h +++ b/methods/server.h @@ -13,6 +13,7 @@ #include #include +#include "aptmethod.h" #include #include @@ -104,7 +105,7 @@ struct ServerState virtual ~ServerState() {}; }; -class ServerMethod : public pkgAcqMethod +class ServerMethod : public aptMethod { protected: virtual bool Fetch(FetchItem *) APT_OVERRIDE; @@ -147,7 +148,6 @@ class ServerMethod : public pkgAcqMethod static time_t FailTime; static APT_NORETURN void SigTerm(int); - virtual bool Configuration(std::string Message) APT_OVERRIDE; virtual bool Flush() { return Server->Flush(File); }; int Loop(); @@ -156,7 +156,7 @@ class ServerMethod : public pkgAcqMethod virtual std::unique_ptr CreateServerState(URI const &uri) = 0; virtual void RotateDNS() = 0; - ServerMethod(const char *Ver,unsigned long Flags = 0); + ServerMethod(char const * const Binary, char const * const Ver,unsigned long const Flags); virtual ~ServerMethod() {}; }; diff --git a/test/integration/framework b/test/integration/framework index f1e2fa090..70f06158d 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -317,14 +317,14 @@ setupenvironment() { echo "Dir::state::status \"${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status\";" >> aptconfig.conf echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf echo "Dir::Bin::Methods \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/methods\";" >> aptconfig.conf - # store apt-key were we can access it, even if we run it as a different user - # destroys coverage reporting though, so just do it for root for now + # either store apt-key were we can access it, even if we run it as a different user + #cp "${BUILDDIRECTORY}/apt-key" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" + #chmod o+rx "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key" + #echo "Dir::Bin::apt-key \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key\";" >> aptconfig.conf + # destroys coverage reporting though, so we disable changing user for the calling gpgv + echo "Dir::Bin::apt-key \"${BUILDDIRECTORY}/apt-key\";" >> aptconfig.conf if [ "$(id -u)" = '0' ]; then - cp "${BUILDDIRECTORY}/apt-key" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" - chmod o+rx "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key" - echo "Dir::Bin::apt-key \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key\";" >> aptconfig.conf - else - echo "Dir::Bin::apt-key \"${BUILDDIRECTORY}/apt-key\";" >> aptconfig.conf + echo 'Binary::gpgv::Debug::NoDropPrivs "true";' >>aptconfig.conf fi cat > "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" <