2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "PasswordManager.h"
22 #include "profiles/ProfilesManager.h"
23 #include "profiles/dialogs/GUIDialogLockSettings.h"
25 #include "utils/XMLUtils.h"
26 #include "threads/SingleLock.h"
27 #include "utils/log.h"
28 #include "filesystem/File.h"
32 CPasswordManager &CPasswordManager::GetInstance()
34 static CPasswordManager sPasswordManager;
35 return sPasswordManager;
38 CPasswordManager::CPasswordManager()
43 bool CPasswordManager::AuthenticateURL(CURL &url)
45 CSingleLock lock(m_critSection);
49 CStdString lookup(GetLookupPath(url));
50 map<CStdString, CStdString>::const_iterator it = m_temporaryCache.find(lookup);
51 if (it == m_temporaryCache.end())
52 { // second step, try something that doesn't quite match
53 it = m_temporaryCache.find(GetServerLookup(lookup));
55 if (it != m_temporaryCache.end())
57 CURL auth(it->second);
58 url.SetPassword(auth.GetPassWord());
59 url.SetUserName(auth.GetUserName());
65 bool CPasswordManager::PromptToAuthenticateURL(CURL &url)
67 CSingleLock lock(m_critSection);
70 CStdString username = url.GetUserName();
71 CStdString path = GetLookupPath(url);
73 bool saveDetails = false;
74 if (!CGUIDialogLockSettings::ShowAndGetUserAndPassword(username, passcode, url.GetWithoutUserDetails(), &saveDetails))
77 url.SetPassword(passcode);
78 url.SetUserName(username);
80 // save the information for later
81 SaveAuthenticatedURL(url, saveDetails);
85 void CPasswordManager::SaveAuthenticatedURL(const CURL &url, bool saveToProfile)
87 // don't store/save authenticated url if it doesn't contain username
88 if (url.GetUserName().empty())
91 CSingleLock lock(m_critSection);
93 CStdString path = GetLookupPath(url);
94 CStdString authenticatedPath = url.Get();
100 { // write to some random XML file...
101 m_permanentCache[path] = authenticatedPath;
105 // save for both this path and more generally the server as a whole.
106 m_temporaryCache[path] = authenticatedPath;
107 m_temporaryCache[GetServerLookup(path)] = authenticatedPath;
110 void CPasswordManager::Clear()
112 m_temporaryCache.clear();
113 m_permanentCache.clear();
117 void CPasswordManager::Load()
120 CStdString passwordsFile = CProfilesManager::Get().GetUserDataItem("passwords.xml");
121 if (XFILE::CFile::Exists(passwordsFile))
124 if (!doc.LoadFile(passwordsFile))
126 CLog::Log(LOGERROR, "%s - Unable to load: %s, Line %d\n%s",
127 __FUNCTION__, passwordsFile.c_str(), doc.ErrorRow(), doc.ErrorDesc());
130 const TiXmlElement *root = doc.RootElement();
131 if (root->ValueStr() != "passwords")
133 // read in our passwords
134 const TiXmlElement *path = root->FirstChildElement("path");
138 if (XMLUtils::GetPath(path, "from", from) && XMLUtils::GetPath(path, "to", to))
140 m_permanentCache[from] = to;
141 m_temporaryCache[from] = to;
142 m_temporaryCache[GetServerLookup(from)] = to;
144 path = path->NextSiblingElement("path");
150 void CPasswordManager::Save() const
152 if (m_permanentCache.empty())
156 TiXmlElement rootElement("passwords");
157 TiXmlNode *root = doc.InsertEndChild(rootElement);
161 for (map<CStdString, CStdString>::const_iterator i = m_permanentCache.begin(); i != m_permanentCache.end(); ++i)
163 TiXmlElement pathElement("path");
164 TiXmlNode *path = root->InsertEndChild(pathElement);
165 XMLUtils::SetPath(path, "from", i->first);
166 XMLUtils::SetPath(path, "to", i->second);
169 doc.SaveFile(CProfilesManager::Get().GetUserDataItem("passwords.xml"));
172 CStdString CPasswordManager::GetLookupPath(const CURL &url) const
174 return "smb://" + url.GetHostName() + "/" + url.GetShareName();
177 CStdString CPasswordManager::GetServerLookup(const CStdString &path) const
180 return "smb://" + url.GetHostName() + "/";