Hello community, here is the log from the commit of package libzypp for openSUSE:Factory checked in at 2020-07-21 15:39:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libzypp (Old) and /work/SRC/openSUSE:Factory/.libzypp.new.3592 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libzypp" Tue Jul 21 15:39:08 2020 rev:432 rq:821339 version:17.24.1 Changes: -------- --- /work/SRC/openSUSE:Factory/libzypp/libzypp.changes 2020-07-16 12:08:47.386378531 +0200 +++ /work/SRC/openSUSE:Factory/.libzypp.new.3592/libzypp.changes 2020-07-21 15:39:11.859432200 +0200 @@ -1,0 +2,9 @@ +Thu Jul 16 18:04:18 CEST 2020 - m...@suse.de + +- Fix bsc#1174011 auth=basic ignored in some cases (bsc#1174011) + Proactively send credentials if the URL specifes '?auth=basic' + and a username. +- ZYPP_MEDIA_CURL_DEBUG: Strip credentials in header log (bsc#1174011) +- version 17.24.1 (22) + +------------------------------------------------------------------- Old: ---- libzypp-17.24.0.tar.bz2 New: ---- libzypp-17.24.1.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libzypp.spec ++++++ --- /var/tmp/diff_new_pack.rKuMPS/_old 2020-07-21 15:39:12.759433386 +0200 +++ /var/tmp/diff_new_pack.rKuMPS/_new 2020-07-21 15:39:12.763433392 +0200 @@ -25,7 +25,7 @@ %bcond_without mediabackend_tests Name: libzypp -Version: 17.24.0 +Version: 17.24.1 Release: 0 URL: https://github.com/openSUSE/libzypp Summary: Library for package, patch, pattern and product management ++++++ libzypp-17.24.0.tar.bz2 -> libzypp-17.24.1.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/VERSION.cmake new/libzypp-17.24.1/VERSION.cmake --- old/libzypp-17.24.0/VERSION.cmake 2020-07-14 13:21:53.000000000 +0200 +++ new/libzypp-17.24.1/VERSION.cmake 2020-07-16 18:11:42.000000000 +0200 @@ -61,8 +61,8 @@ SET(LIBZYPP_MAJOR "17") SET(LIBZYPP_COMPATMINOR "22") SET(LIBZYPP_MINOR "24") -SET(LIBZYPP_PATCH "0") +SET(LIBZYPP_PATCH "1") # -# LAST RELEASED: 17.24.0 (22) +# LAST RELEASED: 17.24.1 (22) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/package/libzypp.changes new/libzypp-17.24.1/package/libzypp.changes --- old/libzypp-17.24.0/package/libzypp.changes 2020-07-14 13:21:53.000000000 +0200 +++ new/libzypp-17.24.1/package/libzypp.changes 2020-07-16 18:11:42.000000000 +0200 @@ -1,4 +1,13 @@ ------------------------------------------------------------------- +Thu Jul 16 18:04:18 CEST 2020 - m...@suse.de + +- Fix bsc#1174011 auth=basic ignored in some cases (bsc#1174011) + Proactively send credentials if the URL specifes '?auth=basic' + and a username. +- ZYPP_MEDIA_CURL_DEBUG: Strip credentials in header log (bsc#1174011) +- version 17.24.1 (22) + +------------------------------------------------------------------- Tue Jul 14 13:19:56 CEST 2020 - m...@suse.de - Completey rework the purge-kernels algorithm (fix bsc#1173106) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/tests/zyppng/media/EvDownloader_test.cc new/libzypp-17.24.1/tests/zyppng/media/EvDownloader_test.cc --- old/libzypp-17.24.0/tests/zyppng/media/EvDownloader_test.cc 2020-02-07 08:56:12.000000000 +0100 +++ new/libzypp-17.24.1/tests/zyppng/media/EvDownloader_test.cc 2020-07-16 10:41:37.000000000 +0200 @@ -3,6 +3,7 @@ #include <zypp/zyppng/media/network/networkrequesterror.h> #include <zypp/zyppng/media/network/networkrequestdispatcher.h> #include <zypp/zyppng/media/network/request.h> +#include <zypp/media/CredentialManager.h> #include <zypp/TmpPath.h> #include <zypp/PathInfo.h> #include <zypp/ZConfig.h> @@ -571,3 +572,66 @@ BOOST_REQUIRE( !gotAuthRequest ); } } + +/** + * Test for bsc#1174011 auth=basic ignored in some cases + * + * If the URL specifes ?auth=basic libzypp should proactively send credentials we have available in the cred store + */ +BOOST_DATA_TEST_CASE( dltest_auth_basic, bdata::make( withSSL ), withSSL ) +{ + //don't write or read creds from real settings dir + zypp::filesystem::TmpDir repoManagerRoot; + zypp::ZConfig::instance().setRepoManagerRoot( repoManagerRoot.path() ); + + auto ev = zyppng::EventDispatcher::createMain(); + + zyppng::Downloader downloader; + + WebServer web((zypp::Pathname(TESTS_SRC_DIR)/"/zyppng/data/downloader").c_str(), 10001, withSSL ); + BOOST_REQUIRE( web.start() ); + + zypp::filesystem::TmpFile targetFile; + zyppng::Url weburl (web.url()); + weburl.setPathName("/handler/test.txt"); + weburl.setQueryParam("auth", "basic"); + weburl.setUsername("test"); + + // make sure the creds are already available + zypp::media::CredentialManager cm( repoManagerRoot.path() ); + zypp::media::AuthData data ("test", "test"); + data.setUrl( weburl ); + cm.addCred( data ); + cm.save(); + + zyppng::TransferSettings set = web.transferSettings(); + + web.addRequestHandler( "test.txt", createAuthHandler() ); + web.addRequestHandler( "quit", [ &ev ]( WebServer::Request & ){ ev->quit();} ); + + { + // simply check by request count if the test was successfull: + // if the proactive code adding the credentials to the first request is not executed we will + // have more than 1 request. + int reqCount = 0; + auto dispatcher = downloader.requestDispatcher(); + dispatcher->sigDownloadStarted().connect([&]( zyppng::NetworkRequestDispatcher &, zyppng::NetworkRequest & ){ + reqCount++; + }); + + + auto dl = downloader.downloadFile( weburl, targetFile.path() ); + dl->setMultiPartHandlingEnabled( false ); + + dl->settings() = set; + + dl->sigFinished( ).connect([ &ev ]( zyppng::Download & ){ + ev->quit(); + }); + + dl->start(); + ev->run(); + BOOST_TEST_REQ_SUCCESS( dl ); + BOOST_REQUIRE_EQUAL( reqCount, 1 ); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/zypp/RepoInfo.cc new/libzypp-17.24.1/zypp/RepoInfo.cc --- old/libzypp-17.24.0/zypp/RepoInfo.cc 2020-04-03 17:01:13.000000000 +0200 +++ new/libzypp-17.24.1/zypp/RepoInfo.cc 2020-07-16 17:57:57.000000000 +0200 @@ -920,7 +920,8 @@ if ( ! (rawMirrorListUrl().asString().empty()) ) str << (_pimpl->_mirrorListForceMetalink ? "metalink=" : "mirrorlist=") << rawMirrorListUrl() << endl; - str << "type=" << type().asString() << endl; + if ( type() != repo::RepoType::NONE ) + str << "type=" << type().asString() << endl; if ( priority() != defaultPriority() ) str << "priority=" << priority() << endl; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/zypp/RepoManager.cc new/libzypp-17.24.1/zypp/RepoManager.cc --- old/libzypp-17.24.0/zypp/RepoManager.cc 2020-04-03 17:01:13.000000000 +0200 +++ new/libzypp-17.24.1/zypp/RepoManager.cc 2020-07-16 17:57:57.000000000 +0200 @@ -1118,20 +1118,24 @@ if ( repokind != probed ) { repokind = probed; - // Adjust the probed type in RepoInfo - info.setProbedType( repokind ); // lazy init! - //save probed type only for repos in system + // update probed type only for repos in system for_( it, repoBegin(), repoEnd() ) { if ( info.alias() == (*it).alias() ) { RepoInfo modifiedrepo = *it; modifiedrepo.setType( repokind ); - modifyRepository( info.alias(), modifiedrepo ); + // don't modify .repo in refresh. + // modifyRepository( info.alias(), modifiedrepo ); break; } } + // Adjust the probed type in RepoInfo + info.setProbedType( repokind ); // lazy init! } + // no need to continue with an unknown type + if ( repokind.toEnum() == RepoType::NONE_e ) + ZYPP_THROW(RepoUnknownTypeException( info )); } Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/zypp/media/CurlHelper.cc new/libzypp-17.24.1/zypp/media/CurlHelper.cc --- old/libzypp-17.24.0/zypp/media/CurlHelper.cc 2020-04-03 17:01:13.000000000 +0200 +++ new/libzypp-17.24.1/zypp/media/CurlHelper.cc 2020-07-15 11:38:29.000000000 +0200 @@ -28,25 +28,33 @@ int log_curl(CURL *curl, curl_infotype info, char *ptr, size_t len, void *max_lvl) { - std::string pfx(" "); - long lvl = 0; - switch( info) + if ( max_lvl == nullptr ) + return 0; + + long maxlvl = *((long *)max_lvl); + + char pfx = ' '; + switch( info ) { - case CURLINFO_TEXT: lvl = 1; pfx = "*"; break; - case CURLINFO_HEADER_IN: lvl = 2; pfx = "<"; break; - case CURLINFO_HEADER_OUT: lvl = 2; pfx = ">"; break; - default: break; + case CURLINFO_TEXT: if ( maxlvl < 1 ) return 0; pfx = '*'; break; + case CURLINFO_HEADER_IN: if ( maxlvl < 2 ) return 0; pfx = '<'; break; + case CURLINFO_HEADER_OUT: if ( maxlvl < 2 ) return 0; pfx = '>'; break; + default: + return 0; } - if( lvl > 0 && max_lvl != NULL && lvl <= *((long *)max_lvl)) + + std::vector<std::string> lines; + str::split( std::string(ptr,len), std::back_inserter(lines), "\r\n" ); + for( const auto & line : lines ) { - std::string msg(ptr, len); - std::list<std::string> lines; - std::list<std::string>::const_iterator line; - zypp::str::split(msg, std::back_inserter(lines), "\r\n"); - for(line = lines.begin(); line != lines.end(); ++line) - { - DBG << pfx << " " << *line << std::endl; + if ( str::startsWith( line, "Authorization:" ) ) { + std::string::size_type pos { line.find( " ", 15 ) }; // Authorization: <type> <credentials> + if ( pos == std::string::npos ) + pos = 15; + DBG << pfx << " " << line.substr( 0, pos ) << " <credentials removed>" << std::endl; } + else + DBG << pfx << " " << line << std::endl; } return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/zypp/media/MediaCurl.cc new/libzypp-17.24.1/zypp/media/MediaCurl.cc --- old/libzypp-17.24.0/zypp/media/MediaCurl.cc 2020-04-03 17:01:13.000000000 +0200 +++ new/libzypp-17.24.1/zypp/media/MediaCurl.cc 2020-07-16 10:41:37.000000000 +0200 @@ -380,6 +380,26 @@ SET_OPTION(CURLOPT_USERAGENT, _settings.userAgentString().c_str() ); + /* Fixes bsc#1174011 "auth=basic ignored in some cases" + * We should proactively add the password to the request if basic auth is configured + * and a password is available in the credentials but not in the URL. + * + * We will be a bit paranoid here and require that the URL has a user embedded, otherwise we go the default route + * and ask the server first about the auth method + */ + if ( _settings.authType() == "basic" + && _settings.username().size() + && !_settings.password().size() ) { + + CredentialManager cm(CredManagerOptions(ZConfig::instance().repoManagerRoot())); + const auto cred = cm.getCred( _url ); + if ( cred && cred->valid() ) { + if ( !_settings.username().size() ) + _settings.setUsername(cred->username()); + _settings.setPassword(cred->password()); + } + } + /*---------------------------------------------------------------* CURLOPT_USERPWD: [user name]:[password] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/zypp/media/MediaUserAuth.cc new/libzypp-17.24.1/zypp/media/MediaUserAuth.cc --- old/libzypp-17.24.0/zypp/media/MediaUserAuth.cc 2020-04-03 17:01:13.000000000 +0200 +++ new/libzypp-17.24.1/zypp/media/MediaUserAuth.cc 2020-07-16 15:21:41.000000000 +0200 @@ -90,7 +90,12 @@ return str; } -long CurlAuthData::auth_type_str2long(std::string & auth_type_str) +long CurlAuthData::auth_type_str2long( std::string & auth_type_str ) +{ + return auth_type_str2long( const_cast< const std::string &>(auth_type_str) ); +} + +long CurlAuthData::auth_type_str2long( const std::string & auth_type_str ) { curl_version_info_data *curl_info = curl_version_info(CURLVERSION_NOW); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/zypp/media/MediaUserAuth.h new/libzypp-17.24.1/zypp/media/MediaUserAuth.h --- old/libzypp-17.24.0/zypp/media/MediaUserAuth.h 2020-04-03 17:01:13.000000000 +0200 +++ new/libzypp-17.24.1/zypp/media/MediaUserAuth.h 2020-07-16 15:21:41.000000000 +0200 @@ -135,7 +135,8 @@ * \throws MediaException if an invalid authentication type name is * encountered. */ - static long auth_type_str2long(std::string & auth_type_str); + static long auth_type_str2long( std::string & auth_type_str ); + static long auth_type_str2long( const std::string &auth_type_str ); /** * Converts a long of ORed CURLAUTH_* identifiers into a string of comma diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.24.0/zypp/zyppng/media/network/downloader.cc new/libzypp-17.24.1/zypp/zyppng/media/network/downloader.cc --- old/libzypp-17.24.0/zypp/zyppng/media/network/downloader.cc 2020-02-03 12:31:09.000000000 +0100 +++ new/libzypp-17.24.1/zypp/zyppng/media/network/downloader.cc 2020-07-16 10:41:37.000000000 +0200 @@ -665,6 +665,26 @@ internal::fillSettingsFromUrl( url, set ); if ( _transferSettings.proxy().empty() ) internal::fillSettingsSystemProxy( url, set ); + + /* Fixes bsc#1174011 "auth=basic ignored in some cases" + * We should proactively add the password to the request if basic auth is configured + * and a password is available in the credentials but not in the URL. + * + * We will be a bit paranoid here and require that the URL has a user embedded, otherwise we go the default route + * and ask the server first about the auth method + */ + if ( set.authType() == "basic" + && set.username().size() + && !set.password().size() ) { + zypp::media::CredentialManager cm( zypp::media::CredManagerOptions( zypp::ZConfig::instance().repoManagerRoot()) ); + const auto cred = cm.getCred( url ); + if ( cred && cred->valid() ) { + if ( !set.username().size() ) + set.setUsername(cred->username()); + set.setPassword(cred->password()); + } + } + } catch ( const zypp::media::MediaBadUrlException & e ) { res = NetworkRequestErrorPrivate::customError( NetworkRequestError::MalformedURL, e.asString(), buildExtraInfo() ); } catch ( const zypp::media::MediaUnauthorizedException & e ) {