/** * Here we use server sync url without protocol prefix and * user account name as the key in the keyring. * * Also since the KWallet's API supports only storing (key,password) * or Map<QString,QString> , the former is used. */ bool KWalletLoadPasswordSlot(const InitStateTri &keyring, const std::string &passwordName, const std::string &descr, const ConfigPasswordKey &key, InitStateString &password) { if (!UseKWallet(keyring, GetLoadPasswordSignal().num_slots() - INTERNAL_LOAD_PASSWORD_SLOTS)) { return false; } QString walletPassword; QString walletKey = QString(key.user.c_str()) + ',' + QString(key.domain.c_str())+ ','+ QString(key.server.c_str())+','+ QString(key.object.c_str())+','+ QString(key.protocol.c_str())+','+ QString(key.authtype.c_str())+','+ QString::number(key.port); QString wallet_name = KWallet::Wallet::NetworkWallet(); //QString folder = QString::fromUtf8("Syncevolution"); const QLatin1String folder("Syncevolution"); if (!KWallet::Wallet::keyDoesNotExist(wallet_name, folder, walletKey)) { KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1, KWallet::Wallet::Synchronous); if (wallet && wallet->setFolder(folder) && wallet->readPassword(walletKey, walletPassword) == 0) { password = walletPassword.toStdString(); } } return true; }
// static bool OTKeyring::KWallet_DeleteSecret(const OTString& strUser, const std::string& str_display) { OT_ASSERT(strUser.Exists()); KWallet::Wallet* pWallet = OTKeyring::OpenKWallet(); if (nullptr != pWallet) { const QString qstrKey(strUser.Get()); bool bResult = false; if (pWallet->removeEntry(qstrKey) == 0) // delete the entry bResult = true; else otErr << "OTKeyring::KWallet_DeleteSecret: Failed trying to erase " "secret from KWallet.\n"; return bResult; } otErr << "OTKeyring::KWallet_DeleteSecret: Unable to open kwallet.\n"; return false; }
// static bool OTKeyring::KWallet_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); KWallet::Wallet* pWallet = OTKeyring::OpenKWallet(); if (nullptr != pWallet) { const QString qstrKey(strUser.Get()); QString qstrPwd; // Get the password // if (pWallet->readPassword(qstrKey, qstrPwd) == 0) { const std::string str_password = qstrPwd.toStdString(); // todo security: notice str_password // isn't zero'd here. OTString strData(str_password); OTASCIIArmor ascData; const bool bLoaded = strData.Exists() && ascData.LoadFromString(strData); strData.zeroMemory(); if (!bLoaded) otErr << __FUNCTION__ << ": Failed trying to decode secret " "from KWallet contents.\n"; else { OTData thePayload(ascData); ascData.zeroMemory(); if (thePayload.IsEmpty()) otErr << __FUNCTION__ << ": Failed trying to decode secret " "OTData from OTASCIIArmor from " "KWallet contents.\n"; else { thePassword.setMemory(thePayload.GetPayloadPointer(), thePayload.GetSize()); thePayload.zeroMemory(); // for security. return true; } } } else otErr << __FUNCITON__ << ": Failed trying to retrieve secret from KWallet.\n"; } // Not an error: what if it just hasn't been set there yet? // otWarn << "OTKeyring::KWallet_RetrieveSecret: No secret found.\n"; return false; }
// static bool OTKeyring::KWallet_StoreSecret(const OTString& strUser, const OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); OT_ASSERT(thePassword.getMemorySize() > 0); KWallet::Wallet* pWallet = OTKeyring::OpenKWallet(); if (nullptr != pWallet) { const QString qstrKey(strUser.Get()); OTData theData(thePassword.getMemory(), thePassword.getMemorySize()); OTASCIIArmor ascData(theData); theData.zeroMemory(); // security reasons. OTString strOutput; const bool bSuccess = ascData.Exists() && ascData.WriteArmoredString( strOutput, "DERIVED KEY"); // There's no default, to force you // to enter the right string. ascData.zeroMemory(); // Set the password // bool bReturnVal = false; if (bSuccess && strOutput.Exists() && pWallet->writePassword(qstrKey, QString::fromUtf8(strOutput.Get())) == 0) bReturnVal = true; else otErr << "OTKeyring::KWallet_StoreSecret: Failed trying to store " "secret into KWallet.\n"; strOutput.zeroMemory(); return bReturnVal; } otErr << "OTKeyring::KWallet_StoreSecret: Unable to open kwallet.\n"; return false; }
extern "C" ppk_error getEntry(const ppk_entry* entry, ppk_data **edata, unsigned int flags) { QString generatedKey; if (generateKey(entry, generatedKey) == PPK_FALSE) return PPK_UNKNOWN_ENTRY_TYPE; KWallet::Wallet *wallet = openWallet(flags); if (wallet == NULL) return PPK_CANNOT_OPEN_PASSWORD_MANAGER; KWallet::Wallet::EntryType entryType = wallet->entryType(generatedKey); if (entryType == KWallet::Wallet::Password) return getPassword(generatedKey, edata, flags); else if (entryType == KWallet::Wallet::Stream) return getBlob(generatedKey, edata, flags); else return PPK_UNKNOWN_ENTRY_TYPE; }
bool KWalletSavePasswordSlot(const InitStateTri &keyring, const std::string &passwordName, const std::string &password, const ConfigPasswordKey &key) { if (!UseKWallet(keyring, GetSavePasswordSignal().num_slots() - INTERNAL_SAVE_PASSWORD_SLOTS)) { return false; } /* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use * but currently only use passed key instead */ // write password to keyring const QString walletKey = QString::fromStdString(key.user + ',' + key.domain + ',' + key.server + ',' + key.object + ',' + key.protocol + ',' + key.authtype + ',')+ QString::number(key.port); const QString walletPassword = QString::fromStdString(password); bool write_success = false; const QString wallet_name = KWallet::Wallet::NetworkWallet(); const QLatin1String folder("Syncevolution"); KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1, KWallet::Wallet::Synchronous); if (wallet) { if (!wallet->hasFolder(folder)) { wallet->createFolder(folder); } if (wallet->setFolder(folder) && wallet->writePassword(walletKey, walletPassword) == 0) { write_success = true; } } if (!write_success) { SyncContext::throwError("Saving " + passwordName + " in KWallet failed."); } return write_success; }
QVector<SieveEditorUtil::SieveServerConfig> SieveEditorUtil::readServerSieveConfig() { QVector<SieveServerConfig> lstConfig; KSharedConfigPtr cfg = KSharedConfig::openConfig(); QRegularExpression re(QStringLiteral("^ServerSieve (.+)$")); const QStringList groups = cfg->groupList().filter(re); KWallet::Wallet *wallet = SieveServerSettings::self()->wallet(); if (wallet && !wallet->setFolder(QStringLiteral("sieveeditor"))) { wallet->createFolder(QStringLiteral("sieveeditor")); wallet->setFolder(QStringLiteral("sieveeditor")); } Q_FOREACH (const QString &conf, groups) { SieveServerConfig sieve; KConfigGroup group = cfg->group(conf); sieve.port = group.readEntry(QStringLiteral("Port"), 0); sieve.serverName = group.readEntry(QStringLiteral("ServerName")); sieve.userName = group.readEntry(QStringLiteral("UserName")); sieve.enabled = group.readEntry(QStringLiteral("Enabled"), true); const QString walletEntry = sieve.userName + QLatin1Char('@') + sieve.serverName; if (wallet && wallet->hasEntry(walletEntry)) { wallet->readPassword(walletEntry, sieve.password); } sieve.authenticationType = static_cast<MailTransport::Transport::EnumAuthenticationType::type>(group.readEntry(QStringLiteral("Authentication"), static_cast<int>(MailTransport::Transport::EnumAuthenticationType::PLAIN))); lstConfig.append(sieve); }
void EncryptedStore::findPasswordInKWallet() { Q_D(KOdfStore); /* About KWallet access * * The choice has been made to postfix every entry in a kwallet concerning passwords for opendocument files with /opendocument * This choice has been made since, at the time of this writing, the author could not find any reference to standardized * naming schemes for entries in the wallet. Since collision of passwords in entries should be avoided and is at least possible, * considering remote files might be both protected by a secured web-area (konqueror makes an entry) and a password (we make an * entry), it seems a good thing to make sure it won't happen. */ if (!m_filename.isNull() && !KWallet::Wallet::folderDoesNotExist(KWallet::Wallet::LocalWallet(), KWallet::Wallet::PasswordFolder()) && !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::LocalWallet(), KWallet::Wallet::PasswordFolder(), m_filename + "/opendocument")) { KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(), d->window ? d->window->winId() : 0); if (wallet) { if (wallet->setFolder(KWallet::Wallet::PasswordFolder())) { QString pass; wallet->readPassword(m_filename + "/opendocument", pass); m_password = QCA::SecureArray(pass.toUtf8()); } delete wallet; } } }
void EncryptedStore::savePasswordInKWallet() { Q_D(KOdfStore); KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(), d->window ? d->window->winId() : 0); if (wallet) { if (!wallet->hasFolder(KWallet::Wallet::PasswordFolder())) { wallet->createFolder(KWallet::Wallet::PasswordFolder()); } if (wallet->setFolder(KWallet::Wallet::PasswordFolder())) { if (wallet->hasEntry(m_filename + "/opendocument")) { wallet->removeEntry(m_filename + "/opendocument"); } wallet->writePassword(m_filename + "/opendocument", m_password.toByteArray().data()); } delete wallet; } }
bool KSaneWidget::openDevice(const QString &deviceName) { int i = 0; const SANE_Option_Descriptor *optDesc; SANE_Status status; SANE_Word numSaneOptions; SANE_Int res; KPasswordDialog *dlg; KWallet::Wallet *saneWallet; QString myFolderName = QStringLiteral("ksane"); QMap<QString, QString> wallet_entry; if (d->m_saneHandle != 0) { // this KSaneWidget already has an open device return false; } // don't bother trying to open if the device string is empty if (deviceName.isEmpty()) { return false; } // save the device name d->m_devName = deviceName; // Try to open the device status = sane_open(deviceName.toLatin1().constData(), &d->m_saneHandle); bool password_dialog_ok = true; // prepare wallet for authentication and create password dialog if (status == SANE_STATUS_ACCESS_DENIED) { saneWallet = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(), winId()); if (saneWallet) { dlg = new KPasswordDialog(this, KPasswordDialog::ShowUsernameLine | KPasswordDialog::ShowKeepPassword); if (!saneWallet->hasFolder(myFolderName)) { saneWallet->createFolder(myFolderName); } saneWallet->setFolder(myFolderName); saneWallet->readMap(deviceName, wallet_entry); if (!wallet_entry.empty() || true) { dlg->setUsername(wallet_entry[QStringLiteral("username")]); dlg->setPassword(wallet_entry[QStringLiteral("password")]); dlg->setKeepPassword(true); } } else { dlg = new KPasswordDialog(this, KPasswordDialog::ShowUsernameLine); } dlg->setPrompt(i18n("Authentication required for resource: %1", deviceName)); } // sane_open failed due to insufficient authorization // retry opening device with user provided data assisted with kwallet records while (status == SANE_STATUS_ACCESS_DENIED) { password_dialog_ok = dlg->exec(); if (!password_dialog_ok) { delete dlg; d->m_devName.clear(); return false; //the user canceled } // add/update the device user-name and password for authentication d->m_auth->setDeviceAuth(d->m_devName, dlg->username(), dlg->password()); status = sane_open(deviceName.toLatin1().constData(), &d->m_saneHandle); // store password in wallet on successful authentication if (dlg->keepPassword() && status != SANE_STATUS_ACCESS_DENIED) { QMap<QString, QString> entry; entry[QStringLiteral("username")] = dlg->username(); entry[QStringLiteral("password")] = dlg->password(); if (saneWallet) { saneWallet->writeMap(deviceName, entry); } } } if (status != SANE_STATUS_GOOD) { qDebug() << "sane_open(\"" << deviceName << "\", &handle) failed! status = " << sane_strstatus(status); d->m_auth->clearDeviceAuth(d->m_devName); d->m_devName.clear(); return false; } // update the device list if needed to get the vendor and model info if (d->m_findDevThread->devicesList().size() == 0) { d->m_findDevThread->start(); } else { // use the "old" existing list d->devListUpdated(); // if m_vendor is not updated it means that the list needs to be updated. if (d->m_vendor.isEmpty()) { d->m_findDevThread->start(); } } // Read the options (start with option 0 the number of parameters) optDesc = sane_get_option_descriptor(d->m_saneHandle, 0); if (optDesc == 0) { d->m_auth->clearDeviceAuth(d->m_devName); d->m_devName.clear(); return false; } QVarLengthArray<char> data(optDesc->size); status = sane_control_option(d->m_saneHandle, 0, SANE_ACTION_GET_VALUE, data.data(), &res); if (status != SANE_STATUS_GOOD) { d->m_auth->clearDeviceAuth(d->m_devName); d->m_devName.clear(); return false; } numSaneOptions = *reinterpret_cast<SANE_Word *>(data.data()); // read the rest of the options for (i = 1; i < numSaneOptions; ++i) { switch (KSaneOption::optionType(sane_get_option_descriptor(d->m_saneHandle, i))) { case KSaneOption::TYPE_DETECT_FAIL: d->m_optList.append(new KSaneOption(d->m_saneHandle, i)); break; case KSaneOption::TYPE_CHECKBOX: d->m_optList.append(new KSaneOptCheckBox(d->m_saneHandle, i)); break; case KSaneOption::TYPE_SLIDER: d->m_optList.append(new KSaneOptSlider(d->m_saneHandle, i)); break; case KSaneOption::TYPE_F_SLIDER: d->m_optList.append(new KSaneOptFSlider(d->m_saneHandle, i)); break; case KSaneOption::TYPE_COMBO: d->m_optList.append(new KSaneOptCombo(d->m_saneHandle, i)); break; case KSaneOption::TYPE_ENTRY: d->m_optList.append(new KSaneOptEntry(d->m_saneHandle, i)); break; case KSaneOption::TYPE_GAMMA: d->m_optList.append(new KSaneOptGamma(d->m_saneHandle, i)); break; case KSaneOption::TYPE_BUTTON: d->m_optList.append(new KSaneOptButton(d->m_saneHandle, i)); break; } } // do the connections of the option parameters for (i = 1; i < d->m_optList.size(); ++i) { //qDebug() << d->m_optList.at(i)->name(); connect(d->m_optList.at(i), SIGNAL(optsNeedReload()), d, SLOT(optReload())); connect(d->m_optList.at(i), SIGNAL(valsNeedReload()), d, SLOT(scheduleValReload())); if (d->m_optList.at(i)->needsPolling()) { //qDebug() << d->m_optList.at(i)->name() << " needs polling"; d->m_pollList.append(d->m_optList.at(i)); KSaneOptCheckBox *buttonOption = qobject_cast<KSaneOptCheckBox *>(d->m_optList.at(i)); if (buttonOption) { connect(buttonOption, SIGNAL(buttonPressed(QString,QString,bool)), this, SIGNAL(buttonPressed(QString,QString,bool))); } } }
/* Implementation of svn_auth__password_set_t that stores the password in KWallet. */ static svn_error_t * kwallet_password_set(svn_boolean_t *done, apr_hash_t *creds, const char *realmstring, const char *username, const char *password, apr_hash_t *parameters, svn_boolean_t non_interactive, apr_pool_t *pool) { QString wallet_name = get_wallet_name(parameters); *done = FALSE; if (! dbus_bus_get(DBUS_BUS_SESSION, NULL)) { return SVN_NO_ERROR; } if (non_interactive) { if (!KWallet::Wallet::isOpen(wallet_name)) return SVN_NO_ERROR; /* There is a race here: the wallet was open just now, but will it still be open when we come to use it below? */ } QCoreApplication *app; if (! qApp) { int argc = q_argc; app = new QCoreApplication(argc, q_argv); } KCmdLineArgs::init(q_argc, q_argv, get_application_name(parameters, pool), "subversion", ki18n(get_application_name(parameters, pool)), SVN_VER_NUMBER, ki18n("Version control system"), KCmdLineArgs::CmdLineArgKDE); KComponentData component_data(KCmdLineArgs::aboutData()); QString q_password = QString::fromUtf8(password); QString folder = QString::fromUtf8("Subversion"); KWallet::Wallet *wallet = get_wallet(wallet_name, parameters); if (wallet) { if (! wallet->hasFolder(folder)) { wallet->createFolder(folder); } if (wallet->setFolder(folder)) { QString key = QString::fromUtf8(username) + "@" + QString::fromUtf8(realmstring); if (wallet->writePassword(key, q_password) == 0) { *done = TRUE; } } } return SVN_NO_ERROR; }