From dc0193ae66b75f0f88bf185936841ec01950068f Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 16 Apr 2013 21:13:42 +0000 Subject: [PATCH] added popup chat window for distant chat, decryption code for private chat links. (W) does not compile git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-GenericTunneling@6310 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsmsgs.h | 11 ++++ libretroshare/src/rsserver/p3msgs.cc | 4 ++ libretroshare/src/rsserver/p3msgs.h | 2 + libretroshare/src/services/p3chatservice.cc | 54 +++++++++++++++++++ libretroshare/src/services/p3chatservice.h | 3 +- retroshare-gui/src/gui/RetroShareLink.cpp | 15 ++++++ retroshare-gui/src/gui/chat/ChatDialog.cpp | 14 ++++- .../src/gui/chat/PopupDistantChatDialog.cpp | 52 ++++++++++++++++++ .../src/gui/chat/PopupDistantChatDialog.h | 52 ++++++++++++++++++ retroshare-gui/src/retroshare-gui.pro | 2 + 10 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp create mode 100644 retroshare-gui/src/gui/chat/PopupDistantChatDialog.h diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index d00e43ccb..6a8cb6bb3 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -144,6 +144,15 @@ public: #define RS_CHAT_PRIVATE 0x0002 #define RS_CHAT_AVATAR_AVAILABLE 0x0004 +#define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0001 +#define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0002 +#define RS_DISTANT_CHAT_STATUS_TUNNEL_OK 0x0003 +#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0004 + +#define RS_DISTANT_CHAT_ERROR_NO_ERROR 0x0000 ; +#define RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED 0x0001 ; +#define RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH 0x0002 ; + class ChatInfo { public: @@ -301,6 +310,8 @@ virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const std::str virtual bool createDistantChatInvite(const std::string& pgp_id,time_t time_of_validity,std::string& encrypted_string) = 0 ; virtual bool getDistantChatInviteList(std::vector& invites) = 0; +virtual bool initiateDistantChatConnexion(const std::string& encrypted_string,std::string& hash,uint32_t& error_code) = 0; +virtual uint32_t getDistantChatStatus(const std::string& hash) = 0; }; diff --git a/libretroshare/src/rsserver/p3msgs.cc b/libretroshare/src/rsserver/p3msgs.cc index 9277e9a67..d6f4a87bb 100644 --- a/libretroshare/src/rsserver/p3msgs.cc +++ b/libretroshare/src/rsserver/p3msgs.cc @@ -338,4 +338,8 @@ bool p3Msgs::getDistantChatInviteList(std::vector& invite { return mChatSrv->getDistantChatInviteList(invites) ; } +bool p3Msgs::initiateDistantChatConnexion(const std::string& encrypted_str,std::string& hash,uint32_t& error_code) +{ + return mChatSrv->initiateDistantChatConnexion(encrypted_str,hash,error_code) ; +} diff --git a/libretroshare/src/rsserver/p3msgs.h b/libretroshare/src/rsserver/p3msgs.h index 33c6c8cee..8fbe7f3bb 100644 --- a/libretroshare/src/rsserver/p3msgs.h +++ b/libretroshare/src/rsserver/p3msgs.h @@ -185,6 +185,8 @@ class p3Msgs: public RsMsgs virtual bool createDistantChatInvite(const std::string& pgp_id,time_t time_of_validity,std::string& encrypted_string) ; virtual bool getDistantChatInviteList(std::vector& invites); + virtual bool initiateDistantChatConnexion(const std::string& encrypted_string,std::string& hash,uint32_t& error_code) ; + virtual uint32_t getDistantChatStatus(const std::string& hash) ; private: diff --git a/libretroshare/src/services/p3chatservice.cc b/libretroshare/src/services/p3chatservice.cc index ef7a82682..0cd692ec4 100644 --- a/libretroshare/src/services/p3chatservice.cc +++ b/libretroshare/src/services/p3chatservice.cc @@ -3016,6 +3016,60 @@ bool p3ChatService::createDistantChatInvite(const std::string& pgp_id,time_t tim return true ; } +bool p3ChatService::initiateDistantChatConnexion(const std::string& encrypted_str,std::string& hash,uint32_t& error_code) +{ + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + + // Un-radix the string. + // + char *encrypted_data_bin = NULL ; + size_t encrypted_data_len ; + + Radix64::decode(encrypted_str,encrypted_data_bin,encrypted_data_len) ; + + // Decrypt it. + // + unsigned char *data = NULL ; + uint32_t data_size ; + + if(!AuthGPG::getAuthGPG()->decryptDataBin((unsigned char *)encrypted_data_bin,encrypted_data_len,data,&data_size)) + { + error_code = RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED ; + return false ; + } + delete[] encrypted_data_bin ; + + std::cerr << "Chat invite was successfuly decrypted!" << std::endl; + + if(!AuthGPG::VerifySignBin(data,32,data+32,data_size-32,fingerprint)) + { + error_code = RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH ; + return false ; + } + std::cerr << "Signature successfuly verified!" << std::endl; + + hash = t_RsGenericIdType<16>(data).toStdString() ; + DistantChatPeerInfo info ; + + info.last_contact = time(NULL) ; + memcpy(info.aes_key,data+16,16) ; + + _distant_chat_peers[hash] = info ; + + delete[] data ; + + // Now ask the turtle router to manage a tunnel for that hash. + + std::cerr << "Asking turtle router to monitor tunnels for hash " << hash << std::endl; + + mTurtle->monitorTunnels(hash,this) ; + + // And notify about chatting. + + error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ; + return true ; +} + void p3ChatService::cleanDistantChatInvites() { RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ diff --git a/libretroshare/src/services/p3chatservice.h b/libretroshare/src/services/p3chatservice.h index 3ecc81b59..8b9bfebba 100644 --- a/libretroshare/src/services/p3chatservice.h +++ b/libretroshare/src/services/p3chatservice.h @@ -310,8 +310,9 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi // Om success, stores the invite in the map above, so that we can respond to tunnel requests. // bool createDistantChatInvite(const std::string& pgp_id,time_t time_of_validity,TurtleFileHash& hash) ; - bool getDistantChatInviteList(std::vector& invites) ; + bool initiateDistantChatConnexion(const std::string& encrypted_string,std::string& hash,uint32_t& error_code) ; + virtual uint32_t getDistantChatStatus(const std::string& hash) ; private: struct DistantChatInvite diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index 461bb1323..7b1290568 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -1190,6 +1190,7 @@ static void processList(const QStringList &list, const QString &textSingular, co std::cerr << " time_stamp = " << link._time_stamp << std::endl; std::cerr << " hash = " << link._hash.toStdString() << std::endl; std::cerr << " PGP Id = " << link._GPGid.toStdString() << std::endl; + std::cerr << "Feature not yet implemented !" << std::endl; } break ; case TYPE_PRIVATE_CHAT: @@ -1198,6 +1199,20 @@ static void processList(const QStringList &list, const QString &textSingular, co std::cerr << " time_stamp = " << link._time_stamp << std::endl; std::cerr << " enc-string = " << link._encrypted_chat_info.toStdString() << std::endl; std::cerr << " PGP Id = " << link._GPGid.toStdString() << std::endl; + + if(link._time_stamp < time(NULL)) + { + QMessageBox::information(NULL,tr("Chat link is expired"),tr("This chat link is expired. The destination peer will not answer.")) ; + break ; + } + if(link._GPGid.toStdString() != rsPeers->getGPGOwnId()) + { + QMessageBox::information(NULL,tr("Chat link cannot be decrypted"),tr("This chat link is encrypted with a key that is not yours. You can't used it. Key ID = ")+link._GPGId) ; + break ; + } + + if(!rsMsgs->initiateDistantChatConnexion(link._encrypted_chat_info.toStdString())) + QMessageBox::information(NULL,tr("Chat connexion is not possible"),tr("The distant chat connexion cannot be openned. Sorry.")) ; } break ; diff --git a/retroshare-gui/src/gui/chat/ChatDialog.cpp b/retroshare-gui/src/gui/chat/ChatDialog.cpp index 45738b92d..bee901e1d 100644 --- a/retroshare-gui/src/gui/chat/ChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatDialog.cpp @@ -26,6 +26,7 @@ #include "ChatDialog.h" #include "gui/common/PeerDefs.h" #include "PopupChatDialog.h" +#include "PopupDistantChatDialog.h" #include "ChatLobbyDialog.h" #include "PopupChatWindow.h" #include "gui/settings/rsharesettings.h" @@ -91,10 +92,17 @@ void ChatDialog::init(const std::string &peerId, const QString &title) ChatDialog *cd = getExistingChat(peerId); if (cd == NULL) { - ChatLobbyId lobby_id; + ChatLobbyId lobby_id = 0; + bool distant_peer = false ; + if (rsMsgs->isLobbyId(peerId, lobby_id)) { chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags } + std::string distant_pgp_id = "" ; + + if(distant_peer = rsMsgs->isDistantId(peerId,distant_pgp_id)) { + chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags + } if (chatflags & RS_CHAT_OPEN) { if (lobby_id) { @@ -108,6 +116,10 @@ void ChatDialog::init(const std::string &peerId, const QString &title) cd->init(peerId, QString::fromUtf8((*it).lobby_name.c_str())); } } + } else if(distant_peer) { + cd = new PopupDistantChatDialog(); + chatDialogs[peerId] = cd; + cd->init(peerId, tr("Distant peer (PGP id=%1)").arg(distant_pgp_id)); } else { RsPeerDetails sslDetails; if (rsPeers->getPeerDetails(peerId, sslDetails)) { diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp new file mode 100644 index 000000000..a6f2b6ff6 --- /dev/null +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp @@ -0,0 +1,52 @@ +#include +#include "PopupDistantChatDialog.h" + +PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WFlags flags) + : PopupChatDialog(parent,flags) +{ + _tunnel_check_timer = new QTimer; + _tunnel_check_timer->setInterval(1000) ; + + QObject::connect(_tunnel_check_timer,SIGNAL(timeout()),this,SLOT(checkTunnel())) ; + + _tunnel_check_timer->start() ; +} + +void PopupDistantChatDialog::init(const std::string& hash,const QString & title) +{ + _hash = hash ; +} + +void PopupDistantChatDialog::checkTunnel() +{ + if(!isVisible()) + return ; + + std::cerr << "Checking tunnel..." ; + // make sure about the tunnel status + // + + uint32_t status = rsMsgs->getDistantChatStatus(_hash) ; + + switch(status) + { + case RS_DISTANT_CHAT_STATUS_UNKNOWN: std::cerr << "Unknown hash. Error!" << std::endl; + break ; + case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl; + break ; + case RS_DISTANT_CHAT_STATUS_TUNNEL_OK: std::cerr << "Tunnel is ok. " << std::endl; + break ; + case RS_DISTANT_CHAT_STATUS_CAN_TALK: std::cerr << "Tunnel is ok and works. You can talk!" << std::endl; + break ; + } +} + + + + + + + + + + diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h new file mode 100644 index 000000000..ef03d2c42 --- /dev/null +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h @@ -0,0 +1,52 @@ + +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2006, crypton + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#pragma once + +#include "PopupChatDialog.h" + +class QTimer ; + +class PopupDistantChatDialog: public PopupChatDialog +{ + Q_OBJECT + + friend class ChatDialog; + + public slots: + void checkTunnel() ; + +protected: + /** Default constructor */ + PopupDistantChatDialog(QWidget *parent = 0, Qt::WFlags flags = 0); + /** Default destructor */ + virtual ~PopupDistantChatDialog(); + + virtual void init(const std::string& _hash, const QString &title); + virtual void updateStatus(int /*status*/) {} + + QTimer *_tunnel_check_timer ; + std::string _hash ; + std::string _virtual_peer_id ; +}; + + diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 67610833c..10a60d250 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -334,6 +334,7 @@ HEADERS += rshare.h \ gui/profile/StatusMessage.h \ gui/chat/PopupChatWindow.h \ gui/chat/PopupChatDialog.h \ + gui/chat/PopupDistantChatDialog.h \ gui/chat/ChatTabWidget.h \ gui/chat/ChatWidget.h \ gui/chat/ChatDialog.h \ @@ -645,6 +646,7 @@ SOURCES += main.cpp \ gui/channels/ChannelUserNotify.cpp \ gui/chat/PopupChatWindow.cpp \ gui/chat/PopupChatDialog.cpp \ + gui/chat/PopupDistantChatDialog.cpp \ gui/chat/ChatTabWidget.cpp \ gui/chat/ChatWidget.cpp \ gui/chat/ChatDialog.cpp \