From 653573025598c982aa1785cc859e08336c7174ec Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jul 2016 08:42:36 -0700 Subject: GitHub issue #352 --- service/OneService.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'service') diff --git a/service/OneService.cpp b/service/OneService.cpp index c1b24050..89d9501d 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1041,13 +1041,13 @@ public: // Begin private implementation methods // Checks if a managed IP or route target is allowed - bool checkIfManagedIsAllowed(const NetworkState &n,const InetAddress &addr) + bool checkIfManagedIsAllowed(const NetworkState &n,const InetAddress &target) { if (!n.settings.allowManaged) return false; - if (addr.isDefaultRoute()) + if (target.isDefaultRoute()) return n.settings.allowDefault; - switch(addr.ipScope()) { + switch(target.ipScope()) { case InetAddress::IP_SCOPE_NONE: case InetAddress::IP_SCOPE_MULTICAST: case InetAddress::IP_SCOPE_LOOPBACK: @@ -1099,10 +1099,12 @@ public: Utils::scopy(tapdev,sizeof(tapdev),n.tap->deviceName().c_str()); #endif + std::vector myIps(n.tap->ips()); + // Nuke applied routes that are no longer in n.config.routes[] and/or are not allowed for(std::list::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();) { bool haveRoute = false; - if (checkIfManagedIsAllowed(n,mr->target())) { + if ( (checkIfManagedIsAllowed(n,mr->target())) && ((!mr->via())||(std::find(myIps.begin(),myIps.end(),mr->via()) == myIps.end())) ) { for(unsigned int i=0;i(&(n.config.routes[i].target)); const InetAddress *const via = reinterpret_cast(&(n.config.routes[i].via)); @@ -1124,7 +1126,7 @@ public: const InetAddress *const target = reinterpret_cast(&(n.config.routes[i].target)); const InetAddress *const via = reinterpret_cast(&(n.config.routes[i].via)); - if (!checkIfManagedIsAllowed(n,*target)) + if ( (!checkIfManagedIsAllowed(n,*target)) || ((via->ss_family == target->ss_family)&&(std::find(myIps.begin(),myIps.end(),*via) != myIps.end())) ) continue; bool haveRoute = false; -- cgit v1.2.3 From cdb5ceac7b5a368d777df7f7de4fadb2555fc00a Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jul 2016 09:43:12 -0700 Subject: Should remove old IPs before trying to add new ones. --- service/OneService.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'service') diff --git a/service/OneService.cpp b/service/OneService.cpp index 89d9501d..c19b266a 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1075,18 +1075,18 @@ public: std::sort(newManagedIps.begin(),newManagedIps.end()); newManagedIps.erase(std::unique(newManagedIps.begin(),newManagedIps.end()),newManagedIps.end()); - for(std::vector::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) { - if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) { - if (!n.tap->addIp(*ip)) - fprintf(stderr,"ERROR: unable to add ip address %s"ZT_EOL_S, ip->toString().c_str()); - } - } for(std::vector::iterator ip(n.managedIps.begin());ip!=n.managedIps.end();++ip) { if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) { if (!n.tap->removeIp(*ip)) fprintf(stderr,"ERROR: unable to remove ip address %s"ZT_EOL_S, ip->toString().c_str()); } } + for(std::vector::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) { + if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) { + if (!n.tap->addIp(*ip)) + fprintf(stderr,"ERROR: unable to add ip address %s"ZT_EOL_S, ip->toString().c_str()); + } + } n.managedIps.swap(newManagedIps); } -- cgit v1.2.3 From 96576757552f1b0ce002df3e904419b7bfca62f8 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jul 2016 11:30:22 -0700 Subject: Plumbing through trusted path stuff to OneService. --- include/ZeroTierOne.h | 5 +++++ node/IncomingPacket.cpp | 10 ++++++---- node/Node.cpp | 1 + service/ControlPlane.cpp | 4 +++- service/OneService.cpp | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 5 deletions(-) (limited to 'service') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index f5523461..2d7b007b 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -892,6 +892,11 @@ typedef struct */ uint64_t lastReceive; + /** + * Is this a trusted path? If so this will be its nonzero ID. + */ + uint64_t trustedPathId; + /** * Is path active? */ diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index fb4562ab..6e1eb493 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -43,6 +43,8 @@ namespace ZeroTier { bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,bool deferred) { try { + const Address sourceAddress(source()); + // Check for trusted paths or unencrypted HELLOs (HELLO is the only packet sent in the clear) const unsigned int c = cipher(); bool trusted = false; @@ -52,8 +54,9 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,bool deferred) // packets are dropped on the floor. if (RR->topology->shouldInboundPathBeTrusted(_remoteAddress,trustedPathId())) { trusted = true; + printf("TRUSTED PATH packet from %s(%s), trusted path ID %llx\n",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str(),trustedPathId()); } else { - TRACE("dropped packet from %s(%s), cipher set to trusted path mode but path %.16llx@%s is not trusted!",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),trustedPathId(),_remoteAddress.toString().c_str()); + TRACE("dropped packet from %s(%s), cipher set to trusted path mode but path %llx@%s is not trusted!",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str(),trustedPathId(),_remoteAddress.toString().c_str()); return true; } } else if ((c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)&&(verb() == Packet::VERB_HELLO)) { @@ -71,18 +74,17 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,bool deferred) } } - const Address sourceAddress(source()); SharedPtr peer(RR->topology->getPeer(sourceAddress)); if (peer) { if (!trusted) { if (!dearmor(peer->key())) { - TRACE("dropped packet from %s(%s), MAC authentication failed (size: %u)",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),size()); + TRACE("dropped packet from %s(%s), MAC authentication failed (size: %u)",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str(),size()); return true; } } if (!uncompress()) { - TRACE("dropped packet from %s(%s), compressed data invalid",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); + TRACE("dropped packet from %s(%s), compressed data invalid",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str()); return true; } diff --git a/node/Node.cpp b/node/Node.cpp index 058df32d..13085028 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -447,6 +447,7 @@ ZT_PeerList *Node::peers() const p->paths[p->pathCount].lastReceive = path->lastReceived(); p->paths[p->pathCount].active = path->active(_now) ? 1 : 0; p->paths[p->pathCount].preferred = ((bestPath)&&(*path == *bestPath)) ? 1 : 0; + p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust(path->address()); ++p->pathCount; } } diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp index 0e2b530d..ced36e75 100644 --- a/service/ControlPlane.cpp +++ b/service/ControlPlane.cpp @@ -190,13 +190,15 @@ static std::string _jsonEnumerate(unsigned int depth,const ZT_PeerPhysicalPath * "%s\t\"lastSend\": %llu,\n" "%s\t\"lastReceive\": %llu,\n" "%s\t\"active\": %s,\n" - "%s\t\"preferred\": %s\n" + "%s\t\"preferred\": %s,\n" + "%s\t\"trustedPathId\": %llx\n" "%s}", prefix,_jsonEscape(reinterpret_cast(&(pp[i].address))->toString()).c_str(), prefix,pp[i].lastSend, prefix,pp[i].lastReceive, prefix,(pp[i].active == 0) ? "false" : "true", prefix,(pp[i].preferred == 0) ? "false" : "true", + prefix,pp[i].trustedPathId, prefix); buf.append(json); } diff --git a/service/OneService.cpp b/service/OneService.cpp index c19b266a..bbd15965 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -759,6 +759,38 @@ public: for(int i=0;i<3;++i) _portsBE[i] = Utils::hton((uint16_t)_ports[i]); + { + FILE *trustpaths = fopen((_homePath + ZT_PATH_SEPARATOR_S + "trustpaths").c_str(),"r"); + uint64_t ids[ZT_MAX_TRUSTED_PATHS]; + InetAddress addresses[ZT_MAX_TRUSTED_PATHS]; + if (trustpaths) { + char buf[1024]; + unsigned int count = 0; + while ((fgets(buf,sizeof(buf),trustpaths))&&(count < ZT_MAX_TRUSTED_PATHS)) { + int fno = 0; + char *saveptr = (char *)0; + uint64_t trustedPathId = 0; + InetAddress trustedPathNetwork; + for(char *f=Utils::stok(buf,"=\r\n \t",&saveptr);(f);f=Utils::stok((char *)0,"=\r\n \t",&saveptr)) { + if (fno == 0) { + trustedPathId = Utils::hexStrToU64(f); + } else if (fno == 1) { + trustedPathNetwork = InetAddress(f); + } else break; + ++fno; + } + if ( (trustedPathId != 0) && ((trustedPathNetwork.ss_family == AF_INET)||(trustedPathNetwork.ss_family == AF_INET6)) && (trustedPathNetwork.ipScope() != InetAddress::IP_SCOPE_GLOBAL) && (trustedPathNetwork.netmaskBits() > 0) ) { + ids[count] = trustedPathId; + addresses[count] = trustedPathNetwork; + ++count; + } + } + fclose(trustpaths); + if (count) + _node->setTrustedPaths(reinterpret_cast(addresses),ids,count); + } + } + #ifdef ZT_ENABLE_NETWORK_CONTROLLER _controller = new SqliteNetworkController(_node,(_homePath + ZT_PATH_SEPARATOR_S + ZT_CONTROLLER_DB_PATH).c_str(),(_homePath + ZT_PATH_SEPARATOR_S + "circuitTestResults.d").c_str()); _node->setNetconfMaster((void *)_controller); -- cgit v1.2.3 From b5e9d3f6f413de4e28caf4c32024a2a1f7ab1d2f Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jul 2016 11:41:19 -0700 Subject: Rename file to be intuitive. --- service/OneService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'service') diff --git a/service/OneService.cpp b/service/OneService.cpp index bbd15965..71bf8e68 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -760,7 +760,7 @@ public: _portsBE[i] = Utils::hton((uint16_t)_ports[i]); { - FILE *trustpaths = fopen((_homePath + ZT_PATH_SEPARATOR_S + "trustpaths").c_str(),"r"); + FILE *trustpaths = fopen((_homePath + ZT_PATH_SEPARATOR_S + "trustedpaths").c_str(),"r"); uint64_t ids[ZT_MAX_TRUSTED_PATHS]; InetAddress addresses[ZT_MAX_TRUSTED_PATHS]; if (trustpaths) { -- cgit v1.2.3 From 6ec3464ee94dc9059477c6ef8f7c4d7e4045b914 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jul 2016 13:58:15 -0700 Subject: JSON fix for trusted paths (does not affect normal op) --- service/ControlPlane.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'service') diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp index ced36e75..a10697a9 100644 --- a/service/ControlPlane.cpp +++ b/service/ControlPlane.cpp @@ -191,7 +191,7 @@ static std::string _jsonEnumerate(unsigned int depth,const ZT_PeerPhysicalPath * "%s\t\"lastReceive\": %llu,\n" "%s\t\"active\": %s,\n" "%s\t\"preferred\": %s,\n" - "%s\t\"trustedPathId\": %llx\n" + "%s\t\"trustedPathId\": %llu\n" "%s}", prefix,_jsonEscape(reinterpret_cast(&(pp[i].address))->toString()).c_str(), prefix,pp[i].lastSend, -- cgit v1.2.3 From 89125150112fecca2372e5531bfefe6becd91129 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jul 2016 15:00:30 -0700 Subject: Fix to fix to GitHub issue #352 --- service/OneService.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'service') diff --git a/service/OneService.cpp b/service/OneService.cpp index 71bf8e68..13820f5c 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1092,6 +1092,16 @@ public: } } + // Match only an IP from a vector of IPs -- used in syncManagedStuff() + bool matchIpOnly(const std::vector &ips,const InetAddress &ip) const + { + for(std::vector::const_iterator i(ips.begin());i!=ips.end();++i) { + if (i->ipsEqual(ip)) + return true; + } + return false; + } + // Apply or update managed IPs for a configured network (be sure n.tap exists) void syncManagedStuff(NetworkState &n,bool syncIps,bool syncRoutes) { @@ -1136,7 +1146,7 @@ public: // Nuke applied routes that are no longer in n.config.routes[] and/or are not allowed for(std::list::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();) { bool haveRoute = false; - if ( (checkIfManagedIsAllowed(n,mr->target())) && ((!mr->via())||(std::find(myIps.begin(),myIps.end(),mr->via()) == myIps.end())) ) { + if ( (checkIfManagedIsAllowed(n,mr->target())) && ((mr->via().ss_family != mr->target().ss_family)||(!matchIpOnly(myIps,mr->via()))) ) { for(unsigned int i=0;i(&(n.config.routes[i].target)); const InetAddress *const via = reinterpret_cast(&(n.config.routes[i].via)); @@ -1158,7 +1168,7 @@ public: const InetAddress *const target = reinterpret_cast(&(n.config.routes[i].target)); const InetAddress *const via = reinterpret_cast(&(n.config.routes[i].via)); - if ( (!checkIfManagedIsAllowed(n,*target)) || ((via->ss_family == target->ss_family)&&(std::find(myIps.begin(),myIps.end(),*via) != myIps.end())) ) + if ( (!checkIfManagedIsAllowed(n,*target)) || ((via->ss_family == target->ss_family)&&(matchIpOnly(myIps,*via))) ) continue; bool haveRoute = false; -- cgit v1.2.3