diff options
-rw-r--r-- | node/IncomingPacket.cpp | 16 | ||||
-rw-r--r-- | service/OneService.cpp | 29 | ||||
-rw-r--r-- | service/OneService.hpp | 30 |
3 files changed, 66 insertions, 9 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 532abafa..871297f7 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -1192,8 +1192,20 @@ bool IncomingPacket::_doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const S bool IncomingPacket::_doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer) { try { - // Right now this is only allowed from root servers -- may be allowed from controllers and relays later. - if (RR->topology->isRoot(peer->identity())) { + // If this were allowed from anyone, it would itself be a DOS vector. Right + // now we only allow it from roots and controllers of networks you have joined. + bool allowed = RR->topology->isRoot(peer->identity()); + if (!allowed) { + std::vector< SharedPtr<Network> > allNetworks(RR->node->allNetworks()); + for(std::vector< SharedPtr<Network> >::const_iterator n(allNetworks.begin());n!=allNetworks.end();++n) { + if (peer->address() == (*n)->controller()) { + allowed = true; + break; + } + } + } + + if (allowed) { const uint64_t pid = packetId(); const unsigned int difficulty = (*this)[ZT_PACKET_IDX_PAYLOAD + 1]; const unsigned int challengeLength = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 2); diff --git a/service/OneService.cpp b/service/OneService.cpp index 8b27ba49..139b1e15 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -531,15 +531,20 @@ public: // Configured networks struct NetworkState { - NetworkState() : tap((EthernetTap *)0),managedIps(),managedRoutes(),allowManaged(true),allowGlobal(true),allowDefault(true) {} + NetworkState() : + tap((EthernetTap *)0) + { + // Default network permission settings: allow management of IPs and routes but only for private and "pseudo-private" IP spaces + settings.allowManaged = true; + settings.allowGlobal = false; + settings.allowDefault = false; + } EthernetTap *tap; ZT_VirtualNetworkConfig config; // memcpy() of raw config from core std::vector<InetAddress> managedIps; std::list<ManagedRoute> managedRoutes; - bool allowManaged; // allow managed addresses and routes - bool allowGlobal; // allow global (non-private) IP routes? - bool allowDefault; // allow default route? + NetworkSettings settings; }; std::map<uint64_t,NetworkState> _nets; Mutex _nets_m; @@ -998,15 +1003,25 @@ public: _phy.whack(); } + virtual bool getNetworkSettings(const uint64_t nwid,NetworkSettings &settings) const + { + Mutex::Lock _l(_nets_m); + std::map<uint64_t,NetworkState>::const_iterator n(_nets.find(nwid)); + if (n == _nets.end()) + return false; + memcpy(&settings,&(n->second.settings),sizeof(NetworkSettings)); + return true; + } + // Begin private implementation methods // Checks if a managed IP or route target is allowed bool checkIfManagedIsAllowed(const NetworkState &n,const InetAddress &addr) { - if (!n.allowManaged) + if (!n.settings.allowManaged) return false; if (addr.isDefaultRoute()) - return n.allowDefault; + return n.settings.allowDefault; switch(addr.ipScope()) { case InetAddress::IP_SCOPE_NONE: case InetAddress::IP_SCOPE_MULTICAST: @@ -1014,7 +1029,7 @@ public: case InetAddress::IP_SCOPE_LINK_LOCAL: return false; case InetAddress::IP_SCOPE_GLOBAL: - return n.allowGlobal; + return n.settings.allowGlobal; default: return true; } diff --git a/service/OneService.hpp b/service/OneService.hpp index 21e80d3f..0faf62f1 100644 --- a/service/OneService.hpp +++ b/service/OneService.hpp @@ -68,6 +68,27 @@ public: }; /** + * Local settings for each network + */ + struct NetworkSettings + { + /** + * Allow this network to configure IP addresses and routes? + */ + bool allowManaged; + + /** + * Allow configuration of IPs and routes within global (Internet) IP space? + */ + bool allowGlobal; + + /** + * Allow overriding of system default routes for "full tunnel" operation? + */ + bool allowDefault; + }; + + /** * @return Platform default home path or empty string if this platform doesn't have one */ static std::string platformDefaultHomePath(); @@ -131,6 +152,15 @@ public: virtual void terminate() = 0; /** + * Get local settings for a network + * + * @param nwid Network ID + * @param settings Buffer to fill with local network settings + * @return True if network was found and settings is filled + */ + virtual bool getNetworkSettings(const uint64_t nwid,NetworkSettings &settings) const = 0; + + /** * @return True if service is still running */ inline bool isRunning() const { return (this->reasonForTermination() == ONE_STILL_RUNNING); } |