]> git.saurik.com Git - apt.git/commitdiff
Merge remote-tracking branch 'mvo/feature/drop-rights' into debian/experimental
authorMichael Vogt <mvo@debian.org>
Wed, 18 Jun 2014 08:47:19 +0000 (10:47 +0200)
committerMichael Vogt <mvo@debian.org>
Wed, 18 Jun 2014 08:47:57 +0000 (10:47 +0200)
Conflicts:
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h

1  2 
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h

index 29450ada05adb2fe4d0f3a4734726d2fcba5dfd7,da81edbcc9e54413eec1722dc993dd2f153681ae..6b8f04dea1519f5206f6385f551dc92cf0764d81
@@@ -47,6 -47,7 +47,7 @@@
  #include <signal.h>
  #include <errno.h>
  #include <glob.h>
+ #include <pwd.h>
  
  #include <set>
  #include <algorithm>
@@@ -656,22 -657,6 +657,22 @@@ string flCombine(string Dir,string File
     return Dir + '/' + File;
  }
                                                                        /*}}}*/
 +// flAbsPath - Return the absolute path of the filename                       /*{{{*/
 +// ---------------------------------------------------------------------
 +/* */
 +string flAbsPath(string File)
 +{
 +   char *p = realpath(File.c_str(), NULL);
 +   if (p == NULL)
 +   {
 +      _error->Errno("realpath", "flAbsPath failed");
 +      return "";
 +   }
 +   std::string AbsPath(p);
 +   free(p);
 +   return AbsPath;
 +}
 +                                                                      /*}}}*/
  // SetCloseExec - Set the close on exec flag                          /*{{{*/
  // ---------------------------------------------------------------------
  /* */
@@@ -852,27 -837,6 +853,27 @@@ bool ExecWait(pid_t Pid,const char *Nam
  }
                                                                        /*}}}*/
  
 +
 +// StartsWithGPGClearTextSignature - Check if a file is Pgp/GPG clearsigned     /*{{{*/
 +// ---------------------------------------------------------------------
 +/* */
 +bool StartsWithGPGClearTextSignature(string const &FileName)
 +{
 +   static const char* SIGMSG = "-----BEGIN PGP SIGNED MESSAGE-----\n";
 +   char buffer[strlen(SIGMSG)+1];
 +   FILE* gpg = fopen(FileName.c_str(), "r");
 +   if (gpg == NULL)
 +      return false;
 +
 +   char const * const test = fgets(buffer, sizeof(buffer), gpg);
 +   fclose(gpg);
 +   if (test == NULL || strcmp(buffer, SIGMSG) != 0)
 +      return false;
 +
 +   return true;
 +}
 +
 +
  class FileFdPrivate {                                                 /*{{{*/
        public:
  #ifdef HAVE_ZLIB
@@@ -1950,6 -1914,7 +1951,6 @@@ bool FileFd::Close(
     {
        if ((Flags & Compressed) != Compressed && iFd > 0 && close(iFd) != 0)
         Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());
 -
        if (d != NULL)
        {
         Res &= d->CloseDown(FileName);
@@@ -2076,31 -2041,6 +2077,31 @@@ std::string GetTempDir(
     return string(tmpdir);
  }
  
 +FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink)
 +{
 +   char fn[512];
 +   FileFd *Fd = new FileFd();
 +
 +   std::string tempdir = GetTempDir();
 +   snprintf(fn, sizeof(fn), "%s/%s.XXXXXX", 
 +            tempdir.c_str(), Prefix.c_str());
 +   int fd = mkstemp(fn);
 +   if(ImmediateUnlink)
 +      unlink(fn);
 +   if (fd < 0) 
 +   {
 +      _error->Errno("GetTempFile",_("Unable to mkstemp %s"), fn);
 +      return NULL;
 +   }
 +   if (!Fd->OpenDescriptor(fd, FileFd::WriteOnly, FileFd::None, true))
 +   {
 +      _error->Errno("GetTempFile",_("Unable to write to %s"),fn);
 +      return NULL;
 +   }
 +
 +   return Fd;
 +}
 +
  bool Rename(std::string From, std::string To)
  {
     if (rename(From.c_str(),To.c_str()) != 0)
     return true;
  }
  
 +bool Popen(const char* Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode)
 +{
 +   int fd;
 +   if (Mode != FileFd::ReadOnly && Mode != FileFd::WriteOnly)
 +      return _error->Error("Popen supports ReadOnly (x)or WriteOnly mode only");
 +
 +   int Pipe[2] = {-1, -1};
 +   if(pipe(Pipe) != 0)
 +   {
 +      return _error->Errno("pipe", _("Failed to create subprocess IPC"));
 +      return NULL;
 +   }
 +   std::set<int> keep_fds;
 +   keep_fds.insert(Pipe[0]);
 +   keep_fds.insert(Pipe[1]);
 +   Child = ExecFork(keep_fds);
 +   if(Child < 0)
 +      return _error->Errno("fork", "Failed to fork");
 +   if(Child == 0)
 +   {
 +      if(Mode == FileFd::ReadOnly)
 +      {
 +         close(Pipe[0]);
 +         fd = Pipe[1];
 +      }
 +      else if(Mode == FileFd::WriteOnly)
 +      {
 +         close(Pipe[1]);
 +         fd = Pipe[0];
 +      }
 +
 +      if(Mode == FileFd::ReadOnly)
 +      {
 +         dup2(fd, 1);
 +         dup2(fd, 2);
 +      } else if(Mode == FileFd::WriteOnly)
 +         dup2(fd, 0);
 +
 +      execv(Args[0], (char**)Args);
 +      _exit(100);
 +   }
 +   if(Mode == FileFd::ReadOnly)
 +   {
 +      close(Pipe[1]);
 +      fd = Pipe[0];
 +   } else if(Mode == FileFd::WriteOnly)
 +   {
 +      close(Pipe[0]);
 +      fd = Pipe[1];
 +   }
 +   Fd.OpenDescriptor(fd, Mode, FileFd::None, true);
 +
 +   return true;
 +}
++
+ bool DropPrivs()
+ {
+    if (getuid() != 0)
+       return true;
+    const std::string nobody = _config->Find("APT::User::Nobody", "nobody");
+    struct passwd *pw = getpwnam(nobody.c_str());
+    if (pw == NULL)
+       return _error->Warning("No user %s, can not drop rights", nobody.c_str());
+    if (setgid(pw->pw_gid) != 0)
+       return _error->Errno("setgid", "Failed to setgid");
+    if (setuid(pw->pw_uid) != 0)
+       return _error->Errno("setuid", "Failed to setuid");
++
+    return true;
+ }
index 0b4d9488519bf5c855fd479483c2d0a65e3bbde5,683c04157b473f4347669a061e75e25cef635a09..e04f75e2aed57eea283c1aad26c82b1887a0bfdf
@@@ -168,8 -168,6 +168,8 @@@ time_t GetModificationTime(std::string 
  bool Rename(std::string From, std::string To);
  
  std::string GetTempDir();
 +FileFd* GetTempFile(std::string const &Prefix = "", 
 +                    bool ImmediateUnlink = true);
  
  /** \brief Ensure the existence of the given Path
   *
@@@ -193,9 -191,9 +193,13 @@@ pid_t ExecFork(std::set<int> keep_fds)
  void MergeKeepFdsFromConfiguration(std::set<int> &keep_fds);
  bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
  
++
 +// check if the given file starts with a PGP cleartext signature
 +bool StartsWithGPGClearTextSignature(std::string const &FileName);
 +
+ // process releated
+ bool DropPrivs();
  // File string manipulators
  std::string flNotDir(std::string File);
  std::string flNotFile(std::string File);
@@@ -203,23 -201,7 +207,23 @@@ std::string flNoLink(std::string File)
  std::string flExtension(std::string File);
  std::string flCombine(std::string Dir,std::string File);
  
 +/** \brief Takes a file path and returns the absolute path
 + */
 +std::string flAbsPath(std::string File);
 +
  // simple c++ glob
  std::vector<std::string> Glob(std::string const &pattern, int flags=0);
  
 +/** \brief Popen() implementation that execv() instead of using a shell
 + *
 + * \param Args the execv style command to run
 + * \param FileFd is a referenz to the FileFd to use for input or output
 + * \param Child a reference to the integer that stores the child pid
 + *        Note that you must call ExecWait() or similar to cleanup
 + * \param Mode is either FileFd::ReadOnly or FileFd::WriteOnly
 + * \return true on success, false on failure with _error set
 + */
 +bool Popen(const char* Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode);
 +
 +
  #endif