Browse Source

Add ability to fully specify controller fingerprint on join for the paranoid.

Adam Ierymenko 5 years ago
parent
commit
1df7f21f5f
5 changed files with 27 additions and 9 deletions
  1. 2 1
      include/ZeroTierCore.h
  2. 14 2
      node/Network.cpp
  3. 3 1
      node/Network.hpp
  4. 7 4
      node/Node.cpp
  5. 1 1
      node/Node.hpp

+ 2 - 1
include/ZeroTierCore.h

@@ -1867,11 +1867,12 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processBackgroundTasks(
  *
  * @param node Node instance
  * @param nwid 64-bit ZeroTier network ID
+ * @param fingerprintHash If non-NULL this is the full fingerprint of the controller
  * @param uptr An arbitrary pointer to associate with this network (default: NULL)
  * @param tptr Thread pointer to pass to functions/callbacks resulting from this call
  * @return OK (0) or error code if a fatal error condition has occurred
  */
-ZT_SDK_API enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tptr);
+ZT_SDK_API enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,const ZT_Fingerprint *controllerFingerprint,void *uptr,void *tptr);
 
 /**
  * Leave a network

+ 14 - 2
node/Network.cpp

@@ -158,7 +158,7 @@ _doZtFilterResult _doZtFilter(
 						case ZT_NETWORK_RULE_ACTION_TEE:
 						case ZT_NETWORK_RULE_ACTION_WATCH:
 						case ZT_NETWORK_RULE_ACTION_REDIRECT:
-							if (RR->identity.address() == rules[rn].v.fwd.address)
+							if (RR->identity.address().toInt() == rules[rn].v.fwd.address)
 								superAccept = true;
 							break;
 						default:
@@ -533,7 +533,7 @@ _doZtFilterResult _doZtFilter(
 
 const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL),0);
 
-Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *uptr,const NetworkConfig *nconf) :
+Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const Fingerprint &controllerFingerprint,void *uptr,const NetworkConfig *nconf) :
 	RR(renv),
 	_uPtr(uptr),
 	_id(nwid),
@@ -543,6 +543,9 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *u
 	_destroyed(false),
 	_netconfFailure(NETCONF_FAILURE_NONE)
 {
+	if (controllerFingerprint)
+		_controllerFingerprint = controllerFingerprint;
+
 	if (nconf) {
 		this->setConfiguration(tPtr,*nconf,false);
 		_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
@@ -868,6 +871,15 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg)
 
 uint64_t Network::handleConfigChunk(void *tPtr,uint64_t packetId,const SharedPtr<Peer> &source,const Buf &chunk,int ptr,int size)
 {
+	// If the controller's full fingerprint is known or was explicitly specified on join(),
+	// require that the controller's identity match. Otherwise learn it.
+	if (_controllerFingerprint) {
+		if (source->identity().fingerprint() != _controllerFingerprint)
+			return 0;
+	} else {
+		_controllerFingerprint = source->identity().fingerprint();
+	}
+
 	return 0;
 #if 0
 	if (_destroyed)

+ 3 - 1
node/Network.hpp

@@ -67,10 +67,11 @@ public:
 	 * @param renv Runtime environment
 	 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
 	 * @param nwid Network ID
+	 * @param controllerFingerprint Initial controller fingerprint if non-NULL
 	 * @param uptr Arbitrary pointer used by externally-facing API (for user use)
 	 * @param nconf Network config, if known
 	 */
-	Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *uptr,const NetworkConfig *nconf);
+	Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const Fingerprint &controllerFingerprint,void *uptr,const NetworkConfig *nconf);
 
 	~Network();
 
@@ -350,6 +351,7 @@ private:
 	const RuntimeEnvironment *const RR;
 	void *_uPtr;
 	const uint64_t _id;
+	Fingerprint _controllerFingerprint;
 	MAC _mac; // local MAC address
 	bool _portInitialized;
 

+ 7 - 4
node/Node.cpp

@@ -347,7 +347,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tPtr, int64_t now, volatile int
 	return ZT_RESULT_OK;
 }
 
-ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr)
+ZT_ResultCode Node::join(uint64_t nwid,const ZT_Fingerprint *controllerFingerprint,void *uptr,void *tptr)
 {
 	RWMutex::Lock l(_networks_m);
 
@@ -382,7 +382,10 @@ try_larger_network_hashtable:
 		nw = &(_networks[(unsigned long)(nwidHashed & newNetworksMask)]);
 	}
 
-	nw->set(new Network(RR,tptr,nwid,uptr,(const NetworkConfig *)0));
+	Fingerprint fp;
+	if (controllerFingerprint)
+		Utils::copy<sizeof(ZT_Fingerprint)>(fp.apiFingerprint(),controllerFingerprint);
+	nw->set(new Network(RR,tptr,nwid,fp,uptr,(const NetworkConfig *)0));
 
 	return ZT_RESULT_OK;
 }
@@ -928,10 +931,10 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,void *tptr,int64
 	}
 }
 
-enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tptr)
+enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,const ZT_Fingerprint *controllerFingerprint,void *uptr,void *tptr)
 {
 	try {
-		return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid,uptr,tptr);
+		return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid,controllerFingerprint,uptr,tptr);
 	} catch (std::bad_alloc &exc) {
 		return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
 	} catch ( ... ) {

+ 1 - 1
node/Node.hpp

@@ -88,7 +88,7 @@ public:
 		unsigned int frameLength,
 		volatile int64_t *nextBackgroundTaskDeadline);
 	ZT_ResultCode processBackgroundTasks(void *tPtr, int64_t now, volatile int64_t *nextBackgroundTaskDeadline);
-	ZT_ResultCode join(uint64_t nwid,void *uptr,void *tptr);
+	ZT_ResultCode join(uint64_t nwid,const ZT_Fingerprint *controllerFingerprint,void *uptr,void *tptr);
 	ZT_ResultCode leave(uint64_t nwid,void **uptr,void *tptr);
 	ZT_ResultCode multicastSubscribe(void *tPtr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
 	ZT_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);