diff options
| -rw-r--r-- | netconf-service/Makefile | 4 | ||||
| -rw-r--r-- | netconf-service/netconf.cpp | 62 | ||||
| -rw-r--r-- | node/Node.cpp | 4 | 
3 files changed, 45 insertions, 25 deletions
diff --git a/netconf-service/Makefile b/netconf-service/Makefile index fc26ddbb..23067d48 100644 --- a/netconf-service/Makefile +++ b/netconf-service/Makefile @@ -1,7 +1,7 @@  all:  	gcc -O6 -c ../ext/lz4/lz4hc.c ../ext/lz4/lz4.c -	g++ -DZT_OSNAME="linux" -DZT_ARCH="x86_64" -I/usr/include/mysql -I../ext/bin/libcrypto/include -O -pthread -o netconf.service netconf.cpp ../node/Utils.cpp ../node/Identity.cpp ../node/Salsa20.cpp ../node/C25519.cpp ../node/SHA512.cpp lz4.o lz4hc.o -lmysqlpp -	g++ -DZT_OSNAME="linux" -DZT_ARCH="x86_64" -I/usr/include/mysql -I../ext/bin/libcrypto/include -O -pthread -o netconf-test netconf-test.cpp ../node/Utils.cpp ../node/Identity.cpp ../node/Salsa20.cpp ../node/Logger.cpp ../node/Service.cpp ../node/C25519.cpp ../node/SHA512.cpp lz4.o lz4hc.o +	g++ -DZT_OSNAME="linux" -DZT_ARCH="x86_64" -I/usr/include/mysql -I../ext/bin/libcrypto/include -O -pthread -o netconf.service netconf.cpp ../node/Utils.cpp ../node/Identity.cpp ../node/Salsa20.cpp ../node/C25519.cpp ../node/SHA512.cpp ../node/CertificateOfMembership.cpp lz4.o lz4hc.o -lmysqlpp +#	g++ -DZT_OSNAME="linux" -DZT_ARCH="x86_64" -I/usr/include/mysql -I../ext/bin/libcrypto/include -O -pthread -o netconf-test netconf-test.cpp ../node/Utils.cpp ../node/Identity.cpp ../node/Salsa20.cpp ../node/Logger.cpp ../node/Service.cpp ../node/C25519.cpp ../node/SHA512.cpp lz4.o lz4hc.o  clean:  	rm -f *.o netconf.service netconf-test diff --git a/netconf-service/netconf.cpp b/netconf-service/netconf.cpp index ddb838c1..7a905863 100644 --- a/netconf-service/netconf.cpp +++ b/netconf-service/netconf.cpp @@ -69,11 +69,13 @@  #include <mysql++/mysql++.h> +#include "../node/Constants.hpp"  #include "../node/Dictionary.hpp"  #include "../node/Identity.hpp"  #include "../node/Utils.hpp"  #include "../node/Mutex.hpp"  #include "../node/NetworkConfig.hpp" +#include "../node/CertificateOfMembership.hpp"  using namespace ZeroTier;  using namespace mysqlpp; @@ -116,6 +118,7 @@ int main(int argc,char **argv)  	}  	char buf[131072],buf2[131072]; +	Identity signingIdentity;  	std::string dictBuf;  	try { @@ -195,7 +198,15 @@ int main(int argc,char **argv)  		try {  			const std::string &reqType = request.get("type"); -			if (reqType == "netconf-request") { // NETWORK_CONFIG_REQUEST packet +			if (reqType == "netconf-init") { // initialization to set things like netconf's identity +				Identity netconfId(request.get("netconfId")); +				if ((netconfId)&&(netconfId.hasPrivate())) +					signingIdentity = netconfId; +				else { +					fprintf(stderr,"netconfId invalid or lacks private key\n"); +					return -1; +				} +			} else if (reqType == "netconf-request") { // NETWORK_CONFIG_REQUEST packet  				// Deserialize querying peer identity and network ID  				Identity peerIdentity(request.get("peerId"));  				uint64_t nwid = strtoull(request.get("nwid").c_str(),(char **)0,16); @@ -224,7 +235,7 @@ int main(int argc,char **argv)  						}  					} else {  						q = dbCon->query(); -						q << "INSERT INTO Node (id,creationTime,lastSeen,identity) VALUES (" << peerIdentity.address().toInt() << "," << Utils::now() << ",0," << quote << peerIdentity.toString(false) << ")"; +						q << "INSERT INTO Node (id,creationTime,identity) VALUES (" << peerIdentity.address().toInt() << "," << Utils::now() << "," << quote << peerIdentity.toString(false) << ")";  						if (!q.exec()) {  							fprintf(stderr,"error inserting Node row for peer %s, aborting netconf request\n",peerIdentity.address().toString().c_str());  							continue; @@ -233,13 +244,6 @@ int main(int argc,char **argv)  					}  				} -				// Update lastSeen for Node, which is always updated on a netconf request -				{ -					Query q = dbCon->query(); -					q << "UPDATE Node SET lastSeen = " << Utils::now() << " WHERE id = " << peerIdentity.address().toInt(); -					q.exec(); -				} -  				// Look up core network information  				bool isOpen = false;  				unsigned int multicastPrefixBits = 0; @@ -278,11 +282,13 @@ int main(int argc,char **argv)  						write(STDOUT_FILENO,&respml,4);  						write(STDOUT_FILENO,respm.data(),respm.length());  						stdoutWriteLock.unlock(); +  						continue; // ABORT, wait for next request  					}  				}  				// Check membership if this is a closed network +				bool authenticated = true;  				if (!isOpen) {  					Query q = dbCon->query();  					q << "SELECT Node_id FROM NetworkNodes WHERE Network_id = " << nwid << " AND Node_id = " << peerIdentity.address().toInt(); @@ -301,10 +307,28 @@ int main(int argc,char **argv)  						write(STDOUT_FILENO,&respml,4);  						write(STDOUT_FILENO,respm.data(),respm.length());  						stdoutWriteLock.unlock(); -						continue; // ABORT, wait for next request + +						authenticated = false; +					} +				} + +				// Update most recent activity entry for this peer, also indicating +				// whether authentication was successful. +				{ +					if (fromAddr.length()) { +						Query q = dbCon->query(); +						q << "INSERT INTO NetworkActivity (Network_id,Node_id,lastActivityTime,authenticated,lastActivityFrom) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << Utils::now() << "," << (authenticated ? 1 : 0) << "," << quote << fromAddr << ") ON DUPLICATE KEY UPDATE lastActivityTime = VALUES(lastActivityTime),authenticated = VALUES(authenticated),lastActivityFrom = VALUES(lastActivityFrom)"; +						q.exec(); +					} else { +						Query q = dbCon->query(); +						q << "INSERT INTO NetworkActivity (Network_id,Node_id,lastActivityTime,authenticated) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << Utils::now() << "," << (authenticated ? 1 : 0) << ") ON DUPLICATE KEY UPDATE lastActivityTime = VALUES(lastActivityTime),authenticated = VALUES(authenticated)"; +						q.exec();  					}  				} +				if (!authenticated) +					continue; // ABORT, wait for next request +  				// Get list of etherTypes in comma-delimited hex format  				std::string etherTypeWhitelist;  				{ @@ -401,19 +425,6 @@ int main(int argc,char **argv)  					}  				} -				// Update activity table for this network to indicate peer's participation -				{ -					if (fromAddr.length()) { -						Query q = dbCon->query(); -						q << "INSERT INTO NetworkActivity (Network_id,Node_id,lastActivityTime,lastActivityFrom) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << Utils::now() << "," << quote << fromAddr << ") ON DUPLICATE KEY UPDATE lastActivityTime = VALUES(lastActivityTime),lastActivityFrom = VALUES(lastActivityFrom)"; -						q.exec(); -					} else { -						Query q = dbCon->query(); -						q << "INSERT INTO NetworkActivity (Network_id,Node_id,lastActivityTime) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << Utils::now() << ") ON DUPLICATE KEY UPDATE lastActivityTime = VALUES(lastActivityTime)"; -						q.exec(); -					} -				} -  				// Assemble response dictionary to send to peer  				Dictionary netconf;  				sprintf(buf,"%.16llx",(unsigned long long)nwid); @@ -448,6 +459,11 @@ int main(int argc,char **argv)  					netconf[ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC] = ipv4Static;  				if (ipv6Static.length())  					netconf[ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC] = ipv6Static; +				if ((!isOpen)&&(authenticated)&&(signingIdentity)&&(signingIdentity.hasPrivate())) { +					CertificateOfMembership com(Utils::now(),ZT_NETWORK_AUTOCONF_DELAY * 3,nwid,peerIdentity.address()); +					com.sign(signingIdentity); +					netconf[ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP] = com.toString(); +				}  				// Send netconf as service bus response  				{ diff --git a/node/Node.cpp b/node/Node.cpp index 593e63bc..815451fd 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -444,6 +444,10 @@ Node::ReasonForTermination Node::run()  		if (Utils::fileExists(netconfServicePath.c_str())) {  			LOG("netconf.d/netconfi.service appears to exist, starting...");  			_r->netconfService = new Service(_r,"netconf",netconfServicePath.c_str(),&_netconfServiceMessageHandler,_r); +			Dictionary initMessage; +			initMessage["type"] = "netconf-init"; +			initMessage["netconfId"] = _r->identity.toString(true); +			_r->netconfService->send(initMessage);  		}  	} catch ( ... ) {  		LOG("unexpected exception attempting to start services");  | 
