mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-01 15:00:54 +00:00
Add an echoed 32-bit token field to command packets.
This commit is contained in:
parent
2e85cf18c1
commit
1fce55fab1
@ -156,30 +156,30 @@ void NodeConfig::_CBcontrolPacketHandler(UdpSocket *sock,void *arg,const InetAdd
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Minimum length
|
// Minimum length
|
||||||
if (len < 24)
|
if (len < 28)
|
||||||
return;
|
return;
|
||||||
if (len >= sizeof(buf)) // only up to len - 24 bytes are used on receive/decrypt
|
if (len >= sizeof(buf)) // only up to len - 28 bytes are used on receive/decrypt
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Compare first 16 bytes of HMAC, which is after IV in packet
|
// Compare first 16 bytes of HMAC, which is after IV in packet
|
||||||
memcpy(hmacKey,nc->_keys + 32,32);
|
memcpy(hmacKey,nc->_keys + 32,32);
|
||||||
*((uint64_t *)hmacKey) ^= *((const uint64_t *)data); // include IV in HMAC
|
*((uint64_t *)hmacKey) ^= *((const uint64_t *)data); // include IV in HMAC
|
||||||
HMAC::sha256(hmacKey,32,((const unsigned char *)data) + 24,len - 24,hmac);
|
HMAC::sha256(hmacKey,32,((const unsigned char *)data) + 28,len - 28,hmac);
|
||||||
if (memcmp(hmac,((const unsigned char *)data) + 8,16))
|
if (memcmp(hmac,((const unsigned char *)data) + 8,16))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Decrypt payload if we passed HMAC
|
// Decrypt payload if we passed HMAC
|
||||||
Salsa20 s20(nc->_keys,256,data); // first 64 bits of data are IV
|
Salsa20 s20(nc->_keys,256,data); // first 64 bits of data are IV
|
||||||
s20.decrypt(((const unsigned char *)data) + 24,buf,len - 24);
|
s20.decrypt(((const unsigned char *)data) + 28,buf,len - 28);
|
||||||
|
|
||||||
// Null-terminate string for execute()
|
// Null-terminate string for execute()
|
||||||
buf[len - 24] = (char)0;
|
buf[len - 28] = (char)0;
|
||||||
|
|
||||||
// Execute command
|
// Execute command
|
||||||
std::vector<std::string> r(nc->execute(buf));
|
std::vector<std::string> r(nc->execute(buf));
|
||||||
|
|
||||||
// Result packet contains a series of null-terminated results
|
// Result packet contains a series of null-terminated results
|
||||||
unsigned int resultLen = 24;
|
unsigned int resultLen = 28;
|
||||||
for(std::vector<std::string>::iterator i(r.begin());i!=r.end();++i) {
|
for(std::vector<std::string>::iterator i(r.begin());i!=r.end();++i) {
|
||||||
if ((resultLen + i->length() + 1) >= sizeof(buf))
|
if ((resultLen + i->length() + 1) >= sizeof(buf))
|
||||||
return; // result too long
|
return; // result too long
|
||||||
@ -193,9 +193,12 @@ void NodeConfig::_CBcontrolPacketHandler(UdpSocket *sock,void *arg,const InetAdd
|
|||||||
// Generate result packet HMAC
|
// Generate result packet HMAC
|
||||||
memcpy(hmacKey,nc->_keys + 32,32);
|
memcpy(hmacKey,nc->_keys + 32,32);
|
||||||
*((uint64_t *)hmacKey) ^= *((const uint64_t *)buf); // include IV in HMAC
|
*((uint64_t *)hmacKey) ^= *((const uint64_t *)buf); // include IV in HMAC
|
||||||
HMAC::sha256(hmacKey,32,((const unsigned char *)buf) + 24,resultLen - 24,hmac);
|
HMAC::sha256(hmacKey,32,((const unsigned char *)buf) + 28,resultLen - 28,hmac);
|
||||||
memcpy(buf + 8,hmac,16);
|
memcpy(buf + 8,hmac,16);
|
||||||
|
|
||||||
|
// Copy arbitrary tag from original packet
|
||||||
|
memcpy(buf + 24,((const unsigned char *)data) + 24,4);
|
||||||
|
|
||||||
// Send encrypted result back to requester
|
// Send encrypted result back to requester
|
||||||
sock->send(remoteAddr,buf,resultLen,-1);
|
sock->send(remoteAddr,buf,resultLen,-1);
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "SharedPtr.hpp"
|
#include "SharedPtr.hpp"
|
||||||
#include "Network.hpp"
|
#include "Network.hpp"
|
||||||
@ -45,7 +46,20 @@ namespace ZeroTier {
|
|||||||
class RuntimeEnvironment;
|
class RuntimeEnvironment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node configuration holder and fetcher
|
* Node configuration endpoint
|
||||||
|
*
|
||||||
|
* Packet format for local UDP configuration packets:
|
||||||
|
* [8] random initialization vector
|
||||||
|
* [16] first 16 bytes of HMAC-SHA-256 of payload
|
||||||
|
* [4] arbitrary tag, echoed in response
|
||||||
|
* [...] payload
|
||||||
|
*
|
||||||
|
* For requests, the payload consists of a single ASCII command. For
|
||||||
|
* responses, the payload consists of one or more response lines delimited
|
||||||
|
* by NULL (0) characters. The tag field is replicated in the result
|
||||||
|
* packet.
|
||||||
|
*
|
||||||
|
* TODO: further document use of keys, encryption...
|
||||||
*/
|
*/
|
||||||
class NodeConfig
|
class NodeConfig
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user