18#include <zypp-media/MediaConfig>
19#include <zypp-core/base/Function.h>
20#include <zypp-core/base/Logger.h>
21#include <zypp-core/base/Easy.h>
22#include <zypp-core/fs/PathInfo.h>
24#include <zypp-media/auth/CredentialFileReader>
25#include <zypp-media/MediaException>
27#include <boost/interprocess/sync/file_lock.hpp>
28#include <boost/interprocess/sync/scoped_lock.hpp>
29#include <boost/interprocess/sync/sharable_lock.hpp>
31namespace bpci = boost::interprocess;
36#define USER_CREDENTIALS_FILE ".zypp/credentials.cat"
58 int cmp = lhs->url().asString(vopt).compare( rhs->url().asString(vopt) );
60 cmp = lhs->username().compare( rhs->username() );
71 : globalCredFilePath(rootdir /
MediaConfig::instance().credentialsGlobalFile())
72 , customCredFileDir(rootdir /
MediaConfig::instance().credentialsGlobalDir())
74 char * homedir = getenv(
"HOME");
122 , _globalDirty(false)
132 if (_options.globalCredFilePath.empty())
133 DBG <<
"global cred file not known";
146 DBG <<
"global cred file does not exist";
148 _credsGlobal = _credsTmp; _credsTmp.clear();
149 DBG <<
"Got " << _credsGlobal.size() <<
" global records." << endl;
155 if (_options.userCredFilePath.empty())
156 DBG <<
"user cred file not known";
168 DBG <<
"user cred file does not exist" << endl;
170 _credsUser = _credsTmp; _credsTmp.clear();
171 DBG <<
"Got " << _credsUser.size() <<
" user records." << endl;
177 _credsTmp.insert(cred);
189 if ( !(*it)->url().isValid() )
193 if ( url.
asString(vopt).find((*it)->url().asString(vopt)) == 0 )
195 if ( username.empty() || username == (*it)->username() )
218 result =
findIn(_credsGlobal, url, vopt);
222 result =
findIn(_credsUser, url, vopt);
225 DBG <<
"Found credentials for '" << url <<
"':" << endl << *result;
227 DBG <<
"No credentials for '" << url <<
"'" << endl;
243 credfile = _options.customCredFileDir / file.
basename();
246 if ( pi.userMayR() )
try {
248 bpci::file_lock lockFile ( credfile.
c_str() );
249 bpci::scoped_lock lock( lockFile );
254 WAR << pi <<
" failed to lock file for reading." << endl;
257 if (_credsTmp.empty())
258 WAR << pi <<
" does not contain valid credentials or is not readable." << endl;
261 result = *_credsTmp.begin();
276 const auto now = time(
nullptr );
279 if ( pi.userMayRW() )
try {
281 bpci::file_lock lockFile ( file.
c_str() );
282 bpci::scoped_lock lock( lockFile );
284 std::ofstream fs(file.
c_str());
285 for_(it, creds.begin(), creds.end())
287 (*it)->dumpAsIniOn(fs);
288 (*it)->setLastDatabaseUpdate( now );
292 WAR << pi <<
" failed to write credentials to file." << endl;
298 WAR << pi <<
" failed to lock file for writing." << endl;
330 if (credfile.empty())
331 return _pimpl->getCred(url);
332 return _pimpl->getCredFromFile(credfile);
337 {
return _pimpl->getCredFromFile(file); }
346 if (credfile.
empty())
360 if (credfile.
empty())
361 credfile =
_pimpl->_options.userCredFilePath;
377 std::pair<CredentialIterator, bool> ret =
_pimpl->_credsGlobal.insert(c_ptr);
379 _pimpl->_globalDirty =
true;
380 else if ((*ret.first)->password() != cred.
password())
382 _pimpl->_credsGlobal.erase(ret.first);
383 _pimpl->_credsGlobal.insert(c_ptr);
384 _pimpl->_globalDirty =
true;
396 std::pair<CredentialIterator, bool> ret =
_pimpl->_credsUser.insert(c_ptr);
398 _pimpl->_userDirty =
true;
399 else if ((*ret.first)->password() != cred.
password())
401 _pimpl->_credsUser.erase(ret.first);
402 _pimpl->_credsUser.insert(c_ptr);
403 _pimpl->_userDirty =
true;
411 _pimpl->saveGlobalCredentials();
413 _pimpl->saveUserCredentials();
414 _pimpl->_globalDirty =
false;
415 _pimpl->_userDirty =
false;
437 c_ptr->setUrl(
Url());
446 creds,
_pimpl->_options.customCredFileDir / credFile, 0600);
451 ERR <<
"error saving the credentials" << endl;
461 ERR <<
"could not delete user credentials file "
462 <<
_pimpl->_options.globalCredFilePath << endl;
463 _pimpl->_credsUser.clear();
468 ERR <<
"could not delete global credentials file"
469 <<
_pimpl->_options.userCredFilePath << endl;
470 _pimpl->_credsGlobal.clear();
476 {
return _pimpl->_credsGlobal.begin(); }
479 {
return _pimpl->_credsGlobal.end(); }
482 {
return _pimpl->_credsGlobal.size(); }
485 {
return _pimpl->_credsGlobal.empty(); }
489 {
return _pimpl->_credsUser.begin(); }
492 {
return _pimpl->_credsUser.end(); }
495 {
return _pimpl->_credsUser.size(); }
498 {
return _pimpl->_credsUser.empty(); }
std::string asString() const
Returns a default string representation of the Url object.
std::string getUsername(EEncoding eflag=zypp::url::E_DECODED) const
Returns the username from the URL authority.
std::string getQueryParam(const std::string ¶m, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
bool isValid() const
Verifies the Url.
Wrapper class for stat/lstat.
bool isExist() const
Return whether valid stat info exists.
bool absolute() const
Test for an absolute path.
const char * c_str() const
String representation.
std::string basename() const
Return the last component of this path.
bool empty() const
Test for an empty path.
#define USER_CREDENTIALS_FILE
int unlink(const Pathname &path)
Like 'unlink'.
int assert_file_mode(const Pathname &path, unsigned mode)
Like assert_file but enforce mode even if the file already exists.
Easy-to use interface to the ZYPP dependency resolver.
Url::asString() view options.
static const ViewOption WITH_PASSWORD
Option to include password in the URL string.
static const ViewOption DEFAULTS
Default combination of view options.
static const ViewOption WITH_USERNAME
Option to include username in the URL string.
static const ViewOption WITH_QUERY_STR
Option to include query string in the URL string.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.