Merged branch v0.5-GenericTunneling into trunk (Rev. 6284 to 6410).

- adds turtle router as a generic tunneling service
- made ftServer a client of the service. Now turtle file items are handled in ftServer
- added new client: p3MsgService to send/recv pgp-encrypted distant messages
- added new client: p3ChatService to perform private (AES-encrypted) distant chat through tunnels.
- The GUI is disabled for now, since it needs some polishing before being fully usable.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6411 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-06-06 19:58:30 +00:00
commit dc2521cf71
62 changed files with 5031 additions and 1989 deletions

View file

@ -0,0 +1,226 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2013 Cyril Soler
*
* This program is free software; you can redistribute it and/or
* 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.
****************************************************************/
#include <iostream>
#include <QMessageBox>
#include <QTimer>
#include <retroshare/rsmsgs.h>
#include <retroshare/rspeers.h>
#include "CreateMsgLinkDialog.h"
#include <gui/common/FriendSelectionWidget.h>
#include <gui/RetroShareLink.h>
CreateMsgLinkDialog::CreateMsgLinkDialog(QWidget *parent)
:QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)
{
/* Invoke the Qt Designer generated object setup routine */
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, false);
_info_GB->layout()->addWidget( _gpg_selection = new FriendSelectionWidget(this) ) ;
QObject::connect(_link_type_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(update())) ;
QObject::connect(_create_link_PB,SIGNAL(clicked()),this,SLOT(createLink())) ;
QObject::connect(_create_new_PB,SIGNAL(toggled(bool)),this,SLOT(toggleCreateLink(bool))) ;
QObject::connect(_existing_links_LW,SIGNAL(currentRowChanged(int)),this,SLOT(updateCurrentRow(int))) ;
_gpg_selection->setModus(FriendSelectionWidget::MODUS_SINGLE) ;
_gpg_selection->setShowType(FriendSelectionWidget::SHOW_NON_FRIEND_GPG | FriendSelectionWidget::SHOW_GPG) ;
_gpg_selection->setHeaderText(QObject::tr("Select who can contact you:")) ;
_gpg_selection->start() ;
toggleCreateLink(false) ;
update() ;
updateCurrentRow(-1) ;
}
void CreateMsgLinkDialog::updateCurrentRow(int r)
{
if(r < 0)
{
_current_link_type_LE->setText("") ;
_current_link_dst_LE->setText("") ;
_current_link_date_DE->setDateTime(QDateTime::fromMSecsSinceEpoch(0)) ;
return ;
}
QUrl text = _existing_links_LW->item(r)->data(Qt::UserRole).toUrl() ;
std::cerr << "Parsing link : " << text.toString().toStdString() << std::endl;
RetroShareLink link(text) ;
if( link.type() == RetroShareLink::TYPE_PRIVATE_CHAT )
_current_link_type_LE->setText( tr("Private chat invite") ) ;
else
_current_link_type_LE->setText( tr("Public message invite") ) ;
_current_link_dst_LE->setText(link.GPGId()) ;
_current_link_date_DE->setDateTime(QDateTime::fromMSecsSinceEpoch(link.timeStamp() * 1000 )) ;
}
void CreateMsgLinkDialog::toggleCreateLink(bool b)
{
_new_link_F->setHidden(!b) ;
}
void CreateMsgLinkDialog::update()
{
if(_link_type_CB->currentIndex() == 0)
{
QString s ;
s += "A private chat invite allows a specific peer to contact you using encrypted private chat. You need to select a destination peer from your PGP keyring before creating the link. The link contains the encryption code and your PGP signature, so that the peer can authenticate you." ;
_info_TB->setHtml(s) ;
_gpg_selection->setHidden(false) ;
}
else
{
QString s ;
s += "A public message link allows any peer in the nearby network to send a private message to you. The message is encrypted and only you can read it." ;
_info_TB->setHtml(s) ;
_gpg_selection->setHidden(true) ;
}
std::vector<DistantChatInviteInfo> invites ;
rsMsgs->getDistantChatInviteList(invites) ;
_existing_links_LW->clear() ;
for(uint32_t i=0;i<invites.size();++i)
{
RetroShareLink link ;
if(!link.createPrivateChatInvite(invites[i].time_of_validity,QString::fromStdString(invites[i].destination_pgp_id),QString::fromStdString(invites[i].encrypted_radix64_string)));
std::cerr << "Cannot create link." << std::endl;
QListWidgetItem *item = new QListWidgetItem;
item->setData(Qt::DisplayRole,tr("Private chat invite to ")+QString::fromStdString(invites[i].destination_pgp_id)) ;
item->setData(Qt::UserRole,link.toString()) ;
_existing_links_LW->insertItem(0,item) ;
}
std::vector<DistantOfflineMessengingInvite> invites2 ;
rsMsgs->getDistantOfflineMessengingInvites(invites2) ;
for(uint32_t i=0;i<invites2.size();++i)
{
RetroShareLink link ;
if(!link.createPublicMsgInvite(invites2[i].time_of_validity,QString::fromStdString(invites2[i].issuer_pgp_id),QString::fromStdString(invites2[i].hash)))
std::cerr << "Cannot create link." << std::endl;
else
{
QListWidgetItem *item = new QListWidgetItem;
item->setData(Qt::DisplayRole,tr("Public message link")) ;
item->setData(Qt::UserRole,link.toString()) ;
_existing_links_LW->insertItem(0,item) ;
}
}
}
time_t CreateMsgLinkDialog::computeValidityDuration() const
{
time_t unit ;
switch(_validity_time_CB->currentIndex())
{
default:
case 0: unit = 3600 ;
break ;
case 1: unit = 3600*24 ;
break ;
case 2: unit = 3600*24*7 ;
break ;
case 3: unit = 3600*24*30 ;
break ;
case 4: unit = 3600*24*365 ;
break ;
}
return unit * _validity_time_SB->value() ;
}
void CreateMsgLinkDialog::createLink()
{
std::cerr << "Creating link!" << std::endl;
if(_link_type_CB->currentIndex() == 0)
{
time_t validity_duration = computeValidityDuration() ;
FriendSelectionWidget::IdType type ;
std::string current_pgp_id = _gpg_selection->selectedId(type) ;
std::string encrypted_string ;
bool res = rsMsgs->createDistantChatInvite(current_pgp_id,validity_duration,encrypted_string) ;
RetroShareLink link ;
if(!link.createPrivateChatInvite(validity_duration + time(NULL),QString::fromStdString(current_pgp_id),QString::fromStdString(encrypted_string)) )
std::cerr << "Cannot create link." << std::endl;
QList<RetroShareLink> links ;
links.push_back(link) ;
RSLinkClipboard::copyLinks(links) ;
if(!res)
QMessageBox::critical(NULL,tr("Private chat invite creation failed"),tr("The creation of the chat invite failed")) ;
else
QMessageBox::information(NULL,tr("Private chat invite created"),tr("Your new chat invite has been copied to clipboard. You can now paste it as a Retroshare link.")) ;
}
else
{
time_t validity_duration = computeValidityDuration() ;
std::string hash;
std::string issuer_pgp_id = rsPeers->getGPGOwnId() ;
bool res = rsMsgs->createDistantOfflineMessengingInvite(validity_duration,hash) ;
RetroShareLink link ;
if(!link.createPublicMsgInvite(validity_duration + time(NULL),QString::fromStdString(issuer_pgp_id),QString::fromStdString(hash)) )
{
std::cerr << "Cannot create link." << std::endl;
return ;
}
QList<RetroShareLink> links ;
links.push_back(link) ;
RSLinkClipboard::copyLinks(links) ;
if(!res)
QMessageBox::critical(NULL,tr("Messenging invite creation failed"),tr("The creation of the messenging invite failed")) ;
else
QMessageBox::information(NULL,tr("Messenging invite created"),tr("Your new messenging chat invite has been copied to clipboard. You can now paste it as a Retroshare link.")) ;
}
QTimer::singleShot(100,this,SLOT(update())) ;
}

View file

@ -0,0 +1,53 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2008 Robert Fernie
*
* 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 "ui_CreateMsgLinkDialog.h"
class FriendSelectionWidget ;
class CreateMsgLinkDialog : public QDialog, public Ui::CreateMsgLinkDialog
{
Q_OBJECT
public:
CreateMsgLinkDialog(QWidget *parent = NULL);
virtual ~CreateMsgLinkDialog() {}
private slots:
/* actions to take.... */
void createLink();
void update() ;
void toggleCreateLink(bool) ;
void updateCurrentRow(int) ;
private:
time_t computeValidityDuration() const ;
/** Qt Designer generated object */
FriendSelectionWidget *_gpg_selection ;
};

View file

@ -0,0 +1,220 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CreateMsgLinkDialog</class>
<widget class="QDialog" name="CreateMsgLinkDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>565</width>
<height>465</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QListWidget" name="_existing_links_LW">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Valid until:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Usable by:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QDateTimeEdit" name="_current_link_date_DE"/>
</item>
<item>
<widget class="QLineEdit" name="_current_link_type_LE"/>
</item>
<item>
<widget class="QLineEdit" name="_current_link_dst_LE"/>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Copy to clipboard</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_create_new_PB">
<property name="text">
<string>Create new</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="_new_link_F">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Invite type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="_link_type_CB">
<item>
<property name="text">
<string>Private chat</string>
</property>
</item>
<item>
<property name="text">
<string>Public message</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Validity time :</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="_validity_time_SB">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="_validity_time_CB">
<item>
<property name="text">
<string>hour</string>
</property>
</item>
<item>
<property name="text">
<string>day</string>
</property>
</item>
<item>
<property name="text">
<string>week</string>
</property>
</item>
<item>
<property name="text">
<string>month</string>
</property>
</item>
<item>
<property name="text">
<string>year</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="_create_link_PB">
<property name="text">
<string>Create!</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="_info_GB">
<property name="title">
<string>Information</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextBrowser" name="_info_TB"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -23,6 +23,7 @@
#include <QShortcut>
#include <QTimer>
#include <QDateTime>
#include <QMessageBox>
#include <QKeyEvent>
#include "MessagesDialog.h"
@ -118,8 +119,8 @@ MessagesDialog::MessagesDialog(QWidget *parent)
inChange = false;
lockUpdate = 0;
connect(ui.messagestreeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(messageslistWidgetCostumPopupMenu(QPoint)));
connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(folderlistWidgetCostumPopupMenu(QPoint)));
connect(ui.messagestreeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(messageslistWidgetCustomPopupMenu(QPoint)));
connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(folderlistWidgetCustomPopupMenu(QPoint)));
connect(ui.messagestreeView, SIGNAL(clicked(const QModelIndex&)) , this, SLOT(clicked(const QModelIndex&)));
connect(ui.messagestreeView, SIGNAL(doubleClicked(const QModelIndex&)) , this, SLOT(doubleClicked(const QModelIndex&)));
connect(ui.listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeBox(int)));
@ -507,7 +508,7 @@ bool MessagesDialog::hasMessageStar(int nRow)
return item->data(ROLE_MSGFLAGS).toInt() & RS_MSG_STAR;
}
void MessagesDialog::messageslistWidgetCostumPopupMenu( QPoint /*point*/ )
void MessagesDialog::messageslistWidgetCustomPopupMenu( QPoint /*point*/ )
{
std::string cid;
std::string mid;
@ -587,6 +588,9 @@ void MessagesDialog::messageslistWidgetCostumPopupMenu( QPoint /*point*/ )
action->setDisabled(true);
}
if(nCount==1 && (msgInfo.msgflags & RS_MSG_ENCRYPTED))
action = contextMnu.addAction(QIcon(IMAGE_SYSTEM), tr("Decrypt Message"), this, SLOT(decryptSelectedMsg()));
int listrow = ui.listWidget->currentRow();
if (listrow == ROW_TRASHBOX) {
action = contextMnu.addAction(tr("Undelete"), this, SLOT(undeletemessage()));
@ -605,7 +609,7 @@ void MessagesDialog::messageslistWidgetCostumPopupMenu( QPoint /*point*/ )
contextMnu.exec(QCursor::pos());
}
void MessagesDialog::folderlistWidgetCostumPopupMenu(QPoint /*point*/)
void MessagesDialog::folderlistWidgetCustomPopupMenu(QPoint /*point*/)
{
if (ui.listWidget->currentRow() != ROW_TRASHBOX) {
/* Context menu only neede for trash box */
@ -1112,7 +1116,11 @@ void MessagesDialog::insertMessages()
}
// Subject
text = QString::fromStdWString(it->title);
if(it->msgflags & RS_MSG_ENCRYPTED)
text = tr("Encrypted message. Right-click to decrypt it.") ;
else
text = QString::fromStdWString(it->title);
item[COLUMN_SUBJECT]->setText(text);
item[COLUMN_SUBJECT]->setData(text + dateString, ROLE_SORT);
@ -1464,6 +1472,28 @@ void MessagesDialog::insertMsgTxtAndFiles(QModelIndex Index, bool bSetToRead)
updateInterface();
}
void MessagesDialog::decryptSelectedMsg()
{
MessageInfo msgInfo;
if (!rsMsgs->getMessage(mCurrMsgId, msgInfo))
return ;
if(!msgInfo.msgflags & RS_MSG_ENCRYPTED)
{
std::cerr << "This message is not encrypted! Cannot decrypt!" << std::endl;
return ;
}
if(!rsMsgs->decryptMessage(mCurrMsgId) )
QMessageBox::warning(NULL,tr("Decryption failed!"),tr("This message could not be decrypted.")) ;
//setMsgAsReadUnread(currentIndex.row(), true);
updateMessageSummaryList();
insertMessages();
insertMsgTxtAndFiles();
}
bool MessagesDialog::getCurrentMsg(std::string &cid, std::string &mid)
{
QModelIndex currentIndex = ui.messagestreeView->currentIndex();

View file

@ -60,8 +60,9 @@ public slots:
private slots:
/** Create the context popup menu and it's submenus */
void messageslistWidgetCostumPopupMenu( QPoint point );
void folderlistWidgetCostumPopupMenu(QPoint);
void messageslistWidgetCustomPopupMenu( QPoint point );
void folderlistWidgetCustomPopupMenu(QPoint);
void decryptSelectedMsg() ;
void changeBox(int newrow);
void changeQuickView(int newrow);

View file

@ -28,6 +28,7 @@
#include <retroshare/rsiface.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsdisc.h>
#include <retroshare/rsmsgs.h>
#include "common/vmessagebox.h"
#include "common/RSTreeWidgetItem.h"
@ -230,7 +231,10 @@ void NetworkDialog::connecttreeWidgetCostumPopupMenu( QPoint /*point*/ )
contextMnu->addAction(QIcon(IMAGE_PEERDETAILS), tr("Peer details..."), this, SLOT(peerdetails()));
contextMnu->addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyLink()));
contextMnu->addSeparator() ;
#ifdef ENABLE_DISTANT_CHAT_AND_MSGS
contextMnu->addAction(QIcon(IMAGE_COPYLINK), tr("Create a distant chat invitation..."), this, SLOT(createChatLink()));
contextMnu->addSeparator() ;
#endif
contextMnu->addAction(QIcon(IMAGE_CLEAN_UNUSED), tr("Remove unused keys..."), this, SLOT(removeUnusedKeys()));
contextMnu->exec(QCursor::pos());
@ -330,6 +334,19 @@ void NetworkDialog::makeFriend()
ConfCertDialog::showIt(getCurrentNeighbour()->text(COLUMN_PEERID).toStdString(), ConfCertDialog::PageTrust);
}
void NetworkDialog::createChatLink()
{
std::string pgp_id = getCurrentNeighbour()->text(COLUMN_PEERID).toStdString() ;
std::cerr << "Creating chat link for pgp id " << pgp_id << std::endl;
std::string hash,estr ;
rsMsgs->createDistantChatInvite(pgp_id,time(NULL)+3600,estr) ;
std::cerr << "Created invite:" << std::endl;
std::cerr << " estr = " << estr << std::endl;
}
/** Shows Peer Information/Auth Dialog */
void NetworkDialog::peerdetails()
{

View file

@ -69,6 +69,7 @@ private slots:
void removeUnusedKeys() ;
void makeFriend() ;
void denyFriend() ;
void createChatLink() ;
void deleteCert() ;
void peerdetails();
void copyLink();

View file

@ -71,7 +71,7 @@ static NewsFeed *instance = NULL;
/** Constructor */
NewsFeed::NewsFeed(QWidget *parent)
: MainPage (parent)
: RsAutoUpdatePage(1000,parent)
{
/* Invoke the Qt Designer generated object setup routine */
setupUi(this);
@ -83,9 +83,9 @@ NewsFeed::NewsFeed(QWidget *parent)
connect(removeAllButton, SIGNAL(clicked()), this, SLOT(removeAll()));
connect(feedOptionsButton, SIGNAL(clicked()), this, SLOT(feedoptions()));
QTimer *timer = new QTimer(this);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(updateFeed()));
timer->start(1000);
// QTimer *timer = new QTimer(this);
// timer->connect(timer, SIGNAL(timeout()), this, SLOT(updateFeed()));
// timer->start(1000);
}
NewsFeed::~NewsFeed()
@ -95,7 +95,7 @@ NewsFeed::~NewsFeed()
}
}
void NewsFeed::updateFeed()
void NewsFeed::updateDisplay()
{
if (!rsNotify)
return;

View file

@ -26,6 +26,7 @@
#include "ui_NewsFeed.h"
#include "gui/feeds/FeedHolder.h"
#include <retroshare-gui/RsAutoUpdatePage.h>
class RsFeedItem;
class ForumNewItem;
@ -33,7 +34,7 @@ class ChanMsgItem;
class ChatMsgItem;
class FeedNotify;
class NewsFeed : public MainPage, public FeedHolder, private Ui::NewsFeed
class NewsFeed : public RsAutoUpdatePage, public FeedHolder, private Ui::NewsFeed
{
Q_OBJECT
@ -52,6 +53,7 @@ public:
static void testFeeds(uint notifyFlags);
static void testFeed(FeedNotify *feedNotify);
virtual void updateDisplay();
signals:
void newsFeedChanged(int count);
@ -59,7 +61,6 @@ private slots:
// void toggleChanMsgItems(bool on);
void feedoptions();
void updateFeed();
void removeAll();
void itemDestroyed(QObject*);

View file

@ -41,6 +41,7 @@
#include "gui/connect/ConfCertDialog.h"
#include <retroshare/rsfiles.h>
#include <retroshare/rsmsgs.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsforums.h>
#include <retroshare/rschannels.h>
@ -55,7 +56,9 @@
#define HOST_MESSAGE "message"
#define HOST_SEARCH "search"
#define HOST_CERTIFICATE "certificate"
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate"
#define HOST_PUBLIC_MSG "public_msg"
#define HOST_PRIVATE_CHAT "private_chat"
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate|private_chat|public_msg"
#define FILE_NAME "name"
#define FILE_SIZE "size"
@ -87,6 +90,14 @@
#define CERTIFICATE_EXT_IPPORT "extipp"
#define CERTIFICATE_LOC_IPPORT "locipp"
#define PRIVATE_CHAT_TIME_STAMP "time_stamp"
#define PRIVATE_CHAT_STRING "encrypted_data"
#define PRIVATE_CHAT_GPG_ID "gpgid"
#define PUBLIC_MSG_TIME_STAMP "time_stamp"
#define PUBLIC_MSG_SRC_PGP_ID "gpgid"
#define PUBLIC_MSG_HASH "hash"
RetroShareLink::RetroShareLink(const QUrl& url)
{
fromUrl(url);
@ -107,7 +118,8 @@ void RetroShareLink::fromString(const QString& url)
#endif
if ((url.startsWith(QString(RSLINK_SCHEME) + "://" + QString(HOST_FILE)) && url.count("|") == 3) ||
(url.startsWith(QString(RSLINK_SCHEME) + "://" + QString(HOST_PERSON)) && url.count("|") == 2)) {
(url.startsWith(QString(RSLINK_SCHEME) + "://" + QString(HOST_PERSON)) && url.count("|") == 2))
{
/* Old link, we try it */
QStringList list = url.split ("|");
@ -158,6 +170,7 @@ void RetroShareLink::fromUrl(const QUrl& url)
if (url.scheme() != RSLINK_SCHEME) {
/* No RetroShare-Link */
std::cerr << "Not a RS link: scheme=" << url.scheme().toStdString() << std::endl;
return;
}
@ -181,6 +194,29 @@ void RetroShareLink::fromUrl(const QUrl& url)
}
}
if(url.host() == HOST_PRIVATE_CHAT)
{
bool ok ;
_type = TYPE_PRIVATE_CHAT ;
_time_stamp = url.queryItemValue(PRIVATE_CHAT_TIME_STAMP).toUInt(&ok) ;
_encrypted_chat_info = url.queryItemValue(PRIVATE_CHAT_STRING) ;
_GPGid = url.queryItemValue(PRIVATE_CHAT_GPG_ID) ;
check() ;
return;
}
if(url.host() == HOST_PUBLIC_MSG)
{
bool ok ;
_type = TYPE_PUBLIC_MSG ;
_hash = url.queryItemValue(PUBLIC_MSG_HASH) ;
_time_stamp = url.queryItemValue(PUBLIC_MSG_TIME_STAMP).toUInt(&ok) ;
_GPGid = url.queryItemValue(PUBLIC_MSG_SRC_PGP_ID) ;
check() ;
return;
}
if (url.host() == HOST_EXTRAFILE) {
bool ok ;
@ -299,6 +335,32 @@ bool RetroShareLink::createFile(const QString& name, uint64_t size, const QStrin
return valid();
}
bool RetroShareLink::createPrivateChatInvite(time_t time_stamp,const QString& gpg_id,const QString& encrypted_chat_info)
{
clear() ;
_type = TYPE_PRIVATE_CHAT ;
_time_stamp = time_stamp ;
_encrypted_chat_info = encrypted_chat_info ;
_GPGid = gpg_id ;
check() ;
return valid() ;
}
bool RetroShareLink::createPublicMsgInvite(time_t time_stamp,const QString& issuer_pgp_id,const QString& hash)
{
clear() ;
_type = TYPE_PUBLIC_MSG ;
_time_stamp = time_stamp ;
_hash = hash ;
_GPGid = issuer_pgp_id ;
check() ;
return valid() ;
}
bool RetroShareLink::createPerson(const std::string& id)
{
clear();
@ -491,78 +553,93 @@ void RetroShareLink::clear()
_hash = "" ;
_size = 0 ;
_name = "" ;
_GPGid = "" ;
_time_stamp = 0 ;
_encrypted_chat_info = "" ;
}
void RetroShareLink::check()
{
_valid = true;
switch (_type) {
case TYPE_UNKNOWN:
_valid = false;
break;
case TYPE_EXTRAFILE:
if(!checkSSLId(_SSLid))
_valid = false; // no break! We also test file stuff below.
case TYPE_FILE:
if(_size > (((uint64_t)1)<<40)) // 1TB. Who has such large files?
switch (_type)
{
case TYPE_UNKNOWN:
_valid = false;
break;
case TYPE_EXTRAFILE:
if(!checkSSLId(_SSLid))
_valid = false; // no break! We also test file stuff below.
case TYPE_FILE:
if(_size > (((uint64_t)1)<<40)) // 1TB. Who has such large files?
_valid = false;
if(!checkName(_name))
_valid = false;
if(!checkName(_name))
_valid = false;
if(!checkHash(_hash))
_valid = false;
break;
case TYPE_PERSON:
if(_size != 0)
_valid = false;
if(!checkHash(_hash))
_valid = false;
break;
if(_name.isEmpty())
_valid = false;
case TYPE_PRIVATE_CHAT:
if(!checkRadix64(_encrypted_chat_info)) _valid = false ;
if(!checkPGPId(_GPGid)) _valid = false ;
break ;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_FORUM:
if(_size != 0)
_valid = false;
case TYPE_PUBLIC_MSG:
if(!checkHash(_hash)) _valid = false ;
if(!checkPGPId(_GPGid)) _valid = false ;
break ;
if(_name.isEmpty())
_valid = false;
case TYPE_PERSON:
if(_size != 0)
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_CHANNEL:
if(_size != 0)
_valid = false;
if(_name.isEmpty())
_valid = false;
if(_name.isEmpty())
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_FORUM:
if(_size != 0)
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_SEARCH:
if(_size != 0)
_valid = false;
if(_name.isEmpty())
_valid = false;
if(_name.isEmpty())
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_CHANNEL:
if(_size != 0)
_valid = false;
if(!_hash.isEmpty())
_valid = false;
break;
case TYPE_MESSAGE:
if(_size != 0)
_valid = false;
if(_name.isEmpty())
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_CERTIFICATE:
break;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_SEARCH:
if(_size != 0)
_valid = false;
if(_name.isEmpty())
_valid = false;
if(!_hash.isEmpty())
_valid = false;
break;
case TYPE_MESSAGE:
if(_size != 0)
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_CERTIFICATE:
break;
}
if (!_valid) {
@ -579,6 +656,22 @@ QString RetroShareLink::title() const
switch (_type) {
case TYPE_UNKNOWN:
break;
case TYPE_PUBLIC_MSG:
{
RsPeerDetails detail;
rsPeers->getPeerDetails(_GPGid.toStdString(), detail) ;
return QString("Click to send a private message to %1 (%2).").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
}
case TYPE_PRIVATE_CHAT:
{
RsPeerDetails detail;
rsPeers->getPeerDetails(_GPGid.toStdString(), detail) ;
if (_GPGid.toStdString() == rsPeers->getGPGOwnId())
return QString("Click to open a private chat canal to %1 (%2).").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
else
return QString("This is a private chat invite for %1 (%2). You can't use it.").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
}
case TYPE_EXTRAFILE:
return QString("%1 (%2, Extra - Source included)").arg(hash()).arg(misc::friendlyUnit(size()));
case TYPE_FILE:
@ -619,6 +712,29 @@ QString RetroShareLink::toString() const
return url.toString();
}
case TYPE_PRIVATE_CHAT:
{
QUrl url;
url.setScheme(RSLINK_SCHEME) ;
url.setHost(HOST_PRIVATE_CHAT) ;
url.addQueryItem(PRIVATE_CHAT_TIME_STAMP,QString::number(_time_stamp)) ;
url.addQueryItem(PRIVATE_CHAT_GPG_ID,_GPGid) ;
url.addQueryItem(PRIVATE_CHAT_STRING,_encrypted_chat_info) ;
return url.toString() ;
}
case TYPE_PUBLIC_MSG:
{
QUrl url;
url.setScheme(RSLINK_SCHEME) ;
url.setHost(HOST_PUBLIC_MSG) ;
url.addQueryItem(PUBLIC_MSG_TIME_STAMP,QString::number(_time_stamp)) ;
url.addQueryItem(PUBLIC_MSG_HASH,_hash) ;
url.addQueryItem(PUBLIC_MSG_SRC_PGP_ID,_GPGid) ;
return url.toString() ;
}
case TYPE_EXTRAFILE:
{
QUrl url;
@ -724,6 +840,14 @@ QString RetroShareLink::niceName() const
return PeerDefs::rsid(name().toUtf8().constData(), hash().toStdString());
}
if(type() == TYPE_PRIVATE_CHAT) {
return QString("Private chat invite (Valid only for key %1)").arg(_GPGid);
}
if(type() == TYPE_PUBLIC_MSG) {
RsPeerDetails detail;
rsPeers->getPeerDetails(_GPGid.toStdString(), detail) ;
return QString("Click this link to send a private message to %1 (%2)").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
}
if(type() == TYPE_CERTIFICATE) {
if (_location.isEmpty()) {
return QString("RetroShare Certificate (%1)").arg(_name);
@ -814,6 +938,41 @@ bool RetroShareLink::checkSSLId(const QString& ssl_id)
return true ;
}
bool RetroShareLink::checkPGPId(const QString& pgp_id)
{
if(pgp_id.length() != 16)
return false ;
QByteArray qb(pgp_id.toAscii()) ;
for(int i=0;i<qb.length();++i)
{
unsigned char b(qb[i]) ;
if(!((b>47 && b<58) || (b>64 && b<71)))
return false ;
}
return true ;
}
bool RetroShareLink::checkRadix64(const QString& s)
{
QByteArray qb(s.toAscii()) ;
for(int i=0;i<qb.length();++i)
{
unsigned char b(qb[i]) ;
if(!( (b > 46 && b < 58) || (b > 64 && b < 91) || (b > 96 && b < 123) || b=='+' || b=='='))
{
std::cerr << "Character not allowed in radix: " << b << std::endl;
return false;
}
}
std::cerr << "Radix check: passed" << std::endl;
return true ;
}
bool RetroShareLink::checkHash(const QString& hash)
{
if(hash.length() != 40)
@ -1028,6 +1187,58 @@ static void processList(const QStringList &list, const QString &textSingular, co
}
break ;
case TYPE_PUBLIC_MSG:
{
std::cerr << "Opening a public msg window " << std::endl;
std::cerr << " time_stamp = " << link._time_stamp << std::endl;
std::cerr << " hash = " << link._hash.toStdString() << std::endl;
std::cerr << " Issuer Id = " << link._GPGid.toStdString() << std::endl;
if(link._time_stamp < time(NULL))
{
QMessageBox::information(NULL,QObject::tr("Messenging link is expired"),QObject::tr("This Messenging link is expired. The destination peer will not receive it.")) ;
break ;
}
MessageComposer::msgDistantPeer(link._hash.toStdString(),link._GPGid.toStdString()) ;
}
break ;
case TYPE_PRIVATE_CHAT:
{
std::cerr << "Opening a private chat window " << std::endl;
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,QObject::tr("Chat link is expired"),QObject::tr("This chat link is expired. The destination peer will not answer.")) ;
break ;
}
if(link._GPGid.toStdString() != rsPeers->getGPGOwnId())
{
QMessageBox::information(NULL,QObject::tr("Chat link cannot be decrypted"),QObject::tr("This chat link is encrypted with a key that is not yours. You can't used it. Key ID = ")+link._GPGid) ;
break ;
}
std::string hash ;
uint32_t error_code ;
if(!rsMsgs->initiateDistantChatConnexion(link._encrypted_chat_info.toStdString(),hash,error_code))
{
QString error_msg ;
switch(error_code)
{
default:
case RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED: error_msg = QObject::tr("The link could not be decrypted.") ; break ;
case RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH: error_msg = QObject::tr("The link signature cannot be checked.") ; break ;
case RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY: error_msg = QObject::tr("The link is signed by an unknown key.") ; break ;
}
QMessageBox::information(NULL,QObject::tr("Chat connexion is not possible"),error_msg) ;
}
}
break ;
case TYPE_FILE:
case TYPE_EXTRAFILE:
{

View file

@ -52,7 +52,18 @@
class RetroShareLink
{
public:
enum enumType { TYPE_UNKNOWN, TYPE_FILE, TYPE_PERSON, TYPE_FORUM, TYPE_CHANNEL, TYPE_SEARCH, TYPE_MESSAGE, TYPE_CERTIFICATE,TYPE_EXTRAFILE };
enum enumType { TYPE_UNKNOWN = 0x00,
TYPE_FILE = 0x01,
TYPE_PERSON = 0x02,
TYPE_FORUM = 0x03,
TYPE_CHANNEL = 0x04,
TYPE_SEARCH = 0x05,
TYPE_MESSAGE = 0x06,
TYPE_CERTIFICATE = 0x07,
TYPE_EXTRAFILE = 0x08,
TYPE_PRIVATE_CHAT = 0x09,
TYPE_PUBLIC_MSG = 0x0a
};
public:
RetroShareLink();
@ -67,6 +78,8 @@ class RetroShareLink
bool createSearch(const QString& keywords);
bool createMessage(const std::string& peerId, const QString& subject);
bool createCertificate(const std::string& ssl_or_gpg_id) ;
bool createPrivateChatInvite(time_t time_stamp,const QString& gpg_id,const QString& encrypted_chat_info) ;
bool createPublicMsgInvite(time_t time_stamp,const QString& pgp_id,const QString& hash) ;
bool createUnknwonSslCertificate(const std::string& sslId, const std::string& gpgId = "") ;
enumType type() const {return _type; }
@ -83,6 +96,8 @@ class RetroShareLink
const QString& localIPAndPort() const { return _loc_ip_port ; }
const QString& externalIPAndPort() const { return _ext_ip_port ; }
const QString& location() const { return _location ; }
const time_t timeStamp() const { return _time_stamp ; }
const QString& encryptedPrivateChatInfo() const { return _encrypted_chat_info ; }
QString title() const;
unsigned int subType() const { return _subType; }
@ -118,8 +133,10 @@ class RetroShareLink
void clear();
void check();
static bool checkHash(const QString& hash);
static bool checkRadix64(const QString& s);
static bool checkName(const QString& name);
static bool checkSSLId(const QString& name);
static bool checkPGPId(const QString& name);
bool _valid;
enumType _type;
@ -135,6 +152,9 @@ class RetroShareLink
QString _location ; // location
QString _ext_ip_port ;
QString _loc_ip_port ;
QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite
time_t _time_stamp ; // time stamp at which the link will expire.
unsigned int _subType; // for general use as sub type for _type (RSLINK_SUBTYPE_...)
};

View file

@ -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,11 +92,19 @@ 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
}
uint32_t distant_peer_status ;
std::string distant_chat_pgp_id ;
if(rsMsgs->getDistantChatStatus(peerId,distant_peer_status,distant_chat_pgp_id))
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags
if (chatflags & RS_CHAT_OPEN) {
if (lobby_id) {
std::list<ChatLobbyInfo> linfos;
@ -108,6 +117,12 @@ void ChatDialog::init(const std::string &peerId, const QString &title)
cd->init(peerId, QString::fromUtf8((*it).lobby_name.c_str()));
}
}
} else if(distant_peer_status > 0) {
cd = new PopupDistantChatDialog();
chatDialogs[peerId] = cd;
std::string peer_name = rsPeers->getGPGName(distant_chat_pgp_id) ;
cd->init(peerId, tr("Talking to ")+QString::fromStdString(peer_name)+" (PGP id="+QString::fromStdString(distant_chat_pgp_id)+")") ;
} else {
RsPeerDetails sslDetails;
if (rsPeers->getPeerDetails(peerId, sslDetails)) {

View file

@ -78,7 +78,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WF
connect(inviteFriendsButton, SIGNAL(clicked()), this , SLOT(inviteFriends()));
getChatWidget()->addChatButton(inviteFriendsButton) ;
getChatWidget()->addChatBarWidget(inviteFriendsButton) ;
unsubscribeButton = new QPushButton ;
unsubscribeButton->setMinimumSize(QSize(28,28)) ;
@ -95,7 +95,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WF
connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby()));
getChatWidget()->addChatButton(unsubscribeButton) ;
getChatWidget()->addChatBarWidget(unsubscribeButton) ;
}
void ChatLobbyDialog::leaveLobby()

View file

@ -36,6 +36,7 @@
#include "ui_ChatWidget.h"
#include "gui/notifyqt.h"
#include "gui/RetroShareLink.h"
#include "gui/CreateMsgLinkDialog.h"
#include "gui/settings/rsharesettings.h"
#include "gui/settings/RsharePeerSettings.h"
#include "gui/im_history/ImHistoryBrowser.h"
@ -139,9 +140,9 @@ void ChatWidget::setDefaultExtraFileFlags(TransferRequestFlags fl)
ui->hashBox->setDefaultTransferRequestFlags(fl) ;
}
void ChatWidget::addChatButton(QPushButton *button)
void ChatWidget::addChatBarWidget(QWidget *w)
{
ui->toolBarFrame->layout()->addWidget(button) ;
ui->toolBarFrame->layout()->addWidget(w) ;
}
void ChatWidget::init(const std::string &peerId, const QString &title)
@ -548,11 +549,22 @@ void ChatWidget::contextMenu(QPoint point)
QAction *action = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink()));
action->setDisabled(RSLinkClipboard::empty());
contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste my certificate link"), this, SLOT(pasteOwnCertificateLink()));
#ifdef ENABLE_DISTANT_CHAT_AND_MSGS
contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste/Create private chat or Message link..."), this, SLOT(pasteCreateMsgLink()));
#endif
contextMnu->exec(QCursor::pos());
delete(contextMnu);
}
void ChatWidget::pasteCreateMsgLink()
{
CreateMsgLinkDialog dialog ;
dialog.exec() ;
ui->chatTextEdit->insertHtml(RSLinkClipboard::toHtml());
}
void ChatWidget::contextMenuTextBrowser(QPoint point)
{
QMatrix matrix;

View file

@ -47,7 +47,6 @@ class ChatWidget : public QWidget
public:
enum enumChatType { TYPE_NORMAL, TYPE_HISTORY, TYPE_OFFLINE, TYPE_SYSTEM };
public:
explicit ChatWidget(QWidget *parent = 0);
~ChatWidget();
@ -74,13 +73,14 @@ public:
bool setStyle();
const RSStyle *getStyle() { return &style; }
void addChatButton(QPushButton *button) ;
void addChatBarWidget(QWidget *w) ;
bool isActive();
void setDefaultExtraFileFlags(TransferRequestFlags f) ;
void pasteText(const QString&);
private slots:
void pasteCreateMsgLink() ;
void clearChatHistory();
void deleteChatHistory();
void messageHistory();

View file

@ -141,9 +141,9 @@ void PopupChatDialog::addIncomingChatMsg(const ChatInfo& info)
}
}
void PopupChatDialog::addButton(QPushButton *button)
void PopupChatDialog::addChatBarWidget(QWidget *w)
{
getChatWidget()->addChatButton(button) ;
getChatWidget()->addChatBarWidget(w) ;
}
void PopupChatDialog::onChatChanged(int list, int type)

View file

@ -57,7 +57,7 @@ protected:
void processSettings(bool load);
// used by plugins
void addButton(QPushButton *button) ;
void addChatBarWidget(QWidget *w) ;
protected:
virtual void addIncomingChatMsg(const ChatInfo& info);

View file

@ -0,0 +1,98 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2013, Cyril Soler
*
* 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.
****************************************************************/
#include <QTimer>
#include "PopupDistantChatDialog.h"
#define IMAGE_RED_LED ":/images/redled.png"
#define IMAGE_YEL_LED ":/images/yellowled.png"
#define IMAGE_GRN_LED ":/images/greenled.png"
#define IMAGE_GRY_LED ":/images/grayled.png"
PopupDistantChatDialog::~PopupDistantChatDialog()
{
delete _tunnel_check_timer ;
}
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() ;
_status_label = new QLabel ;
addChatBarWidget(_status_label) ;
checkTunnel() ;
}
void PopupDistantChatDialog::init(const std::string& hash,const QString & title)
{
_hash = hash ;
PopupChatDialog::init(hash,title) ;
}
void PopupDistantChatDialog::checkTunnel()
{
if(!isVisible())
return ;
std::cerr << "Checking tunnel..." ;
// make sure about the tunnel status
//
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
std::string pgp_id ;
rsMsgs->getDistantChatStatus(_hash,status,pgp_id) ;
switch(status)
{
case RS_DISTANT_CHAT_STATUS_UNKNOWN: std::cerr << "Unknown hash. Error!" << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_GRY_LED)) ;
_status_label->setToolTip(tr("Hash error")) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ;
_status_label->setToolTip(tr("Tunnel is broken")) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_OK: std::cerr << "Tunnel is ok. " << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_YEL_LED)) ;
_status_label->setToolTip(tr("Tunnel established")) ;
break ;
case RS_DISTANT_CHAT_STATUS_CAN_TALK: std::cerr << "Tunnel is ok and works. You can talk!" << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_GRN_LED)) ;
_status_label->setToolTip(tr("Tunnel is working")) ;
break ;
}
}

View file

@ -0,0 +1,53 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2013, Cyril Soler
*
* 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 ;
QLabel *_status_label ;
};

View file

@ -352,6 +352,22 @@ void MessageComposer::processSettings(bool bLoad)
Settings->endGroup();
}
/*static*/ void MessageComposer::msgDistantPeer(const std::string& hash,const std::string& pgp_id)
{
// std::cerr << "MessageComposer::msgfriend()" << std::endl;
/* create a message */
MessageComposer *pMsgDialog = MessageComposer::newMsg();
if (pMsgDialog == NULL)
return;
pMsgDialog->addRecipient(TO, hash,pgp_id) ;
pMsgDialog->show();
/* window will destroy itself! */
}
/*static*/ void MessageComposer::msgFriend(const std::string &id, bool group)
{
@ -1219,7 +1235,7 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
}
}
} else {
if (std::find(peers.begin(), peers.end(), id) == peers.end()) {
if (_distant_peers.find(id)==_distant_peers.end() && std::find(peers.begin(), peers.end(), id) == peers.end()) {
// no friend
continue;
}
@ -1269,6 +1285,7 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
QMessageBox::warning(this, tr("RetroShare"), tr("Please insert at least one recipient."), QMessageBox::Ok);
return false; // Don't send with no recipient
}
mi.encryption_keys = _distant_peers ;
if (rsMsgs->MessageSend(mi) == false) {
return false;
@ -1402,7 +1419,13 @@ void MessageComposer::setRecipientToRow(int row, enumType type, std::string id,
}
} else {
RsPeerDetails details;
if (rsPeers->getPeerDetails(id, 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);
StatusInfo peerStatusInfo;
@ -1546,6 +1569,32 @@ void MessageComposer::editingRecipientFinished()
lineEdit->setText(text);
}
void MessageComposer::addRecipient(enumType type, const std::string& hash,const std::string& pgp_id)
{
_distant_peers[hash] = pgp_id ;
int rowCount = ui.recipientWidget->rowCount();
int row;
for (row = 0; row < rowCount; row++)
{
enumType rowType;
std::string rowId;
bool rowGroup;
if (getRecipientFromRow(row, rowType, rowId, rowGroup) == true)
{
if (rowId.empty()) // use row
break;
if (rowId == hash && rowType == type) // existing row
break;
}
else // use row
break;
}
setRecipientToRow(row, type, hash, false);
}
void MessageComposer::addRecipient(enumType type, const std::string &id, bool group)
{
std::list<std::string> sslIds;

View file

@ -49,6 +49,8 @@ public:
~MessageComposer();
static void msgFriend(const std::string &id, bool group);
static void msgDistantPeer(const std::string& hash,const std::string& pgp_id) ;
static QString recommendMessage();
static void recommendFriend(const std::list <std::string> &sslIds, const std::string &to = "", const QString &msg = "", bool autoSend = false);
static void sendConnectAttemptMsg(const std::string &gpgId, const std::string &sslId, const QString &sslName);
@ -65,6 +67,7 @@ public:
void setQuotedMsg(const QString &msg, const QString &header);
void setMsgText(const QString &msg, bool asHtml = false);
void addRecipient(enumType type, const std::string &id, bool group);
void addRecipient(enumType type, const std::string &hash, const std::string& pgp_id) ;
public slots:
/* actions to take.... */
@ -217,6 +220,7 @@ private:
Ui::MessageComposer ui;
std::list<FileInfo> _recList ;
std::map<std::string,std::string> _distant_peers ; // pairs (hash,pgp_id)
};
#endif

View file

@ -275,6 +275,7 @@ HEADERS += rshare.h \
gui/TurtleRouterStatistics.h \
gui/AboutDialog.h \
gui/ForumsDialog.h \
gui/CreateMsgLinkDialog.h \
gui/forums/ForumDetails.h \
gui/forums/EditForumDetails.h \
gui/forums/CreateForum.h \
@ -333,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 \
@ -471,6 +473,7 @@ FORMS += gui/StartDialog.ui \
gui/MainWindow.ui \
gui/TurtleRouterDialog.ui \
gui/TurtleRouterStatistics.ui \
gui/CreateMsgLinkDialog.ui \
gui/forums/CreateForum.ui \
gui/forums/CreateForumMsg.ui \
gui/forums/ForumDetails.ui \
@ -580,6 +583,7 @@ SOURCES += main.cpp \
gui/TurtleRouterStatistics.cpp \
gui/MainWindow.cpp \
gui/ForumsDialog.cpp \
gui/CreateMsgLinkDialog.cpp \
gui/forums/ForumDetails.cpp \
gui/forums/EditForumDetails.cpp \
gui/forums/CreateForum.cpp \
@ -642,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 \