7#include "kwalletfreedesktopservice.h"
10#include "ksecretd_debug.h"
11#include "kwalletfreedesktopcollection.h"
12#include "kwalletfreedesktopitem.h"
13#include "kwalletfreedesktopprompt.h"
14#include "kwalletfreedesktopserviceadaptor.h"
15#include "kwalletfreedesktopsession.h"
16#include <KConfigGroup>
24[[maybe_unused]]
int DBUS_SECRET_SERVICE_META_TYPE_REGISTER = []() {
25 qDBusRegisterMetaType<StrStrMap>();
26 qDBusRegisterMetaType<QMap<QString, QString>>();
27 qDBusRegisterMetaType<FreedesktopSecret>();
28 qDBusRegisterMetaType<FreedesktopSecretMap>();
29 qDBusRegisterMetaType<PropertiesMap>();
30 qDBusRegisterMetaType<QCA::SecureArray>();
39 const auto utf8Str = str.
toUtf8();
40 static constexpr char hex[] =
"0123456789abcdef";
41 static_assert(
sizeof(
hex) == 17);
44 mangled.
reserve(utf8Str.size());
46 for (
const auto &c : utf8Str) {
47 if ((c <
'A' || c >
'Z') && (c <
'a' || c >
'z') && (c <
'0' || c >
'9') && c !=
'_') {
48 const auto cp =
static_cast<quint8
>(c);
61#define LABEL_NUMBER_PREFIX "__"
62#define LABEL_NUMBER_POSTFIX "_"
63#define LABEL_NUMBER_REGEX "(^.*)" LABEL_NUMBER_PREFIX "(\\d+)" LABEL_NUMBER_POSTFIX "$"
65EntryLocation EntryLocation::fromUniqueLabel(
const FdoUniqueLabel &uniqLabel)
68 QString
name = uniqLabel.label;
71 if (slashPos == -1 || slashPos == uniqLabel.label.
size() - 1) {
72 dir = QStringLiteral(FDO_SECRETS_DEFAULT_DIR);
74 dir = uniqLabel.label.
left(slashPos);
78 return EntryLocation{
dir, FdoUniqueLabel::makeName(name, uniqLabel.copyId)};
81FdoUniqueLabel EntryLocation::toUniqueLabel()
const
83 return FdoUniqueLabel::fromEntryLocation(*
this);
86FdoUniqueLabel FdoUniqueLabel::fromEntryLocation(
const EntryLocation &entryLocation)
88 const auto uniqLabel = FdoUniqueLabel::fromName(entryLocation.key);
90 if (entryLocation.folder == QStringLiteral(FDO_SECRETS_DEFAULT_DIR)) {
93 return {entryLocation.folder +
QChar::fromLatin1(
'/') + uniqLabel.label, uniqLabel.copyId};
97FdoUniqueLabel FdoUniqueLabel::fromName(
const QString &name)
99 static QRegularExpression regexp(QStringLiteral(LABEL_NUMBER_REGEX));
101 const auto match = regexp.match(name);
102 if (
match.hasMatch()) {
103 const QString strNum =
match.captured(2);
105 const int n = strNum.
toInt(&ok);
107 return FdoUniqueLabel{
match.captured(1), n};
110 return FdoUniqueLabel{
name};
118 return label + QStringLiteral(LABEL_NUMBER_PREFIX) +
QString::number(n) + QStringLiteral(LABEL_NUMBER_POSTFIX);
122QString FdoUniqueLabel::toName()
const
124 return makeName(label, copyId);
127EntryLocation FdoUniqueLabel::toEntryLocation()
const
129 return EntryLocation::fromUniqueLabel(*
this);
132QString KWalletFreedesktopService::wrapToCollectionPath(
const QString &itemPath)
138KWalletFreedesktopService::KWalletFreedesktopService(KSecretD *parent)
141 , m_kwalletrc(QStringLiteral(
"kwalletrc"))
143 (void)
new KWalletFreedesktopServiceAdaptor(
this);
148 KConfig kwalletrc(QStringLiteral(
"kwalletrc"));
149 KConfigGroup cfgSecrets(&kwalletrc,
"org.freedesktop.secrets");
151 if (cfgSecrets.readEntry<
bool>(
"apiEnabled",
true)) {
157 if (!parent || !parent->isEnabled()) {
161 connect(m_parent,
static_cast<void (KSecretD::*)(
const QString &)
>(&KSecretD::walletClosed),
this, &KWalletFreedesktopService::lockCollection);
162 connect(m_parent, &KSecretD::entryUpdated,
this, &KWalletFreedesktopService::entryUpdated);
163 connect(m_parent, &KSecretD::entryDeleted,
this, &KWalletFreedesktopService::entryDeleted);
164 connect(m_parent, &KSecretD::entryRenamed,
this, &KWalletFreedesktopService::entryRenamed);
165 connect(m_parent, &KSecretD::walletDeleted,
this, &KWalletFreedesktopService::walletDeleted);
166 connect(m_parent, &KSecretD::walletCreated,
this, &KWalletFreedesktopService::walletCreated);
168 const auto walletNames = backend()->wallets();
171 for (
const QString &walletName : walletNames) {
172 const auto objectPath = makeUniqueObjectPath(walletName);
173 auto collection = std::make_unique<KWalletFreedesktopCollection>(
this, -1, walletName, objectPath);
175 m_collections.emplace(objectPath.path(), std::move(collection));
179KWalletFreedesktopService::~KWalletFreedesktopService() =
default;
183 QList<QDBusObjectPath> result;
184 result.
reserve(m_collections.size());
186 for (
const auto &collectionPair : m_collections) {
187 result.
push_back(QDBusObjectPath(collectionPair.first));
195 prompt.
setPath(QStringLiteral(
"/"));
197 const auto labelIter =
properties.find(QStringLiteral(
"org.freedesktop.Secret.Collection.Label"));
199 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Collection.Label property is missing"));
200 return QDBusObjectPath(
"/");
202 if (!labelIter->canConvert<QString>()) {
203 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Type of Collection.Label property is invalid"));
204 return QDBusObjectPath(
"/");
207 prompt = nextPromptPath();
208 auto fdoPromptPtr = std::make_unique<KWalletFreedesktopPrompt>(
this, prompt, PromptType::Create, message().service());
209 auto &fdoPrompt = *m_prompts.emplace(prompt.
path(), std::move(fdoPromptPtr)).first->second;
211 fdoPrompt.appendProperties(labelIter->toString(), QDBusObjectPath(
"/"), alias);
212 fdoPrompt.subscribeForWalletAsyncOpened();
214 return QDBusObjectPath(
"/");
219 FreedesktopSecretMap result;
221 for (
const QDBusObjectPath &itemPath : items) {
222 const auto item = getItemByObjectPath(itemPath);
225 result.
insert(itemPath, item->getSecret(connection(), message(), session));
227 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Can't find item at path ") + itemPath.path());
237 prompt = QDBusObjectPath(
"/");
238 QList<QDBusObjectPath> result;
241 for (
const QDBusObjectPath &
object : objects) {
242 const QString collectionPath = wrapToCollectionPath(resolveIfAlias(
object.
path()));
244 const auto foundCollection = m_collections.find(collectionPath);
245 if (foundCollection != m_collections.end()) {
246 const int walletHandle = foundCollection->second->walletHandle();
247 const int rc = m_parent->close(walletHandle,
true, FDO_APPID, message());
250 result.
push_back(QDBusObjectPath(collectionPath));
252 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Can't lock object at path ") + collectionPath);
255 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Collection at path ") + collectionPath + QStringLiteral(
" does not exist"));
264 std::unique_ptr<KWalletFreedesktopSessionAlgorithm> sessionAlgorithm;
265 if (algorithm == QStringLiteral(
"plain")) {
266 sessionAlgorithm = createSessionAlgorithmPlain();
267 }
else if (algorithm == QStringLiteral(
"dh-ietf1024-sha256-aes128-cbc-pkcs7")) {
269 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Second input argument must be a byte array."));
275 sendErrorReply(QDBusError::ErrorType::NotSupported,
276 QStringLiteral(
"Algorithm ") + algorithm
277 + QStringLiteral(
" is not supported. (only plain and dh-ietf1024-sha256-aes128-cbc-pkcs7 are supported)"));
281 if (!sessionAlgorithm) {
286 const QString sessionPath = createSession(std::move(sessionAlgorithm));
288 return QDBusVariant(QVariant(m_sessions[sessionPath]->negotiationOutput()));
295 m_kwalletrc.reparseConfiguration();
296 if (name == QStringLiteral(
"default")) {
297 KConfigGroup cfg(&m_kwalletrc,
"Wallet");
298 walletName = defaultWalletName(cfg);
301 KConfigGroup cfg(&m_kwalletrc,
"org.freedesktop.secrets.aliases");
302 walletName = cfg.readEntry(name, QString());
306 const auto *collection = getCollectionByWalletName(walletName);
308 return collection->fdoObjectPath();
312 return QDBusObjectPath(
"/");
317 QList<QDBusObjectPath> unlocked;
319 for (
const auto &collectionPair : m_collections) {
320 auto &collection = *collectionPair.second;
322 if (collection.locked()) {
323 locked += collection.SearchItems(attributes);
325 unlocked += collection.SearchItems(attributes);
334 const auto foundCollection = m_collections.find(collectionPath.
path());
335 if (foundCollection == m_collections.end()) {
339 auto *collection = foundCollection->second.get();
340 createCollectionAlias(name, collection);
345 if (alias.
startsWith(QStringLiteral(FDO_ALIAS_PATH))) {
346 const auto path = ReadAlias(alias.
remove(0, QStringLiteral(FDO_ALIAS_PATH).size())).path();
347 if (path != QStringLiteral(
"/")) {
350 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Alias ") + alias + QStringLiteral(
" does not exist"));
355 if (!alias.
startsWith(QStringLiteral(FDO_SECRETS_COLLECTION_PATH))) {
356 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Collection object path is invalid"));
363struct UnlockedObject {
365 QDBusObjectPath objectPath;
370 prompt = QDBusObjectPath(
"/");
372 QList<QDBusObjectPath> result;
373 QList<UnlockedObject> needUnlock;
376 for (
const QDBusObjectPath &
object : objects) {
377 const QString strPath =
object.path();
378 const QString collectionPath = wrapToCollectionPath(resolveIfAlias(strPath));
380 const auto foundCollection = m_collections.find(collectionPath);
381 if (foundCollection != m_collections.end()) {
382 if (foundCollection->second->locked()) {
383 needUnlock.
push_back({foundCollection->second->walletName(), QDBusObjectPath(strPath)});
385 result.
push_back(QDBusObjectPath(strPath));
388 sendErrorReply(QDBusError::ErrorType::InvalidObjectPath, QStringLiteral(
"Object ") + strPath + QStringLiteral(
" does not exist"));
393 if (!needUnlock.
empty()) {
394 const auto promptPath = nextPromptPath();
395 auto fdoPromptPtr = std::make_unique<KWalletFreedesktopPrompt>(
this, promptPath, PromptType::Open, message().service());
396 auto &fdoPrompt = *m_prompts.emplace(promptPath.path(), std::move(fdoPromptPtr)).first->second;
398 prompt = QDBusObjectPath(promptPath);
400 for (
const auto &[walletName, objectPath] : std::as_const(needUnlock)) {
401 fdoPrompt.appendProperties(walletName, objectPath);
404 fdoPrompt.subscribeForWalletAsyncOpened();
409std::unique_ptr<KWalletFreedesktopSessionAlgorithm> KWalletFreedesktopService::createSessionAlgorithmPlain()
const
411 return std::make_unique<KWalletFreedesktopSessionAlgorithmPlain>();
414std::unique_ptr<KWalletFreedesktopSessionAlgorithm> KWalletFreedesktopService::createSessionAlgorithmDhAes(
const QByteArray &clientKey)
const
416 if (clientKey.
size() < FDO_DH_PUBLIC_KEY_SIZE) {
417 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"Client public key size is invalid"));
421 QCA::KeyGenerator keygen;
423 if (dlGroup.isNull()) {
424 sendErrorReply(QDBusError::ErrorType::InvalidArgs, QStringLiteral(
"createDLGroup failed: maybe libqca-ossl is missing"));
428 auto privateKey = QCA::PrivateKey(keygen.
createDH(dlGroup));
429 const auto publicKey = QCA::PublicKey(privateKey);
430 const auto clientPublicKey = QCA::DHPublicKey(dlGroup, QCA::BigInteger(QCA::SecureArray(clientKey)));
431 const auto commonSecret = privateKey.deriveKey(clientPublicKey);
432 const auto symmetricKey = QCA::HKDF().makeKey(commonSecret, {}, {}, FDO_SECRETS_CIPHER_KEY_SIZE);
434 return std::make_unique<KWalletFreedesktopSessionAlgorithmDhAes>(publicKey, symmetricKey);
437QString KWalletFreedesktopService::createSession(std::unique_ptr<KWalletFreedesktopSessionAlgorithm> algorithm)
439 const QString sessionPath = QStringLiteral(FDO_SECRETS_SESSION_PATH) +
QString::number(++m_session_counter);
440 auto session = std::make_unique<KWalletFreedesktopSession>(
this, std::move(algorithm), sessionPath, connection(), message());
441 m_sessions[sessionPath] = std::move(session);
447 auto walletName = cfg.
readEntry(
"Default Wallet",
"kdewallet");
449 walletName = QStringLiteral(
"kdewallet");
456 auto *collection = getCollectionByWalletName(walletName);
460 collection->onWalletChangeState(handle);
461 onCollectionChanged(collection->fdoObjectPath());
462 objectPath = collection->fdoObjectPath().path();
464 const auto path = makeUniqueObjectPath(walletName);
465 objectPath =
path.path();
466 auto newCollection = std::make_unique<KWalletFreedesktopCollection>(
this, handle, walletName, path);
467 m_collections[objectPath] = std::move(newCollection);
468 onCollectionCreated(path);
471 return QDBusObjectPath(objectPath);
475void KWalletFreedesktopService::lockCollection(
const QString &name)
477 auto *collection = getCollectionByWalletName(name);
479 collection->onWalletChangeState(-1);
480 onCollectionChanged(collection->fdoObjectPath());
485void KWalletFreedesktopService::entryUpdated(
const QString &walletName,
const QString &folder,
const QString &entryName)
487 auto *collection = getCollectionByWalletName(walletName);
492 const EntryLocation entryLocation{folder, entryName};
493 const auto *item = collection->findItemByEntryLocation(entryLocation);
495 collection->onItemChanged(item->fdoObjectPath());
497 auto objectPath = collection->nextItemPath();
498 collection->pushNewItem(entryLocation.toUniqueLabel(), objectPath);
499 collection->onItemCreated(objectPath);
504void KWalletFreedesktopService::entryDeleted(
const QString &walletName,
const QString &folder,
const QString &entryName)
506 auto *collection = getCollectionByWalletName(walletName);
511 const auto *item = collection->findItemByEntryLocation({folder, entryName});
513 collection->onItemDeleted(item->fdoObjectPath());
518void KWalletFreedesktopService::entryRenamed(
const QString &walletName,
const QString &folder,
const QString &oldName,
const QString &newName)
520 auto *collection = getCollectionByWalletName(walletName);
525 const EntryLocation oldLocation{folder, oldName};
526 const EntryLocation newLocation{folder, newName};
528 auto *item = collection->findItemByEntryLocation(oldLocation);
531 if (!collection->findItemByEntryLocation(newLocation)) {
532 qCWarning(KSECRETD_LOG) <<
"Cannot rename secret service label:" << FdoUniqueLabel::fromEntryLocation(oldLocation).label;
538 collection->itemAttributes().renameLabel(oldLocation, newLocation);
539 item->uniqueLabel(newLocation.toUniqueLabel());
540 collection->onItemChanged(item->fdoObjectPath());
545void KWalletFreedesktopService::walletDeleted(
const QString &walletName)
547 auto *collection = getCollectionByWalletName(walletName);
549 collection->Delete();
554void KWalletFreedesktopService::walletCreated(
const QString &walletName)
556 const auto objectPath = makeUniqueObjectPath(walletName);
557 auto collection = std::make_unique<KWalletFreedesktopCollection>(
this, -1, walletName, objectPath);
558 m_collections.emplace(objectPath.path(), std::move(collection));
559 onCollectionCreated(objectPath);
562bool KWalletFreedesktopService::desecret(
const QDBusMessage &message, FreedesktopSecret &secret)
564 const auto foundSession = m_sessions.find(secret.session.
path());
566 if (foundSession != m_sessions.end()) {
567 const KWalletFreedesktopSession &session = *foundSession->second;
568 return session.decrypt(message, secret);
574bool KWalletFreedesktopService::ensecret(
const QDBusMessage &message, FreedesktopSecret &secret)
576 const auto foundSession = m_sessions.find(secret.session.
path());
578 if (foundSession != m_sessions.end()) {
579 const KWalletFreedesktopSession &session = *foundSession->second;
580 return session.encrypt(message, secret);
588 static uint64_t
id = 0;
589 return QDBusObjectPath(QStringLiteral(FDO_SECRET_SERVICE_PROMPT_PATH) + QStringLiteral(
"p") +
QString::number(
id++));
595 arg << secret.session;
596 arg << secret.parameters;
598 arg << secret.mimeType;
606 arg >> secret.session;
607 arg >> secret.parameters;
609 arg >> secret.mimeType;
618 explicit_zero_mem(bytes.data(), bytes.size());
627 explicit_zero_mem(bytes.
data(), bytes.
size());
635 explicit_zero_mem(bytes.data(), bytes.size());
644 explicit_zero_mem(byteArray.
data(), byteArray.
size());
648KSecretD *KWalletFreedesktopService::backend()
const
655 return QDBusObjectPath(FDO_SECRETS_SERVICE_OBJECT);
658KWalletFreedesktopItem *KWalletFreedesktopService::getItemByObjectPath(
const QDBusObjectPath &path)
const
660 const auto str =
path.path();
661 if (!str.
startsWith(QStringLiteral(FDO_SECRETS_COLLECTION_PATH))) {
665 const QString collectionPath = wrapToCollectionPath(str);
666 const auto collectionPos = m_collections.find(collectionPath);
667 if (collectionPos == m_collections.end()) {
671 const auto &collection = collectionPos->second;
672 return collection->getItemByObjectPath(str);
675KWalletFreedesktopPrompt *KWalletFreedesktopService::getPromptByObjectPath(
const QDBusObjectPath &path)
const
677 const auto foundPrompt = m_prompts.find(
path.path());
678 if (foundPrompt != m_prompts.end()) {
679 return foundPrompt->second.get();
685FdoUniqueLabel KWalletFreedesktopService::makeUniqueCollectionLabel(
const QString &label)
688 auto walletName =
label;
689 const QStringList wallets = backend()->wallets();
691 while (wallets.
contains(walletName)) {
692 walletName = FdoUniqueLabel::makeName(label, ++n);
698QString KWalletFreedesktopService::makeUniqueWalletName(
const QString &labelPrefix)
700 return makeUniqueCollectionLabel(labelPrefix).toName();
705 auto mangled = mangleInvalidObjectPathChars(walletName);
706 mangled.
insert(0, QStringLiteral(FDO_SECRETS_COLLECTION_PATH));
708 QString result = mangled;
710 while (m_collections.count(result)) {
714 return QDBusObjectPath(result);
719 m_kwalletrc.reparseConfiguration();
720 KConfigGroup cfg(&m_kwalletrc,
"org.freedesktop.secrets.aliases");
724 for (
auto i =
map.begin(); i !=
map.end(); ++i) {
725 if (i.value() == walletName) {
730 KConfigGroup cfgWallet(&m_kwalletrc,
"Wallet");
731 if (defaultWalletName(cfgWallet) == walletName) {
732 aliases.
push_back(QStringLiteral(
"default"));
738void KWalletFreedesktopService::updateCollectionAlias(
const QString &alias,
const QString &walletName)
740 QString sectName = QStringLiteral(
"org.freedesktop.secrets.aliases");
741 QString sectKey = alias;
743 if (alias == QStringLiteral(
"default")) {
744 sectName = QStringLiteral(
"Wallet");
745 sectKey = QStringLiteral(
"Default Wallet");
748 KConfigGroup cfg(&m_kwalletrc, sectName);
753void KWalletFreedesktopService::createCollectionAlias(
const QString &alias,
const QString &walletName)
755 QString sectName = QStringLiteral(
"org.freedesktop.secrets.aliases");
756 QString sectKey = alias;
758 if (alias == QStringLiteral(
"default")) {
759 sectName = QStringLiteral(
"Wallet");
760 sectKey = QStringLiteral(
"Default Wallet");
763 m_kwalletrc.reparseConfiguration();
764 KConfigGroup cfg(&m_kwalletrc, sectName);
766 const QString prevWalletName = cfg.
readEntry(sectKey, QString());
767 if (!prevWalletName.
isEmpty()) {
768 const auto *prevCollection = getCollectionByWalletName(prevWalletName);
769 if (prevCollection) {
777 auto *collection = getCollectionByWalletName(walletName);
783void KWalletFreedesktopService::createCollectionAlias(
const QString &alias, KWalletFreedesktopCollection *collection)
785 QString sectName = QStringLiteral(
"org.freedesktop.secrets.aliases");
786 QString sectKey = alias;
788 if (alias == QStringLiteral(
"default")) {
789 sectName = QStringLiteral(
"Wallet");
790 sectKey = QStringLiteral(
"Default Wallet");
793 m_kwalletrc.reparseConfiguration();
794 KConfigGroup cfg(&m_kwalletrc, sectName);
796 const QString prevWalletName = cfg.
readEntry(sectKey,
"");
797 if (!prevWalletName.
isEmpty()) {
798 const auto *prevCollection = getCollectionByWalletName(prevWalletName);
799 if (prevCollection) {
804 cfg.
writeEntry(sectKey, collection->walletName());
809void KWalletFreedesktopService::removeAlias(
const QString &alias)
811 if (alias == QStringLiteral(
"default")) {
815 KConfigGroup cfg(&m_kwalletrc,
"org.freedesktop.secrets.aliases");
821KWalletFreedesktopCollection *KWalletFreedesktopService::getCollectionByWalletName(
const QString &walletName)
const
823 for (
const auto &collectionKeyValue : m_collections) {
824 const auto collection = collectionKeyValue.second.get();
825 if (collection->walletName() == walletName) {
833void KWalletFreedesktopService::deletePrompt(
const QString &objectPath)
835 const auto foundPrompt = m_prompts.find(objectPath);
836 if (foundPrompt == m_prompts.end()) {
843 foundPrompt->second->deleteLater();
844 foundPrompt->second.release();
845 m_prompts.erase(foundPrompt);
848void KWalletFreedesktopService::deleteSession(
const QString &objectPath)
850 const auto foundSession = m_sessions.find(objectPath);
851 if (foundSession == m_sessions.end()) {
858 foundSession->second->deleteLater();
859 foundSession->second.release();
860 m_sessions.erase(foundSession);
863void KWalletFreedesktopService::onCollectionCreated(
const QDBusObjectPath &path)
865 Q_EMIT CollectionCreated(path);
869 onPropertiesChanged(props);
872void KWalletFreedesktopService::onCollectionChanged(
const QDBusObjectPath &path)
874 Q_EMIT CollectionChanged(path);
877void KWalletFreedesktopService::onCollectionDeleted(
const QDBusObjectPath &path)
879 const auto collectionMapPos = m_collections.find(
path.path());
880 if (collectionMapPos == m_collections.end()) {
883 auto &collectionPair = *collectionMapPos;
884 collectionPair.second->itemAttributes().deleteFile();
889 collectionPair.second->deleteLater();
890 collectionPair.second.release();
891 m_collections.erase(collectionMapPos);
893 Q_EMIT CollectionDeleted(path);
897 onPropertiesChanged(props);
900void KWalletFreedesktopService::onPropertiesChanged(
const QVariantMap &properties)
902 auto msg =
QDBusMessage::createSignal(fdoObjectPath().
path(), QStringLiteral(
"org.freedesktop.DBus.Properties"), QStringLiteral(
"PropertiesChanged"));
903 auto args = QVariantList();
904 args << QStringLiteral(
"org.freedesktop.Secret.Service") <<
properties << QStringList();
905 msg.setArguments(args);
911 return stream << value.
path();
927 while (!arg.
atEnd()) {
940 value.map.insert(key, val);
955void explicit_zero_mem(
void *data,
size_t size)
957#if defined(KSECRETD_HAVE_EXPLICIT_BZERO)
958 explicit_bzero(data, size);
959#elif defined(KSECRETD_HAVE_RTLSECUREZEROMEMORY)
960 RtlSecureZeroMemory(data, size);
962 auto p =
reinterpret_cast<volatile char *
>(data);
963 for (
size_t i = 0; i < size; ++i) {
969#include "moc_kwalletfreedesktopservice.cpp"
void deleteEntry(const char *key, WriteConfigFlags pFlags=Normal)
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
QMap< QString, QString > entryMap() const
PrivateKey createDH(const DLGroup &domain, const QString &provider=QString())
DLGroup createDLGroup(QCA::DLGroupSet set, const QString &provider=QString())
QByteArray toByteArray() const
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
QString path(const QString &relativePath)
KIOCORE_EXPORT QString dir(const QString &fileClass)
QString name(StandardAction id)
QString label(StandardShortcut id)
qsizetype size() const const
void beginMap(QMetaType keyMetaType, QMetaType valueMetaType)
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
bool registerService(const QString &serviceName)
bool send(const QDBusMessage &message) const const
QDBusConnection sessionBus()
void unregisterObject(const QString &path, UnregisterMode mode)
QDBusMessage createSignal(const QString &path, const QString &interface, const QString &name)
QString path() const const
void setPath(const QString &path)
QVariant variant() const const
void push_back(parameter_type value)
void reserve(qsizetype size)
iterator insert(const Key &key, const T &value)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
QString & insert(qsizetype position, QChar ch)
bool isEmpty() const const
QString left(qsizetype n) const const
QString number(double n, char format, int precision)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
void reserve(qsizetype size)
QString right(qsizetype n) const const
QString section(QChar sep, qsizetype start, qsizetype end, SectionFlags flags) const const
qsizetype size() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
int toInt(bool *ok, int base) const const
QByteArray toUtf8() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QTextStream & hex(QTextStream &stream)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool canConvert() const const
QVariant fromValue(T &&value)
QByteArray toByteArray() const const