implemented deferred signature method in notify system to alow signing from a non GUI thread

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6175 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-03-01 23:00:43 +00:00
parent e397560654
commit 9b01e3658d
8 changed files with 119 additions and 1 deletions

View File

@ -205,6 +205,8 @@ class NotifyBase
virtual bool askForPassword(const std::string& /* key_details */, bool /* prev_is_bad */, std::string& /* password */ ) { return false ;}
virtual bool askForPluginConfirmation(const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */) { return false ;}
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result) { signature_result = false ;return true; }
};
const int NOTIFY_LIST_NEIGHBOURS = 1;

View File

@ -268,6 +268,7 @@ class RsPeers
virtual bool getGPGAllList(std::list<std::string> &gpg_ids) = 0;
virtual bool getGPGDetails(const std::string &gpg_id, RsPeerDetails &d) = 0;
virtual bool getAssociatedSSLIds(const std::string &gpg_id, std::list<std::string> &ids) = 0;
virtual bool gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen) = 0;
/* Add/Remove Friends */
virtual bool addFriend(const std::string &ssl_id, const std::string &gpg_id,ServicePermissionFlags flags = RS_SERVICE_PERM_ALL) = 0;

View File

@ -503,6 +503,10 @@ bool p3Peers::getAssociatedSSLIds(const std::string &gpg_id, std::list<std::stri
return mPeerMgr->getAssociatedPeers(gpg_id, ids);
}
bool p3Peers::gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen)
{
return AuthGPG::getAuthGPG()->SignDataBin(data,len,sign,signlen);
}
bool p3Peers::getGPGDetails(const std::string &id, RsPeerDetails &d)
{

View File

@ -70,6 +70,7 @@ virtual bool getGPGValidList(std::list<std::string> &ids);
virtual bool getGPGAllList(std::list<std::string> &ids);
virtual bool getGPGDetails(const std::string &id, RsPeerDetails &d);
virtual bool getAssociatedSSLIds(const std::string &gpg_id, std::list<std::string> &ids);
virtual bool gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen) ;
/* Add/Remove Friends */
virtual bool addFriend(const std::string &ssl_id, const std::string &gpg_id,ServicePermissionFlags flags = RS_SERVICE_PERM_ALL);

View File

@ -26,6 +26,7 @@
#include "services/p3idservice.h"
#include "serialiser/rsgxsiditems.h"
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsiface.h"
#include "util/rsrandom.h"
#include "util/rsstring.h"
@ -48,6 +49,8 @@
#define ID_REQUEST_REPUTATION 0x0003
#define ID_REQUEST_OPINION 0x0004
#define ENABLE_PGP_SIGNATURES 1
RsIdentity *rsIdentity = NULL;
@ -1340,7 +1343,9 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet
#define MAX_SIGN_SIZE 2048
uint8_t signarray[MAX_SIGN_SIZE];
unsigned int sign_size = MAX_SIGN_SIZE;
if (!AuthGPG::getAuthGPG()->SignDataBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, signarray, &sign_size))
int result ;
if (!rsicontrol->getNotify().askForDeferredSelfSignature((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, signarray, &sign_size,result))
{
/* error */
std::cerr << "p3IdService::service_CreateGroup() ERROR Signing stuff";

View File

@ -28,6 +28,7 @@
#include "notifyqt.h"
#include <retroshare/rsnotify.h>
#include <retroshare/rspeers.h>
#include <util/rsdir.h>
#include "RsAutoUpdatePage.h"
@ -146,6 +147,91 @@ void NotifyQt::notifyOwnAvatarChanged()
emit ownAvatarChanged() ;
}
class SignatureEventData
{
public:
SignatureEventData(const void *_data,int32_t _len,unsigned int _signlen)
: data(_data),len(_len)
{
// We need a new memory chnk because there's no guarranty _sign nor _signlen are not in the stack
sign = (unsigned char *)malloc(_signlen) ;
signlen = new unsigned int ;
*signlen = _signlen ;
signature_result = 0 ;
}
~SignatureEventData()
{
free(sign) ;
delete signlen ;
}
bool performSignature()
{
if(rsPeers->gpgSignData(data,len,sign,signlen))
signature_result = 1 ;
}
const void *data ;
uint32_t len ;
unsigned char *sign ;
unsigned int *signlen ;
int signature_result ; // 0=pending, 1=done, 2=failed.
};
bool NotifyQt::askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result)
{
{
QMutexLocker m(&_mutex) ;
std::cerr << "NotifyQt:: deferred signature event requeted. " << std::endl;
// Look into the queue
Sha1CheckSum chksum = RsDirUtil::sha1sum((uint8_t*)data,len) ;
std::map<std::string,SignatureEventData*>::iterator it = _deferred_signature_queue.find(chksum.toStdString()) ;
if(it != _deferred_signature_queue.end())
if(it->second->signature_result != 0) // found it. Copy the result, and remove from the queue.
{
// We should check for the exact data match, for the sake of being totally secure.
//
std::cerr << "Found into queue: returning it" << std::endl;
memcpy(sign,it->second->sign,*it->second->signlen) ;
*signlen = *(it->second->signlen) ;
signature_result = it->second->signature_result ;
delete it->second ;
_deferred_signature_queue.erase(it) ;
return true ;
}
else
return false ; // already registered, but not done yet.
// Not found. Store in the queue and emit a signal.
//
std::cerr << "NotifyQt:: deferred signature event requeted. Pushing into queue" << std::endl;
SignatureEventData *edta = new SignatureEventData(data,len,*signlen) ;
_deferred_signature_queue[chksum.toStdString()] = edta ;
}
emit deferredSignatureHandlingRequested() ;
return false;
}
void NotifyQt::handleSignatureEvent()
{
std::cerr << "NotifyQt:: performing a deferred signature in the main GUI thread." << std::endl;
for(std::map<std::string,SignatureEventData*>::const_iterator it(_deferred_signature_queue.begin());it!=_deferred_signature_queue.end();++it)
it->second->performSignature() ;
}
bool NotifyQt::askForPassword(const std::string& key_details, bool prev_is_bad, std::string& password)
{
RsAutoUpdatePage::lockAllEvents() ;

View File

@ -20,6 +20,7 @@ class MessagesDialog;
class ChannelsDialog;
class MessengerWindow;
class Toaster;
class SignatureEventData ;
struct TurtleFileInfo;
//class NotifyQt: public NotifyBase, public QObject
@ -61,6 +62,20 @@ class NotifyQt: public QObject, public NotifyBase
virtual bool askForPassword(const std::string& key_details, bool prev_is_bad, std::string& password);
virtual bool askForPluginConfirmation(const std::string& plugin_filename, const std::string& plugin_file_hash);
// Queues the signature event so that it canhappen in the main GUI thread (to ask for passwd).
// To use this function: call is multiple times as soon as it returns true.
//
// Dont' use a while, if you're in a mutexed part, otherwize it will lock. You need to call the function
// and periodically exit the locked code between calls to allow the signature to happen.
//
// Returns:
// false = the signature is registered, but the result is not there yet. Call again soon.
// true = signature done. Data is ready. signature_result takes the following values:
// 1: signature success
// 2: signature failed. Wrong passwd, user pressed cancel, etc.
//
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result) ;
/* Notify from GUI */
void notifyChatStyleChanged(int /*ChatStyle::enumStyleType*/ styleType);
@ -106,6 +121,7 @@ class NotifyQt: public QObject, public NotifyBase
void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status);
void historyChanged(uint msgId, int type);
void chatLobbyInviteReceived() ;
void deferredSignatureHandlingRequested() ;
/* Notify from GUI */
void chatStyleChanged(int /*ChatStyle::enumStyleType*/ styleType);
@ -116,6 +132,7 @@ class NotifyQt: public QObject, public NotifyBase
private slots:
void runningTick();
void handleSignatureEvent() ;
private:
NotifyQt();
@ -134,6 +151,7 @@ class NotifyQt: public QObject, public NotifyBase
bool _enabled ;
QMutex _mutex ;
std::map<std::string,SignatureEventData*> _deferred_signature_queue ;
// void displayNeighbours();
// void displayFriends();
// void displayDirectories();

View File

@ -324,6 +324,7 @@ int main(int argc, char *argv[])
std::cerr << "connecting signals and slots" << std::endl ;
QObject::connect(notify,SIGNAL(gotTurtleSearchResult(qulonglong,FileDetail)),w->transfersDialog->searchDialog ,SLOT(updateFiles(qulonglong,FileDetail))) ;
QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ;
QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ;
QObject::connect(notify,SIGNAL(filesPreModChanged(bool)) ,w->transfersDialog->localSharedFiles ,SLOT(preModDirectories(bool) )) ;
QObject::connect(notify,SIGNAL(filesPreModChanged(bool)) ,w->transfersDialog->remoteSharedFiles ,SLOT(preModDirectories(bool) )) ;