really still wip
This commit is contained in:
@@ -10,9 +10,10 @@
|
||||
|
||||
#define TAG "Anonymous"
|
||||
|
||||
void sendAnonymousRequest (NodeEntry *targetNode, const uint8_t *password, uint32_t sync) {
|
||||
void sendAnonymousRequest (const NodeEntry *targetNode, const uint8_t *password, uint32_t sync) {
|
||||
uint8_t passwordLen = strlen ((const char *)password);
|
||||
FrameStruct frame;
|
||||
frame.path.pathLen = 0;
|
||||
uint8_t offset = 0;
|
||||
|
||||
// 1. Frame header
|
||||
@@ -61,36 +62,103 @@ void sendAnonymousRequest (NodeEntry *targetNode, const uint8_t *password, uint3
|
||||
|
||||
// 5. Finalize and send
|
||||
frame.payloadLen = offset;
|
||||
memcpy(&(frame.path), &(targetNode->path), sizeof(frame.path));
|
||||
memcpy (&(frame.path), &(targetNode->path), sizeof (frame.path));
|
||||
|
||||
hexdump ("Anon payload", frame.payload, frame.payloadLen);
|
||||
|
||||
sendFrame (frame);
|
||||
LoRaTransmit (&frame);
|
||||
}
|
||||
|
||||
AnonymousRequestPayload decodeAnonReq (FrameStruct frame) {
|
||||
void printAnonRequest (const AnonymousRequestPayload *req, int isRoomServer) {
|
||||
if (!req)
|
||||
return;
|
||||
|
||||
printf ("AnonymousRequestPayload at %p\n", (void *)req);
|
||||
printf (" destination hash: 0x%02X\n", req->destinationHash);
|
||||
|
||||
printf (" sender pubKey: ");
|
||||
for (int i = 0; i < sizeof (req->pubKey); i++) {
|
||||
printf ("%02X", req->pubKey[i]);
|
||||
}
|
||||
printf ("\n");
|
||||
|
||||
printf (" cipher MAC: 0x%04X\n", req->cipherMAC);
|
||||
|
||||
printf (" decrypted payload (%u bytes):\n", req->payloadLen);
|
||||
uint8_t index = 0;
|
||||
|
||||
// timestamp (first 4 bytes)
|
||||
if (req->payloadLen >= 4) {
|
||||
uint32_t timestamp = req->payload[index++];
|
||||
timestamp |= req->payload[index++] << 8;
|
||||
timestamp |= req->payload[index++] << 16;
|
||||
timestamp |= req->payload[index++] << 24;
|
||||
printf (" timestamp: %u\n", timestamp);
|
||||
}
|
||||
|
||||
// room server sync timestamp
|
||||
if (isRoomServer && req->payloadLen >= index + 4) {
|
||||
uint32_t syncTimestamp = req->payload[index++];
|
||||
syncTimestamp |= req->payload[index++] << 8;
|
||||
syncTimestamp |= req->payload[index++] << 16;
|
||||
syncTimestamp |= req->payload[index++] << 24;
|
||||
printf (" sync timestamp: %u\n", syncTimestamp);
|
||||
}
|
||||
|
||||
|
||||
// remaining bytes = password
|
||||
if (index < req->payloadLen) {
|
||||
uint8_t passwordLen = req->payloadLen - index;
|
||||
if (passwordLen > 16)
|
||||
passwordLen = 16;
|
||||
passwordLen = strnlen (&(req->payload[index]), passwordLen);
|
||||
printf (" password: ");
|
||||
for (uint8_t i = 0; i < passwordLen; i++) {
|
||||
printf ("%c", req->payload[i + index]);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
size_t strnlen (const char *s, size_t maxLen) {
|
||||
size_t len = 0;
|
||||
while (len < maxLen && s[len] != '\0') {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void decodeAnonReq (const FrameStruct *frame) {
|
||||
uint8_t index = 0;
|
||||
AnonymousRequestPayload anonReq;
|
||||
anonReq.destinationHash = frame.payload[index++];
|
||||
memcpy (anonReq.pubKey, &(frame.payload[index]), sizeof (anonReq.pubKey));
|
||||
|
||||
anonReq.destinationHash = frame->payload[index++];
|
||||
memcpy (anonReq.pubKey, &(frame->payload[index]), sizeof (anonReq.pubKey));
|
||||
index += sizeof (anonReq.pubKey);
|
||||
anonReq.cipherMAC = frame.payload[index];
|
||||
anonReq.cipherMAC |= frame.payload[index + 1] << 8;
|
||||
anonReq.cipherMAC = frame->payload[index];
|
||||
anonReq.cipherMAC |= frame->payload[index + 1] << 8;
|
||||
|
||||
NodeEntry *foundNode = getNode (anonReq.pubKey[0]);
|
||||
if (foundNode == NULL) {
|
||||
foundNode = getNextNode();
|
||||
|
||||
strcpy (foundNode->name, "Anonymous node");
|
||||
memcpy (foundNode->pubKey, anonReq.pubKey, sizeof (foundNode->pubKey));
|
||||
ed25519_key_exchange ((unsigned char *)foundNode->secret, anonReq.pubKey, persistent.privkey);
|
||||
foundNode->gps_latitude = 0;
|
||||
foundNode->gps_longitude = 0;
|
||||
// ADD PATH
|
||||
foundNode->type = 0;
|
||||
foundNode->last_seen_lt = RTC_GetCounter();
|
||||
|
||||
MESH_LOGI (TAG, "New anonymous node created: %s", foundNode->name);
|
||||
} else {
|
||||
MESH_LOGD (TAG, "Existing node found for pubKey[0]=0x%02X", anonReq.pubKey[0]);
|
||||
}
|
||||
mac_then_decrypt (foundNode->secret, 32, &(frame.payload[index]), frame.payloadLen - index, anonReq.payload);
|
||||
anonReq.payloadLen = frame.payloadLen - index - 2;
|
||||
|
||||
mac_then_decrypt (foundNode->secret, 32, &(frame->payload[index]), frame->payloadLen - index, anonReq.payload);
|
||||
anonReq.payloadLen = frame->payloadLen - index - 2;
|
||||
|
||||
hexdump ("AnonReq payload", anonReq.payload, anonReq.payloadLen);
|
||||
|
||||
uint8_t index2 = 0;
|
||||
foundNode->last_seen_rt = anonReq.payload[index2++];
|
||||
foundNode->last_seen_rt |= anonReq.payload[index2++] << 8;
|
||||
@@ -104,30 +172,39 @@ AnonymousRequestPayload decodeAnonReq (FrameStruct frame) {
|
||||
foundNode->sync_timestamp |= anonReq.payload[index2++] << 24;
|
||||
}
|
||||
|
||||
printAnonRequest (&anonReq, persistent.nodeType == NODE_TYPE_ROOM_SERVER);
|
||||
|
||||
uint8_t passwordLen = anonReq.payloadLen - index2;
|
||||
if (passwordLen > 16) {
|
||||
if (passwordLen > 16)
|
||||
passwordLen = 16;
|
||||
}
|
||||
passwordLen = strnlen (&(anonReq.payload[index2]), passwordLen);
|
||||
|
||||
MESH_LOGI (TAG, "Password len is %d.", passwordLen);
|
||||
uint8_t passwordBuf[16];
|
||||
memcpy (passwordBuf, &(anonReq.payload[index2]), passwordLen);
|
||||
if (memcmp (passwordBuf, persistent.password, sizeof (persistent.password)) == 0) {
|
||||
|
||||
if (memcmp (passwordBuf, persistent.password, passwordLen) == 0) {
|
||||
foundNode->authenticated = 1;
|
||||
Response resp;
|
||||
resp.tag = RTC_GetCounter();
|
||||
uint8_t index3 = 0;
|
||||
uint32_t randOut = rand();
|
||||
resp.data[index3++] = RESP_SERVER_LOGIN_OK;
|
||||
resp.data[index3++] = 0;//legacy
|
||||
resp.data[index3++] = 1;//isadmin
|
||||
resp.data[index3++] = PERM_ACL_ADMIN;//permissions
|
||||
resp.data[index3++] = randOut & 0xFF;//rng
|
||||
resp.data[index3++] = (randOut >> 8) & 0xFF;
|
||||
resp.data[index3++] = (randOut >> 16) & 0xFF;
|
||||
resp.data[index3++] = (randOut >> 24) & 0xFF;
|
||||
resp.data[index3++] = FIRMWARE_VER_LEVEL;
|
||||
resp.dataLen = index3;
|
||||
sendEncryptedResponse(foundNode, &resp);
|
||||
MESH_LOGI (TAG, "Password correct, node %s authenticated.", foundNode->name);
|
||||
|
||||
MESH_LOGI (TAG, "Login response sent to node %s.", foundNode->name);
|
||||
} else {
|
||||
MESH_LOGW (TAG, "Password incorrect for node %s.", foundNode->name);
|
||||
}
|
||||
|
||||
return anonReq;
|
||||
}
|
||||
Response resp;
|
||||
resp.tag = RTC_GetCounter();
|
||||
uint8_t index3 = 0;
|
||||
uint32_t randOut = rand();
|
||||
resp.data[index3++] = RESP_SERVER_LOGIN_OK;
|
||||
resp.data[index3++] = 0; // legacy
|
||||
resp.data[index3++] = foundNode->authenticated; // isadmin
|
||||
resp.data[index3++] = foundNode->authenticated ? PERM_ACL_ADMIN : PERM_ACL_GUEST; // permissions
|
||||
resp.data[index3++] = randOut & 0xFF;
|
||||
resp.data[index3++] = (randOut >> 8) & 0xFF;
|
||||
resp.data[index3++] = (randOut >> 16) & 0xFF;
|
||||
resp.data[index3++] = (randOut >> 24) & 0xFF;
|
||||
resp.data[index3++] = FIRMWARE_VER_LEVEL;
|
||||
resp.dataLen = index3;
|
||||
sendEncryptedResponse (foundNode, &resp);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user