1 /*
2 * Copyright (C) 2013 Francois Ferrand
3 * Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
4 * Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 or (at your option)
9 * version 3 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef BROWSERSERVICE_H
21 #define BROWSERSERVICE_H
22
23 #include "core/Entry.h"
24 #include <QObject>
25 #include <QPointer>
26 #include <QSharedPointer>
27 #include <QtCore>
28
29 typedef QPair<QString, QString> StringPair;
30 typedef QList<StringPair> StringPairList;
31
32 enum
33 {
34 max_length = 16 * 1024
35 };
36
37 class DatabaseWidget;
38 class BrowserHost;
39 class BrowserAction;
40
41 class BrowserService : public QObject
42 {
43 Q_OBJECT
44
45 public:
46 explicit BrowserService();
47 static BrowserService* instance();
48
49 void setEnabled(bool enabled);
50
51 QString getKey(const QString& id);
52 QString storeKey(const QString& key);
53 QString getDatabaseHash(bool legacy = false);
54
55 bool isDatabaseOpened() const;
56 bool openDatabase(bool triggerUnlock);
57 void lockDatabase();
58
59 QJsonObject getDatabaseGroups();
60 QJsonObject createNewGroup(const QString& groupName);
61 QString getCurrentTotp(const QString& uuid);
62
63 void addEntry(const QString& dbid,
64 const QString& login,
65 const QString& password,
66 const QString& siteUrlStr,
67 const QString& formUrlStr,
68 const QString& realm,
69 const QString& group,
70 const QString& groupUuid,
71 const QSharedPointer<Database>& selectedDb = {});
72 bool updateEntry(const QString& dbid,
73 const QString& uuid,
74 const QString& login,
75 const QString& password,
76 const QString& siteUrlStr,
77 const QString& formUrlStr);
78
79 QJsonArray findMatchingEntries(const QString& dbid,
80 const QString& siteUrlStr,
81 const QString& formUrlStr,
82 const QString& realm,
83 const StringPairList& keyList,
84 const bool httpAuth = false);
85
86 static void convertAttributesToCustomData(QSharedPointer<Database> db);
87
88 static const QString KEEPASSXCBROWSER_NAME;
89 static const QString KEEPASSXCBROWSER_OLD_NAME;
90 static const QString OPTION_SKIP_AUTO_SUBMIT;
91 static const QString OPTION_HIDE_ENTRY;
92 static const QString OPTION_ONLY_HTTP_AUTH;
93 static const QString OPTION_NOT_HTTP_AUTH;
94 static const QString ADDITIONAL_URL;
95
96 signals:
97 void requestUnlock();
98
99 public slots:
100 void databaseLocked(DatabaseWidget* dbWidget);
101 void databaseUnlocked(DatabaseWidget* dbWidget);
102 void activeDatabaseChanged(DatabaseWidget* dbWidget);
103
104 private slots:
105 void processClientMessage(const QJsonObject& message);
106
107 private:
108 enum Access
109 {
110 Denied,
111 Unknown,
112 Allowed
113 };
114
115 enum WindowState
116 {
117 Normal,
118 Minimized,
119 Hidden
120 };
121
122 QList<Entry*>
123 searchEntries(const QSharedPointer<Database>& db, const QString& siteUrlStr, const QString& formUrlStr);
124 QList<Entry*> searchEntries(const QString& siteUrlStr, const QString& formUrlStr, const StringPairList& keyList);
125 QList<Entry*> sortEntries(QList<Entry*>& pwEntries, const QString& siteUrlStr, const QString& formUrlStr);
126 QList<Entry*> confirmEntries(QList<Entry*>& pwEntriesToConfirm,
127 const QString& siteUrlStr,
128 const QString& siteHost,
129 const QString& formUrlStr,
130 const QString& realm,
131 const bool httpAuth);
132 QJsonObject prepareEntry(const Entry* entry);
133 QJsonArray getChildrenFromGroup(Group* group);
134 Access checkAccess(const Entry* entry, const QString& siteHost, const QString& formHost, const QString& realm);
135 Group* getDefaultEntryGroup(const QSharedPointer<Database>& selectedDb = {});
136 int sortPriority(const QStringList& urls, const QString& siteUrlStr, const QString& formUrlStr);
137 bool schemeFound(const QString& url);
138 bool removeFirstDomain(QString& hostname);
139 bool handleURL(const QString& entryUrl, const QString& siteUrlStr, const QString& formUrlStr);
140 QString baseDomain(const QString& hostname) const;
141 QSharedPointer<Database> getDatabase();
142 QSharedPointer<Database> selectedDatabase();
143 QString getDatabaseRootUuid();
144 QString getDatabaseRecycleBinUuid();
145 bool checkLegacySettings(QSharedPointer<Database> db);
146 QStringList getEntryURLs(const Entry* entry);
147
148 void hideWindow() const;
149 void raiseWindow(const bool force = false);
150 void updateWindowState();
151
152 static bool moveSettingsToCustomData(Entry* entry, const QString& name);
153 static int moveKeysToCustomData(Entry* entry, QSharedPointer<Database> db);
154
155 QPointer<BrowserHost> m_browserHost;
156 QHash<QString, QSharedPointer<BrowserAction>> m_browserClients;
157
158 bool m_dialogActive;
159 bool m_bringToFrontRequested;
160 WindowState m_prevWindowState;
161 QUuid m_keepassBrowserUUID;
162
163 QPointer<DatabaseWidget> m_currentDatabaseWidget;
164
165 Q_DISABLE_COPY(BrowserService);
166
167 friend class TestBrowser;
168 };
169
browserService()170 static inline BrowserService* browserService()
171 {
172 return BrowserService::instance();
173 }
174
175 #endif // BROWSERSERVICE_H
176