Adam Ierymenko 9 ani în urmă
părinte
comite
56febbf2ba
5 a modificat fișierele cu 29 adăugiri și 103 ștergeri
  1. 17 8
      node/Capability.cpp
  2. 2 1
      node/CertificateOfMembership.cpp
  3. 1 1
      node/Membership.cpp
  4. 7 92
      node/Peer.cpp
  5. 2 1
      node/Tag.cpp

+ 17 - 8
node/Capability.cpp

@@ -21,19 +21,29 @@
 #include "Identity.hpp"
 #include "Topology.hpp"
 #include "Switch.hpp"
+#include "Network.hpp"
 
 namespace ZeroTier {
 
 int Capability::verify(const RuntimeEnvironment *RR) const
 {
 	try {
+		if ((_maxCustodyChainLength < 1)||(_maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH))
+			return -1;
+
 		Buffer<(sizeof(Capability) * 2)> tmp;
 		this->serialize(tmp,true);
-		for(unsigned int c=0;c<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH;++c) {
-			if (!_custody[c].to)
-				return ((c == 0) ? -1 : 0);
-			if (!_custody[c].from)
-				return -1;
+		for(unsigned int c=0;c<_maxCustodyChainLength;++c) {
+			if (c == 0) {
+				if ((!_custody[c].to)||(!_custody[c].from)||(_custody[c].from != Network::controllerFor(_nwid)))
+					return -1; // the first entry must be present and from the network's controller
+			} else {
+				if (!_custody[c].to)
+					return 0; // all previous entries were valid, so we are valid
+				else if ((!_custody[c].from)||(_custody[c].from != _custody[c-1].to))
+					return -1; // otherwise if we have another entry it must be from the previous holder in the chain
+			}
+
 			const Identity id(RR->topology->getIdentity(_custody[c].from));
 			if (id) {
 				if (!id.verify(tmp.data(),tmp.size(),_custody[c].signature))
@@ -44,9 +54,8 @@ int Capability::verify(const RuntimeEnvironment *RR) const
 			}
 		}
 		return 0;
-	} catch ( ... ) {
-		return -1;
-	}
+	} catch ( ... ) {}
+	return -1;
 }
 
 } // namespace ZeroTier

+ 2 - 1
node/CertificateOfMembership.cpp

@@ -20,6 +20,7 @@
 #include "RuntimeEnvironment.hpp"
 #include "Topology.hpp"
 #include "Switch.hpp"
+#include "Network.hpp"
 
 namespace ZeroTier {
 
@@ -208,7 +209,7 @@ bool CertificateOfMembership::sign(const Identity &with)
 
 int CertificateOfMembership::verify(const RuntimeEnvironment *RR) const
 {
-	if ((!_signedBy)||(_qualifierCount > ZT_NETWORK_COM_MAX_QUALIFIERS))
+	if ((!_signedBy)||(_signedBy != Network::controllerFor(networkId()))||(_qualifierCount > ZT_NETWORK_COM_MAX_QUALIFIERS))
 		return -1;
 
 	const Identity id(RR->topology->getIdentity(_signedBy));

+ 1 - 1
node/Membership.cpp

@@ -80,8 +80,8 @@ bool Membership::sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint
 		}
 	} catch ( ... ) {
 		TRACE("unable to send credentials due to unexpected exception");
-		return false;
 	}
+	return false;
 }
 
 int Membership::addCredential(const RuntimeEnvironment *RR,const uint64_t now,const CertificateOfMembership &com)

+ 7 - 92
node/Peer.cpp

@@ -371,80 +371,6 @@ void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6)
 	}
 }
 
-bool Peer::networkMembershipCertificatesAgree(uint64_t nwid,const CertificateOfMembership &com) const
-{
-	Mutex::Lock _l(_networkComs_m);
-	const _NetworkCom *ourCom = _networkComs.get(nwid);
-	if (ourCom)
-		return ourCom->com.agreesWith(com);
-	return false;
-}
-
-bool Peer::validateAndSetNetworkMembershipCertificate(uint64_t nwid,const CertificateOfMembership &com)
-{
-	// Sanity checks
-	if ((!com)||(com.issuedTo() != _id.address()))
-		return false;
-
-	// Return true if we already have this *exact* COM
-	{
-		Mutex::Lock _l(_networkComs_m);
-		_NetworkCom *ourCom = _networkComs.get(nwid);
-		if ((ourCom)&&(ourCom->com == com))
-			return true;
-	}
-
-	// Check signature, log and return if cert is invalid
-	if (com.signedBy() != Network::controllerFor(nwid)) {
-		TRACE("rejected network membership certificate for %.16llx signed by %s: signer not a controller of this network",(unsigned long long)nwid,com.signedBy().toString().c_str());
-		return false; // invalid signer
-	}
-
-	if (com.signedBy() == RR->identity.address()) {
-
-		// We are the controller: RR->identity.address() == controller() == cert.signedBy()
-		// So, verify that we signed th cert ourself
-		if (!com.verify(RR->identity)) {
-			TRACE("rejected network membership certificate for %.16llx self signed by %s: signature check failed",(unsigned long long)nwid,com.signedBy().toString().c_str());
-			return false; // invalid signature
-		}
-
-	} else {
-
-		SharedPtr<Peer> signer(RR->topology->getPeer(com.signedBy()));
-
-		if (!signer) {
-			// This would be rather odd, since this is our controller... could happen
-			// if we get packets before we've gotten config.
-			RR->sw->requestWhois(com.signedBy());
-			return false; // signer unknown
-		}
-
-		if (!com.verify(signer->identity())) {
-			TRACE("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)nwid,com.signedBy().toString().c_str());
-			return false; // invalid signature
-		}
-	}
-
-	// If we made it past all those checks, add or update cert in our cert info store
-	{
-		Mutex::Lock _l(_networkComs_m);
-		_networkComs.set(nwid,_NetworkCom(RR->node->now(),com));
-	}
-
-	return true;
-}
-
-bool Peer::needsOurNetworkMembershipCertificate(uint64_t nwid,uint64_t now,bool updateLastPushedTime)
-{
-	Mutex::Lock _l(_networkComs_m);
-	uint64_t &lastPushed = _lastPushedComs[nwid];
-	const uint64_t tmp = lastPushed;
-	if (updateLastPushedTime)
-		lastPushed = now;
-	return ((now - tmp) >= (ZT_NETWORK_AUTOCONF_DELAY / 3));
-}
-
 void Peer::clean(uint64_t now)
 {
 	{
@@ -460,24 +386,13 @@ void Peer::clean(uint64_t now)
 	}
 
 	{
-		Mutex::Lock _l(_networkComs_m);
-		{
-			uint64_t *k = (uint64_t *)0;
-			_NetworkCom *v = (_NetworkCom *)0;
-			Hashtable< uint64_t,_NetworkCom >::Iterator i(_networkComs);
-			while (i.next(k,v)) {
-				if ( (!RR->node->belongsToNetwork(*k)) && ((now - v->ts) >= ZT_PEER_NETWORK_COM_EXPIRATION) )
-					_networkComs.erase(*k);
-			}
-		}
-		{
-			uint64_t *k = (uint64_t *)0;
-			uint64_t *v = (uint64_t *)0;
-			Hashtable< uint64_t,uint64_t >::Iterator i(_lastPushedComs);
-			while (i.next(k,v)) {
-				if ((now - *v) > (ZT_NETWORK_AUTOCONF_DELAY * 2))
-					_lastPushedComs.erase(*k);
-			}
+		Mutex::Lock _l(_memberships_m);
+		uint64_t *nwid = (uint64_t *)0;
+		Membership *m = (Membership *)0;
+		Hashtable<uint64_t,Membership>::Iterator i(_memberships);
+		while (i.next(nwid,m)) {
+			if ((now - m->clean(now)) > ZT_MEMBERSHIP_EXPIRATION_TIME)
+				_memberships.erase(*nwid);
 		}
 	}
 }

+ 2 - 1
node/Tag.cpp

@@ -21,12 +21,13 @@
 #include "Identity.hpp"
 #include "Topology.hpp"
 #include "Switch.hpp"
+#include "Network.hpp"
 
 namespace ZeroTier {
 
 int Tag::verify(const RuntimeEnvironment *RR) const
 {
-	if (!_signedBy)
+	if ((!_signedBy)||(_signedBy != Network::controllerFor(_nwid)))
 		return -1;
 	const Identity id(RR->topology->getIdentity(_signedBy));
 	if (!id) {