mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-07-31 18:29:02 -04:00
Merge pull request #1565 from G10h4ck/short_invites_v2
Short invites support for libretroshare
This commit is contained in:
commit
dac76439bd
11 changed files with 459 additions and 19 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include "retroshare/rsiface.h"
|
#include "retroshare/rsiface.h"
|
||||||
#include "rsserver/p3face.h"
|
#include "rsserver/p3face.h"
|
||||||
#include "util/rsdebug.h"
|
#include "util/rsdebug.h"
|
||||||
|
#include "retroshare/rspeers.h"
|
||||||
|
|
||||||
/****
|
/****
|
||||||
* #define P3DISC_DEBUG 1
|
* #define P3DISC_DEBUG 1
|
||||||
|
@ -1249,9 +1250,25 @@ void p3discovery2::recvInvite(
|
||||||
|
|
||||||
void p3discovery2::rsEventsHandler(const RsEvent& event)
|
void p3discovery2::rsEventsHandler(const RsEvent& event)
|
||||||
{
|
{
|
||||||
|
Dbg3() << __PRETTY_FUNCTION__ << " " << static_cast<uint32_t>(event.mType)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
switch(event.mType)
|
switch(event.mType)
|
||||||
{
|
{
|
||||||
// TODO: When an SSL-only friend become online requestInvite(...)
|
case RsEventType::PEER_STATE_CHANGED:
|
||||||
|
{
|
||||||
|
const RsPeerId& sslId =
|
||||||
|
static_cast<const RsPeerStateChangedEvent&>(event).mSslId;
|
||||||
|
if( rsPeers && rsPeers->isSslOnlyFriend(sslId) &&
|
||||||
|
mServiceCtrl->isPeerConnected(
|
||||||
|
getServiceInfo().mServiceType, sslId ) )
|
||||||
|
{
|
||||||
|
if(!requestInvite(sslId, sslId))
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " requestInvite to peer "
|
||||||
|
<< sslId << " failed" << std::endl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1196,6 +1196,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
|
||||||
std::string sslCn = RsX509Cert::getCertIssuerString(*x509Cert);
|
std::string sslCn = RsX509Cert::getCertIssuerString(*x509Cert);
|
||||||
RsPgpId pgpId(sslCn);
|
RsPgpId pgpId(sslCn);
|
||||||
|
|
||||||
|
|
||||||
if(sslId.isNull())
|
if(sslId.isNull())
|
||||||
{
|
{
|
||||||
std::string errMsg = "x509Cert has invalid sslId!";
|
std::string errMsg = "x509Cert has invalid sslId!";
|
||||||
|
@ -1231,8 +1232,10 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
|
||||||
return verificationFailed;
|
return verificationFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isSslOnlyFriend = rsPeers->isSslOnlyFriend(sslId);
|
||||||
|
|
||||||
uint32_t auth_diagnostic;
|
uint32_t auth_diagnostic;
|
||||||
if(!AuthX509WithGPG(x509Cert, auth_diagnostic))
|
if(!isSslOnlyFriend && !AuthX509WithGPG(x509Cert, auth_diagnostic))
|
||||||
{
|
{
|
||||||
std::string errMsg = "Certificate was rejected because PGP "
|
std::string errMsg = "Certificate was rejected because PGP "
|
||||||
"signature verification failed with diagnostic: "
|
"signature verification failed with diagnostic: "
|
||||||
|
@ -1255,7 +1258,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
|
||||||
return verificationFailed;
|
return verificationFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
if ( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||||
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
||||||
{
|
{
|
||||||
std::string errMsg = "Connection attempt signed by PGP key id: " +
|
std::string errMsg = "Connection attempt signed by PGP key id: " +
|
||||||
|
@ -1279,7 +1282,9 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
|
||||||
setCurrentConnectionAttemptInfo(pgpId, sslId, sslCn);
|
setCurrentConnectionAttemptInfo(pgpId, sslId, sslCn);
|
||||||
LocalStoreCert(x509Cert);
|
LocalStoreCert(x509Cert);
|
||||||
|
|
||||||
Dbg1() << __PRETTY_FUNCTION__ << " authentication successfull!" << std::endl;
|
RsInfo() << __PRETTY_FUNCTION__ << " authentication successfull for "
|
||||||
|
<< "sslId: " << sslId << " isSslOnlyFriend: " << isSslOnlyFriend
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
if(rsEvents)
|
if(rsEvents)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1029,6 +1029,73 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool p3PeerMgrIMPL::addSslOnlyFriend(
|
||||||
|
const RsPeerId& sslId, const RsPeerDetails& dt )
|
||||||
|
{
|
||||||
|
if(sslId.isNull() || sslId == getOwnId()) return false;
|
||||||
|
|
||||||
|
peerState pstate;
|
||||||
|
|
||||||
|
{ RS_STACK_MUTEX(mPeerMtx);
|
||||||
|
|
||||||
|
/* If in mOthersList -> move over */
|
||||||
|
auto it = mOthersList.find(sslId);
|
||||||
|
if (it != mOthersList.end())
|
||||||
|
{
|
||||||
|
pstate = it->second;
|
||||||
|
mOthersList.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // RS_STACK_MUTEX(mPeerMtx);
|
||||||
|
|
||||||
|
pstate.id = sslId;
|
||||||
|
|
||||||
|
if(!dt.name.empty()) pstate.name = dt.name;
|
||||||
|
if(!dt.dyndns.empty()) pstate.dyndns = dt.dyndns;
|
||||||
|
pstate.hiddenNode = dt.isHiddenNode;
|
||||||
|
if(!dt.hiddenNodeAddress.empty())
|
||||||
|
pstate.hiddenDomain = dt.hiddenNodeAddress;
|
||||||
|
if(dt.hiddenNodePort) pstate.hiddenPort = dt.hiddenNodePort;
|
||||||
|
if(dt.hiddenType) pstate.hiddenType = dt.hiddenType;
|
||||||
|
if(!dt.location.empty()) pstate.location = dt.location;
|
||||||
|
|
||||||
|
{ RS_STACK_MUTEX(mPeerMtx);
|
||||||
|
|
||||||
|
mFriendList[sslId] = pstate;
|
||||||
|
mStatusChanged = true;
|
||||||
|
|
||||||
|
} // RS_STACK_MUTEX(mPeerMtx);
|
||||||
|
|
||||||
|
IndicateConfigChanged();
|
||||||
|
mLinkMgr->addFriend(sslId, dt.vs_dht != RS_VS_DHT_OFF);
|
||||||
|
|
||||||
|
// To update IP addresses is much more confortable to use locators
|
||||||
|
if(!dt.isHiddenNode)
|
||||||
|
{
|
||||||
|
for(const std::string& locator : dt.ipAddressList)
|
||||||
|
addPeerLocator(sslId, locator);
|
||||||
|
|
||||||
|
if(dt.extPort && !dt.extAddr.empty())
|
||||||
|
{
|
||||||
|
RsUrl locator;
|
||||||
|
locator.setScheme("ipv4").setHost(dt.extAddr)
|
||||||
|
.setPort(dt.extPort);
|
||||||
|
addPeerLocator(sslId, locator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dt.localPort && !dt.localAddr.empty())
|
||||||
|
{
|
||||||
|
RsUrl locator;
|
||||||
|
locator.setScheme("ipv4").setHost(dt.localAddr)
|
||||||
|
.setPort(dt.localPort);
|
||||||
|
addPeerLocator(sslId, locator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool p3PeerMgrIMPL::removeFriend(const RsPgpId &id)
|
bool p3PeerMgrIMPL::removeFriend(const RsPgpId &id)
|
||||||
{
|
{
|
||||||
#ifdef PEER_DEBUG
|
#ifdef PEER_DEBUG
|
||||||
|
@ -2344,7 +2411,15 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
|
||||||
#endif
|
#endif
|
||||||
/* ************* */
|
/* ************* */
|
||||||
// permission flags is used as a mask for the existing perms, so we set it to 0xffff
|
// permission flags is used as a mask for the existing perms, so we set it to 0xffff
|
||||||
addFriend(peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL);
|
if(!addFriend( peer_id, peer_pgp_id, pitem->netMode,
|
||||||
|
pitem->vs_disc, pitem->vs_dht,
|
||||||
|
pitem->lastContact, RS_NODE_PERM_ALL ))
|
||||||
|
{
|
||||||
|
RsInfo() << __PRETTY_FUNCTION__ << " loading SSL-only "
|
||||||
|
<< "friend: " << peer_id << " " << pitem->location
|
||||||
|
<< std::endl;
|
||||||
|
addSslOnlyFriend(peer_id);
|
||||||
|
}
|
||||||
setLocation(pitem->nodePeerId, pitem->location);
|
setLocation(pitem->nodePeerId, pitem->location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,10 @@ public:
|
||||||
rstime_t lastContact = 0,
|
rstime_t lastContact = 0,
|
||||||
ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT) ) = 0;
|
ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT) ) = 0;
|
||||||
|
|
||||||
|
virtual bool addSslOnlyFriend(
|
||||||
|
const RsPeerId& sslId,
|
||||||
|
const RsPeerDetails& details = RsPeerDetails() ) = 0;
|
||||||
|
|
||||||
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId) = 0;
|
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId) = 0;
|
||||||
virtual bool isFriend(const RsPeerId& ssl_id) = 0;
|
virtual bool isFriend(const RsPeerId& ssl_id) = 0;
|
||||||
|
|
||||||
|
@ -242,6 +246,11 @@ public:
|
||||||
virtual bool addFriend(const RsPeerId&ssl_id, const RsPgpId&gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
|
virtual bool addFriend(const RsPeerId&ssl_id, const RsPgpId&gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
|
||||||
uint16_t vsDisc = RS_VS_DISC_FULL, uint16_t vsDht = RS_VS_DHT_FULL,
|
uint16_t vsDisc = RS_VS_DISC_FULL, uint16_t vsDht = RS_VS_DHT_FULL,
|
||||||
rstime_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT));
|
rstime_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT));
|
||||||
|
|
||||||
|
bool addSslOnlyFriend(
|
||||||
|
const RsPeerId& sslId,
|
||||||
|
const RsPeerDetails& details = RsPeerDetails() ) override;
|
||||||
|
|
||||||
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId);
|
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId);
|
||||||
virtual bool removeFriend(const RsPgpId &pgp_id);
|
virtual bool removeFriend(const RsPgpId &pgp_id);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "rsitems/rsnxsitems.h"
|
#include "rsitems/rsnxsitems.h"
|
||||||
#include "pqi/p3cfgmgr.h"
|
#include "pqi/p3cfgmgr.h"
|
||||||
#include "pqi/pqiservice.h"
|
#include "pqi/pqiservice.h"
|
||||||
|
#include "retroshare/rspeers.h"
|
||||||
|
#include "retroshare/rsevents.h"
|
||||||
|
|
||||||
/*******************************/
|
/*******************************/
|
||||||
// #define SERVICECONTROL_DEBUG 1
|
// #define SERVICECONTROL_DEBUG 1
|
||||||
|
@ -756,6 +758,12 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId)
|
||||||
mPeerFilterMap[peerId] = peerFilter;
|
mPeerFilterMap[peerId] = peerFilter;
|
||||||
}
|
}
|
||||||
recordFilterChanges_locked(peerId, originalFilter, peerFilter);
|
recordFilterChanges_locked(peerId, originalFilter, peerFilter);
|
||||||
|
|
||||||
|
using Evt_t = RsPeerStateChangedEvent;
|
||||||
|
std::shared_ptr<RsEvents> lockedRsEvents = rsEvents;
|
||||||
|
if(lockedRsEvents)
|
||||||
|
lockedRsEvents->postEvent(std::unique_ptr<Evt_t>(new Evt_t(peerId)));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "pqi/pqissllistener.h"
|
#include "pqi/pqissllistener.h"
|
||||||
|
|
||||||
#include "pqi/p3linkmgr.h"
|
#include "pqi/p3linkmgr.h"
|
||||||
#include <retroshare/rspeers.h>
|
#include "retroshare/rspeers.h"
|
||||||
#include <retroshare/rsdht.h>
|
#include <retroshare/rsdht.h>
|
||||||
#include <retroshare/rsbanlist.h>
|
#include <retroshare/rsbanlist.h>
|
||||||
|
|
||||||
|
@ -1180,10 +1180,13 @@ int pqissl::Authorise_SSL_Connection()
|
||||||
|
|
||||||
/* At this point the actual connection authentication has already been
|
/* At this point the actual connection authentication has already been
|
||||||
* performed in AuthSSL::VerifyX509Callback, any furter authentication check
|
* performed in AuthSSL::VerifyX509Callback, any furter authentication check
|
||||||
* like the following two are redundant. */
|
* like the followings are redundant. */
|
||||||
|
|
||||||
|
bool isSslOnlyFriend = rsPeers->isSslOnlyFriend(certPeerId);
|
||||||
|
|
||||||
uint32_t authErrCode = 0;
|
uint32_t authErrCode = 0;
|
||||||
if(!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode))
|
if( !isSslOnlyFriend &&
|
||||||
|
!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode) )
|
||||||
{
|
{
|
||||||
RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
|
RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
|
||||||
<< "certificate signature. This should never happen at this "
|
<< "certificate signature. This should never happen at this "
|
||||||
|
@ -1195,7 +1198,7 @@ int pqissl::Authorise_SSL_Connection()
|
||||||
}
|
}
|
||||||
|
|
||||||
RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert);
|
RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert);
|
||||||
if( pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||||
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
||||||
{
|
{
|
||||||
RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
|
RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
|
||||||
|
|
|
@ -784,10 +784,13 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
|
||||||
#ifdef RS_PQISSL_AUTH_DOUBLE_CHECK
|
#ifdef RS_PQISSL_AUTH_DOUBLE_CHECK
|
||||||
/* At this point the actual connection authentication has already been
|
/* At this point the actual connection authentication has already been
|
||||||
* performed in AuthSSL::VerifyX509Callback, any furter authentication check
|
* performed in AuthSSL::VerifyX509Callback, any furter authentication check
|
||||||
* like the following two are redundant. */
|
* like the followings are redundant. */
|
||||||
|
|
||||||
|
bool isSslOnlyFriend = rsPeers->isSslOnlyFriend(newPeerId);
|
||||||
|
|
||||||
uint32_t authErrCode = 0;
|
uint32_t authErrCode = 0;
|
||||||
if(!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode))
|
if( !isSslOnlyFriend &&
|
||||||
|
!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode) )
|
||||||
{
|
{
|
||||||
RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
|
RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
|
||||||
<< "certificate signature. This should never happen at this "
|
<< "certificate signature. This should never happen at this "
|
||||||
|
@ -798,7 +801,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
|
||||||
exit(failure);
|
exit(failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||||
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
||||||
{
|
{
|
||||||
RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
|
RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
|
||||||
|
@ -822,7 +825,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
|
||||||
else ++it;
|
else ++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found == false)
|
if (!found)
|
||||||
{
|
{
|
||||||
Dbg1() << __PRETTY_FUNCTION__ << " got secure connection from address: "
|
Dbg1() << __PRETTY_FUNCTION__ << " got secure connection from address: "
|
||||||
<< info.addr << " with previously unknown SSL certificate: "
|
<< info.addr << " with previously unknown SSL certificate: "
|
||||||
|
|
|
@ -63,6 +63,9 @@ enum class RsEventType : uint32_t
|
||||||
/// @see RsGxsChanges
|
/// @see RsGxsChanges
|
||||||
GXS_CHANGES = 5,
|
GXS_CHANGES = 5,
|
||||||
|
|
||||||
|
/// Emitted when a peer state changes, @see RsPeers
|
||||||
|
PEER_STATE_CHANGED = 6,
|
||||||
|
|
||||||
MAX /// Used to detect invalid event type passed
|
MAX /// Used to detect invalid event type passed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "util/rsurl.h"
|
#include "util/rsurl.h"
|
||||||
#include "util/rsdeprecate.h"
|
#include "util/rsdeprecate.h"
|
||||||
#include "util/rstime.h"
|
#include "util/rstime.h"
|
||||||
|
#include "retroshare/rsevents.h"
|
||||||
|
|
||||||
class RsPeers;
|
class RsPeers;
|
||||||
|
|
||||||
|
@ -358,6 +359,23 @@ struct RsGroupInfo : RsSerializable
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Event emitted when a peer change state */
|
||||||
|
struct RsPeerStateChangedEvent : RsEvent
|
||||||
|
{
|
||||||
|
/// @param[in] sslId is of the peer which changed state
|
||||||
|
RsPeerStateChangedEvent(RsPeerId sslId);
|
||||||
|
|
||||||
|
/// Storage fot the id of the peer that changed state
|
||||||
|
RsPeerId mSslId;
|
||||||
|
|
||||||
|
void serial_process( RsGenericSerializer::SerializeJob j,
|
||||||
|
RsGenericSerializer::SerializeContext& ctx) override
|
||||||
|
{
|
||||||
|
RsEvent::serial_process(j, ctx);
|
||||||
|
RS_SERIAL_PROCESS(mSslId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** The Main Interface Class - for information about your Peers
|
/** The Main Interface Class - for information about your Peers
|
||||||
* A peer is another RS instance, means associated with an SSL certificate
|
* A peer is another RS instance, means associated with an SSL certificate
|
||||||
* A same GPG person can have multiple peer running with different SSL certs
|
* A same GPG person can have multiple peer running with different SSL certs
|
||||||
|
@ -434,6 +452,16 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool isPgpFriend(const RsPgpId& pgpId) = 0;
|
virtual bool isPgpFriend(const RsPgpId& pgpId) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if given peer is a trusted SSL node pending PGP approval
|
||||||
|
* Peers added through short invite remain in this state as long as their
|
||||||
|
* PGP key is not received and verified/approved by the user.
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @param[in] sslId id of the peer to check
|
||||||
|
* @return true if the node is trusted, false otherwise
|
||||||
|
*/
|
||||||
|
virtual bool isSslOnlyFriend(const RsPeerId& sslId) = 0;
|
||||||
|
|
||||||
virtual std::string getPeerName(const RsPeerId &ssl_id) = 0;
|
virtual std::string getPeerName(const RsPeerId &ssl_id) = 0;
|
||||||
virtual std::string getGPGName(const RsPgpId& gpg_id) = 0;
|
virtual std::string getGPGName(const RsPgpId& gpg_id) = 0;
|
||||||
|
|
||||||
|
@ -474,9 +502,25 @@ public:
|
||||||
* @param[in] flags service permissions flag
|
* @param[in] flags service permissions flag
|
||||||
* @return false if error occurred, true otherwise
|
* @return false if error occurred, true otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool addFriend( const RsPeerId &sslId, const RsPgpId& gpgId,
|
virtual bool addFriend(
|
||||||
|
const RsPeerId& sslId, const RsPgpId& gpgId,
|
||||||
ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0;
|
ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add SSL-only trusted node
|
||||||
|
* When adding an SSL-only node, it is authorized to connect. Every time a
|
||||||
|
* connection is established the user is notified about the need to verify
|
||||||
|
* the PGP fingerprint, until she does, at that point the node become a full
|
||||||
|
* SSL+PGP friend.
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @param[in] sslId SSL id of the node to add
|
||||||
|
* @param[in] details Optional extra details known about the node to add
|
||||||
|
* @return false if error occurred, true otherwise
|
||||||
|
*/
|
||||||
|
virtual bool addSslOnlyFriend(
|
||||||
|
const RsPeerId& sslId,
|
||||||
|
const RsPeerDetails& details = RsPeerDetails() ) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Revoke connection trust from to node
|
* @brief Revoke connection trust from to node
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
|
@ -597,6 +641,38 @@ public:
|
||||||
bool includeSignatures = false,
|
bool includeSignatures = false,
|
||||||
bool includeExtraLocators = true ) = 0;
|
bool includeExtraLocators = true ) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get RetroShare short invite of the given peer
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @param[out] invite storage for the generated invite
|
||||||
|
* @param[in] sslId Id of the peer of which we want to generate an invite,
|
||||||
|
* a null id (all 0) is passed, an invite for own node is returned.
|
||||||
|
* @param[in] formatRadix true to get in base64 format false to get URL.
|
||||||
|
* @param[in] bareBones true to get smallest invite, which miss also
|
||||||
|
* the information necessary to attempt an outgoing connection, but still
|
||||||
|
* enough to accept an incoming one.
|
||||||
|
* @param[in] baseUrl URL into which to sneak in the RetroShare invite
|
||||||
|
* radix, this is primarly useful to trick other applications into making
|
||||||
|
* the invite clickable, or to disguise the RetroShare invite into a
|
||||||
|
* "normal" looking web link. Used only if formatRadix is false.
|
||||||
|
* @return false if error occurred, true otherwise
|
||||||
|
*/
|
||||||
|
virtual bool getShortInvite(
|
||||||
|
std::string& invite, const RsPeerId& sslId = RsPeerId(),
|
||||||
|
bool formatRadix = false, bool bareBones = false,
|
||||||
|
const std::string& baseUrl = "https://retroshare.me/" ) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse the give short invite to extract contained information
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @param[in] invite string containing the short invite to parse
|
||||||
|
* @param[out] details storage for the extracted information, consider it
|
||||||
|
* valid only if the function return true
|
||||||
|
* @return false if error occurred, true otherwise
|
||||||
|
*/
|
||||||
|
virtual bool parseShortInvite(
|
||||||
|
const std::string& invite, RsPeerDetails& details ) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add trusted node from invite
|
* @brief Add trusted node from invite
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
|
@ -749,6 +825,3 @@ public:
|
||||||
RS_DEPRECATED_FOR(isPgpFriend)
|
RS_DEPRECATED_FOR(isPgpFriend)
|
||||||
virtual bool isGPGAccepted(const RsPgpId &gpg_id_is_friend) = 0;
|
virtual bool isGPGAccepted(const RsPgpId &gpg_id_is_friend) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -570,6 +570,9 @@ std::string p3Peers::getGPGName(const RsPgpId &gpg_id)
|
||||||
bool p3Peers::isPgpFriend(const RsPgpId& pgpId)
|
bool p3Peers::isPgpFriend(const RsPgpId& pgpId)
|
||||||
{ return AuthGPG::getAuthGPG()->isGPGAccepted(pgpId); }
|
{ return AuthGPG::getAuthGPG()->isGPGAccepted(pgpId); }
|
||||||
|
|
||||||
|
bool p3Peers::isSslOnlyFriend(const RsPeerId& sslId)
|
||||||
|
{ return isFriend(sslId) && !isPgpFriend(getGPGId(sslId)); }
|
||||||
|
|
||||||
bool p3Peers::isGPGAccepted(const RsPgpId &gpg_id_is_friend)
|
bool p3Peers::isGPGAccepted(const RsPgpId &gpg_id_is_friend)
|
||||||
{ return isPgpFriend(gpg_id_is_friend); }
|
{ return isPgpFriend(gpg_id_is_friend); }
|
||||||
|
|
||||||
|
@ -749,6 +752,10 @@ bool p3Peers::addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePe
|
||||||
return mPeerMgr->addFriend(ssl_id, gpg_id, RS_NET_MODE_UDP, RS_VS_DISC_FULL, RS_VS_DHT_FULL, now, perm_flags);
|
return mPeerMgr->addFriend(ssl_id, gpg_id, RS_NET_MODE_UDP, RS_VS_DISC_FULL, RS_VS_DHT_FULL, now, perm_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool p3Peers::addSslOnlyFriend(
|
||||||
|
const RsPeerId& sslId, const RsPeerDetails& details )
|
||||||
|
{ return mPeerMgr->addSslOnlyFriend(sslId, details); }
|
||||||
|
|
||||||
bool p3Peers::removeKeysFromPGPKeyring(const std::set<RsPgpId>& pgp_ids,std::string& backup_file,uint32_t& error_code)
|
bool p3Peers::removeKeysFromPGPKeyring(const std::set<RsPgpId>& pgp_ids,std::string& backup_file,uint32_t& error_code)
|
||||||
{
|
{
|
||||||
return AuthGPG::getAuthGPG()->removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ;
|
return AuthGPG::getAuthGPG()->removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ;
|
||||||
|
@ -1104,6 +1111,223 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( const RsPgpId& gpg_id,
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class RsShortInviteFieldType : uint8_t
|
||||||
|
{
|
||||||
|
SSL_ID = 0x00,
|
||||||
|
PEER_NAME = 0x01,
|
||||||
|
LOCATOR = 0x02,
|
||||||
|
|
||||||
|
/* The following will be deprecated, and ported to LOCATOR when generic
|
||||||
|
* trasport layer will be implemented */
|
||||||
|
HIDDEN_LOCATOR = 0x90,
|
||||||
|
DNS_LOCATOR = 0x91,
|
||||||
|
EXT4_LOCATOR = 0x92,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool p3Peers::getShortInvite(
|
||||||
|
std::string& invite, const RsPeerId& _sslId, bool formatRadix,
|
||||||
|
bool bareBones, const std::string& baseUrl )
|
||||||
|
{
|
||||||
|
RsPeerId sslId = _sslId;
|
||||||
|
if(sslId.isNull()) sslId = getOwnId();
|
||||||
|
|
||||||
|
RsPeerDetails tDetails;
|
||||||
|
if(!getPeerDetails(sslId, tDetails)) return false;
|
||||||
|
|
||||||
|
std::vector<uint8_t> inviteBuf(1000, 0);
|
||||||
|
RsGenericSerializer::SerializeContext ctx(
|
||||||
|
inviteBuf.data(), static_cast<uint32_t>(inviteBuf.size()));
|
||||||
|
RsGenericSerializer::SerializeJob j = RsGenericSerializer::SERIALIZE;
|
||||||
|
|
||||||
|
RsShortInviteFieldType tType = RsShortInviteFieldType::SSL_ID;
|
||||||
|
RS_SERIAL_PROCESS(tType);
|
||||||
|
RS_SERIAL_PROCESS(sslId);
|
||||||
|
|
||||||
|
tType = RsShortInviteFieldType::PEER_NAME;
|
||||||
|
RS_SERIAL_PROCESS(tType);
|
||||||
|
RS_SERIAL_PROCESS(tDetails.name);
|
||||||
|
|
||||||
|
if(!bareBones)
|
||||||
|
{
|
||||||
|
/* If is hidden use hidden address and port as locator, else if we have
|
||||||
|
* a valid dyndns and extPort use that as locator, else if we have a
|
||||||
|
* valid extAddr and extPort use that as locator, otherwise use most
|
||||||
|
* recently known locator */
|
||||||
|
sockaddr_storage tExt;
|
||||||
|
if(tDetails.isHiddenNode)
|
||||||
|
{
|
||||||
|
tType = RsShortInviteFieldType::HIDDEN_LOCATOR;
|
||||||
|
RS_SERIAL_PROCESS(tType);
|
||||||
|
RS_SERIAL_PROCESS(tDetails.hiddenType);
|
||||||
|
RS_SERIAL_PROCESS(tDetails.hiddenNodeAddress);
|
||||||
|
RS_SERIAL_PROCESS(tDetails.hiddenNodePort);
|
||||||
|
}
|
||||||
|
else if( !tDetails.dyndns.empty() &&
|
||||||
|
(tDetails.extPort || tDetails.localPort) )
|
||||||
|
{
|
||||||
|
uint16_t tPort = tDetails.extPort ?
|
||||||
|
tDetails.extPort : tDetails.localPort;
|
||||||
|
tType = RsShortInviteFieldType::DNS_LOCATOR;
|
||||||
|
RS_SERIAL_PROCESS(tType);
|
||||||
|
RS_SERIAL_PROCESS(tDetails.dyndns);
|
||||||
|
RS_SERIAL_PROCESS(tPort);
|
||||||
|
}
|
||||||
|
else if( sockaddr_storage_inet_pton(tExt, tDetails.extAddr) &&
|
||||||
|
sockaddr_storage_isValidNet(tExt) &&
|
||||||
|
sockaddr_storage_ipv6_to_ipv4(tExt) &&
|
||||||
|
tDetails.extPort )
|
||||||
|
{
|
||||||
|
uint32_t t4Addr =
|
||||||
|
reinterpret_cast<sockaddr_in&>(tExt).sin_addr.s_addr;
|
||||||
|
|
||||||
|
tType = RsShortInviteFieldType::EXT4_LOCATOR;
|
||||||
|
RS_SERIAL_PROCESS(tType);
|
||||||
|
RS_SERIAL_PROCESS(t4Addr);
|
||||||
|
RS_SERIAL_PROCESS(tDetails.extPort);
|
||||||
|
}
|
||||||
|
else if(!tDetails.ipAddressList.empty())
|
||||||
|
{
|
||||||
|
const std::string& tLc = tDetails.ipAddressList.front();
|
||||||
|
std::string tLocator = tLc.substr(0, tLc.find_first_of(" ")-1);
|
||||||
|
tType = RsShortInviteFieldType::LOCATOR;
|
||||||
|
RS_SERIAL_PROCESS(tType);
|
||||||
|
RS_SERIAL_PROCESS(tLocator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Radix64::encode(ctx.mData, static_cast<int>(ctx.mOffset), invite);
|
||||||
|
|
||||||
|
if(!formatRadix)
|
||||||
|
{
|
||||||
|
RsUrl inviteUrl(baseUrl);
|
||||||
|
inviteUrl.setQueryKV("rsInvite", invite);
|
||||||
|
invite = inviteUrl.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.mOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3Peers::parseShortInvite(
|
||||||
|
const std::string& inviteStrUrl, RsPeerDetails& details )
|
||||||
|
{
|
||||||
|
if(inviteStrUrl.empty())
|
||||||
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " can't parse empty invite"
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string* rsInvite = &inviteStrUrl;
|
||||||
|
|
||||||
|
RsUrl inviteUrl(inviteStrUrl);
|
||||||
|
if(inviteUrl.hasQueryK("rsInvite"))
|
||||||
|
rsInvite = inviteUrl.getQueryV("rsInvite");
|
||||||
|
|
||||||
|
std::vector<uint8_t> inviteBuf = Radix64::decode(*rsInvite);
|
||||||
|
RsGenericSerializer::SerializeContext ctx(
|
||||||
|
inviteBuf.data(), static_cast<uint32_t>(inviteBuf.size()));
|
||||||
|
RsGenericSerializer::SerializeJob j = RsGenericSerializer::DESERIALIZE;
|
||||||
|
|
||||||
|
while(ctx.mOk && ctx.mOffset < ctx.mSize)
|
||||||
|
{
|
||||||
|
RsShortInviteFieldType fieldType;
|
||||||
|
RS_SERIAL_PROCESS(fieldType);
|
||||||
|
|
||||||
|
if(!ctx.mOk)
|
||||||
|
{
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " failed to parse fieldType"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (fieldType)
|
||||||
|
{
|
||||||
|
case RsShortInviteFieldType::SSL_ID:
|
||||||
|
RS_SERIAL_PROCESS(details.id);
|
||||||
|
break;
|
||||||
|
case RsShortInviteFieldType::PEER_NAME:
|
||||||
|
RS_SERIAL_PROCESS(details.name);
|
||||||
|
break;
|
||||||
|
case RsShortInviteFieldType::LOCATOR:
|
||||||
|
{
|
||||||
|
std::string locatorStr;
|
||||||
|
RS_SERIAL_PROCESS(locatorStr);
|
||||||
|
if(ctx.mOk) details.ipAddressList.push_back(locatorStr);
|
||||||
|
else RsWarn() << __PRETTY_FUNCTION__ << " failed to parse locator"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RsShortInviteFieldType::DNS_LOCATOR:
|
||||||
|
RS_SERIAL_PROCESS(details.dyndns);
|
||||||
|
if(!ctx.mOk)
|
||||||
|
{
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " failed to parse DNS "
|
||||||
|
<< "locator host" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RS_SERIAL_PROCESS(details.extPort);
|
||||||
|
if(!ctx.mOk) RsWarn() << __PRETTY_FUNCTION__ << " failed to parse "
|
||||||
|
<< "DNS locator port" << std::endl;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::EXT4_LOCATOR:
|
||||||
|
{
|
||||||
|
uint32_t t4Addr = 0;
|
||||||
|
RS_SERIAL_PROCESS(t4Addr);
|
||||||
|
if(!ctx.mOk)
|
||||||
|
{
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " failed to parse IPv4"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sockaddr_in tExtAddr;
|
||||||
|
tExtAddr.sin_addr.s_addr = t4Addr;
|
||||||
|
details.extAddr = rs_inet_ntoa(tExtAddr.sin_addr);
|
||||||
|
|
||||||
|
RS_SERIAL_PROCESS(details.extPort);
|
||||||
|
if(!ctx.mOk)
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " failed to parse extPort"
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::HIDDEN_LOCATOR:
|
||||||
|
RS_SERIAL_PROCESS(details.hiddenType);
|
||||||
|
if(!ctx.mOk)
|
||||||
|
{
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " failed to parse hiddenType"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RS_SERIAL_PROCESS(details.hiddenNodeAddress);
|
||||||
|
if(!ctx.mOk)
|
||||||
|
{
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " failed to parse "
|
||||||
|
<< "hiddenNodeAddress" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RS_SERIAL_PROCESS(details.hiddenNodePort);
|
||||||
|
if(!ctx.mOk) RsWarn() << __PRETTY_FUNCTION__ << " failed to parse "
|
||||||
|
<< "hiddenNodePort" << std::endl;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " got unkown field type: "
|
||||||
|
<< static_cast<uint32_t>(fieldType) << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ctx.mOk;
|
||||||
|
}
|
||||||
|
|
||||||
bool p3Peers::acceptInvite( const std::string& invite,
|
bool p3Peers::acceptInvite( const std::string& invite,
|
||||||
ServicePermissionFlags flags )
|
ServicePermissionFlags flags )
|
||||||
{
|
{
|
||||||
|
@ -1503,4 +1727,5 @@ void p3Peers::setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermi
|
||||||
mPeerMgr->setServicePermissionFlags(gpg_id,flags) ;
|
mPeerMgr->setServicePermissionFlags(gpg_id,flags) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RsPeerStateChangedEvent::RsPeerStateChangedEvent(RsPeerId sslId) :
|
||||||
|
RsEvent(RsEventType::PEER_STATE_CHANGED), mSslId(sslId) {}
|
||||||
|
|
|
@ -69,6 +69,9 @@ public:
|
||||||
virtual bool isFriend(const RsPeerId &id);
|
virtual bool isFriend(const RsPeerId &id);
|
||||||
virtual bool isPgpFriend(const RsPgpId& pgpId);
|
virtual bool isPgpFriend(const RsPgpId& pgpId);
|
||||||
|
|
||||||
|
/// @see RsPeers
|
||||||
|
bool isSslOnlyFriend(const RsPeerId& sslId) override;
|
||||||
|
|
||||||
RS_DEPRECATED_FOR(isPgpFriend)
|
RS_DEPRECATED_FOR(isPgpFriend)
|
||||||
virtual bool isGPGAccepted(const RsPgpId &gpg_id_is_friend);
|
virtual bool isGPGAccepted(const RsPgpId &gpg_id_is_friend);
|
||||||
|
|
||||||
|
@ -90,6 +93,12 @@ public:
|
||||||
|
|
||||||
/* Add/Remove Friends */
|
/* Add/Remove Friends */
|
||||||
virtual bool addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT);
|
virtual bool addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT);
|
||||||
|
|
||||||
|
/// @see RsPeers
|
||||||
|
bool addSslOnlyFriend(
|
||||||
|
const RsPeerId& sslId,
|
||||||
|
const RsPeerDetails& details = RsPeerDetails() ) override;
|
||||||
|
|
||||||
virtual bool removeFriend(const RsPgpId& gpgid);
|
virtual bool removeFriend(const RsPgpId& gpgid);
|
||||||
virtual bool removeFriendLocation(const RsPeerId& sslId);
|
virtual bool removeFriendLocation(const RsPeerId& sslId);
|
||||||
|
|
||||||
|
@ -128,6 +137,16 @@ public:
|
||||||
|
|
||||||
virtual bool GetPGPBase64StringAndCheckSum(const RsPgpId& gpg_id,std::string& gpg_base64_string,std::string& gpg_base64_checksum);
|
virtual bool GetPGPBase64StringAndCheckSum(const RsPgpId& gpg_id,std::string& gpg_base64_string,std::string& gpg_base64_checksum);
|
||||||
|
|
||||||
|
/// @see RsPeers
|
||||||
|
bool getShortInvite(
|
||||||
|
std::string& invite, const RsPeerId& sslId = RsPeerId(),
|
||||||
|
bool formatRadix = false, bool bareBones = false,
|
||||||
|
const std::string& baseUrl = "https://retroshare.me/" ) override;
|
||||||
|
|
||||||
|
/// @see RsPeers
|
||||||
|
bool parseShortInvite(
|
||||||
|
const std::string& invite, RsPeerDetails& details ) override;
|
||||||
|
|
||||||
/// @see RsPeers::acceptInvite
|
/// @see RsPeers::acceptInvite
|
||||||
virtual bool acceptInvite(
|
virtual bool acceptInvite(
|
||||||
const std::string& invite,
|
const std::string& invite,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue