diff --git a/libretroshare/src/retroshare/rsiface.h b/libretroshare/src/retroshare/rsiface.h index c0b30cb43..f2a4184ef 100644 --- a/libretroshare/src/retroshare/rsiface.h +++ b/libretroshare/src/retroshare/rsiface.h @@ -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; diff --git a/libretroshare/src/retroshare/rspeers.h b/libretroshare/src/retroshare/rspeers.h index 088e6fecc..12b0b78a9 100644 --- a/libretroshare/src/retroshare/rspeers.h +++ b/libretroshare/src/retroshare/rspeers.h @@ -268,6 +268,7 @@ class RsPeers virtual bool getGPGAllList(std::list &gpg_ids) = 0; virtual bool getGPGDetails(const std::string &gpg_id, RsPeerDetails &d) = 0; virtual bool getAssociatedSSLIds(const std::string &gpg_id, std::list &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; diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 842d26729..508fc8321 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -503,6 +503,10 @@ bool p3Peers::getAssociatedSSLIds(const std::string &gpg_id, std::listgetAssociatedPeers(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) { diff --git a/libretroshare/src/rsserver/p3peers.h b/libretroshare/src/rsserver/p3peers.h index a33c0f340..3f3d5a316 100644 --- a/libretroshare/src/rsserver/p3peers.h +++ b/libretroshare/src/rsserver/p3peers.h @@ -70,6 +70,7 @@ virtual bool getGPGValidList(std::list &ids); virtual bool getGPGAllList(std::list &ids); virtual bool getGPGDetails(const std::string &id, RsPeerDetails &d); virtual bool getAssociatedSSLIds(const std::string &gpg_id, std::list &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); diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 3fb30ae3a..41b9785c2 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -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"; diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 1c3c9c9d8..9c9b65545 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -28,6 +28,7 @@ #include "notifyqt.h" #include #include +#include #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::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::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() ; diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index cb4b0f300..4ef685d63 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -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 _deferred_signature_queue ; // void displayNeighbours(); // void displayFriends(); // void displayDirectories(); diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 29aadda49..6e380ea99 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -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) )) ;