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