kutils: allow storing and retreiving of temporary passwords via KPasswdStore

the implementation supports it and KIO now uses that feature

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-05-05 07:22:39 +03:00
parent 972b231e4a
commit 3716b1ffe5
7 changed files with 63 additions and 26 deletions

View file

@ -303,7 +303,7 @@ void SlaveBase::dispatchLoop()
int ret = -1; int ret = -1;
if (d->appConnection.hasTaskAvailable() || d->appConnection.waitForIncomingTask(ms)) { if (d->appConnection.hasTaskAvailable() || d->appConnection.waitForIncomingTask(ms)) {
// dispatch application messages // dispatch application messages
int cmd; int cmd = 0;
QByteArray data; QByteArray data;
ret = d->appConnection.read(&cmd, data); ret = d->appConnection.read(&cmd, data);
@ -578,6 +578,14 @@ void SlaveBase::reparseConfiguration()
bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg) bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg)
{ {
KPasswdStore* passwdstore = d->passwdStore();
Q_ASSERT(passwdstore);
passwdstore->openStore();
if (checkCachedAuthentication(info)) {
return true;
}
if (metaData(QLatin1String("no-auth-prompt")).compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) { if (metaData(QLatin1String("no-auth-prompt")).compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) {
return false; return false;
} }
@ -587,9 +595,6 @@ bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg)
AuthInfo dlgInfo(info); AuthInfo dlgInfo(info);
KPasswdStore* passwdstore = d->passwdStore();
Q_ASSERT(passwdstore);
// assemble dialog-flags // assemble dialog-flags
KPasswordDialog::KPasswordDialogFlags dialogFlags; KPasswordDialog::KPasswordDialogFlags dialogFlags;
@ -605,9 +610,8 @@ bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg)
dialogFlags |= KPasswordDialog::ShowUsernameLine; dialogFlags |= KPasswordDialog::ShowUsernameLine;
} }
// If store is not enabled and the caller explicitly requested for it, // If the caller explicitly requested for it do not show the keep password checkbox.
// do not show the keep password checkbox. if (dlgInfo.keepPassword) {
if (dlgInfo.keepPassword && !passwdstore->cacheOnly()) {
dialogFlags |= KPasswordDialog::ShowKeepPassword; dialogFlags |= KPasswordDialog::ShowKeepPassword;
} }
@ -636,9 +640,8 @@ bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg)
dlg->setUsernameReadOnly(true); dlg->setUsernameReadOnly(true);
} }
if (!passwdstore->cacheOnly()) { // even if the store is not open passwords can be temporary stored
dlg->setKeepPassword(true); dlg->setKeepPassword(true);
}
if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) { if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) {
dlg->setDomain(dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).toString()); dlg->setDomain(dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).toString());
@ -948,16 +951,21 @@ bool SlaveBase::checkCachedAuthentication(AuthInfo &info)
{ {
KPasswdStore* passwdstore = d->passwdStore(); KPasswdStore* passwdstore = d->passwdStore();
Q_ASSERT(passwdstore); Q_ASSERT(passwdstore);
if (!passwdstore->isOpen() && !passwdstore->cacheOnly()) {
// let it fail the first time, if authorization is really required openPasswordDialog()
// will open the store and call this method
return false;
}
const qlonglong windowId = metaData(QLatin1String("window-id")).toLongLong(); const qlonglong windowId = metaData(QLatin1String("window-id")).toLongLong();
QByteArray authkey = authInfoKey(info); QByteArray authkey = authInfoKey(info);
if (passwdstore->hasPasswd(authkey, windowId)) { QString passwd = passwdstore->getPasswd(authkey, windowId);
const QString passwd = passwdstore->getPasswd(authkey, windowId); if (!passwd.isEmpty()) {
info = authInfoFromData(passwd.toLatin1()); info = authInfoFromData(passwd.toLatin1());
return true; return true;
} }
authkey = authInfoKey2(info); authkey = authInfoKey2(info);
if (passwdstore->hasPasswd(authkey, windowId)) { passwd = passwdstore->getPasswd(authkey, windowId);
const QString passwd = passwdstore->getPasswd(authkey, windowId); if (!passwd.isEmpty()) {
info = authInfoFromData(passwd.toLatin1()); info = authInfoFromData(passwd.toLatin1());
return true; return true;
} }

View file

@ -32,6 +32,23 @@ KPasswdStoreModule::~KPasswdStoreModule()
qDeleteAll(m_stores); qDeleteAll(m_stores);
} }
bool KPasswdStoreModule::isOpen(const QByteArray &cookie, const QString &storeid)
{
KPasswdStoreMap::const_iterator it = m_stores.begin();
while (it != m_stores.end()) {
if (it.key() != cookie) {
it++;
continue;
}
KPasswdStoreImpl *store = it.value();
if (store->storeID() == storeid) {
return store->isOpen();
}
it++;
}
return false;
}
bool KPasswdStoreModule::openStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid) bool KPasswdStoreModule::openStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid)
{ {
KPasswdStoreMap::iterator it = m_stores.begin(); KPasswdStoreMap::iterator it = m_stores.begin();

View file

@ -34,6 +34,7 @@ public:
~KPasswdStoreModule(); ~KPasswdStoreModule();
public Q_SLOTS: public Q_SLOTS:
Q_SCRIPTABLE bool isOpen(const QByteArray &cookie, const QString &storeid);
Q_SCRIPTABLE bool openStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid = 0); Q_SCRIPTABLE bool openStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid = 0);
Q_SCRIPTABLE bool closeStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid = 0); Q_SCRIPTABLE bool closeStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid = 0);

View file

@ -91,6 +91,11 @@ QString KPasswdStoreImpl::storeID() const
return m_storeid; return m_storeid;
} }
bool KPasswdStoreImpl::isOpen() const
{
return (m_passwdtimer.elapsed() < m_timeout);
}
bool KPasswdStoreImpl::openStore(const qlonglong windowid) bool KPasswdStoreImpl::openStore(const qlonglong windowid)
{ {
if (m_cacheonly) { if (m_cacheonly) {

View file

@ -35,6 +35,7 @@ public:
QString storeID() const; QString storeID() const;
bool isOpen() const;
bool openStore(const qlonglong windowid); bool openStore(const qlonglong windowid);
bool closeStore(); bool closeStore();

View file

@ -97,6 +97,16 @@ void KPasswdStore::setStoreID(const QString &id)
d->storeid = id; d->storeid = id;
} }
bool KPasswdStore::isOpen() const
{
d->ensureInterface();
KLockFile klockfile(getLockName(d->cookie, d->storeid));
klockfile.lock();
QDBusReply<bool> result = d->interface->call("isOpen", d->cookie, d->storeid);
klockfile.unlock();
return result.value();
}
bool KPasswdStore::openStore(const qlonglong windowid) bool KPasswdStore::openStore(const qlonglong windowid)
{ {
d->ensureInterface(); d->ensureInterface();
@ -120,14 +130,9 @@ bool KPasswdStore::cacheOnly() const
return result.value(); return result.value();
} }
bool KPasswdStore::hasPasswd(const QByteArray &key, const qlonglong windowid)
{
return !getPasswd(key, windowid).isEmpty();
}
QString KPasswdStore::getPasswd(const QByteArray &key, const qlonglong windowid) QString KPasswdStore::getPasswd(const QByteArray &key, const qlonglong windowid)
{ {
if (!openStore(windowid)) { if (!openStore(windowid) && !cacheOnly()) {
return QString(); return QString();
} }
QDBusReply<QString> result = d->interface->call("getPasswd", d->cookie, d->storeid, key, windowid); QDBusReply<QString> result = d->interface->call("getPasswd", d->cookie, d->storeid, key, windowid);
@ -136,7 +141,7 @@ QString KPasswdStore::getPasswd(const QByteArray &key, const qlonglong windowid)
bool KPasswdStore::storePasswd(const QByteArray &key, const QString &passwd, const qlonglong windowid) bool KPasswdStore::storePasswd(const QByteArray &key, const QString &passwd, const qlonglong windowid)
{ {
if (!openStore(windowid)) { if (!openStore(windowid) && !cacheOnly()) {
return false; return false;
} }
QDBusReply<bool> result = d->interface->call("storePasswd", d->cookie, d->storeid, key, passwd, windowid); QDBusReply<bool> result = d->interface->call("storePasswd", d->cookie, d->storeid, key, passwd, windowid);

View file

@ -70,6 +70,11 @@ public:
*/ */
void setStoreID(const QString &id); void setStoreID(const QString &id);
/*!
@brief Returns true if the store is open, false otherwise
*/
bool isOpen() const;
/*! /*!
@brief Opens the store by asking for the password for it and returns @brief Opens the store by asking for the password for it and returns
@p true if the store is open, @p false otherwise @p true if the store is open, @p false otherwise
@ -88,11 +93,6 @@ public:
*/ */
bool cacheOnly() const; bool cacheOnly() const;
/*!
@brief Returns @p true if there is password for the given @p key in the
password store, @p false otherwise
*/
bool hasPasswd(const QByteArray &key, const qlonglong windowid = 0);
/*! /*!
@brief Retrieves password for the given @p key from the password store @brief Retrieves password for the given @p key from the password store
*/ */