diff options
Diffstat (limited to 'netconf-service/netconf.cpp')
-rw-r--r-- | netconf-service/netconf.cpp | 62 |
1 files changed, 39 insertions, 23 deletions
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 { |