File indexing completed on 2024-06-16 03:53:04

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2001-2004 George Staikos <staikos@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef _KWALLETBACKEND_H
0009 #define _KWALLETBACKEND_H
0010 
0011 #include "backendpersisthandler.h"
0012 #include "kwalletbackend_export.h"
0013 #include "kwalletentry.h"
0014 #include <QMap>
0015 #include <QString>
0016 #include <QStringList>
0017 
0018 #ifdef HAVE_GPGMEPP
0019 #include <gpgme++/key.h>
0020 #endif // HAVE_GPGMEPP
0021 
0022 #define PBKDF2_SHA512_KEYSIZE 56
0023 #define PBKDF2_SHA512_SALTSIZE 56
0024 #define PBKDF2_SHA512_ITERATIONS 50000
0025 
0026 namespace KWallet
0027 {
0028 /**
0029  * @internal
0030  */
0031 class MD5Digest : public QByteArray
0032 {
0033 public:
0034     MD5Digest()
0035         : QByteArray(16, 0)
0036     {
0037     }
0038     MD5Digest(const char *data)
0039         : QByteArray(data, 16)
0040     {
0041     }
0042     MD5Digest(const QByteArray &digest)
0043         : QByteArray(digest)
0044     {
0045     }
0046     virtual ~MD5Digest()
0047     {
0048     }
0049 
0050     int operator<(const MD5Digest &r) const
0051     {
0052         int i = 0;
0053         char x, y;
0054         for (; i < 16; ++i) {
0055             x = at(i);
0056             y = r.at(i);
0057             if (x != y) {
0058                 break;
0059             }
0060         }
0061         if (i < 16 && x < y) {
0062             return 1;
0063         }
0064         return 0;
0065     }
0066 };
0067 
0068 /* @internal
0069  */
0070 class KWALLETBACKEND_EXPORT Backend
0071 {
0072 public:
0073     explicit Backend(const QString &name = QStringLiteral("kdewallet"), bool isPath = false);
0074     ~Backend();
0075 
0076     // Open and unlock the wallet.
0077     // If opening succeeds, the password's hash will be remembered.
0078     // If opening fails, the password's hash will be cleared.
0079     int open(const QByteArray &password, WId w = 0);
0080 #ifdef HAVE_GPGMEPP
0081     int open(const GpgME::Key &key);
0082 #endif
0083 
0084     // Open and unlock the wallet using a pre-hashed password.
0085     // If opening succeeds, the password's hash will be remembered.
0086     // If opening fails, the password's hash will be cleared.
0087     int openPreHashed(const QByteArray &passwordHash);
0088 
0089     // Close the wallet, losing any changes.
0090     // if save is true, the wallet is saved prior to closing it.
0091     int close(bool save = false);
0092 
0093     // Write the wallet to disk
0094     int sync(WId w);
0095 
0096     // Returns true if the current wallet is open.
0097     bool isOpen() const;
0098 
0099     // Returns the current wallet name.
0100     const QString &walletName() const;
0101 
0102     // Rename the wallet
0103     int renameWallet(const QString &newName, bool isPath = false);
0104 
0105     // The list of folders.
0106     QStringList folderList() const;
0107 
0108     // Force creation of a folder.
0109     bool createFolder(const QString &f);
0110 
0111     // Change the folder.
0112     void setFolder(const QString &f)
0113     {
0114         _folder = f;
0115     }
0116 
0117     // Current folder.  If empty, it's the global folder.
0118     const QString &folder() const
0119     {
0120         return _folder;
0121     }
0122 
0123     // Does it have this folder?
0124     bool hasFolder(const QString &f) const
0125     {
0126         return _entries.contains(f);
0127     }
0128 
0129     // Look up an entry.  Returns null if it doesn't exist.
0130     Entry *readEntry(const QString &key);
0131 
0132 #if KWALLET_BUILD_DEPRECATED_SINCE(5, 72)
0133     // Look up a list of entries.  Supports wildcards.
0134     // You delete the list.
0135     // Deprecated since 5.72, use entriesList()
0136     QList<Entry *> readEntryList(const QString &key);
0137 #endif
0138 
0139     // Get a list of all the entries in the current folder.
0140     // @since 5.72
0141     QList<Entry *> entriesList() const;
0142 
0143     // Store an entry.
0144     void writeEntry(Entry *e);
0145 
0146     // Does this folder contain this entry?
0147     bool hasEntry(const QString &key) const;
0148 
0149     // Returns true if the entry was removed
0150     bool removeEntry(const QString &key);
0151 
0152     // Returns true if the folder was removed
0153     bool removeFolder(const QString &f);
0154 
0155     // The list of entries in this folder.
0156     QStringList entryList() const;
0157 
0158     // Rename an entry in this folder.
0159     int renameEntry(const QString &oldName, const QString &newName);
0160 
0161     // Set the password used for opening/closing the wallet.
0162     // This does not sync the wallet to disk!
0163     void setPassword(const QByteArray &password);
0164 
0165     int ref()
0166     {
0167         return ++_ref;
0168     }
0169 
0170     int deref();
0171 
0172     int refCount() const
0173     {
0174         return _ref;
0175     }
0176 
0177     static bool exists(const QString &wallet);
0178 
0179     bool folderDoesNotExist(const QString &folder) const;
0180 
0181     bool entryDoesNotExist(const QString &folder, const QString &entry) const;
0182 
0183     static QString openRCToString(int rc);
0184 
0185     void setCipherType(BackendCipherType ct);
0186     BackendCipherType cipherType() const
0187     {
0188         return _cipherType;
0189     }
0190 #ifdef HAVE_GPGMEPP
0191     const GpgME::Key &gpgKey() const;
0192 #endif
0193 
0194     static QString getSaveLocation();
0195     static QString encodeWalletName(const QString &name);
0196     static QString decodeWalletName(const QString &encodedName);
0197 
0198 private:
0199     Q_DISABLE_COPY(Backend)
0200     class BackendPrivate;
0201     BackendPrivate *const d;
0202     QString _name;
0203     QString _path;
0204     bool _open;
0205     bool _useNewHash = false;
0206     QString _folder;
0207     int _ref = 0;
0208     // Map Folder->Entries
0209     typedef QMap<QString, Entry *> EntryMap;
0210     typedef QMap<QString, EntryMap> FolderMap;
0211     FolderMap _entries;
0212     typedef QMap<MD5Digest, QList<MD5Digest>> HashMap;
0213     HashMap _hashes;
0214     QByteArray _passhash; // password hash used for saving the wallet
0215     QByteArray _newPassHash; // Modern hash using KWALLET_HASH_PBKDF2_SHA512
0216     BackendCipherType _cipherType; // the kind of encryption used for this wallet
0217 
0218 #ifdef HAVE_GPGMEPP
0219     GpgME::Key _gpgKey;
0220 #endif
0221     friend class BlowfishPersistHandler;
0222     friend class GpgPersistHandler;
0223 
0224     // open the wallet with the password already set. This is
0225     // called internally by both open and openPreHashed.
0226     int openInternal(WId w = 0);
0227     int closeInternal(bool save);
0228     void swapToNewHash();
0229     QByteArray createAndSaveSalt(const QString &path) const;
0230 };
0231 
0232 }
0233 
0234 #endif