0006-libzypp-Enable-netrcoptional-on-libcurl-to-allow-for.patch 4.87 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
From 6630721a6fdedb2613e234372a079ca942007072 Thu, 9 Aug 2018 11:36:55 +0200
From: Juha Kallioinen <juha.kallioinen@jolla.com>
Date: Wed, 6 Nov 2013 14:05:27 +0000
Subject: [PATCH] [libzypp] Enable netrc-optional on libcurl to allow for easier image building in SDK


Original patch from: Islam Amer <islam.amer@jollamobile.com>

Signed-off-by: Juha Kallioinen <juha.kallioinen@jolla.com>

diff --git a/zypp/media/MediaCurl.cc b/zypp/media/MediaCurl.cc
index 599e145..115e06f 100644
--- a/zypp/media/MediaCurl.cc
+++ b/zypp/media/MediaCurl.cc
@@ -984,8 +984,8 @@
 
   Url fileurl(getFileUrl(filename));
 
-  bool retry = false;
-
+  bool retry = false, netrc = false;
+  int numTry = 0;
   do
   {
     try
@@ -996,7 +996,7 @@
     // retry with proper authentication data
     catch (MediaUnauthorizedException & ex_r)
     {
-      if(authenticate(ex_r.hint(), !retry))
+      if (authenticate(ex_r.hint(), numTry++, netrc))
         retry = true;
       else
       {
@@ -1026,8 +1026,8 @@
 
 bool MediaCurl::getDoesFileExist( const Pathname & filename ) const
 {
-  bool retry = false;
-
+  bool retry = false, netrc = false;
+  int numTry = 0;
   do
   {
     try
@@ -1037,7 +1037,7 @@
     // authentication problem, retry with proper authentication data
     catch (MediaUnauthorizedException & ex_r)
     {
-      if(authenticate(ex_r.hint(), !retry))
+      if (authenticate(ex_r.hint(), numTry++, netrc))
         retry = true;
       else
         ZYPP_RETHROW(ex_r);
@@ -1693,9 +1693,32 @@
 }
 
 ///////////////////////////////////////////////////////////////////
-
-bool MediaCurl::authenticate(const string & availAuthTypes, bool firstTry) const
+/*
+ * The authentication is a challenge-response type transaction. We
+ * come here after the challenge has been received and need to send a
+ * response. There are plenty of ways to send the right and the wrong
+ * response. All of these preconditions need to be considered:
+ *
+ * 1) there are no existing credentials
+ * 2) credential manager has right/wrong credentials
+ * 3) user enters right/wrong credentials interactively
+ * 4) .netrc contains right/wrong credentials
+ * 5) client (e.g. zypper) can be in interactive or non-interactive mode
+ *
+ * First we always want to try to send a response with any stored
+ * credentials. If there are none, then we'll try using a .netrc. Only
+ * after these methods have failed to authenticate the user, we'll
+ * prompt the user for the credentials or give up if in
+ * non-interactive mode.
+ *
+ * The challenge-response loop needs to be able to end in the
+ * non-interactive mode in case none of the available methods provide
+ * the correct response.
+ *
+ */
+bool MediaCurl::authenticate(const string & availAuthTypes, int numTry, bool &netrcUsed) const
 {
+  DBG << "numtry: " << numTry << endl;
   //! \todo need a way to pass different CredManagerOptions here
   CredentialManager cm(CredManagerOptions(ZConfig::instance().repoManagerRoot()));
   CurlAuthData_Ptr credentials;
@@ -1703,21 +1726,29 @@
   // get stored credentials
   AuthData_Ptr cmcred = cm.getCred(_url);
 
-  if (cmcred && firstTry)
+  // first try with any stored credentials
+  if (cmcred && (numTry == 0))
   {
     credentials.reset(new CurlAuthData(*cmcred));
     DBG << "got stored credentials:" << endl << *credentials << endl;
   }
-  // if not found, ask user
-  else
-  {
+  // no stored creds or they failed, try .netrc instead if not already tried
+  else if ((numTry == 0 || numTry == 1) && (!netrcUsed)) {
+    DBG << "try with .netrc" << endl;
+    CURLcode ret = curl_easy_setopt(_curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
+    if ( ret != 0 ) ZYPP_THROW(MediaCurlSetOptException(_url, _curlError));
+    netrcUsed = true;
+    return true;
+  }
+  // stored creds and .netrc failed, ask user
+  else {
 
     CurlAuthData_Ptr curlcred;
     curlcred.reset(new CurlAuthData());
     callback::SendReport<AuthenticationReport> auth_report;
 
     // preset the username if present in current url
-    if (!_url.getUsername().empty() && firstTry)
+    if (!_url.getUsername().empty() && (numTry == 0))
       curlcred->setUsername(_url.getUsername());
     // if CM has found some credentials, preset the username from there
     else if (cmcred)
@@ -1754,6 +1785,7 @@
     }
     else
     {
+      // can be the result of the non-interactive client mode
       DBG << "callback answer: cancel" << endl;
     }
   }
@@ -1792,6 +1824,7 @@
     return true;
   }
 
+  // ends the authentication challenge-response loop
   return false;
 }
 
diff --git a/zypp/media/MediaCurl.h b/zypp/media/MediaCurl.h
index 48a8dcf..816a4f1 100644
--- a/zypp/media/MediaCurl.h
+++ b/zypp/media/MediaCurl.h
@@ -158,7 +158,7 @@
      */
     std::string getAuthHint() const;
 
-    bool authenticate(const std::string & availAuthTypes, bool firstTry) const;
+    bool authenticate(const std::string & availAuthTypes, int numTry, bool& netrcUsed) const;
 
     bool detectDirIndex() const;