mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-19 03:06:26 +00:00
Revert some bad docs in Packet -- I think we will still use that. Also rename addMembershipCertificate to more security-descriptive validateAndAddMembershipCertificate, give it a return value, and drop unused force parameter.
This commit is contained in:
parent
56285ec0d4
commit
f398952a6c
@ -429,7 +429,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
|
|||||||
offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS);
|
offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS);
|
||||||
SharedPtr<Network> network(RR->node->network(nwid));
|
SharedPtr<Network> network(RR->node->network(nwid));
|
||||||
if ((network)&&(com.hasRequiredFields()))
|
if ((network)&&(com.hasRequiredFields()))
|
||||||
network->addMembershipCertificate(com,false);
|
network->validateAndAddMembershipCertificate(com);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & 0x02) != 0) {
|
if ((flags & 0x02) != 0) {
|
||||||
@ -558,7 +558,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
|
|||||||
CertificateOfMembership com;
|
CertificateOfMembership com;
|
||||||
comLen = com.deserialize(*this,ZT_PROTO_VERB_EXT_FRAME_IDX_COM);
|
comLen = com.deserialize(*this,ZT_PROTO_VERB_EXT_FRAME_IDX_COM);
|
||||||
if (com.hasRequiredFields())
|
if (com.hasRequiredFields())
|
||||||
network->addMembershipCertificate(com,false);
|
network->validateAndAddMembershipCertificate(com);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!network->isAllowed(peer->address())) {
|
if (!network->isAllowed(peer->address())) {
|
||||||
@ -648,7 +648,7 @@ bool IncomingPacket::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment
|
|||||||
if (com.hasRequiredFields()) {
|
if (com.hasRequiredFields()) {
|
||||||
SharedPtr<Network> network(RR->node->network(com.networkId()));
|
SharedPtr<Network> network(RR->node->network(com.networkId()));
|
||||||
if (network)
|
if (network)
|
||||||
network->addMembershipCertificate(com,false);
|
network->validateAndAddMembershipCertificate(com);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,7 +806,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
|
|||||||
CertificateOfMembership com;
|
CertificateOfMembership com;
|
||||||
offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM);
|
offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM);
|
||||||
if (com.hasRequiredFields())
|
if (com.hasRequiredFields())
|
||||||
network->addMembershipCertificate(com,false);
|
network->validateAndAddMembershipCertificate(com);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check membership after we've read any included COM, since
|
// Check membership after we've read any included COM, since
|
||||||
|
@ -267,53 +267,55 @@ void Network::requestConfiguration()
|
|||||||
RR->sw->send(outp,true,_id);
|
RR->sw->send(outp,true,_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Network::addMembershipCertificate(const CertificateOfMembership &cert,bool forceAccept)
|
bool Network::validateAndAddMembershipCertificate(const CertificateOfMembership &cert)
|
||||||
{
|
{
|
||||||
if (!cert) // sanity check
|
if (!cert) // sanity check
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
Mutex::Lock _l(_lock);
|
Mutex::Lock _l(_lock);
|
||||||
CertificateOfMembership &old = _membershipCertificates[cert.issuedTo()];
|
CertificateOfMembership &old = _membershipCertificates[cert.issuedTo()];
|
||||||
|
|
||||||
// Nothing to do if the cert hasn't changed -- we get duplicates due to zealous cert pushing
|
// Nothing to do if the cert hasn't changed -- we get duplicates due to zealous cert pushing
|
||||||
if (old == cert)
|
if (old == cert)
|
||||||
return;
|
return true; // but if it's a duplicate of one we already accepted, return is 'true'
|
||||||
|
|
||||||
// Check signature, log and return if cert is invalid
|
// Check signature, log and return if cert is invalid
|
||||||
if (!forceAccept) {
|
if (cert.signedBy() != controller()) {
|
||||||
if (cert.signedBy() != controller()) {
|
TRACE("rejected network membership certificate for %.16llx signed by %s: signer not a controller of this network",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
||||||
TRACE("rejected network membership certificate for %.16llx signed by %s: signer not a controller of this network",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
return false; // invalid signer
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
if (cert.signedBy() == RR->identity.address()) {
|
||||||
|
|
||||||
|
// We are the controller: RR->identity.address() == controller() == cert.signedBy()
|
||||||
|
// So, verify that we signed th cert ourself
|
||||||
|
if (!cert.verify(RR->identity)) {
|
||||||
|
TRACE("rejected network membership certificate for %.16llx self signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
||||||
|
return false; // invalid signature
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cert.signedBy() == RR->identity.address()) {
|
} else {
|
||||||
// We are the controller: RR->identity.address() == controller() == cert.signedBy()
|
|
||||||
// So, verify that we signed th cert ourself
|
|
||||||
if (!cert.verify(RR->identity)) {
|
|
||||||
TRACE("rejected network membership certificate for %.16llx self signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
SharedPtr<Peer> signer(RR->topology->getPeer(cert.signedBy()));
|
SharedPtr<Peer> signer(RR->topology->getPeer(cert.signedBy()));
|
||||||
|
|
||||||
if (!signer) {
|
if (!signer) {
|
||||||
// This would be rather odd, since this is our controller... could happen
|
// This would be rather odd, since this is our controller... could happen
|
||||||
// if we get packets before we've gotten config.
|
// if we get packets before we've gotten config.
|
||||||
RR->sw->requestWhois(cert.signedBy());
|
RR->sw->requestWhois(cert.signedBy());
|
||||||
return;
|
return false; // signer unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cert.verify(signer->identity())) {
|
if (!cert.verify(signer->identity())) {
|
||||||
TRACE("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
TRACE("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
||||||
return;
|
return false; // invalid signature
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we made it past authentication, update cert
|
// If we made it past authentication, update cert
|
||||||
if (cert.revision() != old.revision())
|
if (cert.revision() != old.revision())
|
||||||
old = cert;
|
old = cert;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Network::peerNeedsOurMembershipCertificate(const Address &to,uint64_t now)
|
bool Network::peerNeedsOurMembershipCertificate(const Address &to,uint64_t now)
|
||||||
|
@ -179,9 +179,9 @@ public:
|
|||||||
* Add or update a membership certificate
|
* Add or update a membership certificate
|
||||||
*
|
*
|
||||||
* @param cert Certificate of membership
|
* @param cert Certificate of membership
|
||||||
* @param forceAccept If true, accept without validating signature
|
* @return True if certificate was accepted as valid
|
||||||
*/
|
*/
|
||||||
void addMembershipCertificate(const CertificateOfMembership &cert,bool forceAccept);
|
bool validateAndAddMembershipCertificate(const CertificateOfMembership &cert);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if we should push membership certificate to a peer, and update last pushed
|
* Check if we should push membership certificate to a peer, and update last pushed
|
||||||
|
@ -680,12 +680,6 @@ public:
|
|||||||
*
|
*
|
||||||
* Certificate contains network ID, peer it was issued for, etc.
|
* Certificate contains network ID, peer it was issued for, etc.
|
||||||
*
|
*
|
||||||
* Note that in the current code base, separate COM pushes are not done.
|
|
||||||
* Instead the "bundled COM" options are utilized in EXT_FRAME and
|
|
||||||
* MULTICAST_FRAME to push the COM along with frames. This is slightly
|
|
||||||
* more efficient. But we'll keep this simple message around in case we
|
|
||||||
* want to use it in the future.
|
|
||||||
*
|
|
||||||
* OK/ERROR are not generated.
|
* OK/ERROR are not generated.
|
||||||
*/
|
*/
|
||||||
VERB_NETWORK_MEMBERSHIP_CERTIFICATE = 10,
|
VERB_NETWORK_MEMBERSHIP_CERTIFICATE = 10,
|
||||||
|
Loading…
Reference in New Issue
Block a user