2
0
Эх сурвалжийг харах

Plumbing for network setting control, and GitHub issue #330

Adam Ierymenko 9 жил өмнө
parent
commit
674b84d908

+ 14 - 2
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)
 bool IncomingPacket::_doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
 {
 {
 	try {
 	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 uint64_t pid = packetId();
 			const unsigned int difficulty = (*this)[ZT_PACKET_IDX_PAYLOAD + 1];
 			const unsigned int difficulty = (*this)[ZT_PACKET_IDX_PAYLOAD + 1];
 			const unsigned int challengeLength = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 2);
 			const unsigned int challengeLength = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 2);

+ 22 - 7
service/OneService.cpp

@@ -531,15 +531,20 @@ public:
 	// Configured networks
 	// Configured networks
 	struct NetworkState
 	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;
 		EthernetTap *tap;
 		ZT_VirtualNetworkConfig config; // memcpy() of raw config from core
 		ZT_VirtualNetworkConfig config; // memcpy() of raw config from core
 		std::vector<InetAddress> managedIps;
 		std::vector<InetAddress> managedIps;
 		std::list<ManagedRoute> managedRoutes;
 		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;
 	std::map<uint64_t,NetworkState> _nets;
 	Mutex _nets_m;
 	Mutex _nets_m;
@@ -998,15 +1003,25 @@ public:
 		_phy.whack();
 		_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
 	// Begin private implementation methods
 
 
 	// Checks if a managed IP or route target is allowed
 	// 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 &addr)
 	{
 	{
-		if (!n.allowManaged)
+		if (!n.settings.allowManaged)
 			return false;
 			return false;
 		if (addr.isDefaultRoute())
 		if (addr.isDefaultRoute())
-			return n.allowDefault;
+			return n.settings.allowDefault;
 		switch(addr.ipScope()) {
 		switch(addr.ipScope()) {
 			case InetAddress::IP_SCOPE_NONE:
 			case InetAddress::IP_SCOPE_NONE:
 			case InetAddress::IP_SCOPE_MULTICAST:
 			case InetAddress::IP_SCOPE_MULTICAST:
@@ -1014,7 +1029,7 @@ public:
 			case InetAddress::IP_SCOPE_LINK_LOCAL:
 			case InetAddress::IP_SCOPE_LINK_LOCAL:
 				return false;
 				return false;
 			case InetAddress::IP_SCOPE_GLOBAL:
 			case InetAddress::IP_SCOPE_GLOBAL:
-				return n.allowGlobal;
+				return n.settings.allowGlobal;
 			default:
 			default:
 				return true;
 				return true;
 		}
 		}

+ 30 - 0
service/OneService.hpp

@@ -67,6 +67,27 @@ public:
 		ONE_IDENTITY_COLLISION = 3
 		ONE_IDENTITY_COLLISION = 3
 	};
 	};
 
 
+	/**
+	 * 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
 	 * @return Platform default home path or empty string if this platform doesn't have one
 	 */
 	 */
@@ -130,6 +151,15 @@ public:
 	 */
 	 */
 	virtual void terminate() = 0;
 	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
 	 * @return True if service is still running
 	 */
 	 */