KIO::AuthInfo KPasswdServer::checkAuthInfo(KIO::AuthInfo info, long windowId, unsigned long usertime) { kdDebug(130) << "KPasswdServer::checkAuthInfo: User= "******", WindowId = " << windowId << endl; if( usertime != 0 ) kapp->updateUserTimestamp( usertime ); QString key = createCacheKey(info); Request *request = m_authPending.first(); QString path2 = info.url.directory(false, false); for(; request; request = m_authPending.next()) { if (request->key != key) continue; if (info.verifyPath) { QString path1 = request->info.url.directory(false, false); if (!path2.startsWith(path1)) continue; } request = new Request; request->client = callingDcopClient(); request->transaction = request->client->beginTransaction(); request->key = key; request->info = info; m_authWait.append(request); return info; } const AuthInfo *result = findAuthInfoItem(key, info); if (!result || result->isCanceled) { if (!result && (info.username.isEmpty() || info.password.isEmpty()) && !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), KWallet::Wallet::PasswordFolder(), makeWalletKey(key, info.realmValue))) { QMap<QString, QString> knownLogins; if (openWallet(windowId)) { if (readFromWallet(m_wallet, key, info.realmValue, info.username, info.password, info.readOnly, knownLogins)) { info.setModified(true); return info; } } } info.setModified(false); return info; } updateAuthExpire(key, result, windowId, false); return copyAuthInfo(result); }
void KPasswdServer::addAuthInfoItem(const QString &key, const KIO::AuthInfo &info, long windowId, long seqNr, bool canceled) { AuthInfoList *authList = m_authDict.find(key); if (!authList) { authList = new AuthInfoList; m_authDict.insert(key, authList); } AuthInfo *current = authList->first(); for(; current; current = authList->next()) { if (current->realmValue == info.realmValue) { authList->take(); break; } } if (!current) { current = new AuthInfo; current->expire = AuthInfo::expTime; kdDebug(130) << "Creating AuthInfo" << endl; } else { kdDebug(130) << "Updating AuthInfo" << endl; } current->url = info.url; current->directory = info.url.directory(false, false); current->username = info.username; current->password = info.password; current->realmValue = info.realmValue; current->digestInfo = info.digestInfo; current->seqNr = seqNr; current->isCanceled = canceled; updateAuthExpire(key, current, windowId, info.keepPassword && !canceled); // Insert into list, keep the list sorted "longest path" first. authList->inSort(current); }
void KPasswdServer::processRequest() { Request *request = m_authPending.first(); if(!request) return; KIO::AuthInfo &info = request->info; kdDebug(130) << "KPasswdServer::processRequest: User= "******", Message= " << info.prompt << endl; const AuthInfo *result = findAuthInfoItem(request->key, request->info); if(result && (request->seqNr < result->seqNr)) { kdDebug(130) << "KPasswdServer::processRequest: auto retry!" << endl; if(result->isCanceled) { info.setModified(false); } else { updateAuthExpire(request->key, result, request->windowId, false); info = copyAuthInfo(result); } } else { m_seqNr++; bool askPw = request->prompt; if(result && !info.username.isEmpty() && !request->errorMsg.isEmpty()) { QString prompt = request->errorMsg; prompt += i18n(" Do you want to retry?"); int dlgResult = KMessageBox::warningContinueCancelWId(request->windowId, prompt, i18n("Authentication"), i18n("Retry")); if(dlgResult != KMessageBox::Continue) askPw = false; } int dlgResult = QDialog::Rejected; if(askPw) { QString username = info.username; QString password = info.password; bool hasWalletData = false; QMap< QString, QString > knownLogins; if((username.isEmpty() || password.isEmpty()) && !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), KWallet::Wallet::PasswordFolder(), makeWalletKey(request->key, info.realmValue))) { // no login+pass provided, check if kwallet has one if(openWallet(request->windowId)) hasWalletData = readFromWallet(m_wallet, request->key, info.realmValue, username, password, info.readOnly, knownLogins); } KIO::PasswordDialog dlg(info.prompt, username, info.keepPassword); if(info.caption.isEmpty()) dlg.setPlainCaption(i18n("Authorization Dialog")); else dlg.setPlainCaption(info.caption); if(!info.comment.isEmpty()) dlg.addCommentLine(info.commentLabel, info.comment); if(!password.isEmpty()) dlg.setPassword(password); if(info.readOnly) dlg.setUserReadOnly(true); else dlg.setKnownLogins(knownLogins); if(hasWalletData) dlg.setKeepPassword(true); #ifdef Q_WS_X11 XSetTransientForHint(qt_xdisplay(), dlg.winId(), request->windowId); #endif dlgResult = dlg.exec(); if(dlgResult == QDialog::Accepted) { info.username = dlg.username(); info.password = dlg.password(); info.keepPassword = dlg.keepPassword(); // When the user checks "keep password", that means: // * if the wallet is enabled, store it there for long-term, and in kpasswdserver // only for the duration of the window (#92928) // * otherwise store in kpasswdserver for the duration of the KDE session. if(info.keepPassword) { if(openWallet(request->windowId)) { if(storeInWallet(m_wallet, request->key, info)) // password is in wallet, don't keep it in memory after window is closed info.keepPassword = false; } } } } if(dlgResult != QDialog::Accepted) { addAuthInfoItem(request->key, info, 0, m_seqNr, true); info.setModified(false); } else { addAuthInfoItem(request->key, info, request->windowId, m_seqNr, false); info.setModified(true); } } QCString replyType; QByteArray replyData; QDataStream stream2(replyData, IO_WriteOnly); stream2 << info << m_seqNr; replyType = "KIO::AuthInfo"; request->client->endTransaction(request->transaction, replyType, replyData); m_authPending.remove((unsigned int)0); // Check all requests in the wait queue. for(Request *waitRequest = m_authWait.first(); waitRequest;) { bool keepQueued = false; QString key = waitRequest->key; request = m_authPending.first(); QString path2 = waitRequest->info.url.directory(false, false); for(; request; request = m_authPending.next()) { if(request->key != key) continue; if(info.verifyPath) { QString path1 = request->info.url.directory(false, false); if(!path2.startsWith(path1)) continue; } keepQueued = true; break; } if(keepQueued) { waitRequest = m_authWait.next(); } else { const AuthInfo *result = findAuthInfoItem(waitRequest->key, waitRequest->info); QCString replyType; QByteArray replyData; QDataStream stream2(replyData, IO_WriteOnly); if(!result || result->isCanceled) { waitRequest->info.setModified(false); stream2 << waitRequest->info; } else { updateAuthExpire(waitRequest->key, result, waitRequest->windowId, false); KIO::AuthInfo info = copyAuthInfo(result); stream2 << info; } replyType = "KIO::AuthInfo"; waitRequest->client->endTransaction(waitRequest->transaction, replyType, replyData); m_authWait.remove(); waitRequest = m_authWait.current(); } } if(m_authPending.count()) QTimer::singleShot(0, this, SLOT(processRequest())); }