File indexing completed on 2024-11-24 03:41:07
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2021 Slava Aseev <nullptrnine@basealt.ru> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 #ifndef _KWALLETFREEDESKTOPSERVICE_H_ 0008 #define _KWALLETFREEDESKTOPSERVICE_H_ 0009 0010 #include <KConfig> 0011 #include <QDBusArgument> 0012 #include <QDBusServiceWatcher> 0013 #include <QHash> 0014 #include <QPointer> 0015 #include <QString> 0016 #include <QtCrypto> 0017 #include <QtDBus> 0018 0019 #include "kwalletdbuscontext.h" 0020 0021 #define FDO_APPID QString() 0022 #define FDO_SECRETS_SERVICE_OBJECT "/org/freedesktop/secrets" 0023 #define FDO_ALIAS_PATH "/org/freedesktop/secrets/aliases/" 0024 0025 static inline constexpr size_t FDO_SECRETS_CIPHER_KEY_SIZE = 16; 0026 static inline constexpr int FDO_DH_PUBLIC_KEY_SIZE = 128; 0027 0028 class KWalletD; 0029 0030 class FreedesktopSecret 0031 { 0032 public: 0033 FreedesktopSecret() = default; 0034 0035 FreedesktopSecret(QDBusObjectPath iSession, const QCA::SecureArray &iValue, QString iMimeType) 0036 : session(std::move(iSession)) 0037 , value(iValue) 0038 , mimeType(std::move(iMimeType)) 0039 { 0040 } 0041 0042 friend QDBusArgument &operator<<(QDBusArgument &arg, const FreedesktopSecret &secret); 0043 friend const QDBusArgument &operator>>(const QDBusArgument &arg, FreedesktopSecret &secret); 0044 0045 QDBusObjectPath session; 0046 QCA::SecureArray parameters; 0047 QCA::SecureArray value; 0048 QString mimeType; 0049 }; 0050 0051 struct PropertiesMap { 0052 QVariantMap map; 0053 }; 0054 0055 struct EntryLocation { 0056 static EntryLocation fromUniqueLabel(const struct FdoUniqueLabel &uniqLabel); 0057 struct FdoUniqueLabel toUniqueLabel() const; 0058 0059 bool operator==(const EntryLocation &rhs) const 0060 { 0061 return folder == rhs.folder && key == rhs.key; 0062 } 0063 0064 bool operator!=(const EntryLocation &rhs) const 0065 { 0066 return !(*this == rhs); 0067 } 0068 0069 QString folder; 0070 QString key; 0071 }; 0072 0073 struct FdoUniqueLabel { 0074 static FdoUniqueLabel fromEntryLocation(const EntryLocation &entryLocation); 0075 static FdoUniqueLabel fromName(const QString &name); 0076 static QString makeName(const QString &label, int copyId); 0077 0078 bool operator==(const FdoUniqueLabel &rhs) const 0079 { 0080 return copyId == rhs.copyId && label == rhs.label; 0081 } 0082 0083 bool operator!=(const FdoUniqueLabel &rhs) const 0084 { 0085 return !(*this == rhs); 0086 } 0087 0088 QString toName() const; 0089 EntryLocation toEntryLocation() const; 0090 0091 QString label; 0092 int copyId = -1; 0093 }; 0094 0095 typedef QMap<QDBusObjectPath, FreedesktopSecret> FreedesktopSecretMap; 0096 typedef QMap<QString, QString> StrStrMap; 0097 0098 Q_DECLARE_METATYPE(FreedesktopSecret) 0099 Q_DECLARE_METATYPE(FreedesktopSecretMap) 0100 Q_DECLARE_METATYPE(PropertiesMap) 0101 Q_DECLARE_METATYPE(StrStrMap) 0102 Q_DECLARE_METATYPE(QCA::SecureArray) 0103 0104 class KWalletFreedesktopSession; 0105 class KWalletFreedesktopSessionAlgorithm; 0106 class KWalletFreedesktopCollection; 0107 class KWalletFreedesktopPrompt; 0108 class KWalletFreedesktopItem; 0109 0110 class KWalletFreedesktopService : public QObject, protected FDO_DBUS_CONTEXT 0111 { 0112 /* org.freedesktop.Secret.Service properties */ 0113 public: 0114 Q_PROPERTY(QList<QDBusObjectPath> Collections READ collections) 0115 QList<QDBusObjectPath> collections() const; 0116 0117 Q_OBJECT 0118 0119 public: 0120 explicit KWalletFreedesktopService(KWalletD *parent); 0121 ~KWalletFreedesktopService(); 0122 0123 KWalletFreedesktopService(const KWalletFreedesktopService &) = delete; 0124 KWalletFreedesktopService &operator=(const KWalletFreedesktopService &) = delete; 0125 0126 KWalletFreedesktopService(KWalletFreedesktopService &&) = delete; 0127 KWalletFreedesktopService &operator=(KWalletFreedesktopService &&) = delete; 0128 0129 static QString wrapToCollectionPath(const QString &itemPath); 0130 0131 static QDBusObjectPath nextPromptPath(); 0132 KWalletD *backend() const; 0133 QDBusObjectPath fdoObjectPath() const; 0134 0135 bool desecret(const QDBusMessage &message, FreedesktopSecret &secret); 0136 bool ensecret(const QDBusMessage &message, FreedesktopSecret &secret); 0137 KWalletFreedesktopItem *getItemByObjectPath(const QDBusObjectPath &path) const; 0138 KWalletFreedesktopCollection *getCollectionByWalletName(const QString &walletName) const; 0139 KWalletFreedesktopPrompt *getPromptByObjectPath(const QDBusObjectPath &path) const; 0140 0141 FdoUniqueLabel makeUniqueCollectionLabel(const QString &label); 0142 QString makeUniqueWalletName(const QString &labelPrefix); 0143 QDBusObjectPath makeUniqueObjectPath(const QString &walletName) const; 0144 0145 QString resolveIfAlias(QString alias); 0146 QStringList readAliasesFor(const QString &walletName); 0147 void createCollectionAlias(const QString &alias, KWalletFreedesktopCollection *collection); 0148 void createCollectionAlias(const QString &alias, const QString &walletName); 0149 void updateCollectionAlias(const QString &alias, const QString &walletName); 0150 void removeAlias(const QString &alias); 0151 0152 void deletePrompt(const QString &objectPath); 0153 void deleteSession(const QString &objectPath); 0154 QDBusObjectPath promptUnlockCollection(const QString &walletName, int handle); 0155 0156 /* Emitters */ 0157 void onCollectionCreated(const QDBusObjectPath &path); 0158 void onCollectionChanged(const QDBusObjectPath &path); 0159 void onCollectionDeleted(const QDBusObjectPath &path); 0160 void onPropertiesChanged(const QVariantMap &properties); 0161 0162 private Q_SLOTS: 0163 void lockCollection(const QString &name); 0164 void entryUpdated(const QString &walletName, const QString &folder, const QString &entryName); 0165 void entryDeleted(const QString &walletName, const QString &folder, const QString &entryName); 0166 void entryRenamed(const QString &walletName, const QString &folder, const QString &oldName, const QString &newName); 0167 void walletDeleted(const QString &walletName); 0168 void walletCreated(const QString &walletCreated); 0169 /* 0170 void slotServiceOwnerChanged(const QString &name, const QString &oldOwner, 0171 const QString &newOwner); 0172 */ 0173 0174 private: 0175 std::unique_ptr<KWalletFreedesktopSessionAlgorithm> createSessionAlgorithmPlain() const; 0176 std::unique_ptr<KWalletFreedesktopSessionAlgorithm> createSessionAlgorithmDhAes(const QByteArray &clientKey) const; 0177 QString createSession(std::unique_ptr<KWalletFreedesktopSessionAlgorithm> algorithm); 0178 QString defaultWalletName(KConfigGroup &cfg); 0179 0180 private: 0181 std::map<QString, std::unique_ptr<KWalletFreedesktopSession>> m_sessions; 0182 std::map<QString, std::unique_ptr<KWalletFreedesktopCollection>> m_collections; 0183 std::map<QString, std::unique_ptr<KWalletFreedesktopPrompt>> m_prompts; 0184 0185 uint64_t m_session_counter = 0; 0186 0187 /* 0188 QDBusServiceWatcher _serviceWatcher; 0189 */ 0190 KWalletD *m_parent; 0191 QCA::Initializer m_init; 0192 KConfig m_kwalletrc; 0193 0194 /* Freedesktop API */ 0195 0196 /* org.freedesktop.Secret.Service methods */ 0197 public Q_SLOTS: 0198 QDBusObjectPath CreateCollection(const QVariantMap &properties, const QString &alias, QDBusObjectPath &prompt); 0199 FreedesktopSecretMap GetSecrets(const QList<QDBusObjectPath> &items, const QDBusObjectPath &session); 0200 QList<QDBusObjectPath> Lock(const QList<QDBusObjectPath> &objects, QDBusObjectPath &Prompt); 0201 QDBusVariant OpenSession(const QString &algorithm, const QDBusVariant &input, QDBusObjectPath &result); 0202 QDBusObjectPath ReadAlias(const QString &name); 0203 QList<QDBusObjectPath> SearchItems(const StrStrMap &attributes, QList<QDBusObjectPath> &locked); 0204 void SetAlias(const QString &name, const QDBusObjectPath &collection); 0205 QList<QDBusObjectPath> Unlock(const QList<QDBusObjectPath> &objects, QDBusObjectPath &prompt); 0206 0207 /* org.freedesktop.Secret.Service signals */ 0208 Q_SIGNALS: 0209 void CollectionChanged(const QDBusObjectPath &collection); 0210 void CollectionCreated(const QDBusObjectPath &collection); 0211 void CollectionDeleted(const QDBusObjectPath &collection); 0212 }; 0213 0214 QDataStream &operator<<(QDataStream &stream, const QDBusObjectPath &value); 0215 QDataStream &operator>>(QDataStream &stream, QDBusObjectPath &value); 0216 0217 const QDBusArgument &operator>>(const QDBusArgument &arg, PropertiesMap &value); 0218 QDBusArgument &operator<<(QDBusArgument &arg, const PropertiesMap &value); 0219 0220 QDataStream &operator<<(QDataStream &stream, const QCA::SecureArray &value); 0221 QDataStream &operator>>(QDataStream &stream, QCA::SecureArray &value); 0222 QDBusArgument &operator<<(QDBusArgument &arg, const QCA::SecureArray &value); 0223 const QDBusArgument &operator>>(const QDBusArgument &arg, QCA::SecureArray &buf); 0224 0225 void explicit_zero_mem(void *data, size_t size); 0226 0227 #endif