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