From 365682d7719f7db8221da7981af63bcbb94fc371 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 16 Jan 2022 15:50:21 +0100 Subject: [PATCH 1/3] added PGP-encryption to server communication to avoid data harvesting --- libretroshare | 2 +- retroshare-friendserver/src/friendserver.cc | 109 +++++++++++++----- retroshare-friendserver/src/friendserver.h | 5 +- retroshare-gui/src/gui/settings/ServerPage.ui | 2 +- 4 files changed, 88 insertions(+), 30 deletions(-) diff --git a/libretroshare b/libretroshare index a7a430008..89b4d9c33 160000 --- a/libretroshare +++ b/libretroshare @@ -1 +1 @@ -Subproject commit a7a430008b76e53727598c4d13106e7ce95221d7 +Subproject commit 89b4d9c3352c02630cd555918515b1412b3264ff diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index b3c5d55ec..577730e73 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -4,6 +4,8 @@ #include "util/rsbase64.h" #include "util/radix64.h" +#include "crypto/hashstream.h" + #include "pgp/pgpkeyutil.h" #include "pgp/rscertificate.h" #include "pgp/openpgpsdkhandler.h" @@ -60,7 +62,7 @@ void FriendServer::threadTick() if(last_debugprint_TS + DELAY_BETWEEN_TWO_DEBUG_PRINT < now) { last_debugprint_TS = now; - debugPrint(); + debugPrint(false); } } @@ -82,12 +84,12 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it RsDbg() << "Sending response item to " << item->PeerId() ; - RsFriendServerServerResponseItem *sr_item = new RsFriendServerServerResponseItem; + RsFriendServerServerResponseItem sr_item; std::map friends; - sr_item->nonce = pi->second.last_nonce; - sr_item->friend_invites = computeListOfFriendInvites(item->n_requested_friends,pi->first,friends); - sr_item->PeerId(item->PeerId()); + sr_item.nonce = pi->second.last_nonce; + sr_item.friend_invites = computeListOfFriendInvites(item->n_requested_friends,pi->first,friends); + sr_item.PeerId(item->PeerId()); // Update the have_added_as_friend for the list of each peer. We do that before sending because sending destroys // the item. @@ -100,10 +102,29 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it // Now encrypt the item with the public PGP key of the destination. This prevents the wrong person to request for // someone else's data. -#warning TODO + RsFriendServerEncryptedServerResponseItem *encrypted_response_item = new RsFriendServerEncryptedServerResponseItem; + uint32_t serialized_clear_size = FsSerializer().size(&sr_item); + RsTemporaryMemory serialized_clear_mem(serialized_clear_size); + FsSerializer().serialise(&sr_item,serialized_clear_mem,&serialized_clear_size); + + uint32_t encrypted_mem_size = serialized_clear_size+1000; // leave some extra space + RsTemporaryMemory encrypted_mem(encrypted_mem_size); + + if(!mPgpHandler->encryptDataBin(PGPHandler::pgpIdFromFingerprint(pi->second.pgp_fingerprint), + serialized_clear_mem,serialized_clear_size, + encrypted_mem,&encrypted_mem_size)) + { + RsErr() << "Cannot encrypt item for PGP Id/FPR " << pi->second.pgp_fingerprint << ". Something went wrong." ; + return; + } + encrypted_response_item->PeerId(item->PeerId()); + encrypted_response_item->bin_len = encrypted_mem_size; + encrypted_response_item->bin_data = malloc(encrypted_mem_size); + + memcpy(encrypted_response_item->bin_data,encrypted_mem,encrypted_mem_size); // Send the item. - mni->SendItem(sr_item); + mni->SendItem(encrypted_response_item); // Update the list of closest peers for all peers currently in the database. @@ -349,8 +370,6 @@ void FriendServer::run() void FriendServer::autoWash() { rstime_t now = time(nullptr); - RsDbg() << "autoWash..." ; - std::list to_remove; for(std::map::iterator it(mCurrentClientPeers.begin());it!=mCurrentClientPeers.end();++it) @@ -380,32 +399,68 @@ void FriendServer::updateClosestPeers(const RsPeerId& pid,const RsPgpFingerprint } } -void FriendServer::debugPrint() +Sha1CheckSum FriendServer::computeDataHash() { - RsDbg() << "========== FriendServer statistics ============"; - RsDbg() << " Base directory: "<< mBaseDirectory; - RsDbg() << " Random peer bias: "<< mRandomPeerBias; - RsDbg() << " Network interface: "; - RsDbg() << " Max peers in n-closest list: " << MAXIMUM_PEERS_TO_REQUEST; - RsDbg() << " Current active peers: " << mCurrentClientPeers.size() ; + librs::crypto::HashStream s(librs::crypto::HashStream::SHA1); - rstime_t now = time(nullptr); - - for(const auto& it:mCurrentClientPeers) + for(auto p(mCurrentClientPeers.begin());p!=mCurrentClientPeers.end();++p) { - RsDbg() << " " << it.first << ": nonce=" << std::hex << it.second.last_nonce << std::dec << " fpr: " << it.second.pgp_fingerprint << ", last contact: " << now - it.second.last_connection_TS << " secs ago."; - RsDbg() << " Closest peers:" ; + s << p->first; - for(const auto& pit:it.second.closest_peers) - RsDbg() << " " << pit.second << " distance=" << pit.first ; + const auto& inf(p->second); - RsDbg() << " Have added this peer:" ; + s << inf.pgp_fingerprint; + s << inf.short_certificate; + s << (uint64_t)inf.last_connection_TS; + s << inf.last_nonce; - for(const auto& pit:it.second.have_added_this_peer) - RsDbg() << " " << pit.second << " distance=" << pit.first ; + for(auto d(inf.closest_peers.begin());d!=inf.closest_peers.end();++d) + { + s << d->first ; + s << d->second; + } + for(auto d(inf.have_added_this_peer.begin());d!=inf.have_added_this_peer.end();++d) + { + s << d->first ; + s << d->second; + } } + return s.hash(); +} +void FriendServer::debugPrint(bool force) +{ + auto h = computeDataHash(); - RsDbg() << "==============================================="; + if((h != mCurrentDataHash) || force) + { + RsDbg() << "========== FriendServer statistics ============"; + RsDbg() << " Base directory: "<< mBaseDirectory; + RsDbg() << " Random peer bias: "<< mRandomPeerBias; + RsDbg() << " Current hash: "<< h; + RsDbg() << " Network interface: "; + RsDbg() << " Max peers in n-closest list: " << MAXIMUM_PEERS_TO_REQUEST; + RsDbg() << " Current active peers: " << mCurrentClientPeers.size() ; + + rstime_t now = time(nullptr); + + for(const auto& it:mCurrentClientPeers) + { + RsDbg() << " " << it.first << ": nonce=" << std::hex << it.second.last_nonce << std::dec << " fpr: " << it.second.pgp_fingerprint << ", last contact: " << now - it.second.last_connection_TS << " secs ago."; + RsDbg() << " Closest peers:" ; + + for(const auto& pit:it.second.closest_peers) + RsDbg() << " " << pit.second << " distance=" << pit.first ; + + RsDbg() << " Have added this peer:" ; + + for(const auto& pit:it.second.have_added_this_peer) + RsDbg() << " " << pit.second << " distance=" << pit.first ; + } + + RsDbg() << "==============================================="; + + mCurrentDataHash = h; + } } diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h index 202f6a1e0..4f46bebdc 100644 --- a/retroshare-friendserver/src/friendserver.h +++ b/retroshare-friendserver/src/friendserver.h @@ -75,7 +75,8 @@ private: PeerInfo::PeerDistance computePeerDistance(const RsPgpFingerprint &p1, const RsPgpFingerprint &p2); void autoWash(); - void debugPrint(); + void debugPrint(bool force); + Sha1CheckSum computeDataHash(); // Local members @@ -88,4 +89,6 @@ private: std::map mCurrentClientPeers; std::string mListeningAddress; uint16_t mListeningPort; + + Sha1CheckSum mCurrentDataHash; }; diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 6b78b988c..60abc5fd8 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -6,7 +6,7 @@ 0 0 - 726 + 738 579 From eefbd8a71086d07827a3fd8797f90ea14e5461b3 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 16 Jan 2022 21:17:10 +0100 Subject: [PATCH 2/3] fixed initing of profile passphrase for friend server manager --- libretroshare | 2 +- .../src/gui/FileTransfer/SearchDialog.h | 4 +- .../src/gui/FriendServerControl.cpp | 41 +++++-- retroshare-gui/src/gui/FriendServerControl.h | 4 +- retroshare-gui/src/gui/FriendServerControl.ui | 112 ++++++++++++------ retroshare-gui/src/gui/StartDialog.cpp | 2 +- 6 files changed, 107 insertions(+), 58 deletions(-) diff --git a/libretroshare b/libretroshare index 89b4d9c33..f03008485 160000 --- a/libretroshare +++ b/libretroshare @@ -1 +1 @@ -Subproject commit 89b4d9c3352c02630cd555918515b1412b3264ff +Subproject commit f0300848539b3decd7034e5c221eed33c1c784bc diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h index 55db103ca..25925c36d 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h @@ -21,9 +21,9 @@ #ifndef _SEARCHDIALOG_H #define _SEARCHDIALOG_H -#include +#include "retroshare/rstypes.h" #include "ui_SearchDialog.h" -#include +#include "retroshare-gui/mainpage.h" class AdvancedSearchDialog; class RSTreeWidgetItemCompareRole; diff --git a/retroshare-gui/src/gui/FriendServerControl.cpp b/retroshare-gui/src/gui/FriendServerControl.cpp index c946521e6..3cc029ecd 100644 --- a/retroshare-gui/src/gui/FriendServerControl.cpp +++ b/retroshare-gui/src/gui/FriendServerControl.cpp @@ -20,12 +20,14 @@ #include #include +#include #include #include "retroshare/rsfriendserver.h" #include "retroshare/rstor.h" #include "util/qtthreadsutils.h" +#include "util/misc.h" #include "gui/common/FilesDefs.h" #include "FriendServerControl.h" @@ -37,7 +39,7 @@ /** Constructor */ FriendServerControl::FriendServerControl(QWidget *parent) - : QWidget(parent) + : MainPage(parent) { /* Invoke the Qt Designer generated object setup routine */ setupUi(this); @@ -48,6 +50,22 @@ FriendServerControl::FriendServerControl(QWidget *parent) return; } + int H = QFontMetricsF(torServerAddress_LE->font()).height(); + + QString help_str = tr("\ +

  Friend Server

\ +

This configuration panel allows you to specify the onion address of a \ + friend server. Retroshare will talk to that server anonymously through Tor \ + and use it to acquire a fixed number of friends.

\ +

The friend server will continue supplying new friends until that number is reached \ + in particular if you add your own friends manually, the friend server may become useless \ + and you will save bandwidth disabling it. When disabling it, you will keep existing friends.

\ +

The friend server only knows your peer ID and profile public key. It doesn't know your IP address.

\ + " + ).arg(QString::number(2*H), QString::number(2*H)) ; + + registerHelpButton(helpButton,help_str,"Friend Server") ; + mConnectionCheckTimer = new QTimer; // init values @@ -69,18 +87,6 @@ FriendServerControl::FriendServerControl(QWidget *parent) serverStatusCheckResult_LB->setMovie(mCheckingServerMovie); updateFriendServerStatusIcon(false); - updateTorProxyInfo(); -} - -void FriendServerControl::updateTorProxyInfo() -{ - std::string friend_proxy_address; - uint16_t friend_proxy_port; - - RsTor::getProxyServerInfo(friend_proxy_address,friend_proxy_port); - - torProxyPort_SB->setValue(friend_proxy_port); - torProxyAddress_LE->setText(QString::fromStdString(friend_proxy_address)); } FriendServerControl::~FriendServerControl() @@ -92,7 +98,16 @@ FriendServerControl::~FriendServerControl() void FriendServerControl::onOnOffClick(bool b) { if(b) + { + if(passphrase_LE->text().isNull()) + { + QMessageBox::critical(nullptr,tr("Missing profile passphrase."),tr("Your profile passphrase is missing. Please enter is in the field below before enabling the friend server.")); + whileBlocking(friendServerOnOff_CB)->setCheckState(Qt::Unchecked); + return; + } + rsFriendServer->setProfilePassphrase(passphrase_LE->text().toStdString()); rsFriendServer->startServer(); + } else rsFriendServer->stopServer(); } diff --git a/retroshare-gui/src/gui/FriendServerControl.h b/retroshare-gui/src/gui/FriendServerControl.h index 7217bcd5d..465c5d1ec 100644 --- a/retroshare-gui/src/gui/FriendServerControl.h +++ b/retroshare-gui/src/gui/FriendServerControl.h @@ -22,9 +22,10 @@ #include +#include "retroshare-gui/mainpage.h" #include "ui_FriendServerControl.h" -class FriendServerControl : public QWidget, public Ui::FriendServerControl +class FriendServerControl : public MainPage, public Ui::FriendServerControl { Q_OBJECT @@ -37,7 +38,6 @@ protected slots: void onOnionAddressEdit(const QString&); void onOnionPortEdit(int); void onNbFriendsToRequestsChanged(int n); - void updateTorProxyInfo(); void checkServerAddress(); private: diff --git a/retroshare-gui/src/gui/FriendServerControl.ui b/retroshare-gui/src/gui/FriendServerControl.ui index 73a5625d6..2ac69969b 100644 --- a/retroshare-gui/src/gui/FriendServerControl.ui +++ b/retroshare-gui/src/gui/FriendServerControl.ui @@ -12,11 +12,48 @@ - - - On/Off - - + + + + + On/Off + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::NoFocus + + + + :/icons/help_64.png:/icons/help_64.png + + + true + + + false + + + true + + + + @@ -72,13 +109,22 @@ 0 + + <html><head/><body><p>Enter here the onion address of the Friend Server that was given to you. The address will be automatically checked after you enter it and a green bullet will appear if the server is online.</p></body></html> + .onion + + Onion address of the friend server + + + <html><head/><body><p>Communication port of the server. You usually get a server address as somestring.onion:port. The port is the number right after &quot;:&quot;</p></body></html> + 1025 @@ -107,49 +153,35 @@ - + - + - Tor proxy address: + Retroshare passphrase: - - - 127.0.0.1 + + + + 0 + 0 + + + + <html><head/><body><p>Your Retroshare login passphrase is needed to ensure the security of data exchange with the friend server.</p></body></html> + + + QLineEdit::Password + + + Your retroshare passphrase - - - 1025 - - - 65535 - - - 9050 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + Qt::Horizontal @@ -178,6 +210,8 @@ - + + + diff --git a/retroshare-gui/src/gui/StartDialog.cpp b/retroshare-gui/src/gui/StartDialog.cpp index 4a07d43c8..d6f9f707d 100644 --- a/retroshare-gui/src/gui/StartDialog.cpp +++ b/retroshare-gui/src/gui/StartDialog.cpp @@ -123,7 +123,7 @@ void StartDialog::loadPerson() rsNotify->cachePgpPassphrase(ui.password_input->text().toUtf8().constData()) ; rsNotify->setDisableAskPassword(true); - bool res = Rshare::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ; + bool res = Rshare::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ; rsNotify->setDisableAskPassword(false); rsNotify->clearPgpPassphrase(); From e7b822d1cb1679ab34afdb96120fca5a021319bf Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 17 Jan 2022 23:01:07 +0100 Subject: [PATCH 3/3] fixed bug in friend server auto wash --- libretroshare | 2 +- retroshare-friendserver/src/friendserver.cc | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libretroshare b/libretroshare index f03008485..47548627a 160000 --- a/libretroshare +++ b/libretroshare @@ -1 +1 @@ -Subproject commit f0300848539b3decd7034e5c221eed33c1c784bc +Subproject commit 47548627adddc444a5d36368bd7a5f5baeed17ba diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index 577730e73..523a76640 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -323,7 +323,7 @@ void FriendServer::removePeer(const RsPeerId& peer_id) auto tmp(fit); ++tmp; - it.second.closest_peers.erase(fit); + it.second.have_added_this_peer.erase(fit); fit=tmp; } else @@ -381,8 +381,6 @@ void FriendServer::autoWash() for(auto peer_id:to_remove) removePeer(peer_id); - - RsDbg() << "done." ; } void FriendServer::updateClosestPeers(const RsPeerId& pid,const RsPgpFingerprint& fpr)