From 3f86a707b725a917722d3ebcc382211f46dd9a63 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 31 Jul 2013 16:34:34 +0000 Subject: [PATCH] Distant messages GUI code. Now the GUI can receive/send/decrypt distant messages. Since the protocols are not finalized, the GUI is disabled, to avoid later crashes git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6549 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsmsgs.h | 5 +- libretroshare/src/rsserver/p3msgs.cc | 13 +- libretroshare/src/rsserver/p3msgs.h | 4 + libretroshare/src/services/p3msgservice.cc | 132 ++++++++++++++++-- libretroshare/src/services/p3msgservice.h | 5 + retroshare-gui/src/gui/MessagesDialog.cpp | 11 +- .../src/gui/msgs/MessageComposer.cpp | 70 +++++++--- retroshare-gui/src/gui/msgs/MessageComposer.h | 1 + .../src/gui/settings/MessagePage.cpp | 11 +- retroshare-gui/src/gui/settings/MessagePage.h | 1 + .../src/gui/settings/MessagePage.ui | 68 ++++++--- 11 files changed, 259 insertions(+), 62 deletions(-) diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index a2594b9ee..964d00266 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -184,7 +184,7 @@ class ChatLobbyInvite class VisibleChatLobbyRecord { public: - VisibleChatLobbyRecord() { total_number_of_peers = 0 ; } + VisibleChatLobbyRecord() { total_number_of_peers = 0 ; } ChatLobbyId lobby_id ; // unique id of the lobby std::string lobby_name ; // name to use for this lobby @@ -279,6 +279,9 @@ virtual bool resetMessageStandardTagTypes(MsgTagType& tags) = 0; virtual bool createDistantOfflineMessengingInvite(time_t validity_time_stamp, std::string& hash)=0 ; virtual bool getDistantOfflineMessengingInvites(std::vector& invites) = 0 ; +virtual void enableDistantMessaging(bool b) = 0; +virtual bool distantMessagingEnabled() = 0; +virtual bool getDistantMessageHash(const std::string& pgp_id, std::string& hash) = 0; /****************************************/ /* Chat */ diff --git a/libretroshare/src/rsserver/p3msgs.cc b/libretroshare/src/rsserver/p3msgs.cc index a404572ad..58613ac26 100644 --- a/libretroshare/src/rsserver/p3msgs.cc +++ b/libretroshare/src/rsserver/p3msgs.cc @@ -108,7 +108,18 @@ bool p3Msgs::getDistantOfflineMessengingInvites(std::vectorgetDistantOfflineMessengingInvites(invites); } - +void p3Msgs::enableDistantMessaging(bool b) +{ + mMsgSrv->enableDistantMessaging(b); +} +bool p3Msgs::distantMessagingEnabled() +{ + return mMsgSrv->distantMessagingEnabled(); +} +bool p3Msgs::getDistantMessageHash(const std::string& pgp_id,std::string& hash) +{ + return mMsgSrv->getDistantMessageHash(pgp_id,hash); +} bool p3Msgs::SystemMessage(const std::wstring &title, const std::wstring &message, uint32_t systemFlag) { diff --git a/libretroshare/src/rsserver/p3msgs.h b/libretroshare/src/rsserver/p3msgs.h index ca5191ef2..c42888a4e 100644 --- a/libretroshare/src/rsserver/p3msgs.h +++ b/libretroshare/src/rsserver/p3msgs.h @@ -82,6 +82,10 @@ class p3Msgs: public RsMsgs virtual bool createDistantOfflineMessengingInvite(time_t, std::string&) ; virtual bool getDistantOfflineMessengingInvites(std::vector&); + virtual void enableDistantMessaging(bool b) ; + virtual bool distantMessagingEnabled() ; + virtual bool getDistantMessageHash(const std::string& pgp_id,std::string& hash) ; + /*! * gets avatar from peer, image data in jpeg format */ diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index a6df2077c..dd9a5caf6 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -45,7 +45,8 @@ #include #include -//#define DEBUG_DISTANT_MSG +#define DEBUG_DISTANT_MSG +#define DISABLE_DISTANT_MESSAGES const int msgservicezone = 54319; @@ -1682,13 +1683,19 @@ bool p3MsgService::decryptMessage(const std::string& mId) uint32_t msgId = atoi(mId.c_str()); std::string encrypted_string ; +#ifdef DEBUG_DISTANT_MSG + std::cerr << "Decrypting message with Id " << mId << std::endl; +#endif { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ std::map::iterator mit = imsg.find(msgId); if(mit == imsg.end() || !librs::util::ConvertUtf16ToUtf8(mit->second->message,encrypted_string)) + { + std::cerr << "Can't find this message in msg list. Id=" << mId << std::endl; return false; + } } char *encrypted_data ; @@ -1696,6 +1703,10 @@ bool p3MsgService::decryptMessage(const std::string& mId) Radix64::decode(encrypted_string,encrypted_data,encrypted_size) ; +#ifdef DEBUG_DISTANT_MSG + std::cerr << "Message has been radix64 decoded." << std::endl; +#endif + uint32_t decrypted_size = encrypted_size + 500 ; unsigned char *decrypted_data = new unsigned char[decrypted_size] ; @@ -1706,15 +1717,31 @@ bool p3MsgService::decryptMessage(const std::string& mId) std::cerr << "decryption failed!" << std::endl; return false; } +#ifdef DEBUG_DISTANT_MSG + std::cerr << "Message has succesfully decrypted." << std::endl; +#endif RsMsgItem *item = dynamic_cast(_serialiser->deserialise(decrypted_data,&decrypted_size)) ; if(item == NULL) + { + std::cerr << "Decrypted message could not be deserialized." << std::endl; return false ; + } +#ifdef DEBUG_DISTANT_MSG + std::cerr << "Decrypted message was succesfully deserialized. New message:" << std::endl; + item->print(std::cerr,0) ; +#endif { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - *imsg[msgId] = *item ; + + // Keer the id. + RsMsgItem& msgi( *imsg[msgId] ) ; + + msgi = *item ; // copy everything + msgi.msgId = msgId ; // restore the correct message id, to make it consistent + msgi.msgFlags &= ~RS_MSG_FLAGS_ENCRYPTED ; // just in case. } delete item ; @@ -1746,6 +1773,65 @@ bool p3MsgService::createDistantOfflineMessengingInvite(time_t time_of_validity, return true ; } +void p3MsgService::enableDistantMessaging(bool b) +{ + // compute the hash + + std::string hash ; + + if(!getDistantMessageHash(AuthGPG::getAuthGPG()->getGPGOwnId(),hash)) + return ; + +#ifdef DEBUG_DISTANT_MSG + std::cerr << (b?"Enabling":"Disabling") << " distant messaging, with hash = " << hash << std::endl; +#endif + std::map::iterator it = _messenging_invites.find(hash) ; + + if(b && it == _messenging_invites.end()) + { + DistantMessengingInvite invite ; + invite.time_of_validity = time(NULL) + 10*365*86400; // 10 years from now + _messenging_invites[hash] = invite ; + + IndicateConfigChanged() ; + } + if((!b) && it != _messenging_invites.end()) + { + _messenging_invites.erase(it) ; + IndicateConfigChanged() ; + } + +#ifdef DEBUG_DISTANT_MSG + std::cerr << "List of distant message invites: " << std::endl; + for(std::map::const_iterator it(_messenging_invites.begin());it!=_messenging_invites.end();++it) + std::cerr << " hash = " << it->first << std::endl; +#endif +} +bool p3MsgService::distantMessagingEnabled() +{ + // compute the hash + + std::string hash ; + + if(!getDistantMessageHash(AuthGPG::getAuthGPG()->getGPGOwnId(),hash)) + return false; + + return _messenging_invites.find(hash) != _messenging_invites.end() ; +} +bool p3MsgService::getDistantMessageHash(const std::string& pgp_id,std::string& hash) +{ + if(pgp_id.length() != 16) + { + std::cerr << "pgp id \"" << pgp_id << "\" is not valid! Something definitly wrong." << std::endl; + return false; + } + + hash = RsDirUtil::sha1sum((uint8_t*)pgp_id.c_str(),16).toStdString() ; + + // Also check that we have the public key. + + return AuthGPG::getAuthGPG()->isKeySupported(pgp_id) ; +} bool p3MsgService::getDistantOfflineMessengingInvites(std::vector& invites) { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1763,21 +1849,20 @@ bool p3MsgService::getDistantOfflineMessengingInvites(std::vector::const_iterator it = _messenging_invites.find(hash) ; #ifdef DEBUG_DISTANT_MSG if(it != _messenging_invites.end()) + { + std::cerr << "p3MsgService::handleTunnelRequest: received TR for hash " << hash << std::endl; std::cerr << "Responding OK!" << std::endl; + } #endif return it != _messenging_invites.end() ; @@ -1868,17 +1953,32 @@ void p3MsgService::addVirtualPeer(const TurtleFileHash& hash, const TurtleVirtua std::cerr << "p3MsgService::addVirtualPeer(): adding virtual peer " << vpid << " for hash " << hash << std::endl; #endif } -void p3MsgService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& /*vpid*/) +void p3MsgService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid) { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - // A new tunnel has been created. We need to flush pending messages for the corresponding peer. +#ifdef DEBUG_DISTANT_MSG + std::cerr << "Removing virtual peer " << vpid << " for hash " << hash << std::endl; +#endif - //std::map::const_iterator it = _messenging_contacts.find(hash) ; + bool remove_tunnel = false ; + { + RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - DistantMessengingContact& contact(_messenging_contacts[hash]) ; // possibly creates it. + DistantMessengingContact& contact(_messenging_contacts[hash]) ; // possibly creates it. - contact.status = RS_DISTANT_MSG_STATUS_TUNNEL_DN ; - contact.virtual_peer_id.clear() ; + contact.status = RS_DISTANT_MSG_STATUS_TUNNEL_DN ; + contact.virtual_peer_id.clear() ; + + if(contact.pending_messages.empty()) + remove_tunnel = true ; + } + + if(remove_tunnel) + { +#ifdef DEBUG_DISTANT_MSG + std::cerr << "Also removing tunnel, since pending messages have been sent." << std::endl; +#endif + mTurtle->stopMonitoringTunnels(hash) ; + } } #ifdef DEBUG_DISTANT_MSG static void printBinaryData(void *data,uint32_t size) @@ -1960,6 +2060,12 @@ void p3MsgService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,const std: std::cerr << "(EE) p3MsgService::receiveTurtleData(): item is not a data item. That is an error." << std::endl; return ; } +#ifdef DISABLE_DISTANT_MESSAGES + std::cerr << "Received distant message item. Protocol is not yet finalized. Droping the item." << std::endl; + delete item ; + return ; +#endif + #ifdef DEBUG_DISTANT_MSG std::cerr << "p3MsgService::sendTurtleData(): Receiving through virtual peer: " << virtual_peer_id << std::endl; std::cerr << " gitem->data_size = " << item->data_size << std::endl; diff --git a/libretroshare/src/services/p3msgservice.h b/libretroshare/src/services/p3msgservice.h index 2f6592fe7..35d7d6a4a 100644 --- a/libretroshare/src/services/p3msgservice.h +++ b/libretroshare/src/services/p3msgservice.h @@ -118,6 +118,11 @@ int checkOutgoingMessages(); bool createDistantOfflineMessengingInvite(time_t time_of_validity,TurtleFileHash& hash) ; bool getDistantOfflineMessengingInvites(std::vector& invites) ; + + void enableDistantMessaging(bool b) ; + bool distantMessagingEnabled() ; + bool getDistantMessageHash(const std::string& pgp_id,std::string& hash) ; + void sendPrivateMsgItem(RsMsgItem *) ; private: diff --git a/retroshare-gui/src/gui/MessagesDialog.cpp b/retroshare-gui/src/gui/MessagesDialog.cpp index ee9be718a..4b7e78112 100644 --- a/retroshare-gui/src/gui/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/MessagesDialog.cpp @@ -1493,7 +1493,7 @@ void MessagesDialog::decryptSelectedMsg() if(!msgInfo.msgflags & RS_MSG_ENCRYPTED) { - std::cerr << "This message is not encrypted! Cannot decrypt!" << std::endl; + QMessageBox::warning(NULL,tr("Decryption failed!"),tr("This message is not encrypted. Cannot decrypt!")) ; return ; } @@ -1501,7 +1501,16 @@ void MessagesDialog::decryptSelectedMsg() QMessageBox::warning(NULL,tr("Decryption failed!"),tr("This message could not be decrypted.")) ; //setMsgAsReadUnread(currentIndex.row(), true); + timer->start(); + updateMessageSummaryList(); + + //QModelIndex currentIndex = ui.messagestreeView->currentIndex(); + //QModelIndex index = ui.messagestreeView->model()->index(currentIndex.row(), COLUMN_UNREAD, currentIndex.parent()); + //currentChanged(index); + + MessagesModel->removeRows (0, MessagesModel->rowCount()); + insertMessages(); insertMsgTxtAndFiles(); } diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.cpp b/retroshare-gui/src/gui/msgs/MessageComposer.cpp index 4a360034d..0051dd5e3 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.cpp +++ b/retroshare-gui/src/gui/msgs/MessageComposer.cpp @@ -209,7 +209,8 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WFlags flags) /* initialize friends list */ ui.friendSelectionWidget->setHeaderText(tr("Send To:")); ui.friendSelectionWidget->setModus(FriendSelectionWidget::MODUS_MULTI); - ui.friendSelectionWidget->setShowType(FriendSelectionWidget::SHOW_GROUP | FriendSelectionWidget::SHOW_SSL); + //ui.friendSelectionWidget->setShowType(FriendSelectionWidget::SHOW_GROUP | FriendSelectionWidget::SHOW_SSL | FriendSelectionWidget::SHOW_NON_FRIEND_GPG ); + ui.friendSelectionWidget->setShowType(FriendSelectionWidget::SHOW_GROUP | FriendSelectionWidget::SHOW_SSL ); ui.friendSelectionWidget->start(); QActionGroup *grp = new QActionGroup(this); @@ -1406,8 +1407,10 @@ void MessageComposer::setRecipientToRow(int row, enumType type, std::string id, QIcon icon; QString name; - if (id.empty() == FALSE) { - if (group) { + if (!id.empty()) + { + if (group) + { icon = QIcon(IMAGE_GROUP16); RsGroupInfo groupInfo; @@ -1417,28 +1420,39 @@ void MessageComposer::setRecipientToRow(int row, enumType type, std::string id, name = tr("Unknown"); id.clear(); } - } else { - RsPeerDetails details; - if(_distant_peers.find(id) != _distant_peers.end()) - { - name = tr("Distant peer (PGP key: %1)").arg(QString::fromStdString(_distant_peers[id])) ; - icon = QIcon(StatusDefs::imageUser(RS_STATUS_ONLINE)); - } - else if (rsPeers->getPeerDetails(id, details)) - { - name = PeerDefs::nameWithLocation(details); + } + else + { + RsPeerDetails details; - StatusInfo peerStatusInfo; - // No check of return value. Non existing status info is handled as offline. - rsStatus->getStatus(id, peerStatusInfo); + if(_distant_peers.find(id) != _distant_peers.end()) + { + if(!rsPeers->getPeerDetails(_distant_peers[id], details)) + { + std::cerr << "Can't get peer details from " << _distant_peers[id] << std::endl; + return ; + } - icon = QIcon(StatusDefs::imageUser(peerStatusInfo.status)); - } else { - icon = QIcon(StatusDefs::imageUser(RS_STATUS_OFFLINE)); - name = tr("Unknown friend"); - id.clear(); - } - } + name = tr("Distant peer (name: %2, PGP key: %1)").arg(QString::fromStdString(_distant_peers[id])).arg(QString::fromStdString(details.name)) ; + icon = QIcon(StatusDefs::imageUser(RS_STATUS_ONLINE)); + } + else if(rsPeers->getPeerDetails(id, details) && (!details.isOnlyGPGdetail)) + { + name = PeerDefs::nameWithLocation(details); + + StatusInfo peerStatusInfo; + // No check of return value. Non existing status info is handled as offline. + rsStatus->getStatus(id, peerStatusInfo); + + icon = QIcon(StatusDefs::imageUser(peerStatusInfo.status)); + } + else + { + icon = QIcon(StatusDefs::imageUser(RS_STATUS_OFFLINE)); + name = tr("Unknown friend"); + id.clear(); + } + } } comboBox->setCurrentIndex(comboBox->findData(type, Qt::UserRole)); @@ -2291,6 +2305,16 @@ void MessageComposer::addContact(enumType type) for (idIt = ids.begin(); idIt != ids.end(); idIt++) { addRecipient(type, *idIt, false); } + + ids.empty(); + ui.friendSelectionWidget->selectedGpgIds(ids, true); + for (idIt = ids.begin(); idIt != ids.end(); idIt++) + { + std::string hash ; + + if(rsMsgs->getDistantMessageHash(*idIt,hash)) + addRecipient(type, hash, *idIt); + } } void MessageComposer::addTo() diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.h b/retroshare-gui/src/gui/msgs/MessageComposer.h index f5aa98bee..ed0b11698 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.h +++ b/retroshare-gui/src/gui/msgs/MessageComposer.h @@ -50,6 +50,7 @@ public: static void msgFriend(const std::string &id, bool group); static void msgDistantPeer(const std::string& hash,const std::string& pgp_id) ; + static void msgDistantPeer(const std::string& pgp_id) ; static QString recommendMessage(); static void recommendFriend(const std::list &sslIds, const std::string &to = "", const QString &msg = "", bool autoSend = false); diff --git a/retroshare-gui/src/gui/settings/MessagePage.cpp b/retroshare-gui/src/gui/settings/MessagePage.cpp index 7b50bb742..ec1770474 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.cpp +++ b/retroshare-gui/src/gui/settings/MessagePage.cpp @@ -25,9 +25,7 @@ #include "MessagePage.h" #include "gui/common/TagDefs.h" - #include - #include "NewTag.h" MessagePage::MessagePage(QWidget * parent, Qt::WFlags flags) @@ -41,6 +39,7 @@ MessagePage::MessagePage(QWidget * parent, Qt::WFlags flags) connect (ui.editpushButton, SIGNAL(clicked(bool)), this, SLOT (editTag())); connect (ui.deletepushButton, SIGNAL(clicked(bool)), this, SLOT (deleteTag())); connect (ui.defaultTagButton, SIGNAL(clicked(bool)), this, SLOT (defaultTag())); + connect (ui.encryptedMsgs_CB, SIGNAL(toggled(bool)), this, SLOT (toggleEnableEncryptedDistantMsgs(bool))); connect (ui.tags_listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(currentRowChangedTag(int))); @@ -49,6 +48,8 @@ MessagePage::MessagePage(QWidget * parent, Qt::WFlags flags) ui.openComboBox->addItem(tr("A new tab"), RshareSettings::MSG_OPEN_TAB); ui.openComboBox->addItem(tr("A new window"), RshareSettings::MSG_OPEN_WINDOW); + + ui.encryptedMsgs_CB->setEnabled(false) ; } MessagePage::~MessagePage() @@ -56,6 +57,11 @@ MessagePage::~MessagePage() delete(m_pTags); } +void MessagePage::toggleEnableEncryptedDistantMsgs(bool b) +{ + rsMsgs->enableDistantMessaging(b) ; +} + /** Saves the changes on this page */ bool MessagePage::save(QString &/*errmsg*/) @@ -91,6 +97,7 @@ MessagePage::load() ui.setMsgToReadOnActivate->setChecked(Settings->getMsgSetToReadOnActivate()); ui.openComboBox->setCurrentIndex(ui.openComboBox->findData(Settings->getMsgOpen())); + ui.encryptedMsgs_CB->setChecked(rsMsgs->distantMessagingEnabled()) ; // fill items rsMsgs->getMessageTagTypes(*m_pTags); fillTags(); diff --git a/retroshare-gui/src/gui/settings/MessagePage.h b/retroshare-gui/src/gui/settings/MessagePage.h index 57996c990..21c0f8ca1 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.h +++ b/retroshare-gui/src/gui/settings/MessagePage.h @@ -53,6 +53,7 @@ private slots: void defaultTag(); void currentRowChangedTag(int row); + void toggleEnableEncryptedDistantMsgs(bool) ; private: void fillTags(); diff --git a/retroshare-gui/src/gui/settings/MessagePage.ui b/retroshare-gui/src/gui/settings/MessagePage.ui index 271793ab6..7680ef67c 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.ui +++ b/retroshare-gui/src/gui/settings/MessagePage.ui @@ -6,8 +6,8 @@ 0 0 - 423 - 340 + 500 + 485 @@ -16,8 +16,8 @@ 0 - - + + Reading @@ -47,7 +47,33 @@ - + + + + Distant messages: + + + + + + <html><head/><body><p align="justify">The link below allows people in the network to send encrypted messages to you, using tunnels. To do that, they need your public PGP key, which they will get using the Retroshare discovery system. </p></body></html> + + + true + + + + + + + Accept encrypted distant messages from everyone + + + + + + + Tags @@ -60,6 +86,22 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + @@ -104,22 +146,6 @@ - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - -