]> git.saurik.com Git - apt.git/commitdiff
make http size check work
authorMichael Vogt <mvo@ubuntu.com>
Mon, 6 Oct 2014 15:42:39 +0000 (17:42 +0200)
committerMichael Vogt <mvo@ubuntu.com>
Mon, 6 Oct 2014 15:42:39 +0000 (17:42 +0200)
1  2 
apt-pkg/acquire-method.cc
apt-pkg/acquire-method.h
methods/http.cc
methods/http.h
methods/https.cc
methods/https.h
methods/server.cc
methods/server.h
test/integration/test-apt-update-expected-size

index 9fc17674730f50fb66b1c2e7f4283e61d4a9986b,82f2fb3ce091e51c9e11afe88f21bedc60bef096..330854e752adc655b6fa6f111a45c71acbd74757
@@@ -118,6 -118,18 +118,18 @@@ void pkgAcqMethod::Fail(string Err,boo
  
     std::cout << "\n" << std::flush;
  }
+                                                                       /*}}}*/
+ // AcqMethod::DropPrivsOrDie - Drop privileges or die         /*{{{*/
+ // ---------------------------------------------------------------------
+ /* */
+ void pkgAcqMethod::DropPrivsOrDie()
+ {
+    if (!DropPrivs()) {
+       Fail(false);
+       exit(112);      /* call the european emergency number */
+    }
+ }
                                                                        /*}}}*/
  // AcqMethod::URIStart - Indicate a download is starting              /*{{{*/
  // ---------------------------------------------------------------------
@@@ -360,8 -372,6 +372,8 @@@ int pkgAcqMethod::Run(bool Single
               if (hash.empty() == false)
                  Tmp->ExpectedHashes.push_back(HashString(*t, hash));
            }
 +            char *End;
 +            Tmp->ExpectedSize = strtoll(LookupTag(Message, "Expected-Size", "0").c_str(), &End, 10);
            Tmp->Next = 0;
            
            // Append it to the list
diff --combined apt-pkg/acquire-method.h
index 8a680335e1bb20b8e38b4e26dc8bb68db6cd5e2f,cdeecc9a73983d602db3e304da750e6bcf9c7d3c..2e4e8281a978d92bb13c48fe2cdebaffabf2fad9
@@@ -48,7 -48,6 +48,7 @@@ class pkgAcqMetho
        bool IndexFile;
        bool FailIgnore;
        HashStringList ExpectedHashes;
 +      unsigned long long ExpectedSize;
     };
     
     struct FetchResult
     
     pkgAcqMethod(const char *Ver,unsigned long Flags = 0);
     virtual ~pkgAcqMethod() {};
+    void DropPrivsOrDie();
     private:
     APT_HIDDEN void Dequeue();
  };
diff --combined methods/http.cc
index 916fa464f7d79c3c41cb5a1af5eb650eea14aa47,f2a4a4db631add976bcbf36d329a57d45d3304a5..b076e59ccc52f883fb96643acaef39f9d8550aa6
@@@ -34,6 -34,7 +34,7 @@@
  #include <apt-pkg/hashes.h>
  #include <apt-pkg/netrc.h>
  #include <apt-pkg/strutl.h>
+ #include <apt-pkg/proxy.h>
  
  #include <stddef.h>
  #include <stdlib.h>
@@@ -63,8 -64,7 +64,8 @@@ const unsigned int CircleBuf::BW_HZ=10
  // CircleBuf::CircleBuf - Circular input buffer                               /*{{{*/
  // ---------------------------------------------------------------------
  /* */
 -CircleBuf::CircleBuf(unsigned long long Size) : Size(Size), Hash(0)
 +CircleBuf::CircleBuf(unsigned long long Size) 
 +   : Size(Size), Hash(0), TotalWriten(0)
  {
     Buf = new unsigned char[Size];
     Reset();
@@@ -80,7 -80,6 +81,7 @@@ void CircleBuf::Reset(
     InP = 0;
     OutP = 0;
     StrPos = 0;
 +   TotalWriten = 0;
     MaxGet = (unsigned long long)-1;
     OutQueue = string();
     if (Hash != 0)
@@@ -218,8 -217,6 +219,8 @@@ bool CircleBuf::Write(int Fd
         
         return false;
        }
 +
 +      TotalWriten += Res;
        
        if (Hash != 0)
         Hash->Add(Buf + (OutP%Size),Res);
@@@ -308,6 -305,7 +309,7 @@@ bool HttpServerState::Open(
     Persistent = true;
     
     // Determine the proxy setting
+    AutoDetectProxy(ServerName);
     string SpecificProxy = _config->Find("Acquire::http::Proxy::" + ServerName.Host);
     if (!SpecificProxy.empty())
     {
@@@ -653,10 -651,6 +655,12 @@@ bool HttpServerState::Go(bool ToFile, F
         return _error->Errno("write",_("Error writing to output file"));
     }
  
-    if (ExpectedSize > 0 && In.TotalWriten > ExpectedSize)
++   if (ExpectedSize > 0 && File && File->Tell() > ExpectedSize)
++   {
 +      return _error->Error("Writing more data than expected (%llu > %llu)",
-                            In.TotalWriten, ExpectedSize);
++                           File->Tell(), ExpectedSize);
++   }
 +
     // Handle commands from APT
     if (FD_ISSET(STDIN_FILENO,&rfds))
     {
@@@ -752,7 -746,7 +756,7 @@@ void HttpMethod::SendReq(FetchItem *Itm
     Req << "\r\n";
  
     if (Debug == true)
-       cerr << Req << endl;
+       cerr << Req.str() << endl;
  
     Server->WriteResponse(Req.str());
  }
@@@ -770,66 -764,6 +774,6 @@@ bool HttpMethod::Configuration(string M
                                  PipelineDepth);
     Debug = _config->FindB("Debug::Acquire::http",false);
  
-    // Get the proxy to use
-    AutoDetectProxy();
-    return true;
- }
-                                                                       /*}}}*/
- // HttpMethod::AutoDetectProxy - auto detect proxy                    /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool HttpMethod::AutoDetectProxy()
- {
-    // option is "Acquire::http::Proxy-Auto-Detect" but we allow the old
-    // name without the dash ("-")
-    AutoDetectProxyCmd = _config->Find("Acquire::http::Proxy-Auto-Detect",
-                                       _config->Find("Acquire::http::ProxyAutoDetect"));
-    if (AutoDetectProxyCmd.empty())
-       return true;
-    if (Debug)
-       clog << "Using auto proxy detect command: " << AutoDetectProxyCmd << endl;
-    int Pipes[2] = {-1,-1};
-    if (pipe(Pipes) != 0)
-       return _error->Errno("pipe", "Failed to create Pipe");
-    pid_t Process = ExecFork();
-    if (Process == 0)
-    {
-       close(Pipes[0]);
-       dup2(Pipes[1],STDOUT_FILENO);
-       SetCloseExec(STDOUT_FILENO,false);
-       const char *Args[2];
-       Args[0] = AutoDetectProxyCmd.c_str();
-       Args[1] = 0;
-       execv(Args[0],(char **)Args);
-       cerr << "Failed to exec method " << Args[0] << endl;
-       _exit(100);
-    }
-    char buf[512];
-    int InFd = Pipes[0];
-    close(Pipes[1]);
-    int res = read(InFd, buf, sizeof(buf)-1);
-    ExecWait(Process, "ProxyAutoDetect", true);
-    if (res < 0)
-       return _error->Errno("read", "Failed to read");
-    if (res == 0)
-       return _error->Warning("ProxyAutoDetect returned no data");
-    // add trailing \0
-    buf[res] = 0;
-    if (Debug)
-       clog << "auto detect command returned: '" << buf << "'" << endl;
-    if (strstr(buf, "http://") == buf)
-       _config->Set("Acquire::http::proxy", _strstrip(buf));
     return true;
  }
                                                                        /*}}}*/
diff --combined methods/http.h
index c98fe8e5fbfba2f5a4c07c88f5b7bd68aa9c7a57,1df9fa07d68c60849d375cb3a7cc952b6c144625..40a88a7be03b3a8e254b981ca6711f833c8173e7
@@@ -63,8 -63,6 +63,8 @@@ class CircleBu
  
     public:
     Hashes *Hash;
 +   // total amount of data that got written so far
 +   unsigned long long TotalWriten;
  
     // Read data in
     bool Read(int Fd);
@@@ -83,8 -81,8 +83,8 @@@
     bool ReadSpace() const {return Size - (InP - OutP) > 0;};
     bool WriteSpace() const {return InP - OutP > 0;};
  
 -   // Dump everything
     void Reset();
 +   // Dump everything
     void Stats();
  
     CircleBuf(unsigned long long Size);
@@@ -126,9 -124,6 +126,6 @@@ class HttpMethod : public ServerMetho
     public:
     virtual void SendReq(FetchItem *Itm);
  
-    /** \brief Try to AutoDetect the proxy */
-    bool AutoDetectProxy();
     virtual bool Configuration(std::string Message);
  
     virtual ServerState * CreateServerState(URI uri);
diff --combined methods/https.cc
index cacd8a6bc9e2985b83611b47fdf18000ab0b53b4,a74d2a38be4ba416ee7f1bfffbc1fdc3e43a9e0a..eec858417af0262c8496ea665f901274301515d1
@@@ -20,6 -20,7 +20,7 @@@
  #include <apt-pkg/configuration.h>
  #include <apt-pkg/macros.h>
  #include <apt-pkg/strutl.h>
+ #include <apt-pkg/proxy.h>
  
  #include <sys/stat.h>
  #include <sys/time.h>
@@@ -81,12 -82,6 +82,12 @@@ HttpsMethod::write_data(void *buffer, s
     if(me->File->Write(buffer, size*nmemb) != true)
        return false;
  
 +   me->TotalWritten += size*nmemb;
 +   if(me->TotalWritten > me->Queue->ExpectedSize)
 +      return _error->Error("Writing more data than expected (%llu > %llu)",
 +                           me->TotalWritten, me->Queue->ExpectedSize);
 +
 +
     return size*nmemb;
  }
  
@@@ -113,6 -108,9 +114,9 @@@ void HttpsMethod::SetupProxy()                                     /*
  {
     URI ServerName = Queue->Uri;
  
+    // Determine the proxy setting
+    AutoDetectProxy(ServerName);
     // Curl should never read proxy settings from the environment, as
     // we determine which proxy to use.  Do this for consistency among
     // methods and prevent an environment variable overriding a
@@@ -448,6 -446,8 +452,8 @@@ int main(
     HttpsMethod Mth;
     curl_global_init(CURL_GLOBAL_SSL) ;
  
+    Mth.DropPrivsOrDie();
     return Mth.Run();
  }
  
diff --combined methods/https.h
index 2335559fb0e4073020e2ddd53f60b8b57553b0d0,45d1f7f63a94858731e3659fa0742e8fc0ec3622..0387cb9b579764c4615808531630ce4007698145
@@@ -66,14 -66,12 +66,13 @@@ class HttpsMethod : public pkgAcqMetho
     CURL *curl;
     FetchResult Res;
     HttpsServerState *Server;
 +   unsigned long long TotalWritten;
  
     public:
     FileFd *File;
 -
 -   HttpsMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig), Server(NULL), File(NULL)
 +      
-    HttpsMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig), TotalWritten(0), File(NULL)
++   HttpsMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig), Server(NULL), TotalWritten(0), File(NULL)
     {
-       File = 0;
        curl = curl_easy_init();
     };
  
diff --combined methods/server.cc
index 1b6511c59dc0525bc0b4e8ae116594a9c4bda42c,4a961f454df65bd152e29c75ed04afec920db620..2237379010d809544183a9ae96336ee315ccdf2d
@@@ -44,7 -44,8 +44,8 @@@ time_t ServerMethod::FailTime = 0
  // ---------------------------------------------------------------------
  /* Returns 0 if things are OK, 1 if an IO error occurred and 2 if a header
     parse error occurred */
- ServerState::RunHeadersResult ServerState::RunHeaders(FileFd * const File)
+ ServerState::RunHeadersResult ServerState::RunHeaders(FileFd * const File,
+                                                       const std::string &Uri)
  {
     State = Header;
     
@@@ -66,7 -67,7 +67,7 @@@
         continue;
  
        if (Owner->Debug == true)
-        clog << Data;
+        clog << "Answer for: " << Uri << endl << Data;
        
        for (string::const_iterator I = Data.begin(); I < Data.end(); ++I)
        {
@@@ -323,10 -324,10 +324,10 @@@ ServerMethod::DealWithHeaders(FetchResu
        failure */
     if (Server->Result < 200 || Server->Result >= 300)
     {
-       char err[255];
-       snprintf(err,sizeof(err)-1,"HttpError%i",Server->Result);
+       std::string err;
+       strprintf(err, "HttpError%u", Server->Result);
        SetFailReason(err);
-       _error->Error("%u %s",Server->Result,Server->Code);
+       _error->Error("%u %s", Server->Result, Server->Code);
        if (Server->HaveContent == true)
         return ERROR_WITH_CONTENT_PAGE;
        return ERROR_UNRECOVERABLE;
@@@ -485,7 -486,7 +486,7 @@@ int ServerMethod::Loop(
        Fetch(0);
        
        // Fetch the next URL header data from the server.
-       switch (Server->RunHeaders(File))
+       switch (Server->RunHeaders(File, Queue->Uri))
        {
         case ServerState::RUN_HEADERS_OK:
         break;
  
            // Run the data
            bool Result = true;
 +
 +            // ensure we don't fetch too much
 +            if (Queue->ExpectedSize > 0)
 +               Server->ExpectedSize = Queue->ExpectedSize;
 +
              if (Server->HaveContent)
               Result = Server->RunData(File);
  
                  QueueBack = Queue;
               }
               else
++               {
++                  Server->Close();
                  Fail(true);
++               }
            }
            break;
         }
diff --combined methods/server.h
index 0d733314046093bbe8d1d0b0bb2043cf4d63746a,aa692ea931ba5773a2dd8d4453916bfcb4793972..0134a95385cb60dc1eba9499cd0aa088a12ba587
@@@ -49,8 -49,6 +49,8 @@@ struct ServerStat
     URI Proxy;
     unsigned long TimeOut;
  
 +   unsigned long long ExpectedSize;
 +
     protected:
     ServerMethod *Owner;
  
        RUN_HEADERS_PARSE_ERROR
     };
     /** \brief Get the headers before the data */
-    RunHeadersResult RunHeaders(FileFd * const File);
+    RunHeadersResult RunHeaders(FileFd * const File, const std::string &Uri);
  
     bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;};
     virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0;
                 StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false;
 -               State = Header; Persistent = false; Pipeline = true;};
 +               State = Header; Persistent = false; Pipeline = true; ExpectedSize = 0;};
     virtual bool WriteResponse(std::string const &Data) = 0;
  
     /** \brief Transfer the data from the socket */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..72812336dec811c9bad76dc939f5ef726e79fd26
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,27 @@@
++#!/bin/sh
++set -e
++
++TESTDIR=$(readlink -f $(dirname $0))
++. $TESTDIR/framework
++
++setupenvironment
++configarchitecture "i386"
++
++insertpackage 'unstable' 'apt' 'all' '1.0'
++
++setupaptarchive --no-update
++changetowebserver
++
++# normal update works fine
++testsuccess aptget update
++
++# append junk at the end of the Packages.gz/Packages
++SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)"
++echo "1234567890" >> aptarchive/dists/unstable/main/binary-i386/Packages.gz
++echo "1234567890" >> aptarchive/dists/unstable/main/binary-i386/Packages
++NEW_SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)"
++rm -f rootdir/var/lib/apt/lists/localhost*
++testequal "W: Failed to fetch http://localhost:8080/dists/unstable/main/binary-i386/Packages  Writing more data than expected ($NEW_SIZE > $SIZE) [IP: ::1 8080]
++
++E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
++