mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Merge pull request #1565 from G10h4ck/short_invites_v2
Short invites support for libretroshare
This commit is contained in:
commit
dac76439bd
@ -27,6 +27,7 @@
|
||||
#include "retroshare/rsiface.h"
|
||||
#include "rsserver/p3face.h"
|
||||
#include "util/rsdebug.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
|
||||
/****
|
||||
* #define P3DISC_DEBUG 1
|
||||
@ -1249,9 +1250,25 @@ void p3discovery2::recvInvite(
|
||||
|
||||
void p3discovery2::rsEventsHandler(const RsEvent& event)
|
||||
{
|
||||
Dbg3() << __PRETTY_FUNCTION__ << " " << static_cast<uint32_t>(event.mType)
|
||||
<< std::endl;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1196,6 +1196,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
|
||||
std::string sslCn = RsX509Cert::getCertIssuerString(*x509Cert);
|
||||
RsPgpId pgpId(sslCn);
|
||||
|
||||
|
||||
if(sslId.isNull())
|
||||
{
|
||||
std::string errMsg = "x509Cert has invalid sslId!";
|
||||
@ -1231,8 +1232,10 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
|
||||
return verificationFailed;
|
||||
}
|
||||
|
||||
bool isSslOnlyFriend = rsPeers->isSslOnlyFriend(sslId);
|
||||
|
||||
uint32_t auth_diagnostic;
|
||||
if(!AuthX509WithGPG(x509Cert, auth_diagnostic))
|
||||
if(!isSslOnlyFriend && !AuthX509WithGPG(x509Cert, auth_diagnostic))
|
||||
{
|
||||
std::string errMsg = "Certificate was rejected because PGP "
|
||||
"signature verification failed with diagnostic: "
|
||||
@ -1255,7 +1258,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
|
||||
return verificationFailed;
|
||||
}
|
||||
|
||||
if ( pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||
if ( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
||||
{
|
||||
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);
|
||||
LocalStoreCert(x509Cert);
|
||||
|
||||
Dbg1() << __PRETTY_FUNCTION__ << " authentication successfull!" << std::endl;
|
||||
RsInfo() << __PRETTY_FUNCTION__ << " authentication successfull for "
|
||||
<< "sslId: " << sslId << " isSslOnlyFriend: " << isSslOnlyFriend
|
||||
<< std::endl;
|
||||
|
||||
if(rsEvents)
|
||||
{
|
||||
|
@ -1029,6 +1029,73 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
|
||||
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)
|
||||
{
|
||||
#ifdef PEER_DEBUG
|
||||
@ -2344,7 +2411,15 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
|
||||
#endif
|
||||
/* ************* */
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,10 @@ public:
|
||||
rstime_t lastContact = 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 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,
|
||||
uint16_t vsDisc = RS_VS_DISC_FULL, uint16_t vsDht = RS_VS_DHT_FULL,
|
||||
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 RsPgpId &pgp_id);
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "rsitems/rsnxsitems.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
#include "pqi/pqiservice.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
#include "retroshare/rsevents.h"
|
||||
|
||||
/*******************************/
|
||||
// #define SERVICECONTROL_DEBUG 1
|
||||
@ -756,6 +758,12 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId)
|
||||
mPeerFilterMap[peerId] = 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;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "pqi/pqissllistener.h"
|
||||
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include <retroshare/rspeers.h>
|
||||
#include "retroshare/rspeers.h"
|
||||
#include <retroshare/rsdht.h>
|
||||
#include <retroshare/rsbanlist.h>
|
||||
|
||||
@ -1180,10 +1180,13 @@ int pqissl::Authorise_SSL_Connection()
|
||||
|
||||
/* At this point the actual connection authentication has already been
|
||||
* 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;
|
||||
if(!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode))
|
||||
if( !isSslOnlyFriend &&
|
||||
!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode) )
|
||||
{
|
||||
RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
|
||||
<< "certificate signature. This should never happen at this "
|
||||
@ -1195,7 +1198,7 @@ int pqissl::Authorise_SSL_Connection()
|
||||
}
|
||||
|
||||
RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert);
|
||||
if( pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||
if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
||||
{
|
||||
RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
|
||||
|
@ -784,10 +784,13 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
|
||||
#ifdef RS_PQISSL_AUTH_DOUBLE_CHECK
|
||||
/* At this point the actual connection authentication has already been
|
||||
* 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;
|
||||
if(!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode))
|
||||
if( !isSslOnlyFriend &&
|
||||
!AuthSSL::instance().AuthX509WithGPG(peercert, authErrCode) )
|
||||
{
|
||||
RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
|
||||
<< "certificate signature. This should never happen at this "
|
||||
@ -798,7 +801,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
|
||||
exit(failure);
|
||||
}
|
||||
|
||||
if( pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||
if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
|
||||
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
|
||||
{
|
||||
RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
|
||||
@ -822,7 +825,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
|
||||
else ++it;
|
||||
}
|
||||
|
||||
if (found == false)
|
||||
if (!found)
|
||||
{
|
||||
Dbg1() << __PRETTY_FUNCTION__ << " got secure connection from address: "
|
||||
<< info.addr << " with previously unknown SSL certificate: "
|
||||
|
@ -63,6 +63,9 @@ enum class RsEventType : uint32_t
|
||||
/// @see RsGxsChanges
|
||||
GXS_CHANGES = 5,
|
||||
|
||||
/// Emitted when a peer state changes, @see RsPeers
|
||||
PEER_STATE_CHANGED = 6,
|
||||
|
||||
MAX /// Used to detect invalid event type passed
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "util/rsurl.h"
|
||||
#include "util/rsdeprecate.h"
|
||||
#include "util/rstime.h"
|
||||
#include "retroshare/rsevents.h"
|
||||
|
||||
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
|
||||
* 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
|
||||
@ -434,6 +452,16 @@ public:
|
||||
*/
|
||||
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 getGPGName(const RsPgpId& gpg_id) = 0;
|
||||
|
||||
@ -474,8 +502,24 @@ public:
|
||||
* @param[in] flags service permissions flag
|
||||
* @return false if error occurred, true otherwise
|
||||
*/
|
||||
virtual bool addFriend( const RsPeerId &sslId, const RsPgpId& gpgId,
|
||||
ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0;
|
||||
virtual bool addFriend(
|
||||
const RsPeerId& sslId, const RsPgpId& gpgId,
|
||||
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
|
||||
@ -597,6 +641,38 @@ public:
|
||||
bool includeSignatures = false,
|
||||
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
|
||||
* @jsonapi{development}
|
||||
@ -749,6 +825,3 @@ public:
|
||||
RS_DEPRECATED_FOR(isPgpFriend)
|
||||
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)
|
||||
{ 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)
|
||||
{ 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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return AuthGPG::getAuthGPG()->removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ;
|
||||
@ -1104,6 +1111,223 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( const RsPgpId& gpg_id,
|
||||
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,
|
||||
ServicePermissionFlags flags )
|
||||
{
|
||||
@ -1503,4 +1727,5 @@ void p3Peers::setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermi
|
||||
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 isPgpFriend(const RsPgpId& pgpId);
|
||||
|
||||
/// @see RsPeers
|
||||
bool isSslOnlyFriend(const RsPeerId& sslId) override;
|
||||
|
||||
RS_DEPRECATED_FOR(isPgpFriend)
|
||||
virtual bool isGPGAccepted(const RsPgpId &gpg_id_is_friend);
|
||||
|
||||
@ -90,6 +93,12 @@ public:
|
||||
|
||||
/* Add/Remove Friends */
|
||||
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 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);
|
||||
|
||||
/// @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
|
||||
virtual bool acceptInvite(
|
||||
const std::string& invite,
|
||||
|
Loading…
Reference in New Issue
Block a user