1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/CredentialManager.h
15 #include "zypp/ZConfig.h"
16 #include "zypp/base/Function.h"
17 #include "zypp/base/Logger.h"
18 #include "zypp/base/Easy.h"
19 #include "zypp/PathInfo.h"
21 #include "zypp/media/CredentialFileReader.h"
23 #include "zypp/media/CredentialManager.h"
25 #define USER_CREDENTIALS_FILE ".zypp/credentials.cat"
29 //////////////////////////////////////////////////////////////////////
31 { ////////////////////////////////////////////////////////////////////
32 //////////////////////////////////////////////////////////////////////
34 { ////////////////////////////////////////////////////////////////////
37 //////////////////////////////////////////////////////////////////////
39 // CLASS NAME : CredManagerOptions
41 //////////////////////////////////////////////////////////////////////
43 CredManagerOptions::CredManagerOptions(const Pathname & rootdir)
44 : globalCredFilePath(rootdir / ZConfig::instance().credentialsGlobalFile())
45 , customCredFileDir(rootdir / ZConfig::instance().credentialsGlobalDir())
47 char * homedir = getenv("HOME");
49 userCredFilePath = rootdir / homedir / USER_CREDENTIALS_FILE;
53 //////////////////////////////////////////////////////////////////////
55 // CLASS NAME : CredentialManager::Impl
57 struct CredentialManager::Impl
59 Impl(const CredManagerOptions & options);
64 void init_globalCredentials();
65 void init_userCredentials();
67 bool processCredentials(AuthData_Ptr & cred);
69 AuthData_Ptr getCred(const Url & url) const;
70 AuthData_Ptr getCredFromFile(const Pathname & file);
71 void saveGlobalCredentials();
72 void saveUserCredentials();
75 CredManagerOptions _options;
77 CredentialSet _credsGlobal;
78 CredentialSet _credsUser;
79 CredentialSet _credsTmp;
84 //////////////////////////////////////////////////////////////////////
87 //////////////////////////////////////////////////////////////////////
89 // CLASS NAME : CredentialManager::Impl
91 //////////////////////////////////////////////////////////////////////
93 CredentialManager::Impl::Impl(const CredManagerOptions & options)
98 init_globalCredentials();
99 init_userCredentials();
103 void CredentialManager::Impl::init_globalCredentials()
105 if (_options.globalCredFilePath.empty())
106 DBG << "global cred file not known";
107 else if (PathInfo(_options.globalCredFilePath).isExist())
109 /* list<Pathname> entries;
110 if (filesystem::readdir(entries, _options.globalCredFilePath, false) != 0)
111 ZYPP_THROW(Exception("failed to read directory"));
113 for_(it, entries.begin(), entries.end())*/
115 CredentialFileReader(_options.globalCredFilePath,
116 bind(&Impl::processCredentials, this, _1));
119 DBG << "global cred file does not exist";
121 _credsGlobal = _credsTmp; _credsTmp.clear();
122 DBG << "Got " << _credsGlobal.size() << " global records." << endl;
126 void CredentialManager::Impl::init_userCredentials()
128 if (_options.userCredFilePath.empty())
129 DBG << "user cred file not known";
130 else if (PathInfo(_options.userCredFilePath).isExist())
132 /* list<Pathname> entries;
133 if (filesystem::readdir(entries, _options.userCredFilePath, false ) != 0)
134 ZYPP_THROW(Exception("failed to read directory"));
136 for_(it, entries.begin(), entries.end())*/
137 CredentialFileReader(_options.userCredFilePath,
138 bind(&Impl::processCredentials, this, _1));
141 DBG << "user cred file does not exist" << endl;
143 _credsUser = _credsTmp; _credsTmp.clear();
144 DBG << "Got " << _credsUser.size() << " user records." << endl;
148 bool CredentialManager::Impl::processCredentials(AuthData_Ptr & cred)
150 _credsTmp.insert(cred);
155 static AuthData_Ptr findIn(const CredentialManager::CredentialSet & set,
157 url::ViewOption vopt)
159 const string & username = url.getUsername();
160 for(CredentialManager::CredentialIterator it = set.begin(); it != set.end(); ++it)
162 // this ignores url params - not sure if it is good or bad...
163 if (url.asString(vopt).find((*it)->url().asString(vopt)) == 0)
165 if (username.empty() || username == (*it)->username())
170 return AuthData_Ptr();
174 AuthData_Ptr CredentialManager::Impl::getCred(const Url & url) const
178 // compare the urls via asString(), but ignore password
179 // default url::ViewOption will take care of that.
180 // operator==(Url,Url) compares the whole Url
182 url::ViewOption vopt;
184 - url::ViewOption::WITH_USERNAME
185 - url::ViewOption::WITH_PASSWORD
186 - url::ViewOption::WITH_QUERY_STR;
188 // search in global credentials
189 result = findIn(_credsGlobal, url, vopt);
191 // search in home credentials
193 result = findIn(_credsUser, url, vopt);
196 DBG << "Found credentials for '" << url << "':" << endl << *result;
198 DBG << "No credentials for '" << url << "'" << endl;
204 AuthData_Ptr CredentialManager::Impl::getCredFromFile(const Pathname & file)
210 // get from that file
213 // get from /etc/zypp/credentials.d, delete the leading path
214 credfile = _options.customCredFileDir / file.basename();
216 CredentialFileReader(credfile, bind(&Impl::processCredentials, this, _1));
217 if (_credsTmp.empty())
218 WAR << file << " does not contain valid credentials or is not readable." << endl;
221 result = *_credsTmp.begin();
228 static int save_creds_in_file(
229 const CredentialManager::CredentialSet creds,
230 const Pathname & file,
234 filesystem::assert_dir(file.dirname());
236 std::ofstream fs(file.c_str());
240 for_(it, creds.begin(), creds.end())
242 (*it)->dumpAsIniOn(fs);
247 filesystem::chmod(file, mode);
252 void CredentialManager::Impl::saveGlobalCredentials()
254 save_creds_in_file(_credsGlobal, _options.globalCredFilePath, 0640);
257 void CredentialManager::Impl::saveUserCredentials()
259 save_creds_in_file(_credsUser, _options.userCredFilePath, 0600);
263 //////////////////////////////////////////////////////////////////////
265 // CLASS NAME : CredentialManager
267 //////////////////////////////////////////////////////////////////////
269 CredentialManager::CredentialManager(const CredManagerOptions & opts)
270 : _pimpl(new Impl(opts))
274 AuthData_Ptr CredentialManager::getCred(const Url & url)
276 string credfile = url.getQueryParam("credentials");
277 if (credfile.empty())
278 return _pimpl->getCred(url);
279 return _pimpl->getCredFromFile(credfile);
283 AuthData_Ptr CredentialManager::getCredFromFile(const Pathname & file)
284 { return _pimpl->getCredFromFile(file); }
287 void CredentialManager::addCred(const AuthData & cred)
289 #warning addCred(const AuthData & cred) not implemented
290 // add with user callbacks
294 void CredentialManager::addGlobalCred(const AuthData & cred)
297 c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed
298 if (_pimpl->_credsGlobal.insert(c_ptr).second)
299 _pimpl->_globalDirty = true;
303 void CredentialManager::addUserCred(const AuthData & cred)
306 c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed
307 if (_pimpl->_credsUser.insert(c_ptr).second)
308 _pimpl->_userDirty = true;
312 void CredentialManager::save()
314 if (_pimpl->_globalDirty)
315 _pimpl->saveGlobalCredentials();
316 if (_pimpl->_userDirty)
317 _pimpl->saveUserCredentials();
318 _pimpl->_globalDirty = false;
319 _pimpl->_userDirty = false;
323 void CredentialManager::saveInGlobal(const AuthData & cred)
330 void CredentialManager::saveInUser(const AuthData & cred)
337 void CredentialManager::saveInFile(const AuthData & cred, const Pathname & credFile)
340 c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed
341 CredentialManager::CredentialSet creds;
345 if (credFile.absolute())
346 ret = save_creds_in_file(creds, credFile, 0640);
348 ret = save_creds_in_file(
349 creds, _pimpl->_options.customCredFileDir / credFile, 0600);
353 //! \todo figure out the reason(?), call back to user
354 ERR << "error saving the credentials" << endl;
359 void CredentialManager::clearAll(bool global)
363 if (!filesystem::unlink(_pimpl->_options.globalCredFilePath))
364 ERR << "could not delete user credentials file "
365 << _pimpl->_options.globalCredFilePath << endl;
366 _pimpl->_credsUser.clear();
370 if (!filesystem::unlink(_pimpl->_options.userCredFilePath))
371 ERR << "could not delete global credentials file"
372 << _pimpl->_options.userCredFilePath << endl;
373 _pimpl->_credsGlobal.clear();
378 CredentialManager::CredentialIterator CredentialManager::credsGlobalBegin() const
379 { return _pimpl->_credsGlobal.begin(); }
381 CredentialManager::CredentialIterator CredentialManager::credsGlobalEnd() const
382 { return _pimpl->_credsGlobal.end(); }
384 CredentialManager::CredentialSize CredentialManager::credsGlobalSize() const
385 { return _pimpl->_credsGlobal.size(); }
387 bool CredentialManager::credsGlobalEmpty() const
388 { return _pimpl->_credsGlobal.empty(); }
391 CredentialManager::CredentialIterator CredentialManager::credsUserBegin() const
392 { return _pimpl->_credsUser.begin(); }
394 CredentialManager::CredentialIterator CredentialManager::credsUserEnd() const
395 { return _pimpl->_credsUser.end(); }
397 CredentialManager::CredentialSize CredentialManager::credsUserSize() const
398 { return _pimpl->_credsUser.size(); }
400 bool CredentialManager::credsUserEmpty() const
401 { return _pimpl->_credsUser.empty(); }
404 ////////////////////////////////////////////////////////////////////
406 //////////////////////////////////////////////////////////////////////
407 ////////////////////////////////////////////////////////////////////
409 //////////////////////////////////////////////////////////////////////