Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Database.h « core « src - github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8feb7e56bf813117898ed4d158d8afd504c29c77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*
 *  Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
 *  Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 or (at your option)
 *  version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef KEEPASSX_DATABASE_H
#define KEEPASSX_DATABASE_H

#include <QDateTime>
#include <QHash>
#include <QMutex>
#include <QPointer>
#include <QScopedPointer>
#include <QTimer>

#include "config-keepassx.h"
#include "crypto/kdf/AesKdf.h"
#include "crypto/kdf/Kdf.h"
#include "format/KeePass2.h"
#include "keys/CompositeKey.h"
#include "keys/PasswordKey.h"

class Entry;
enum class EntryReferenceType;
class FileWatcher;
class Group;
class Metadata;
class QIODevice;

struct DeletedObject
{
    QUuid uuid;
    QDateTime deletionTime;
    bool operator==(const DeletedObject& other) const
    {
        return uuid == other.uuid && deletionTime == other.deletionTime;
    }
};

Q_DECLARE_TYPEINFO(DeletedObject, Q_MOVABLE_TYPE);

class Database : public QObject
{
    Q_OBJECT

public:
    enum CompressionAlgorithm
    {
        CompressionNone = 0,
        CompressionGZip = 1
    };
    static const quint32 CompressionAlgorithmMax = CompressionGZip;

    Database();
    explicit Database(const QString& filePath);
    ~Database() override;

    bool open(QSharedPointer<const CompositeKey> key, QString* error = nullptr, bool readOnly = false);
    bool open(const QString& filePath,
              QSharedPointer<const CompositeKey> key,
              QString* error = nullptr,
              bool readOnly = false);
    bool save(QString* error = nullptr, bool atomic = true, bool backup = false);
    bool saveAs(const QString& filePath, QString* error = nullptr, bool atomic = true, bool backup = false);
    bool extract(QByteArray&, QString* error = nullptr);
    bool import(const QString& xmlExportPath, QString* error = nullptr);

    void releaseData();

    bool isInitialized() const;
    bool isModified() const;
    void setEmitModified(bool value);
    bool isReadOnly() const;
    void setReadOnly(bool readOnly);
    bool isSaving();

    QUuid uuid() const;
    QString filePath() const;
    QString canonicalFilePath() const;
    void setFilePath(const QString& filePath);

    Metadata* metadata();
    const Metadata* metadata() const;
    Group* rootGroup();
    const Group* rootGroup() const;
    void setRootGroup(Group* group);
    QVariantMap& publicCustomData();
    const QVariantMap& publicCustomData() const;
    void setPublicCustomData(const QVariantMap& customData);

    void recycleGroup(Group* group);
    void recycleEntry(Entry* entry);
    void emptyRecycleBin();
    QList<DeletedObject> deletedObjects();
    const QList<DeletedObject>& deletedObjects() const;
    void addDeletedObject(const DeletedObject& delObj);
    void addDeletedObject(const QUuid& uuid);
    bool containsDeletedObject(const QUuid& uuid) const;
    bool containsDeletedObject(const DeletedObject& uuid) const;
    void setDeletedObjects(const QList<DeletedObject>& delObjs);

    QList<QString> commonUsernames();

    QSharedPointer<const CompositeKey> key() const;
    bool setKey(const QSharedPointer<const CompositeKey>& key,
                bool updateChangedTime = true,
                bool updateTransformSalt = false,
                bool transformKey = true);
    QString keyError();
    QByteArray challengeResponseKey() const;
    bool challengeMasterSeed(const QByteArray& masterSeed);
    const QUuid& cipher() const;
    void setCipher(const QUuid& cipher);
    Database::CompressionAlgorithm compressionAlgorithm() const;
    void setCompressionAlgorithm(Database::CompressionAlgorithm algo);

    QSharedPointer<Kdf> kdf() const;
    void setKdf(QSharedPointer<Kdf> kdf);
    bool changeKdf(const QSharedPointer<Kdf>& kdf);
    QByteArray transformedMasterKey() const;

    static Database* databaseByUuid(const QUuid& uuid);

public slots:
    void markAsModified();
    void markAsClean();
    void updateCommonUsernames(int topN = 10);

signals:
    void filePathChanged(const QString& oldPath, const QString& newPath);
    void groupDataChanged(Group* group);
    void groupAboutToAdd(Group* group, int index);
    void groupAdded();
    void groupAboutToRemove(Group* group);
    void groupRemoved();
    void groupAboutToMove(Group* group, Group* toGroup, int index);
    void groupMoved();
    void databaseOpened();
    void databaseModified();
    void databaseSaved();
    void databaseDiscarded();
    void databaseFileChanged();

private:
    struct DatabaseData
    {
        QString filePath;
        bool isReadOnly = false;
        QUuid cipher = KeePass2::CIPHER_AES256;
        CompressionAlgorithm compressionAlgorithm = CompressionGZip;

        QScopedPointer<PasswordKey> masterSeed;
        QScopedPointer<PasswordKey> transformedMasterKey;
        QScopedPointer<PasswordKey> challengeResponseKey;

        QSharedPointer<const CompositeKey> key;
        QSharedPointer<Kdf> kdf = QSharedPointer<AesKdf>::create(true);

        QVariantMap publicCustomData;

        DatabaseData()
            : masterSeed(new PasswordKey())
            , transformedMasterKey(new PasswordKey())
            , challengeResponseKey(new PasswordKey())
        {
            kdf->randomizeSeed();
        }

        void clear()
        {
            filePath.clear();

            masterSeed.reset();
            transformedMasterKey.reset();
            challengeResponseKey.reset();

            key.reset();
            kdf.reset();

            publicCustomData.clear();
        }
    };

    void createRecycleBin();

    bool writeDatabase(QIODevice* device, QString* error = nullptr);
    bool backupDatabase(const QString& filePath);
    bool restoreDatabase(const QString& filePath);
    bool performSave(const QString& filePath, QString* error, bool atomic, bool backup);

    QPointer<Metadata> const m_metadata;
    DatabaseData m_data;
    QPointer<Group> m_rootGroup;
    QList<DeletedObject> m_deletedObjects;
    QTimer m_modifiedTimer;
    QMutex m_saveMutex;
    QPointer<FileWatcher> m_fileWatcher;
    bool m_modified = false;
    bool m_emitModified;
    QString m_keyError;

    QList<QString> m_commonUsernames;

    QUuid m_uuid;
    static QHash<QUuid, QPointer<Database>> s_uuidMap;
};

#endif // KEEPASSX_DATABASE_H