diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 0b2fa91ec..1d500d74e 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -1189,6 +1189,8 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) if(rsEvents) { ev->mErrorMsg = errMsg; + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::NO_CERTIFICATE_SUPPLIED; + rsEvents->postEvent(std::move(ev)); } @@ -1218,7 +1220,8 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) { ev->mSslCn = sslCn; ev->mPgpId = pgpId; - ev->mErrorMsg = errMsg; + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::MISSING_AUTHENTICATION_INFO; + rsEvents->postEvent(std::move(ev)); } @@ -1237,6 +1240,8 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslId = sslId; ev->mSslCn = sslCn; ev->mErrorMsg = errMsg; + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::MISSING_AUTHENTICATION_INFO; + rsEvents->postEvent(std::move(ev)); } @@ -1266,6 +1271,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslCn = sslCn; ev->mPgpId = pgpId; ev->mErrorMsg = errorMsg; + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::MISMATCHED_PGP_ID; rsEvents->postEvent(std::move(ev)); } @@ -1290,6 +1296,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslId = sslId; ev->mSslCn = sslCn; ev->mPgpId = pgpId; + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::PGP_SIGNATURE_VALIDATION_FAILED; ev->mErrorMsg = errMsg; rsEvents->postEvent(std::move(ev)); } @@ -1311,6 +1318,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslCn = sslCn; ev->mPgpId = pgpId; ev->mErrorMsg = errMsg; + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::NOT_A_FRIEND; rsEvents->postEvent(std::move(ev)); } @@ -1330,6 +1338,8 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslId = sslId; ev->mSslCn = sslCn; ev->mPgpId = pgpId; + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::NO_ERROR; + rsEvents->postEvent(std::move(ev)); } diff --git a/libretroshare/src/pqi/authssl.h b/libretroshare/src/pqi/authssl.h index d7973e869..c38eab7ba 100644 --- a/libretroshare/src/pqi/authssl.h +++ b/libretroshare/src/pqi/authssl.h @@ -52,34 +52,6 @@ RsPeerId getCertSslId(const X509& x509); const EVP_PKEY* getPubKey(const X509& x509); }; -/** - * Event triggered by AuthSSL when authentication of a connection attempt either - * fail or success - */ -struct RsAuthSslConnectionAutenticationEvent : RsEvent -{ - RsAuthSslConnectionAutenticationEvent(); - - bool mSuccess; - RsPeerId mSslId; - std::string mSslCn; - RsPgpId mPgpId; - std::string mErrorMsg; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mSuccess); - RS_SERIAL_PROCESS(mSslId); - RS_SERIAL_PROCESS(mSslCn); - RS_SERIAL_PROCESS(mPgpId); - RS_SERIAL_PROCESS(mErrorMsg); - } -}; - - /** * This is an implementation of SSL certificate authentication with PGP * signatures, instead of centralized certification authority. diff --git a/libretroshare/src/pqi/p3notify.cc b/libretroshare/src/pqi/p3notify.cc index 621c34119..c2ce4e059 100644 --- a/libretroshare/src/pqi/p3notify.cc +++ b/libretroshare/src/pqi/p3notify.cc @@ -236,7 +236,6 @@ void p3Notify::notifyOwnStatusMessageChanged() void p3Notify::notifyDiskFull (uint32_t location , uint32_t size_limit_in_MB ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiskFull (location,size_limit_in_MB) ; } void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint32_t status ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChanged (peer_id,status) ; } void p3Notify::notifyGxsChange (const RsGxsChanges& changes) {FOR_ALL_NOTIFY_CLIENTS (*it)->notifyGxsChange(changes) ;} -void p3Notify::notifyConnectionWithoutCert () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyConnectionWithoutCert(); } void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; } void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; } diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index 3d62db9ea..879360fba 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -486,6 +486,20 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool break; } + if(rsEvents) + { + auto ev = std::unique_ptr(new RsAuthSslConnectionAutenticationEvent); + + ev->mSslId = incoming_connexion_info.sslid; + ev->mPgpId = incoming_connexion_info.gpgid; + ev->mSslCn = incoming_connexion_info.sslcn; + ev->mLocator = RsUrl(sockaddr_storage_iptostring(incoming_connexion_info.addr)); + ev->mSuccess = false; + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::MISSING_AUTHENTICATION_INFO; + + rsEvents->postEvent(std::move(ev)); + } + closeConnection(fd, incoming_connexion_info.ssl) ; pqioutput(PQL_WARNING, pqissllistenzone, "Read Error on the SSL Socket\nShutting it down!"); diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index dbb4a4cee..a2fc7abbf 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -25,6 +25,7 @@ #include #include "util/rsmemory.h" +#include "util/rsurl.h" #include "serialiser/rsserializable.h" #include "serialiser/rstypeserializer.h" @@ -170,3 +171,51 @@ public: virtual ~RsEvents(); }; + +//===================================================================================================// +// Connexion events // +//===================================================================================================// + +/** + * Event triggered by AuthSSL when authentication of a connection attempt either + * fail or success + */ +struct RsAuthSslConnectionAutenticationEvent : RsEvent +{ + RsAuthSslConnectionAutenticationEvent(); + + enum ConnextionErrorCode: uint8_t { + UNKNOWN_ERROR = 0x00, + MISSING_AUTHENTICATION_INFO = 0x01, + PGP_SIGNATURE_VALIDATION_FAILED = 0x02, + MISMATCHED_PGP_ID = 0x03, + NO_CERTIFICATE_SUPPLIED = 0x04, + NOT_A_FRIEND = 0x05, + MISSING_CERTIFICATE = 0x06, + IP_IS_BLACKLISTED = 0x07, + NO_ERROR = 0x08, + }; + + bool mSuccess; + RsPeerId mSslId; + std::string mSslCn; + RsPgpId mPgpId; + RsUrl mLocator; + std::string mErrorMsg; + ConnextionErrorCode mErrorCode; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mSuccess); + RS_SERIAL_PROCESS(mSslId); + RS_SERIAL_PROCESS(mSslCn); + RS_SERIAL_PROCESS(mPgpId); + RS_SERIAL_PROCESS(mLocator); + RS_SERIAL_PROCESS(mErrorMsg); + RS_SERIAL_PROCESS(mErrorCode); + } +}; + diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index 894d1f30d..b30c15170 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -231,7 +231,6 @@ public: virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {} virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {} virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {} - virtual void notifyConnectionWithoutCert () {} /* one or more peers has changed the states */ virtual void notifyPeerStatusChangedSummary () {} diff --git a/retroshare-gui/src/gui/AboutWidget.cpp b/retroshare-gui/src/gui/AboutWidget.cpp index c2b07a6fe..e48b34804 100644 --- a/retroshare-gui/src/gui/AboutWidget.cpp +++ b/retroshare-gui/src/gui/AboutWidget.cpp @@ -973,11 +973,13 @@ void AboutWidget::on_copy_button_clicked() verInfo+=addLibraries("libretroshare", libraries); #ifdef RS_JSONAPI - /* Add version numbers of RetroShare */ - // Add versions here. Find a better place. - libraries.clear(); - libraries.push_back(RsLibraryInfo("RestBed", restbed::get_version())); - verInfo+=addLibraries("RetroShare", libraries); +// No version number available for restbed apparently. +// +// /* Add version numbers of RetroShare */ +// // Add versions here. Find a better place. +// libraries.clear(); +// libraries.push_back(RsLibraryInfo("RestBed", restbed::get_version())); +// verInfo+=addLibraries("RetroShare", libraries); #endif /* Add version numbers of plugins */ diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 9a017270c..665817005 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -33,6 +33,7 @@ #include #include +#include "util/qtthreadsutils.h" #include "feeds/ChatMsgItem.h" #include "feeds/GxsCircleItem.h" #include "feeds/GxsChannelGroupItem.h" @@ -74,6 +75,8 @@ NewsFeed::NewsFeed(QWidget *parent) : RsAutoUpdatePage(1000,parent), ui(new Ui::NewsFeed) { + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { handleEvent(event); }, mEventHandlerId ); + /* Invoke the Qt Designer generated object setup routine */ ui->setupUi(this); @@ -123,6 +126,8 @@ QString hlp_str = tr( NewsFeed::~NewsFeed() { + rsEvents->unregisterEventsHandler(mEventHandlerId); + // save settings processSettings(false); @@ -176,6 +181,88 @@ void NewsFeed::sortChanged(int index) ui->feedWidget->setSortRole(ROLE_RECEIVED, sortOrder); } +// handler for the new notification system in libretroshare. + +void NewsFeed::handleEvent(std::shared_ptr event) +{ + uint flags = Settings->getNewsFeedFlags(); + + const RsAuthSslConnectionAutenticationEvent *pssl_e = dynamic_cast(event.get()); + + if(pssl_e != nullptr && (flags & (RS_FEED_TYPE_SECURITY | RS_FEED_TYPE_PEER))) + { + RsAuthSslConnectionAutenticationEvent e = *pssl_e; // make a copy because we lose memory ownership here + + RsQThreadUtils::postToObject( [=]() + { + /* Here it goes any code you want to be executed on the Qt Gui + * thread, for example to update the data model with new information + * after a blocking call to RetroShare API complete, note that + * Qt::QueuedConnection is important! + */ + handleSecurityEvent(e); + + }, this ); + } +} + +void NewsFeed::handleSecurityEvent(const RsAuthSslConnectionAutenticationEvent& e) +{ + std::cerr << "NotifyQt: handling connection security event from (" << e.mSslId << "," << e.mPgpId << ") error code: " << e.mErrorCode << std::endl; + uint flags = Settings->getNewsFeedFlags(); + + if(e.mSuccess) + if(flags & RS_FEED_TYPE_PEER) + { + addFeedItem(new PeerItem(this, NEWSFEED_PEERLIST, e.mSslId, PEER_TYPE_CONNECT, false)); + return; + } + else + return; + + uint32_t FeedItemType=0; + + switch(e.mErrorCode) + { + case RsAuthSslConnectionAutenticationEvent::NO_CERTIFICATE_SUPPLIED: + case RsAuthSslConnectionAutenticationEvent::MISMATCHED_PGP_ID: // fallthrough + case RsAuthSslConnectionAutenticationEvent::MISSING_AUTHENTICATION_INFO: FeedItemType = RS_FEED_ITEM_SEC_BAD_CERTIFICATE; + break; + + case RsAuthSslConnectionAutenticationEvent::PGP_SIGNATURE_VALIDATION_FAILED: FeedItemType = RS_FEED_ITEM_SEC_WRONG_SIGNATURE; + break; + + case RsAuthSslConnectionAutenticationEvent::NOT_A_FRIEND: FeedItemType = RS_FEED_ITEM_SEC_AUTH_DENIED; + break; + + case RsAuthSslConnectionAutenticationEvent::IP_IS_BLACKLISTED: FeedItemType = RS_FEED_ITEM_SEC_IP_BLACKLISTED; + break; + + case RsAuthSslConnectionAutenticationEvent::MISSING_CERTIFICATE: FeedItemType = RS_FEED_ITEM_SEC_MISSING_CERTIFICATE; + break; + + default: + return; // display nothing + } + + RsPeerDetails det; + rsPeers->getPeerDetails(e.mSslId,det) || rsPeers->getGPGDetails(e.mPgpId,det); + + addFeedItemIfUnique(new SecurityItem(this, + NEWSFEED_SECLIST, + det.gpg_id, det.id, + det.location, + e.mLocator.toString(), + FeedItemType, + false), + RS_FEED_ITEM_SEC_BAD_CERTIFICATE, + det.gpg_id.toStdString(), + std::string(), + std::string(), + std::string(), + true ); +} + void NewsFeed::updateDisplay() { if (!rsNotify) diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h index 3b91774ce..097260913 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -83,6 +83,8 @@ public: virtual void updateDisplay(); + void handleEvent(std::shared_ptr event); // get events from libretroshare + signals: void newsFeedChanged(int count); @@ -100,6 +102,8 @@ private slots: void sendNewsFeedChanged(); private: + void handleSecurityEvent(const RsAuthSslConnectionAutenticationEvent& e); + void addFeedItem(FeedItem *item); void addFeedItemIfUnique(FeedItem *item, int itemType, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, bool replace); void remUniqueFeedItem(FeedItem *item, int itemType, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4); @@ -165,6 +169,8 @@ private: /* UI - from Designer */ Ui::NewsFeed *ui; + + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 5d1a2396f..d4ffa44b7 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -89,6 +89,10 @@ void NotifyQt::SetDisableAll(bool bValue) } } +NotifyQt::~NotifyQt() +{ +} + NotifyQt::NotifyQt() : cDialog(NULL) { runningToasterTimer = new QTimer(this); @@ -492,20 +496,6 @@ void NotifyQt::notifyChatLobbyTimeShift(int shift) emit chatLobbyTimeShift(shift) ; } -void NotifyQt::notifyConnectionWithoutCert() -{ - { - QMutexLocker m(&_mutex) ; - if(!_enabled) - return ; - } - -#ifdef NOTIFY_DEBUG - std::cerr << "notifyQt: Received notifyConnectionWithoutCert" << std::endl; -#endif - emit connectionWithoutCert(); -} - void NotifyQt::handleChatLobbyTimeShift(int /*shift*/) { return ; // we say nothing. The help dialog of lobbies explains this already. diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index de0fb7aca..82376304c 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -56,7 +56,7 @@ class NotifyQt: public QObject, public NotifyClient static bool isAllDisable(); void enable() ; - virtual ~NotifyQt() { return; } + virtual ~NotifyQt() ; void setNetworkDialog(NetworkDialog *c) { cDialog = c; } @@ -76,7 +76,6 @@ class NotifyQt: public QObject, public NotifyClient virtual void notifyOwnAvatarChanged() ; virtual void notifyChatLobbyEvent(uint64_t /* lobby id */, uint32_t /* event type */, const RsGxsId & /*nickname*/, const std::string& /* any string */) ; virtual void notifyChatLobbyTimeShift(int time_shift) ; - void notifyConnectionWithoutCert(); virtual void notifyOwnStatusMessageChanged() ; virtual void notifyDiskFull(uint32_t loc,uint32_t size_in_mb) ;