From 6630721a6fdedb2613e234372a079ca942007072 Thu, 9 Aug 2018 11:36:55 +0200 From: Juha Kallioinen 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 Signed-off-by: Juha Kallioinen 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 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;