ported branch commit 2732: fixed deadlock in passwd callback

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2734 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-04-19 21:50:03 +00:00
parent 768b9288b5
commit 38463c905e
12 changed files with 102 additions and 61 deletions

View File

@ -1894,7 +1894,8 @@ int pem_passwd_cb(char *buf, int size, int rwflag, void *password)
return(strlen(buf)); return(strlen(buf));
} }
bool AuthSSL::LocalStoreCert(X509* x509) { bool AuthSSL::LocalStoreCert(X509* x509)
{
//store the certificate in the local cert list //store the certificate in the local cert list
std::string peerId; std::string peerId;
if(!getX509id(x509, peerId)) if(!getX509id(x509, peerId))
@ -1904,8 +1905,10 @@ bool AuthSSL::LocalStoreCert(X509* x509) {
#endif #endif
return false; return false;
} }
if (peerId != mOwnId) { if (peerId != mOwnId)
if (mCerts[peerId]) { {
if (mCerts[peerId])
{
#ifdef AUTHSSL_DEBUG #ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSL::LocalStoreCert() get duplicate for " << mCerts[peerId]->id << std::endl; std::cerr << "AuthSSL::LocalStoreCert() get duplicate for " << mCerts[peerId]->id << std::endl;
#endif #endif
@ -1918,7 +1921,9 @@ bool AuthSSL::LocalStoreCert(X509* x509) {
std::cerr << std::endl; std::cerr << std::endl;
return false; return false;
} }
} else { }
else
{
RsStackMutex stack(sslMtx); /******* LOCKED ******/ RsStackMutex stack(sslMtx); /******* LOCKED ******/
#ifdef AUTHSSL_DEBUG #ifdef AUTHSSL_DEBUG
@ -1927,7 +1932,7 @@ bool AuthSSL::LocalStoreCert(X509* x509) {
//have a deep copy of the x509 cert //have a deep copy of the x509 cert
BIO *bp = BIO_new(BIO_s_mem()); BIO *bp = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bp, x509); PEM_write_bio_X509(bp, x509);
X509 *certCopy = PEM_read_bio_X509(bp, NULL, 0, NULL);certCopy->cert_info->key->pkey; X509 *certCopy = PEM_read_bio_X509(bp, NULL, 0, NULL);
mCerts[peerId] = new sslcert(certCopy, peerId); mCerts[peerId] = new sslcert(certCopy, peerId);
/* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(), /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(),
@ -1947,6 +1952,8 @@ bool AuthSSL::LocalStoreCert(X509* x509) {
std::cerr << "AuthSSL::LocalStoreCert() not storing certificate because it's our own " << peerId << std::endl; std::cerr << "AuthSSL::LocalStoreCert() not storing certificate because it's our own " << peerId << std::endl;
#endif #endif
} }
return true ;
} }
int AuthSSL::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx) int AuthSSL::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)

View File

@ -208,7 +208,7 @@ class NotifyBase
virtual void notifyOwnAvatarChanged() {} virtual void notifyOwnAvatarChanged() {}
virtual void notifyOwnStatusMessageChanged() {} virtual void notifyOwnStatusMessageChanged() {}
virtual std::string askForPassword(const std::string& key_details) { return "" ;} virtual std::string askForPassword(const std::string& key_details,bool prev_is_bad) { return "" ;}
}; };
const int NOTIFY_LIST_NEIGHBOURS = 1; const int NOTIFY_LIST_NEIGHBOURS = 1;

View File

@ -1234,7 +1234,7 @@ int RsInit::LoadCertificates(bool autoLoginNT)
RsInitConfig::passwd = ""; RsInitConfig::passwd = "";
create_configinit(RsInitConfig::basedir, RsInitConfig::preferedId); create_configinit(RsInitConfig::basedir, RsInitConfig::preferedId);
//don't autorise the password callback again because it will lead to deadlock due to QT reentrance //don't autorise the password callback again because it will lead to deadlock due to QT reentrance
AuthGPG::getAuthGPG()->setAutorisePasswordCallbackNotify(false); // AuthGPG::getAuthGPG()->setAutorisePasswordCallbackNotify(false);
return 1; return 1;
} }

View File

@ -329,6 +329,9 @@ void MainWindow::displaySystrayMsg(const QString& title,const QString& msg)
void MainWindow::updateStatus() void MainWindow::updateStatus()
{ {
// This call is essential to remove locks due to QEventLoop re-entrance while asking gpg passwds. Dont' remove it!
if(RsAutoUpdatePage::eventsLocked())
return ;
if (ratesstatus) if (ratesstatus)
ratesstatus->getRatesStatus(); ratesstatus->getRatesStatus();

View File

@ -969,6 +969,9 @@ void MessengerWindow::loadOwnStatus()
/** Save own status Online,Away,Busy **/ /** Save own status Online,Away,Busy **/
void MessengerWindow::savestatus() void MessengerWindow::savestatus()
{ {
if(RsAutoUpdatePage::eventsLocked())
return ;
//rsiface->lockData(); /* Lock Interface */ //rsiface->lockData(); /* Lock Interface */
RsPeerDetails detail; RsPeerDetails detail;

View File

@ -710,6 +710,9 @@ void NetworkDialog::displayInfoLogMenu(const QPoint& pos) {
void NetworkDialog::getNetworkStatus() void NetworkDialog::getNetworkStatus()
{ {
if(RsAutoUpdatePage::eventsLocked())
return ;
rsiface->lockData(); /* Lock Interface */ rsiface->lockData(); /* Lock Interface */
/* now the extra bit .... switch on check boxes */ /* now the extra bit .... switch on check boxes */
@ -766,6 +769,9 @@ void NetworkDialog::getNetworkStatus()
void NetworkDialog::updateNetworkStatus() void NetworkDialog::updateNetworkStatus()
{ {
if(RsAutoUpdatePage::eventsLocked())
return ;
rsiface->lockData(); /* Lock Interface */ rsiface->lockData(); /* Lock Interface */
/* now the extra bit .... switch on check boxes */ /* now the extra bit .... switch on check boxes */

View File

@ -3,6 +3,8 @@
#include "RsAutoUpdatePage.h" #include "RsAutoUpdatePage.h"
#include "MessengerWindow.h" #include "MessengerWindow.h"
bool RsAutoUpdatePage::_locked = false ;
RsAutoUpdatePage::RsAutoUpdatePage(int ms_update_period,QWidget *parent) RsAutoUpdatePage::RsAutoUpdatePage(int ms_update_period,QWidget *parent)
: MainPage(parent) : MainPage(parent)
{ {
@ -16,6 +18,7 @@ RsAutoUpdatePage::RsAutoUpdatePage(int ms_update_period,QWidget *parent)
void RsAutoUpdatePage::showEvent(QShowEvent *event) void RsAutoUpdatePage::showEvent(QShowEvent *event)
{ {
//std::cout << "RsAutoUpdatePage::showEvent() In show event !!" << std::endl ; //std::cout << "RsAutoUpdatePage::showEvent() In show event !!" << std::endl ;
if(!_locked)
updateDisplay(); updateDisplay();
} }
@ -23,7 +26,7 @@ void RsAutoUpdatePage::timerUpdate()
{ {
// only update when the widget is visible. // only update when the widget is visible.
// //
if(!isVisible()) if(_locked || !isVisible())
return ; return ;
updateDisplay(); updateDisplay();
@ -31,3 +34,6 @@ void RsAutoUpdatePage::timerUpdate()
update() ; // Qt flush update() ; // Qt flush
} }
void RsAutoUpdatePage::lockAllEvents() { _locked = true ; }
void RsAutoUpdatePage::unlockAllEvents() { _locked = false ; }
bool RsAutoUpdatePage::eventsLocked() { return _locked ; }

View File

@ -22,6 +22,10 @@ class RsAutoUpdatePage: public MainPage
virtual void updateDisplay() {} virtual void updateDisplay() {}
static void lockAllEvents() ;
static void unlockAllEvents() ;
static bool eventsLocked() ;
protected: protected:
virtual void showEvent(QShowEvent *e) ; virtual void showEvent(QShowEvent *e) ;
@ -30,4 +34,7 @@ class RsAutoUpdatePage: public MainPage
private: private:
QTimer *_timer ; QTimer *_timer ;
static bool _locked ;
}; };

View File

@ -211,7 +211,7 @@ void StartDialog::notSecureWarning() {
if(ui.autologin_checkbox->isChecked()){ if(ui.autologin_checkbox->isChecked()){
QMessageBox::StandardButton sb = QMessageBox::warning ( NULL, QMessageBox::StandardButton sb = QMessageBox::warning ( NULL,
tr("Insecure"), tr("Insecure"),
tr("Auto-Login is not Secure \n It can be disabled in General Settings"), tr("Auto Login is not so much secure:\n - Your SSL certificate will be stored unprotected. \n - Your PGP key will however not be stored.\nThis choice be reverted in settings."),
QMessageBox::Ok); QMessageBox::Ok);
} }

View File

@ -24,6 +24,7 @@
#include <rshare.h> #include <rshare.h>
#include <control/bandwidthevent.h> #include <control/bandwidthevent.h>
#include "bwgraph.h" #include "bwgraph.h"
#include <gui/RsAutoUpdatePage.h>
#include "rsiface/rsiface.h" #include "rsiface/rsiface.h"
#include <sstream> #include <sstream>
@ -119,6 +120,9 @@ BandwidthGraph::timerEvent( QTimerEvent * )
void void
BandwidthGraph::updategraphstatus( ) BandwidthGraph::updategraphstatus( )
{ {
if(RsAutoUpdatePage::eventsLocked())
return ;
/* set users/friends/network */ /* set users/friends/network */
float downKb = 0; float downKb = 0;
float upKb = 0; float upKb = 0;

View File

@ -42,13 +42,18 @@ void NotifyQt::notifyOwnAvatarChanged()
emit ownAvatarChanged() ; emit ownAvatarChanged() ;
} }
std::string NotifyQt::askForPassword(const std::string& key_details) std::string NotifyQt::askForPassword(const std::string& key_details,bool prev_is_bad)
{ {
return QInputDialog::getText(NULL, tr("GPG key passphrase"), RsAutoUpdatePage::lockAllEvents() ;
tr("Please enter the password to unlock the following GPG key:\n") + QString::fromStdString(key_details),
QLineEdit::Password, std::string res = QInputDialog::getText(NULL, tr("GPG key passphrase"),
NULL, NULL).toStdString(); (prev_is_bad?tr("Wrong password !\n\n"):QString()) +
tr("Please enter the password to unlock the following GPG key:\n") + QString::fromStdString(key_details), QLineEdit::Password, NULL, NULL).toStdString();
RsAutoUpdatePage::unlockAllEvents() ;
return res ;
} }
void NotifyQt::notifyOwnStatusMessageChanged() void NotifyQt::notifyOwnStatusMessageChanged()

View File

@ -41,7 +41,7 @@ class NotifyQt: public QObject, public NotifyBase
virtual void notifyOwnAvatarChanged() ; virtual void notifyOwnAvatarChanged() ;
virtual void notifyOwnStatusMessageChanged() ; virtual void notifyOwnStatusMessageChanged() ;
virtual std::string askForPassword(const std::string& key_details) ; virtual std::string askForPassword(const std::string& key_details,bool prev_is_bad) ;
signals: signals:
// It's beneficial to send info to the GUI using signals, because signals are thread-safe // It's beneficial to send info to the GUI using signals, because signals are thread-safe