summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/Capability.cpp25
-rw-r--r--node/CertificateOfMembership.cpp3
-rw-r--r--node/Membership.cpp2
-rw-r--r--node/Peer.cpp99
-rw-r--r--node/Tag.cpp3
5 files changed, 29 insertions, 103 deletions
diff --git a/node/Capability.cpp b/node/Capability.cpp
index 07eb41a9..ee798a6c 100644
--- a/node/Capability.cpp
+++ b/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
diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp
index 0c36aa45..43efcd20 100644
--- a/node/CertificateOfMembership.cpp
+++ b/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));
diff --git a/node/Membership.cpp b/node/Membership.cpp
index 91cf693a..a1a8eb8a 100644
--- a/node/Membership.cpp
+++ b/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)
diff --git a/node/Peer.cpp b/node/Peer.cpp
index cc581004..a994c4b2 100644
--- a/node/Peer.cpp
+++ b/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);
}
}
}
diff --git a/node/Tag.cpp b/node/Tag.cpp
index 1ad17251..352ecde8 100644
--- a/node/Tag.cpp
+++ b/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) {