[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / PasswordManager.cpp
blobd379b84c1334a8359031ffa58697b8f7865db624
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "PasswordManager.h"
11 #include "ServiceBroker.h"
12 #include "URL.h"
13 #include "profiles/ProfileManager.h"
14 #include "profiles/dialogs/GUIDialogLockSettings.h"
15 #include "settings/SettingsComponent.h"
16 #include "utils/FileUtils.h"
17 #include "utils/StringUtils.h"
18 #include "utils/XBMCTinyXML2.h"
19 #include "utils/XMLUtils.h"
20 #include "utils/log.h"
22 #include <cstring>
23 #include <mutex>
25 CPasswordManager &CPasswordManager::GetInstance()
27 static CPasswordManager sPasswordManager;
28 return sPasswordManager;
31 CPasswordManager::CPasswordManager()
33 m_loaded = false;
36 bool CPasswordManager::AuthenticateURL(CURL &url)
38 std::unique_lock<CCriticalSection> lock(m_critSection);
40 if (!m_loaded)
41 Load();
42 std::string lookup(GetLookupPath(url));
43 std::map<std::string, std::string>::const_iterator it = m_temporaryCache.find(lookup);
44 if (it == m_temporaryCache.end())
45 { // second step, try something that doesn't quite match
46 it = m_temporaryCache.find(GetServerLookup(lookup));
48 if (it != m_temporaryCache.end())
50 CURL auth(it->second);
51 url.SetDomain(auth.GetDomain());
52 url.SetPassword(auth.GetPassWord());
53 url.SetUserName(auth.GetUserName());
54 return true;
56 return false;
59 bool CPasswordManager::PromptToAuthenticateURL(CURL &url)
61 std::unique_lock<CCriticalSection> lock(m_critSection);
63 std::string passcode;
64 std::string username = url.GetUserName();
65 std::string domain = url.GetDomain();
66 if (!domain.empty())
67 username = domain + '\\' + username;
69 bool saveDetails = false;
70 if (!CGUIDialogLockSettings::ShowAndGetUserAndPassword(username, passcode, url.GetWithoutUserDetails(), &saveDetails))
71 return false;
73 // domain/name to domain\name
74 std::string name = username;
75 std::replace(name.begin(), name.end(), '/', '\\');
77 if (url.IsProtocol("smb") && name.find('\\') != std::string::npos)
79 auto pair = StringUtils::Split(name, '\\', 2);
80 url.SetDomain(pair[0]);
81 url.SetUserName(pair[1]);
83 else
85 url.SetDomain("");
86 url.SetUserName(username);
89 url.SetPassword(passcode);
91 // save the information for later
92 SaveAuthenticatedURL(url, saveDetails);
93 return true;
96 void CPasswordManager::SaveAuthenticatedURL(const CURL &url, bool saveToProfile)
98 // don't store/save authenticated url if it doesn't contain username
99 if (url.GetUserName().empty())
100 return;
102 std::unique_lock<CCriticalSection> lock(m_critSection);
104 std::string path = GetLookupPath(url);
105 std::string authenticatedPath = url.Get();
107 if (!m_loaded)
108 Load();
110 if (saveToProfile)
111 { // write to some random XML file...
112 m_permanentCache[path] = authenticatedPath;
113 Save();
116 // save for both this path and more generally the server as a whole.
117 m_temporaryCache[path] = authenticatedPath;
118 m_temporaryCache[GetServerLookup(path)] = authenticatedPath;
121 bool CPasswordManager::IsURLSupported(const CURL &url)
123 return url.IsProtocol("smb")
124 || url.IsProtocol("nfs")
125 || url.IsProtocol("ftp")
126 || url.IsProtocol("ftps")
127 || url.IsProtocol("sftp")
128 || url.IsProtocol("http")
129 || url.IsProtocol("https")
130 || url.IsProtocol("dav")
131 || url.IsProtocol("davs");
134 void CPasswordManager::Clear()
136 m_temporaryCache.clear();
137 m_permanentCache.clear();
138 m_loaded = false;
141 void CPasswordManager::Load()
143 Clear();
145 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
147 std::string passwordsFile = profileManager->GetUserDataItem("passwords.xml");
148 if (CFileUtils::Exists(passwordsFile))
150 CXBMCTinyXML2 doc;
151 if (!doc.LoadFile(passwordsFile))
153 CLog::LogF(LOGERROR, "Unable to load: {}, Line {}\n{}", passwordsFile, doc.ErrorLineNum(),
154 doc.ErrorStr());
155 return;
157 const auto* root = doc.RootElement();
158 if (root == nullptr)
159 return;
161 if (std::strcmp(root->Value(), "passwords") != 0)
162 return;
163 // read in our passwords
164 const auto* path = root->FirstChildElement("path");
165 while (path != nullptr)
167 std::string from, to;
168 if (XMLUtils::GetPath(path, "from", from) && XMLUtils::GetPath(path, "to", to))
170 m_permanentCache[from] = to;
171 m_temporaryCache[from] = to;
172 m_temporaryCache[GetServerLookup(from)] = to;
174 path = path->NextSiblingElement("path");
177 m_loaded = true;
180 void CPasswordManager::Save() const
182 if (m_permanentCache.empty())
183 return;
185 CXBMCTinyXML2 doc;
186 auto* rootElement = doc.NewElement("passwords");
187 if (rootElement == nullptr)
188 return;
190 auto* root = doc.InsertEndChild(rootElement);
191 if (root == nullptr)
192 return;
194 for (std::map<std::string, std::string>::const_iterator i = m_permanentCache.begin(); i != m_permanentCache.end(); ++i)
196 auto* pathElement = doc.NewElement("path");
197 if (pathElement == nullptr)
198 continue;
200 auto* path = root->InsertEndChild(pathElement);
201 if (path == nullptr)
202 continue;
204 XMLUtils::SetPath(path, "from", i->first);
205 XMLUtils::SetPath(path, "to", i->second);
208 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
210 doc.SaveFile(profileManager->GetUserDataItem("passwords.xml"));
213 std::string CPasswordManager::GetLookupPath(const CURL &url) const
215 if (url.IsProtocol("sftp"))
216 return GetServerLookup(url.Get());
218 return url.GetProtocol() + "://" + url.GetHostName() + "/" + url.GetShareName();
221 std::string CPasswordManager::GetServerLookup(const std::string &path) const
223 CURL url(path);
224 return url.GetProtocol() + "://" + url.GetHostName() + "/";