1 /*
2     This file is part of the KDE project
3     SPDX-FileCopyrightText: 2001-2004 George Staikos <staikos@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #ifndef _KWALLETBACKEND_H
9 #define _KWALLETBACKEND_H
10 
11 #include "backendpersisthandler.h"
12 #include "kwalletbackend5_export.h"
13 #include "kwalletentry.h"
14 #include <QMap>
15 #include <QString>
16 #include <QStringList>
17 
18 #ifdef HAVE_GPGMEPP
19 #include <gpgme++/key.h>
20 #endif // HAVE_GPGMEPP
21 
22 #define PBKDF2_SHA512_KEYSIZE 56
23 #define PBKDF2_SHA512_SALTSIZE 56
24 #define PBKDF2_SHA512_ITERATIONS 50000
25 
26 namespace KWallet
27 {
28 /**
29  * @internal
30  */
31 class MD5Digest : public QByteArray
32 {
33 public:
MD5Digest()34     MD5Digest()
35         : QByteArray(16, 0)
36     {
37     }
MD5Digest(const char * data)38     MD5Digest(const char *data)
39         : QByteArray(data, 16)
40     {
41     }
MD5Digest(const QByteArray & digest)42     MD5Digest(const QByteArray &digest)
43         : QByteArray(digest)
44     {
45     }
~MD5Digest()46     virtual ~MD5Digest()
47     {
48     }
49 
50     int operator<(const MD5Digest &r) const
51     {
52         int i = 0;
53         char x, y;
54         for (; i < 16; ++i) {
55             x = at(i);
56             y = r.at(i);
57             if (x != y) {
58                 break;
59             }
60         }
61         if (i < 16 && x < y) {
62             return 1;
63         }
64         return 0;
65     }
66 };
67 
68 /* @internal
69  */
70 class KWALLETBACKEND5_EXPORT Backend
71 {
72 public:
73     explicit Backend(const QString &name = QStringLiteral("kdewallet"), bool isPath = false);
74     ~Backend();
75 
76     // Open and unlock the wallet.
77     // If opening succeeds, the password's hash will be remembered.
78     // If opening fails, the password's hash will be cleared.
79     int open(const QByteArray &password, WId w = 0);
80 #ifdef HAVE_GPGMEPP
81     int open(const GpgME::Key &key);
82 #endif
83 
84     // Open and unlock the wallet using a pre-hashed password.
85     // If opening succeeds, the password's hash will be remembered.
86     // If opening fails, the password's hash will be cleared.
87     int openPreHashed(const QByteArray &passwordHash);
88 
89     // Close the wallet, losing any changes.
90     // if save is true, the wallet is saved prior to closing it.
91     int close(bool save = false);
92 
93     // Write the wallet to disk
94     int sync(WId w);
95 
96     // Returns true if the current wallet is open.
97     bool isOpen() const;
98 
99     // Returns the current wallet name.
100     const QString &walletName() const;
101 
102     // The list of folders.
103     QStringList folderList() const;
104 
105     // Force creation of a folder.
106     bool createFolder(const QString &f);
107 
108     // Change the folder.
setFolder(const QString & f)109     void setFolder(const QString &f)
110     {
111         _folder = f;
112     }
113 
114     // Current folder.  If empty, it's the global folder.
folder()115     const QString &folder() const
116     {
117         return _folder;
118     }
119 
120     // Does it have this folder?
hasFolder(const QString & f)121     bool hasFolder(const QString &f) const
122     {
123         return _entries.contains(f);
124     }
125 
126     // Look up an entry.  Returns null if it doesn't exist.
127     Entry *readEntry(const QString &key);
128 
129 #if KWALLET_BUILD_DEPRECATED_SINCE(5, 72)
130     // Look up a list of entries.  Supports wildcards.
131     // You delete the list.
132     // Deprecated since 5.72, use entriesList()
133     QList<Entry *> readEntryList(const QString &key);
134 #endif
135 
136     // Get a list of all the entries in the current folder.
137     // @since 5.72
138     QList<Entry *> entriesList() const;
139 
140     // Store an entry.
141     void writeEntry(Entry *e);
142 
143     // Does this folder contain this entry?
144     bool hasEntry(const QString &key) const;
145 
146     // Returns true if the entry was removed
147     bool removeEntry(const QString &key);
148 
149     // Returns true if the folder was removed
150     bool removeFolder(const QString &f);
151 
152     // The list of entries in this folder.
153     QStringList entryList() const;
154 
155     // Rename an entry in this folder.
156     int renameEntry(const QString &oldName, const QString &newName);
157 
158     // Set the password used for opening/closing the wallet.
159     // This does not sync the wallet to disk!
160     void setPassword(const QByteArray &password);
161 
ref()162     int ref()
163     {
164         return ++_ref;
165     }
166 
167     int deref();
168 
refCount()169     int refCount() const
170     {
171         return _ref;
172     }
173 
174     static bool exists(const QString &wallet);
175 
176     bool folderDoesNotExist(const QString &folder) const;
177 
178     bool entryDoesNotExist(const QString &folder, const QString &entry) const;
179 
180     static QString openRCToString(int rc);
181 
182     void setCipherType(BackendCipherType ct);
cipherType()183     BackendCipherType cipherType() const
184     {
185         return _cipherType;
186     }
187 #ifdef HAVE_GPGMEPP
188     const GpgME::Key &gpgKey() const;
189 #endif
190 
191     static QString getSaveLocation();
192 
193 private:
194     Q_DISABLE_COPY(Backend)
195     class BackendPrivate;
196     BackendPrivate *const d;
197     const QString _name;
198     QString _path;
199     bool _open;
200     bool _useNewHash = false;
201     QString _folder;
202     int _ref = 0;
203     // Map Folder->Entries
204     typedef QMap<QString, Entry *> EntryMap;
205     typedef QMap<QString, EntryMap> FolderMap;
206     FolderMap _entries;
207     typedef QMap<MD5Digest, QList<MD5Digest>> HashMap;
208     HashMap _hashes;
209     QByteArray _passhash; // password hash used for saving the wallet
210     QByteArray _newPassHash; // Modern hash using KWALLET_HASH_PBKDF2_SHA512
211     BackendCipherType _cipherType; // the kind of encryption used for this wallet
212 #ifdef HAVE_GPGMEPP
213     GpgME::Key _gpgKey;
214 #endif
215     friend class BlowfishPersistHandler;
216     friend class GpgPersistHandler;
217 
218     // open the wallet with the password already set. This is
219     // called internally by both open and openPreHashed.
220     int openInternal(WId w = 0);
221     void swapToNewHash();
222     QByteArray createAndSaveSalt(const QString &path) const;
223 };
224 
225 }
226 
227 #endif
228