From 59ee0cfe8812b61bf4ac74b0431800050dd1d528 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 28 Aug 2019 10:34:32 -0700 Subject: [PATCH] Safety upgrades to code --- node/CMakeLists.txt | 1 + node/Credential.cpp | 4 +- node/Locator.hpp | 20 ++--- node/Network.cpp | 74 +++++++------------ node/NetworkConfig.cpp | 161 +++++++++++++++++++---------------------- node/NetworkConfig.hpp | 2 +- node/Node.cpp | 71 +++++++++--------- node/Peer.cpp | 4 +- node/ScopedPtr.hpp | 50 +++++++++++++ 9 files changed, 196 insertions(+), 191 deletions(-) create mode 100644 node/ScopedPtr.hpp diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt index b7fbcc171..195ed8484 100644 --- a/node/CMakeLists.txt +++ b/node/CMakeLists.txt @@ -38,6 +38,7 @@ set(core_headers RingBuffer.hpp RuntimeEnvironment.hpp Salsa20.hpp + ScopedPtr.hpp SelfAwareness.hpp SHA512.hpp SharedPtr.hpp diff --git a/node/Credential.cpp b/node/Credential.cpp index af9783675..5e5ebe9bf 100644 --- a/node/Credential.cpp +++ b/node/Credential.cpp @@ -21,6 +21,7 @@ #include "Revocation.hpp" #include "Switch.hpp" #include "Network.hpp" +#include "ScopedPtr.hpp" namespace ZeroTier { @@ -37,10 +38,9 @@ static inline Credential::VerifyResult _credVerify(const RuntimeEnvironment *con return Credential::VERIFY_NEED_IDENTITY; } try { - Buffer<(sizeof(CRED) + 64)> *const tmp = new Buffer<(sizeof(CRED) + 64)>(); + ScopedPtr< Buffer<(sizeof(CRED) + 64)> > tmp(new Buffer<(sizeof(CRED) + 64)>()); credential.serialize(*tmp,true); const Credential::VerifyResult result = (id.verify(tmp->data(),tmp->size(),credential.signature(),credential.signatureLength()) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE); - delete tmp; return result; } catch ( ... ) {} return Credential::VERIFY_BAD_SIGNATURE; diff --git a/node/Locator.hpp b/node/Locator.hpp index 28bffa34c..14ef1e7d3 100644 --- a/node/Locator.hpp +++ b/node/Locator.hpp @@ -21,6 +21,7 @@ #include "Buffer.hpp" #include "SHA512.hpp" #include "Str.hpp" +#include "ScopedPtr.hpp" #include #include @@ -101,14 +102,12 @@ public: } else { _signedBy = signingId; } - Buffer<65536> *tmp = new Buffer<65536>(); try { + ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>()); serialize(*tmp,true); _signatureLength = signingId.sign(tmp->data(),tmp->size(),_signature,ZT_SIGNATURE_BUFFER_SIZE); - delete tmp; return (_signatureLength > 0); } catch ( ... ) { - delete tmp; return false; } } @@ -120,15 +119,12 @@ public: { if ((_signatureLength == 0)||(_signatureLength > sizeof(_signature))) return false; - Buffer<65536> *tmp = nullptr; try { - tmp = new Buffer<65536>(); + ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>()); serialize(*tmp,true); const bool ok = (_signedBy) ? _signedBy.verify(tmp->data(),tmp->size(),_signature,_signatureLength) : _id.verify(tmp->data(),tmp->size(),_signature,_signatureLength); - delete tmp; return ok; } catch ( ... ) { - if (tmp) delete tmp; return false; } } @@ -150,7 +146,7 @@ public: uint8_t s384[48]; char enc[256]; - Buffer<65536> *const tmp = new Buffer<65536>(); + ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>()); serialize(*tmp,false); SHA384(s384,tmp->data(),tmp->size()); ECC384ECDSASign(p384SigningKeyPrivate,s384,((uint8_t *)tmp->unsafeData()) + tmp->size()); @@ -172,7 +168,6 @@ public: ++txtRecNo; } - delete tmp; return txtRecords; } @@ -192,7 +187,6 @@ public: inline bool decodeTxtRecords(I start,I end,const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE]) { uint8_t dec[256],s384[48]; - Buffer<65536> *tmp = nullptr; try { std::vector txtRecords; while (start != end) { @@ -206,26 +200,22 @@ public: return false; std::sort(txtRecords.begin(),txtRecords.end()); - tmp = new Buffer<65536>(); + ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>()); for(std::vector::const_iterator i(txtRecords.begin());i!=txtRecords.end();++i) tmp->append(dec,Utils::b64d(i->c_str() + 2,dec,sizeof(dec))); if (tmp->size() <= ZT_ECC384_SIGNATURE_SIZE) { - delete tmp; return false; } SHA384(s384,tmp->data(),tmp->size() - ZT_ECC384_SIGNATURE_SIZE); if (!ECC384ECDSAVerify(p384SigningKeyPublic,s384,((const uint8_t *)tmp->data()) + (tmp->size() - ZT_ECC384_SIGNATURE_SIZE))) { - delete tmp; return false; } deserialize(*tmp,0); - delete tmp; return verify(); } catch ( ... ) { - if (tmp) delete tmp; return false; } } diff --git a/node/Network.cpp b/node/Network.cpp index ef651978f..3a7f8a8a7 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -31,6 +31,7 @@ #include "Node.hpp" #include "Peer.hpp" #include "Trace.hpp" +#include "ScopedPtr.hpp" #include @@ -561,22 +562,20 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *u tmp[0] = nwid; tmp[1] = 0; bool got = false; - Dictionary *dict = new Dictionary(); + ScopedPtr< Dictionary > dict(new Dictionary()); try { int n = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,dict->unsafeData(),ZT_NETWORKCONFIG_DICT_CAPACITY - 1); if (n > 1) { - NetworkConfig *nconf = new NetworkConfig(); try { + ScopedPtr nconf(new NetworkConfig()); if (nconf->fromDictionary(*dict)) { this->setConfiguration(tPtr,*nconf,false); _lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated got = true; } } catch ( ... ) {} - delete nconf; } } catch ( ... ) {} - delete dict; if (!got) RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,"\n",1); @@ -856,7 +855,6 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add const unsigned int chunkLen = chunk.at(ptr); ptr += 2; const void *chunkData = chunk.field(ptr,chunkLen); ptr += chunkLen; - NetworkConfig *nc = (NetworkConfig *)0; uint64_t configUpdateId; { Mutex::Lock l1(_config_l); @@ -953,27 +951,16 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add if (c->haveBytes == totalLength) { c->data.unsafeData()[c->haveBytes] = (char)0; // ensure null terminated - nc = new NetworkConfig(); + ScopedPtr nc(new NetworkConfig()); try { - if (!nc->fromDictionary(c->data)) { - delete nc; - nc = (NetworkConfig *)0; + if (nc->fromDictionary(c->data)) { + this->setConfiguration(tPtr,*nc,true); + return configUpdateId; } - } catch ( ... ) { - delete nc; - nc = (NetworkConfig *)0; - } + } catch ( ... ) {} } } - if (nc) { - this->setConfiguration(tPtr,*nc,true); - delete nc; - return configUpdateId; - } else { - return 0; - } - return 0; } @@ -1007,15 +994,14 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD _portError = RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); if (saveToDisk) { - Dictionary *const d = new Dictionary(); try { + ScopedPtr< Dictionary > d(new Dictionary()); if (nconf.toDictionary(*d,false)) { uint64_t tmp[2]; tmp[0] = _id; tmp[1] = 0; RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,d->data(),d->sizeBytes()); } } catch ( ... ) {} - delete d; } return 2; // OK and configuration has changed @@ -1120,7 +1106,7 @@ void Network::_requestConfiguration(void *tPtr) const uint16_t startPortRange = (uint16_t)((_id >> 40) & 0xffff); const uint16_t endPortRange = (uint16_t)((_id >> 24) & 0xffff); if (endPortRange >= startPortRange) { - NetworkConfig *const nconf = new NetworkConfig(); + ScopedPtr nconf(new NetworkConfig()); nconf->networkId = _id; nconf->timestamp = RR->node->now(); @@ -1182,7 +1168,6 @@ void Network::_requestConfiguration(void *tPtr) nconf->name[15] = (char)0; this->setConfiguration(tPtr,*nconf,false); - delete nconf; } else { this->setNotFound(); } @@ -1200,7 +1185,7 @@ void Network::_requestConfiguration(void *tPtr) char v4ascii[24]; Utils::decimal(ipv4[0],v4ascii); - NetworkConfig *const nconf = new NetworkConfig(); + ScopedPtr nconf(new NetworkConfig()); nconf->networkId = _id; nconf->timestamp = RR->node->now(); @@ -1241,32 +1226,31 @@ void Network::_requestConfiguration(void *tPtr) nconf->name[nn++] = (char)0; this->setConfiguration(tPtr,*nconf,false); - delete nconf; } return; } const Address ctrl(controller()); - Dictionary rmd; - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR,(uint64_t)ZT_VENDOR_ZEROTIER); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MINOR); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,(uint64_t)ZEROTIER_ONE_VERSION_REVISION); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_RULES,(uint64_t)ZT_MAX_NETWORK_RULES); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_CAPABILITIES,(uint64_t)ZT_MAX_NETWORK_CAPABILITIES); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_CAPABILITY_RULES,(uint64_t)ZT_MAX_CAPABILITY_RULES); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0); - rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION); + ScopedPtr< Dictionary > rmd(new Dictionary()); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR,(uint64_t)ZT_VENDOR_ZEROTIER); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MINOR); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,(uint64_t)ZEROTIER_ONE_VERSION_REVISION); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_RULES,(uint64_t)ZT_MAX_NETWORK_RULES); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_CAPABILITIES,(uint64_t)ZT_MAX_NETWORK_CAPABILITIES); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_CAPABILITY_RULES,(uint64_t)ZT_MAX_CAPABILITY_RULES); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0); + rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION); RR->t->networkConfigRequestSent(tPtr,*this,ctrl); if (ctrl == RR->identity.address()) { if (RR->localNetworkController) { - RR->localNetworkController->request(_id,InetAddress(),0xffffffffffffffffULL,RR->identity,rmd); + RR->localNetworkController->request(_id,InetAddress(),0xffffffffffffffffULL,RR->identity,*rmd); } else { this->setNotFound(); } @@ -1275,9 +1259,9 @@ void Network::_requestConfiguration(void *tPtr) Packet outp(ctrl,RR->identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST); outp.append((uint64_t)_id); - const unsigned int rmdSize = rmd.sizeBytes(); + const unsigned int rmdSize = rmd->sizeBytes(); outp.append((uint16_t)rmdSize); - outp.append((const void *)rmd.data(),rmdSize); + outp.append((const void *)rmd->data(),rmdSize); if (_config) { outp.append((uint64_t)_config.revision); outp.append((uint64_t)_config.timestamp); @@ -1373,7 +1357,7 @@ void Network::_announceMulticastGroups(void *tPtr,bool force) void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector &allMulticastGroups) { // Assumes _myMulticastGroups_l and _memberships_l are locked - Packet *const outp = new Packet(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE); + ScopedPtr outp(new Packet(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE)); for(std::vector::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) { if ((outp->size() + 24) >= ZT_PROTO_MAX_PACKET_LENGTH) { @@ -1392,8 +1376,6 @@ void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const st outp->compress(); RR->sw->send(tPtr,*outp,true); } - - delete outp; } std::vector Network::_allMulticastGroups() const diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index 353fe4d37..3d62456b9 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -16,99 +16,93 @@ #include #include "NetworkConfig.hpp" +#include "ScopedPtr.hpp" namespace ZeroTier { bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const { - Buffer *tmp = new Buffer(); + ScopedPtr< Buffer > tmp(new Buffer()); char tmp2[128]; - try { - d.clear(); + d.clear(); - // Try to put the more human-readable fields first + // Try to put the more human-readable fields first - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,this->networkId)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,this->timestamp)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,this->credentialTimeMaxDelta)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REVISION,this->revision)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,this->issuedTo.toString(tmp2))) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET,this->remoteTraceTarget.toString(tmp2))) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL,(uint64_t)this->remoteTraceLevel)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,this->flags)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,(uint64_t)this->multicastLimit)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)this->type)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) return false; - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,this->networkId)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,this->timestamp)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,this->credentialTimeMaxDelta)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REVISION,this->revision)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,this->issuedTo.toString(tmp2))) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET,this->remoteTraceTarget.toString(tmp2))) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL,(uint64_t)this->remoteTraceLevel)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,this->flags)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,(uint64_t)this->multicastLimit)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)this->type)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) return false; - // Then add binary blobs - - if (this->com) { - tmp->clear(); - this->com.serialize(*tmp); - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) return false; - } + // Then add binary blobs + if (this->com) { tmp->clear(); - for(unsigned int i=0;icapabilityCount;++i) - this->capabilities[i].serialize(*tmp); - if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) return false; - } + this->com.serialize(*tmp); + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) return false; + } + tmp->clear(); + for(unsigned int i=0;icapabilityCount;++i) + this->capabilities[i].serialize(*tmp); + if (tmp->size()) { + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) return false; + } + + tmp->clear(); + for(unsigned int i=0;itagCount;++i) + this->tags[i].serialize(*tmp); + if (tmp->size()) { + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) return false; + } + + tmp->clear(); + for(unsigned int i=0;icertificateOfOwnershipCount;++i) + this->certificatesOfOwnership[i].serialize(*tmp); + if (tmp->size()) { + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) return false; + } + + tmp->clear(); + for(unsigned int i=0;ispecialistCount;++i) + tmp->append((uint64_t)this->specialists[i]); + if (tmp->size()) { + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) return false; + } + + tmp->clear(); + for(unsigned int i=0;irouteCount;++i) { + reinterpret_cast(&(this->routes[i].target))->serialize(*tmp); + reinterpret_cast(&(this->routes[i].via))->serialize(*tmp); + tmp->append((uint16_t)this->routes[i].flags); + tmp->append((uint16_t)this->routes[i].metric); + } + if (tmp->size()) { + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) return false; + } + + tmp->clear(); + for(unsigned int i=0;istaticIpCount;++i) + this->staticIps[i].serialize(*tmp); + if (tmp->size()) { + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) return false; + } + + if (this->ruleCount) { tmp->clear(); - for(unsigned int i=0;itagCount;++i) - this->tags[i].serialize(*tmp); + Capability::serializeRules(*tmp,rules,ruleCount); if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) return false; + if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) return false; } - - tmp->clear(); - for(unsigned int i=0;icertificateOfOwnershipCount;++i) - this->certificatesOfOwnership[i].serialize(*tmp); - if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) return false; - } - - tmp->clear(); - for(unsigned int i=0;ispecialistCount;++i) - tmp->append((uint64_t)this->specialists[i]); - if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) return false; - } - - tmp->clear(); - for(unsigned int i=0;irouteCount;++i) { - reinterpret_cast(&(this->routes[i].target))->serialize(*tmp); - reinterpret_cast(&(this->routes[i].via))->serialize(*tmp); - tmp->append((uint16_t)this->routes[i].flags); - tmp->append((uint16_t)this->routes[i].metric); - } - if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) return false; - } - - tmp->clear(); - for(unsigned int i=0;istaticIpCount;++i) - this->staticIps[i].serialize(*tmp); - if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) return false; - } - - if (this->ruleCount) { - tmp->clear(); - Capability::serializeRules(*tmp,rules,ruleCount); - if (tmp->size()) { - if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) return false; - } - } - - delete tmp; - } catch ( ... ) { - delete tmp; - throw; } return true; @@ -117,25 +111,21 @@ bool NetworkConfig::toDictionary(Dictionary &d,b bool NetworkConfig::fromDictionary(const Dictionary &d) { static const NetworkConfig NIL_NC; - Buffer *const tmp = new Buffer(); + ScopedPtr< Buffer > tmp(new Buffer()); try { *this = NIL_NC; // Fields that are always present, new or old this->networkId = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,0); - if (!this->networkId) { - delete tmp; + if (!this->networkId) return false; - } this->timestamp = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,0); this->credentialTimeMaxDelta = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,0); this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION,0); this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,0); - if (!this->issuedTo) { - delete tmp; + if (!this->issuedTo) return false; - } this->remoteTraceTarget = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET); this->remoteTraceLevel = (Trace::Level)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL); this->multicastLimit = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,0); @@ -148,7 +138,6 @@ bool NetworkConfig::fromDictionary(const Dictionarymtu = ZT_MAX_MTU; if (d.getUI(ZT_NETWORKCONFIG_DICT_KEY_VERSION,0) < 6) { - delete tmp; return false; } else { // Otherwise we can use the new fields @@ -228,10 +217,8 @@ bool NetworkConfig::fromDictionary(const DictionarysetConfiguration((void *)0,nc,true); } else { - Dictionary *dconf = new Dictionary(); - try { - if (nc.toDictionary(*dconf,sendLegacyFormatConfig)) { - uint64_t configUpdateId = Utils::random(); - if (!configUpdateId) ++configUpdateId; + ScopedPtr< Dictionary > dconf(new Dictionary()); + if (nc.toDictionary(*dconf,sendLegacyFormatConfig)) { + uint64_t configUpdateId = Utils::random(); + if (!configUpdateId) ++configUpdateId; - const unsigned int totalSize = dconf->sizeBytes(); - unsigned int chunkIndex = 0; - while (chunkIndex < totalSize) { - const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256))); - Packet outp(destination,RR->identity.address(),(requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG); - if (requestPacketId) { - outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST); - outp.append(requestPacketId); - } - - const unsigned int sigStart = outp.size(); - outp.append(nwid); - outp.append((uint16_t)chunkLen); - outp.append((const void *)(dconf->data() + chunkIndex),chunkLen); - - outp.append((uint8_t)0); // no flags - outp.append((uint64_t)configUpdateId); - outp.append((uint32_t)totalSize); - outp.append((uint32_t)chunkIndex); - - uint8_t sig[256]; - const unsigned int siglen = RR->identity.sign(reinterpret_cast(outp.data()) + sigStart,outp.size() - sigStart,sig,sizeof(sig)); - outp.append((uint8_t)1); - outp.append((uint16_t)siglen); - outp.append(sig,siglen); - - outp.compress(); - RR->sw->send((void *)0,outp,true); - chunkIndex += chunkLen; + const unsigned int totalSize = dconf->sizeBytes(); + unsigned int chunkIndex = 0; + while (chunkIndex < totalSize) { + const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256))); + Packet outp(destination,RR->identity.address(),(requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG); + if (requestPacketId) { + outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST); + outp.append(requestPacketId); } + + const unsigned int sigStart = outp.size(); + outp.append(nwid); + outp.append((uint16_t)chunkLen); + outp.append((const void *)(dconf->data() + chunkIndex),chunkLen); + + outp.append((uint8_t)0); // no flags + outp.append((uint64_t)configUpdateId); + outp.append((uint32_t)totalSize); + outp.append((uint32_t)chunkIndex); + + uint8_t sig[256]; + const unsigned int siglen = RR->identity.sign(reinterpret_cast(outp.data()) + sigStart,outp.size() - sigStart,sig,sizeof(sig)); + outp.append((uint8_t)1); + outp.append((uint16_t)siglen); + outp.append(sig,siglen); + + outp.compress(); + RR->sw->send((void *)0,outp,true); + chunkIndex += chunkLen; } - delete dconf; - } catch ( ... ) { - delete dconf; - throw; } } } diff --git a/node/Peer.cpp b/node/Peer.cpp index 7bde40001..6a8bbc009 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -22,6 +22,7 @@ #include "InetAddress.hpp" #include "RingBuffer.hpp" #include "Utils.hpp" +#include "ScopedPtr.hpp" namespace ZeroTier { @@ -173,7 +174,7 @@ void Peer::received( if (pathsToPush.size() > 0) { std::vector::const_iterator p(pathsToPush.begin()); while (p != pathsToPush.end()) { - Packet *const outp = new Packet(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS); + ScopedPtr outp(new Packet(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS)); outp->addSize(2); // leave room for count unsigned int count = 0; while ((p != pathsToPush.end())&&((outp->size() + 24) < 1200)) { @@ -205,7 +206,6 @@ void Peer::received( outp->armor(_key,true); path->send(RR,tPtr,outp->data(),outp->size(),now); } - delete outp; } } } diff --git a/node/ScopedPtr.hpp b/node/ScopedPtr.hpp new file mode 100644 index 000000000..5fa97729a --- /dev/null +++ b/node/ScopedPtr.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2023-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#ifndef ZT_SCOPEDPTR_HPP +#define ZT_SCOPEDPTR_HPP + +#include "Constants.hpp" + +namespace ZeroTier { + +/** + * Simple scoped pointer + * + * This is used in the core to avoid requiring C++11 and because auto_ptr is weird. + */ +template +class ScopedPtr +{ +public: + ZT_ALWAYS_INLINE ScopedPtr(T *const p) : _p(p) {} + ZT_ALWAYS_INLINE ~ScopedPtr() { delete _p; } + + ZT_ALWAYS_INLINE T *operator->() const { return _p; } + ZT_ALWAYS_INLINE T &operator*() const { return *_p; } + ZT_ALWAYS_INLINE operator bool() const { return (_p != (T *)0); } + ZT_ALWAYS_INLINE T *ptr() const { return _p; } + + ZT_ALWAYS_INLINE bool operator==(const ScopedPtr &p) const { return (_p == p._p); } + ZT_ALWAYS_INLINE bool operator!=(const ScopedPtr &p) const { return (_p != p._p); } + ZT_ALWAYS_INLINE bool operator==(T *const p) const { return (_p == p); } + ZT_ALWAYS_INLINE bool operator!=(T *const p) const { return (_p != p); } + +private: + ZT_ALWAYS_INLINE ScopedPtr() {} + T *const _p; +}; + +} // namespace ZeroTier + +#endif