KWallet

kwalletfreedesktopitem.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2021 Slava Aseev <nullptrnine@basealt.ru>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7#include "kwalletfreedesktopitem.h"
8
9#include "kwalletd.h"
10#include "kwalletd_debug.h"
11#include "kwalletfreedesktopcollection.h"
12#include "kwalletfreedesktopitemadaptor.h"
13
14KWalletFreedesktopItem::KWalletFreedesktopItem(KWalletFreedesktopCollection *collection, FdoUniqueLabel uniqLabel, QDBusObjectPath path)
15 : m_collection(collection)
16 , m_uniqueLabel(std::move(uniqLabel))
17 , m_path(std::move(path))
18{
19 (void)new KWalletFreedesktopItemAdaptor(this);
20 QDBusConnection::sessionBus().registerObject(fdoObjectPath().path(), this);
21}
22
23KWalletFreedesktopItem::~KWalletFreedesktopItem()
24{
25 onPropertiesChanged(QVariantMap());
26
28
29 if (!m_wasDeleted) {
30 m_collection->onItemChanged(fdoObjectPath());
31 }
32}
33
34StrStrMap KWalletFreedesktopItem::attributes() const
35{
36 return fdoCollection()->itemAttributes().getAttributes(m_uniqueLabel);
37}
38
39void KWalletFreedesktopItem::setAttributes(const StrStrMap &value)
40{
41 fdoCollection()->itemAttributes().setAttributes(m_uniqueLabel, value);
42}
43
44qulonglong KWalletFreedesktopItem::created() const
45{
46 return fdoCollection()->itemAttributes().getULongLongParam(m_uniqueLabel, FDO_KEY_CREATED, fdoCollection()->modified());
47}
48
49qulonglong KWalletFreedesktopItem::modified() const
50{
51 return fdoCollection()->itemAttributes().getULongLongParam(m_uniqueLabel, FDO_KEY_MODIFIED, fdoCollection()->modified());
52}
53
54QString KWalletFreedesktopItem::label() const
55{
56 return m_uniqueLabel.label;
57}
58
59void KWalletFreedesktopItem::setLabel(const QString &value)
60{
61 const auto entryLocation = m_uniqueLabel.toEntryLocation();
62 m_uniqueLabel = fdoCollection()->makeUniqueItemLabel(value);
63 const auto newEntryLocation = m_uniqueLabel.toEntryLocation();
64
65 if (newEntryLocation.folder != entryLocation.folder) {
66 const auto data = backend()->readEntry(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, FDO_APPID);
67 backend()->writeEntry(fdoCollection()->walletHandle(), newEntryLocation.folder, newEntryLocation.key, data, FDO_APPID);
68 backend()->removeEntry(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, FDO_APPID);
69 } else if (newEntryLocation.key != entryLocation.key) {
70 backend()->renameEntry(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, newEntryLocation.key, FDO_APPID);
71 }
72
73 fdoCollection()->itemAttributes().setParam(entryLocation, FDO_KEY_MODIFIED, static_cast<qulonglong>(QDateTime::currentSecsSinceEpoch()));
74 fdoCollection()->itemAttributes().renameLabel(entryLocation, newEntryLocation);
75
76 fdoCollection()->onItemChanged(fdoObjectPath());
77}
78
79bool KWalletFreedesktopItem::locked() const
80{
81 return m_collection->locked();
82}
83
84QString KWalletFreedesktopItem::type() const
85{
86 const auto attribs = fdoCollection()->itemAttributes().getAttributes(m_uniqueLabel);
87 const auto found = attribs.find(FDO_KEY_XDG_SCHEMA);
88 if (found != attribs.end()) {
89 return found.value();
90 } else {
91 return QStringLiteral("org.freedesktop.Secret.Generic");
92 }
93}
94
95void KWalletFreedesktopItem::setType(const QString &value)
96{
97 auto attribs = fdoCollection()->itemAttributes().getAttributes(m_uniqueLabel);
98 attribs[FDO_KEY_XDG_SCHEMA] = value;
99 fdoCollection()->itemAttributes().setAttributes(m_uniqueLabel, attribs);
100}
101
102QDBusObjectPath KWalletFreedesktopItem::Delete()
103{
104 const auto entryLocation = m_uniqueLabel.toEntryLocation();
105
106 backend()->removeEntry(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, FDO_APPID);
108
109 m_collection->onItemDeleted(fdoObjectPath());
110
111 return QDBusObjectPath("/");
112}
113
114FreedesktopSecret KWalletFreedesktopItem::getSecret(const QDBusConnection &connection, const QDBusMessage &message, const QDBusObjectPath &session)
115{
116 const auto entryLocation = m_uniqueLabel.toEntryLocation();
117 const auto mimeType = fdoCollection()->itemAttributes().getStringParam(entryLocation, FDO_KEY_MIME, QStringLiteral("application/octet-stream"));
118
119 FreedesktopSecret fdoSecret;
120
121 const auto entryType = backend()->entryType(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, FDO_APPID);
122 if (entryType == KWallet::Wallet::Password) {
123 auto password = backend()->readPassword(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, FDO_APPID);
124 auto bytes = password.toUtf8();
125 fdoSecret = FreedesktopSecret(session, bytes, mimeType);
126 explicit_zero_mem(bytes.data(), bytes.size());
127 explicit_zero_mem(password.data(), password.size() * sizeof(QChar));
128 } else {
129 auto bytes = backend()->readEntry(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, FDO_APPID);
130 fdoSecret = FreedesktopSecret(session, bytes, mimeType);
131 explicit_zero_mem(bytes.data(), bytes.size());
132 }
133
134 if (!fdoService()->ensecret(message, fdoSecret)) {
135 message.setDelayedReply(true);
136 connection.send(message.createErrorReply(QDBusError::ErrorType::UnknownObject, QStringLiteral("Can't find session ") + session.path()));
137 }
138
139 return fdoSecret;
140}
141
142FreedesktopSecret KWalletFreedesktopItem::GetSecret(const QDBusObjectPath &session)
143{
144 return getSecret(connection(), message(), session);
145}
146
147void KWalletFreedesktopItem::SetSecret(const FreedesktopSecret &secret)
148{
149 const auto entryLocation = m_uniqueLabel.toEntryLocation();
150
151 fdoCollection()->itemAttributes().setParam(entryLocation, FDO_KEY_MIME, secret.mimeType);
152 fdoCollection()->itemAttributes().setParam(entryLocation, FDO_KEY_MODIFIED, static_cast<qulonglong>(QDateTime::currentSecsSinceEpoch()));
153
154 auto decrypted = secret;
155 if (!fdoService()->desecret(message(), decrypted)) {
156 sendErrorReply(QDBusError::ErrorType::UnknownObject, QStringLiteral("Can't find session ") + secret.session.path());
157 return;
158 }
159
160 QString xdgSchema = QStringLiteral("org.kde.KWallet.Stream");
161 const auto attribs = fdoCollection()->itemAttributes().getAttributes(entryLocation);
162 const auto found = attribs.find(FDO_KEY_XDG_SCHEMA);
163 if (found != attribs.end()) {
164 xdgSchema = found.value();
165 }
166
167 if (xdgSchema == QStringLiteral("org.kde.KWallet.Password") || secret.mimeType.startsWith(QStringLiteral("text/"))) {
168 auto bytes = decrypted.value.toByteArray();
169 auto str = QString::fromUtf8(bytes);
170 backend()->writePassword(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, str, FDO_APPID);
171 explicit_zero_mem(bytes.data(), bytes.size());
172 explicit_zero_mem(str.data(), str.size() * sizeof(QChar));
173 } else {
174 auto bytes = decrypted.value.toByteArray();
175 backend()->writeEntry(fdoCollection()->walletHandle(), entryLocation.folder, entryLocation.key, bytes, KWallet::Wallet::Stream, FDO_APPID);
176 }
177}
178
179KWalletFreedesktopCollection *KWalletFreedesktopItem::fdoCollection() const
180{
181 return m_collection;
182}
183
184KWalletFreedesktopService *KWalletFreedesktopItem::fdoService() const
185{
186 return fdoCollection()->fdoService();
187}
188
189KWalletD *KWalletFreedesktopItem::backend() const
190{
191 return fdoCollection()->fdoService()->backend();
192}
193
194QDBusObjectPath KWalletFreedesktopItem::fdoObjectPath() const
195{
196 return m_path;
197}
198
199const FdoUniqueLabel &KWalletFreedesktopItem::uniqueLabel() const
200{
201 return m_uniqueLabel;
202}
203
204void KWalletFreedesktopItem::uniqueLabel(const FdoUniqueLabel &uniqueLabel)
205{
206 m_uniqueLabel = uniqueLabel;
207}
208
209void KWalletFreedesktopItem::setDeleted()
210{
211 m_wasDeleted = true;
212 fdoCollection()->itemAttributes().remove(m_uniqueLabel);
213}
214
215void KWalletFreedesktopItem::onPropertiesChanged(const QVariantMap &properties)
216{
217 auto msg = QDBusMessage::createSignal(fdoObjectPath().path(), QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("PropertiesChanged"));
218 auto args = QVariantList();
219 args << QStringLiteral("org.freedesktop.Secret.Item") << properties << QStringList();
220 msg.setArguments(args);
222}
223
224#include "moc_kwalletfreedesktopitem.cpp"
KCALUTILS_EXPORT QString mimeType()
KIOCORE_EXPORT CopyJob * move(const QList< QUrl > &src, const QUrl &dest, JobFlags flags=DefaultFlags)
QString path(const QString &relativePath)
KGuiItem properties()
qint64 currentSecsSinceEpoch()
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
bool send(const QDBusMessage &message) const const
QDBusConnection sessionBus()
void unregisterObject(const QString &path, UnregisterMode mode)
QDBusMessage createErrorReply(QDBusError::ErrorType type, const QString &msg) const const
QDBusMessage createSignal(const QString &path, const QString &interface, const QString &name)
void setDelayedReply(bool enable) const const
QString path() const const
iterator find(const Key &key)
QString fromUtf8(QByteArrayView str)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:12:12 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.