]> git.saurik.com Git - apt.git/commitdiff
* merge lp:~mvo/apt/netrc branch, this adds support for a
authorMichael Vogt <michael.vogt@ubuntu.com>
Thu, 10 Dec 2009 15:06:40 +0000 (16:06 +0100)
committerMichael Vogt <michael.vogt@ubuntu.com>
Thu, 10 Dec 2009 15:06:40 +0000 (16:06 +0100)
  /etc/apt/auth.conf that can be used to store username/passwords
  in a "netrc" style file (with the extension that it supports "/"
  in a machine definition). Based on the maemo git branch.
* apt-pkg/deb/dpkgpm.cc:
  - add "purge" to list of known actions

apt-pkg/contrib/netrc.cc [new file with mode: 0644]
apt-pkg/contrib/netrc.h [new file with mode: 0644]
apt-pkg/deb/dpkgpm.cc
apt-pkg/init.cc
apt-pkg/makefile
debian/changelog
doc/examples/configure-index
methods/ftp.cc
methods/http.cc
methods/https.cc

diff --git a/apt-pkg/contrib/netrc.cc b/apt-pkg/contrib/netrc.cc
new file mode 100644 (file)
index 0000000..d8027fc
--- /dev/null
@@ -0,0 +1,211 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: netrc.c,v 1.38 2007-11-07 09:21:35 bagder Exp $
+/* ######################################################################
+
+   netrc file parser - returns the login and password of a give host in
+                       a specified netrc-type file
+
+   Originally written by Daniel Stenberg, <daniel@haxx.se>, et al. and
+   placed into the Public Domain, do with it what you will.
+
+   ##################################################################### */
+                                                                       /*}}}*/
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/fileutl.h>
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#include "netrc.h"
+
+
+/* Get user and password from .netrc when given a machine name */
+
+enum {
+  NOTHING,
+  HOSTFOUND,    /* the 'machine' keyword was found */
+  HOSTCOMPLETE, /* the machine name following the keyword was found too */
+  HOSTVALID,    /* this is "our" machine! */
+  HOSTEND /* LAST enum */
+};
+
+/* make sure we have room for at least this size: */
+#define LOGINSIZE 64
+#define PASSWORDSIZE 64
+#define NETRC DOT_CHAR "netrc"
+
+/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
+int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
+{
+  FILE *file;
+  int retcode = 1;
+  int specific_login = (login[0] != 0);
+  char *home = NULL;
+  bool netrc_alloc = false;
+  int state = NOTHING;
+
+  char state_login = 0;        /* Found a login keyword */
+  char state_password = 0;     /* Found a password keyword */
+  int state_our_login = false;  /* With specific_login,
+                                   found *our* login name */
+
+  if (!netrcfile) {
+    home = getenv ("HOME"); /* portable environment reader */
+
+    if (!home) {
+      struct passwd *pw;
+      pw = getpwuid (geteuid ());
+      if(pw)
+        home = pw->pw_dir;
+    }
+
+    if (!home)
+      return -1;
+
+    asprintf (&netrcfile, "%s%s%s", home, DIR_CHAR, NETRC);
+    if(!netrcfile)
+      return -1;
+    else
+      netrc_alloc = true;
+  }
+
+  file = fopen (netrcfile, "r");
+  if(file) {
+    char *tok;
+    char *tok_buf;
+    bool done = false;
+    char netrcbuffer[256];
+
+    while (!done && fgets(netrcbuffer, sizeof (netrcbuffer), file)) {
+      tok = strtok_r (netrcbuffer, " \t\n", &tok_buf);
+      while (!done && tok) {
+        if(login[0] && password[0]) {
+          done = true;
+          break;
+        }
+
+        switch(state) {
+        case NOTHING:
+          if (!strcasecmp ("machine", tok)) {
+            /* the next tok is the machine name, this is in itself the
+               delimiter that starts the stuff entered for this machine,
+               after this we need to search for 'login' and
+               'password'. */
+            state = HOSTFOUND;
+          }
+          break;
+        case HOSTFOUND:
+          /* extended definition of a "machine" if we have a "/"
+             we match the start of the string (host.startswith(token) */
+         if ((strchr(host, '/') && strstr(host, tok) == host) ||
+             (!strcasecmp (host, tok))) {
+            /* and yes, this is our host! */
+            state = HOSTVALID;
+            retcode = 0; /* we did find our host */
+          }
+          else
+            /* not our host */
+            state = NOTHING;
+          break;
+        case HOSTVALID:
+          /* we are now parsing sub-keywords concerning "our" host */
+          if (state_login) {
+            if (specific_login)
+              state_our_login = !strcasecmp (login, tok);
+            else
+              strncpy (login, tok, LOGINSIZE - 1);
+            state_login = 0;
+          } else if (state_password) {
+            if (state_our_login || !specific_login)
+              strncpy (password, tok, PASSWORDSIZE - 1);
+            state_password = 0;
+          } else if (!strcasecmp ("login", tok))
+            state_login = 1;
+          else if (!strcasecmp ("password", tok))
+            state_password = 1;
+          else if(!strcasecmp ("machine", tok)) {
+            /* ok, there's machine here go => */
+            state = HOSTFOUND;
+            state_our_login = false;
+          }
+          break;
+        } /* switch (state) */
+
+        tok = strtok_r (NULL, " \t\n", &tok_buf);
+      } /* while(tok) */
+    } /* while fgets() */
+
+    fclose(file);
+  }
+
+  if (netrc_alloc)
+    free(netrcfile);
+
+  return retcode;
+}
+
+void maybe_add_auth (URI &Uri, string NetRCFile)
+{
+  if (_config->FindB("Debug::Acquire::netrc", false) == true)
+     std::clog << "maybe_add_auth: " << (string)Uri 
+              << " " << NetRCFile << std::endl;
+  if (Uri.Password.empty () == true || Uri.User.empty () == true)
+  {
+    if (NetRCFile.empty () == false)
+    {
+      char login[64] = "";
+      char password[64] = "";
+      char *netrcfile = strdupa (NetRCFile.c_str ());
+
+      // first check for a generic host based netrc entry
+      char *host = strdupa (Uri.Host.c_str ());
+      if (host && parsenetrc (host, login, password, netrcfile) == 0)
+      {
+        if (_config->FindB("Debug::Acquire::netrc", false) == true)
+           std::clog << "host: " << host 
+                     << " user: " << login
+                     << " pass-size: " << strlen(password)
+                     << std::endl;
+        Uri.User = string (login);
+        Uri.Password = string (password);
+       return;
+      }
+
+      // if host did not work, try Host+Path next, this will trigger
+      // a lookup uri.startswith(host) in the netrc file parser (because
+      // of the "/"
+      char *hostpath = strdupa (string(Uri.Host+Uri.Path).c_str ());
+      if (hostpath && parsenetrc (hostpath, login, password, netrcfile) == 0)
+      {
+        if (_config->FindB("Debug::Acquire::netrc", false) == true)
+           std::clog << "hostpath: " << hostpath
+                     << " user: " << login
+                     << " pass-size: " << strlen(password)
+                     << std::endl;
+        Uri.User = string (login);
+        Uri.Password = string (password);
+        return;
+      }
+    }
+  }
+}
+
+#ifdef DEBUG
+int main(int argc, char* argv[])
+{
+  char login[64] = "";
+  char password[64] = "";
+
+  if(argc < 2)
+    return -1;
+
+  if(0 == parsenetrc (argv[1], login, password, argv[2])) {
+    printf("HOST: %s LOGIN: %s PASSWORD: %s\n", argv[1], login, password);
+  }
+}
+#endif
diff --git a/apt-pkg/contrib/netrc.h b/apt-pkg/contrib/netrc.h
new file mode 100644 (file)
index 0000000..02a5eb0
--- /dev/null
@@ -0,0 +1,29 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: netrc.h,v 1.11 2004/01/07 09:19:35 bagder Exp $
+/* ######################################################################
+
+   netrc file parser - returns the login and password of a give host in
+                       a specified netrc-type file
+
+   Originally written by Daniel Stenberg, <daniel@haxx.se>, et al. and
+   placed into the Public Domain, do with it what you will.
+
+   ##################################################################### */
+                                                                       /*}}}*/
+#ifndef NETRC_H
+#define NETRC_H
+
+#include <apt-pkg/strutl.h>
+
+#define DOT_CHAR "."
+#define DIR_CHAR "/"
+
+// Assume: password[0]=0, host[0] != 0.
+// If login[0] = 0, search for login and password within a machine section
+// in the netrc.
+// If login[0] != 0, search for password within machine and login.
+int parsenetrc (char *host, char *login, char *password, char *filename);
+
+void maybe_add_auth (URI &Uri, string NetRCFile);
+#endif
index adaf362fa2e7df529ea2e1e55ac80732c053ac82..6eb3b40acf7e5b862754f5ee65c2edc8262f1491 100644 (file)
@@ -49,6 +49,7 @@ namespace
     std::make_pair("install",   N_("Installing %s")),
     std::make_pair("configure", N_("Configuring %s")),
     std::make_pair("remove",    N_("Removing %s")),
+    std::make_pair("purge",    N_("Completely removing %s")),
     std::make_pair("trigproc",  N_("Running post-installation trigger %s"))
   };
 
index 15efb1a3d58b708518a6cd78daa5cdeaa43b48a9..a54c09a3613d2c7edaa7f54fb6c6f12a94b9f61e 100644 (file)
@@ -65,6 +65,7 @@ bool pkgInitConfig(Configuration &Cnf)
    Cnf.Set("Dir::Etc::vendorlist","vendors.list");
    Cnf.Set("Dir::Etc::vendorparts","vendors.list.d");
    Cnf.Set("Dir::Etc::main","apt.conf");
+   Cnf.Set("Dir::ETc::netrc", "auth.conf");
    Cnf.Set("Dir::Etc::parts","apt.conf.d");
    Cnf.Set("Dir::Etc::preferences","preferences");
    Cnf.Set("Dir::Etc::preferencesparts","preferences.d");
index 7816ecf0d0d86db1241ad69f935655c1fde3b38e..f2a8460a9e64e9336c72bb194d6305fa40c3b321 100644 (file)
@@ -22,10 +22,10 @@ APT_DOMAIN:=libapt-pkg$(MAJOR)
 SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
          contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \
         contrib/md5.cc contrib/sha1.cc contrib/sha256.cc contrib/hashes.cc \
-        contrib/cdromutl.cc contrib/crc-16.cc \
+        contrib/cdromutl.cc contrib/crc-16.cc contrib/netrc.cc \
         contrib/fileutl.cc 
-HEADERS = mmap.h error.h configuration.h fileutl.h  cmndline.h \
-         md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h
+HEADERS = mmap.h error.h configuration.h fileutl.h  cmndline.h netrc.h\
+         md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h 
 
 # Source code for the core main library
 SOURCE+= pkgcache.cc version.cc depcache.cc \
index 5cff0919ad30a2bdd6e454a18fd8530dfb0173f5..8c5cbac7c652724bc65a5c40f67b858d2fcae6af 100644 (file)
@@ -30,6 +30,12 @@ apt (0.7.25) UNRELEASED; urgency=low
   * methods/https.cc:
     - fix incorrect use of CURLOPT_TIMEOUT, closes: #497983, LP: #354972
       thanks to Brian Thomason for the patch
+  * merge lp:~mvo/apt/netrc branch, this adds support for a
+    /etc/apt/auth.conf that can be used to store username/passwords
+    in a "netrc" style file (with the extension that it supports "/"
+    in a machine definition). Based on the maemo git branch.
+  * apt-pkg/deb/dpkgpm.cc:
+    - add "purge" to list of known actions
 
   [ Brian Murray ]
   * apt-pkg/depcache.cc, apt-pkg/indexcopy.cc:
index 27118fb7e85f8e7c34534b7c4a75a57d51072a08..f5f9964609282e6d75c4ae562b192f0bc52da9b6 100644 (file)
@@ -282,6 +282,7 @@ Dir "/"
   // Config files
   Etc "etc/apt/" {
      Main "apt.conf";
+     Netrc "auth.conf";
      Parts "apt.conf.d/";
      Preferences "preferences";
      PreferencesParts "preferences.d";
@@ -380,6 +381,7 @@ Debug
   Acquire::gpgv "false";   // Show the gpgv traffic
   aptcdrom "false";        // Show found package files
   IdentCdrom "false";
+  acquire::netrc "false";  // netrc parser
   
 }
 
index c91600ad5388f7cc675922ce731e37ad43faf59e..3e1725823d9a16e98b20adcfe73434723d79cbde 100644 (file)
@@ -19,6 +19,7 @@
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/hashes.h>
+#include <apt-pkg/netrc.h>
 
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -982,7 +983,9 @@ bool FtpMethod::Fetch(FetchItem *Itm)
    FetchResult Res;
    Res.Filename = Itm->DestFile;
    Res.IMSHit = false;
-   
+
+   maybe_add_auth (Get, _config->FindFile("Dir::Etc::netrc"));
+
    // Connect to the server
    if (Server == 0 || Server->Comp(Get) == false)
    {
index 461a984067079f6c3f4ed261180d64a3203d3701..3b210f6b612153fd5a433e784956b28c22ce6677 100644 (file)
@@ -29,6 +29,7 @@
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/hashes.h>
+#include <apt-pkg/netrc.h>
 
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -42,6 +43,7 @@
 #include <map>
 #include <apti18n.h>
 
+
 // Internet stuff
 #include <netdb.h>
 
@@ -49,7 +51,6 @@
 #include "connect.h"
 #include "rfc2553emu.h"
 #include "http.h"
-
                                                                        /*}}}*/
 using namespace std;
 
@@ -724,10 +725,12 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
       Req += string("Proxy-Authorization: Basic ") + 
           Base64Encode(Proxy.User + ":" + Proxy.Password) + "\r\n";
 
+   maybe_add_auth (Uri, _config->FindFile("Dir::Etc::netrc"));
    if (Uri.User.empty() == false || Uri.Password.empty() == false)
+   {
       Req += string("Authorization: Basic ") + 
           Base64Encode(Uri.User + ":" + Uri.Password) + "\r\n";
-   
+   }
    Req += "User-Agent: Debian APT-HTTP/1.3 ("VERSION")\r\n\r\n";
    
    if (Debug == true)
index 47988970b5c93c8b89733383a985efe0c0c439d9..3717ded7be85ce6581a9ec97ca85d795a170edfb 100644 (file)
@@ -14,6 +14,7 @@
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/hashes.h>
+#include <apt-pkg/netrc.h>
 
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -126,8 +127,10 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
    curl_easy_reset(curl);
    SetupProxy();
 
+   maybe_add_auth (Uri, _config->FindFile("Dir::Etc::netrc"));
+
    // callbacks
-   curl_easy_setopt(curl, CURLOPT_URL, Itm->Uri.c_str());
+   curl_easy_setopt(curl, CURLOPT_URL, static_cast<string>(Uri).c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);