Merge pull request #1142 from csoler/v0.6-SecurityFixes

prevent sending/receiving of IP addresses to/at hidden nodes
This commit is contained in:
csoler 2018-01-03 18:42:04 +01:00 committed by GitHub
commit ee81eef7f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 24 deletions

View File

@ -519,6 +519,25 @@ uint32_t p3PeerMgrIMPL::getHiddenType(const RsPeerId &ssl_id)
return (it->second).hiddenType;
}
bool p3PeerMgrIMPL::isHiddenNode(const RsPeerId& id)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (id == AuthSSL::getAuthSSL()->OwnId())
return mOwnState.hiddenNode ;
else
{
std::map<RsPeerId,peerState>::const_iterator it = mFriendList.find(id);
if (it == mFriendList.end())
{
std::cerr << "p3PeerMgrIMPL::isHiddenNode() Peer Not Found" << std::endl;
return false;
}
return it->second.hiddenNode ;
}
}
/**
* @brief sets hidden domain and port for a given ssl ID
* @param ssl_id peer to set domain and port for
@ -1632,6 +1651,8 @@ bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet
cleanIpList(clean_set.mExt.mAddrs,id,mLinkMgr) ;
cleanIpList(clean_set.mLocal.mAddrs,id,mLinkMgr) ;
bool am_I_a_hidden_node = isHiddenNode(getOwnId()) ;
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* check if it is our own ip */
@ -1655,7 +1676,12 @@ bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet
}
/* "it" points to peer */
it->second.ipAddrs.updateAddrs(clean_set);
if(!am_I_a_hidden_node)
it->second.ipAddrs.updateAddrs(clean_set);
else
it->second.ipAddrs.clear();
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setLocalAddress() Updated Address for: " << id;
std::cerr << std::endl;
@ -2173,6 +2199,7 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
#endif
RsPeerId ownId = getOwnId();
bool am_I_a_hidden_node = isHiddenNode(ownId) ;
/* load the list of peers */
std::list<RsItem *>::iterator it;
@ -2220,16 +2247,20 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
}
else
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
updateAddressList(peer_id, addrs);
if(!am_I_a_hidden_node) // clear IPs if w're a hidden node. Friend's clear node IPs where previously sent.
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
}
updateAddressList(peer_id, addrs);
}
delete(*it);

View File

@ -171,6 +171,7 @@ virtual bool setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht)
virtual bool setLocation(const RsPeerId &pid, const std::string &location) = 0;
virtual bool setHiddenDomainPort(const RsPeerId &id, const std::string &domain_addr, const uint16_t domain_port) = 0;
virtual bool isHiddenNode(const RsPeerId& id) = 0 ;
virtual bool updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr) = 0;
virtual bool updateLastContact(const RsPeerId& id) = 0;
@ -284,6 +285,7 @@ public:
virtual bool setLocation(const RsPeerId &pid, const std::string &location);
virtual bool setHiddenDomainPort(const RsPeerId &id, const std::string &domain_addr, const uint16_t domain_port);
virtual bool isHiddenNode(const RsPeerId& id);
virtual bool updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr);
virtual bool updateLastContact(const RsPeerId& id);

View File

@ -68,6 +68,12 @@ class pqiIpAddrSet
void printAddrs(std::string &out) const;
pqiIpAddrList mLocal;
pqiIpAddrList mExt;
void clear()
{
mLocal.mAddrs.clear();
mExt.mAddrs.clear();
}
};

View File

@ -368,6 +368,7 @@ public:
virtual bool setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address) = 0;
virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port) = 0;
virtual bool isHiddenNode(const RsPeerId &id) = 0;
virtual bool setLocalAddress(const RsPeerId &ssl_id, const std::string &addr, uint16_t port) = 0;
virtual bool setExtAddress( const RsPeerId &ssl_id, const std::string &addr, uint16_t port) = 0;

View File

@ -882,6 +882,11 @@ bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &hidden_node_
}
bool p3Peers::isHiddenNode(const RsPeerId &id)
{
return mPeerMgr->isHiddenNode(id) ;
}
bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port)
{
#ifdef P3PEERS_DEBUG

View File

@ -94,6 +94,7 @@ public:
virtual bool setLocation(const RsPeerId &ssl_id, const std::string &location);//location is shown in the gui to differentiate ssl certs
virtual bool setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address);
virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port);
virtual bool isHiddenNode(const RsPeerId &id);
virtual bool setLocalAddress(const RsPeerId &id, const std::string &addr, uint16_t port);
virtual bool setExtAddress(const RsPeerId &id, const std::string &addr, uint16_t port);

View File

@ -38,7 +38,7 @@ RsDisc *rsDisc = NULL;
* #define P3DISC_DEBUG 1
****/
bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt)
static bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt,bool include_ip_information)
{
pkt->clear();
@ -62,14 +62,24 @@ bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt)
{
pkt->isHidden = false;
pkt->localAddrV4.addr = detail.localaddr;
pkt->extAddrV4.addr = detail.serveraddr;
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
if(include_ip_information)
{
pkt->localAddrV4.addr = detail.localaddr;
pkt->extAddrV4.addr = detail.serveraddr;
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
pkt->dyndns = detail.dyndns;
detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList);
detail.ipAddrs.mExt.loadTlv(pkt->extAddrList);
pkt->dyndns = detail.dyndns;
detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList);
detail.ipAddrs.mExt.loadTlv(pkt->extAddrList);
}
else
{
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
sockaddr_storage_clear(pkt->localAddrV4.addr);
sockaddr_storage_clear(pkt->extAddrV4.addr);
}
}
return true;
@ -334,9 +344,8 @@ void p3discovery2::sendOwnContactInfo(const SSLID &sslid)
if (mPeerMgr->getOwnNetStatus(detail))
{
RsDiscContactItem *pkt = new RsDiscContactItem();
populateContactInfo(detail, pkt);
populateContactInfo(detail, pkt, !rsPeers->isHiddenNode(sslid)); // we dont send our own IP to an hidden node. It will not use it anyway.
pkt->version = RsUtil::retroshareVersion();
pkt->PeerId(sslid);
#ifdef P3DISC_DEBUG
@ -372,6 +381,7 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
mPeerMgr->setVisState(fromId, item->vs_disc, item->vs_dht);
setPeerVersion(fromId, item->version);
updatePeerAddresses(item);
// This information will be sent out to online peers, at the receipt of their PGPList.
@ -423,13 +433,10 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
void p3discovery2::updatePeerAddresses(const RsDiscContactItem *item)
{
if (item->isHidden)
{
mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr, item->hiddenPort);
}
else
{
mPeerMgr->setDynDNS(item->sslId, item->dyndns);
updatePeerAddressList(item);
}
}
@ -440,7 +447,7 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
if (item->isHidden)
{
}
else
else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId())) // we don't store IP addresses if we're a hidden node. Normally they should not be sent to us, except for old peers.
{
pqiIpAddrSet addrsFromPeer;
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList);
@ -817,7 +824,7 @@ void p3discovery2::sendContactInfo_locked(const PGPID &aboutId, const SSLID &toI
if (mPeerMgr->getFriendNetStatus(sit->first, detail))
{
RsDiscContactItem *pkt = new RsDiscContactItem();
populateContactInfo(detail, pkt);
populateContactInfo(detail, pkt,!mPeerMgr->isHiddenNode(toId));// never send IPs to an hidden node. The node will not use them anyway.
pkt->PeerId(toId);
// send to each peer its own connection address.