Repair room mailbox adapters in sensor reply bounds tests
This commit is contained in:
1 parent
3e8c637866
commit
32a994e838
2 files changed
+84
-2
No files matched your search
@@ -9,6 +9,8 @@
|
||||
#include <helpers/sensors/LPPDataHelpers.h>
|
||||
#include "../room_history_store/filesystem.h"
|
||||
#include <helpers/RoomBoardProtocol.h>
|
||||
#include <helpers/RoomMailProtocol.h>
|
||||
#include <helpers/RoomAccessPolicy.h>
|
||||
|
||||
#include "telemetry_capacity.inc"
|
||||
#include "telemetry_access.inc"
|
||||
@@ -17,6 +19,8 @@
|
||||
#define REQ_TYPE_GET_AVG_MIN_MAX 0x04
|
||||
#define PERM_ACL_ROLE_MASK 7
|
||||
#define PERM_ACL_READ_ONLY 1
|
||||
#define PERM_ACL_READ_WRITE 2
|
||||
#define PERM_ACL_ADMIN 3
|
||||
#define TELEM_PERM_BASE 1
|
||||
#define TELEM_PERM_LOCATION 2
|
||||
#define TELEM_PERM_ENVIRONMENT 4
|
||||
@@ -60,6 +64,7 @@ public:
|
||||
struct ClientInfo {
|
||||
mesh::Identity id;
|
||||
uint8_t permissions = 3;
|
||||
uint32_t last_activity = 0;
|
||||
bool isAdmin() const { return (permissions & PERM_ACL_ROLE_MASK) == 3; }
|
||||
};
|
||||
struct Clock : mesh::RTCClock {
|
||||
@@ -131,9 +136,11 @@ class MyMesh : public SensorMesh {
|
||||
public:
|
||||
MemoryFS room_fs;
|
||||
MemoryFS* _fs = &room_fs;
|
||||
mesh::RoomAccessPolicy room_access;
|
||||
MyMesh() {
|
||||
telemetry.max_len = ROOM_TELEMETRY_CAPACITY; telemetry.data.reserve(telemetry.max_len);
|
||||
metadata_filesystem = _fs;
|
||||
assert(room_access.load(_fs));
|
||||
}
|
||||
int handleRequest(ClientInfo*, uint32_t, uint8_t*, size_t,
|
||||
size_t = mesh::CLIENT_ACL_DIRECT_REPLY_CAPACITY);
|
||||
@@ -276,6 +283,64 @@ static void room_board_dispatch_checks() {
|
||||
assert(target.reply_data[6] == 0);
|
||||
}
|
||||
|
||||
static void room_mail_dispatch_checks() {
|
||||
uint8_t settings[] = {mesh::ROOM_MAIL_REQUEST_SUBTYPE, 0, 0, 0, 0, 0, 0};
|
||||
for (uint8_t permissions : {uint8_t(0), uint8_t(1), uint8_t(2), uint8_t(3), uint8_t(4), uint8_t(131)}) {
|
||||
for (uint32_t activity : {uint32_t(0), uint32_t(1000)}) {
|
||||
const uint8_t role = permissions & PERM_ACL_ROLE_MASK;
|
||||
const bool allowed = role == PERM_ACL_READ_ONLY || role == PERM_ACL_READ_WRITE
|
||||
|| role == PERM_ACL_ADMIN || (role == PERM_ACL_GUEST && activity != 0);
|
||||
for (size_t capacity = 0; capacity <= MAX_PACKET_PAYLOAD; ++capacity) {
|
||||
MyMesh target;
|
||||
ClientInfo client; client.id.pub_key[0] = 1;
|
||||
client.permissions = permissions; client.last_activity = activity;
|
||||
memset(target.reply_data, 0xee, sizeof(target.reply_data));
|
||||
const unsigned writes = target.room_fs.write_opens;
|
||||
const int length = target.handleRequest(&client, 51, settings, sizeof(settings), capacity);
|
||||
const int expected = !allowed || capacity < 7 ? 0 : capacity < 17 ? 7 : 17;
|
||||
assert(length == expected && size_t(length) <= capacity);
|
||||
for (size_t i = capacity; i < sizeof(target.reply_data); ++i) assert(target.reply_data[i] == 0xee);
|
||||
assert(target.room_fs.write_opens == writes); // Checking must not provision an inbox.
|
||||
if (length) {
|
||||
uint32_t tag = 0; memcpy(&tag, target.reply_data, 4);
|
||||
assert(tag == 51 && target.reply_data[4] == mesh::ROOM_MAIL_REQUEST_SUBTYPE);
|
||||
assert(target.reply_data[5] == 0 && target.reply_data[6] == (capacity < 17 ? 1 : 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t capacity : {size_t(10), size_t(11)}) {
|
||||
MyMesh target;
|
||||
ClientInfo owner; owner.permissions = PERM_ACL_READ_ONLY; owner.id.pub_key[0] = 1;
|
||||
uint8_t policy[] = {mesh::ROOM_MAIL_REQUEST_SUBTYPE, 8, 0, 0, 0, 0, 1};
|
||||
const int length = target.handleRequest(&owner, 51, policy, sizeof(policy), capacity);
|
||||
assert(length == (capacity < 11 ? 7 : 11));
|
||||
mesh::RoomMailStatus status;
|
||||
const auto result = mesh::getRoomMailStatus(&target.room_fs, owner.id.pub_key, status);
|
||||
assert(result == (capacity < 11 ? mesh::RoomMailResult::NotFound : mesh::RoomMailResult::Success));
|
||||
if (capacity >= 11) assert(status.settings.mode == mesh::RoomMailMode::Public);
|
||||
}
|
||||
for (uint8_t role : {uint8_t(PERM_ACL_READ_ONLY), uint8_t(PERM_ACL_READ_WRITE), uint8_t(PERM_ACL_ADMIN)}) {
|
||||
MyMesh target;
|
||||
ClientInfo sender; sender.permissions = role; sender.id.pub_key[0] = 1;
|
||||
uint8_t recipient[32] = {}; recipient[0] = 2;
|
||||
mesh::RoomMailSettings public_box; public_box.mode = mesh::RoomMailMode::Public;
|
||||
assert(mesh::saveRoomMailSettings(&target.room_fs, recipient, public_box, 0) == mesh::RoomMailResult::Success);
|
||||
uint8_t send[37] = {mesh::ROOM_MAIL_REQUEST_SUBTYPE, 3};
|
||||
memcpy(send + 2, recipient, 32); send[34] = 1; send[36] = 'x';
|
||||
assert(target.handleRequest(&sender, 51, send, sizeof(send), 11) == 11);
|
||||
assert(target.reply_data[6] == (role == PERM_ACL_READ_ONLY ? 6 : 0));
|
||||
mesh::RoomMailStatus status;
|
||||
assert(mesh::getRoomMailStatus(&target.room_fs, recipient, status) == mesh::RoomMailResult::Success);
|
||||
assert(status.count == (role == PERM_ACL_READ_ONLY ? 0 : 1));
|
||||
assert(target.room_access.addBan(&target.room_fs, recipient) == mesh::RoomAccessPolicy::BanResult::Saved);
|
||||
for (size_t capacity = 0; capacity <= 11; ++capacity) {
|
||||
assert(target.handleRequest(&sender, 52, send, sizeof(send), capacity) == (capacity < 7 ? 0 : 7));
|
||||
if (capacity >= 7) assert(target.reply_data[6] == 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void history_checks() {
|
||||
ClientInfo client;
|
||||
uint8_t query[10] = {};
|
||||
@@ -345,6 +410,7 @@ int main(int argc, char** argv) {
|
||||
assert(argc == 2);
|
||||
if (!strcmp(argv[1], "room")) room_telemetry_checks();
|
||||
else if (!strcmp(argv[1], "room.board")) room_board_dispatch_checks();
|
||||
else if (!strcmp(argv[1], "room.mail")) room_mail_dispatch_checks();
|
||||
else if (!strcmp(argv[1], "telemetry")) telemetry_checks();
|
||||
else if (!strcmp(argv[1], "history")) history_checks();
|
||||
else if (!strcmp(argv[1], "empty")) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import tempfile
|
||||
import unittest
|
||||
|
||||
from test_replay_reset_integration import extract_braced
|
||||
from test_client_acl_infrastructure import room_mail_crypto_arguments
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
FIXTURE = ROOT / "test/fixtures/sensor_reply_bounds/test_sensor_reply_bounds.cpp"
|
||||
@@ -92,7 +93,8 @@ class SensorReplyBoundsTest(unittest.TestCase):
|
||||
(work / "history_types.inc").write_text(history_types, encoding="ascii")
|
||||
binary = work / "sensor.exe"
|
||||
command = [compiler, "-std=c++17", "-Wall", "-Wextra", "-Werror", "-Wno-unused-parameter", "-Wno-reorder",
|
||||
"-I" + str(work), "-I" + str(ROOT / "src"), str(FIXTURE), "-o", str(binary)]
|
||||
"-I" + str(work), "-I" + str(ROOT / "src"), str(FIXTURE),
|
||||
*room_mail_crypto_arguments("room"), "-o", str(binary)]
|
||||
if sys.platform.startswith("linux"):
|
||||
command[1:1] = ["-fsanitize=address,undefined,float-cast-overflow", "-fno-sanitize-recover=all",
|
||||
"-fno-pie", "-no-pie"]
|
||||
@@ -113,9 +115,23 @@ class SensorReplyBoundsTest(unittest.TestCase):
|
||||
|
||||
def test_old_room_board_tag_only_response_is_rejected(self):
|
||||
def old(source):
|
||||
return source.replace("return length ? 4 + length : 0;", "return 4 + length;", 1)
|
||||
branch = extract_braced(source, "if (payload[0] == mesh::ROOM_BOARD_REQUEST_SUBTYPE)")
|
||||
changed = branch.replace("return length ? 4 + length : 0;", "return 4 + length;", 1)
|
||||
self.assertNotEqual(changed, branch)
|
||||
return source.replace(branch, changed, 1)
|
||||
self.assertNotEqual(self.execute("room.board", room_transform=old).returncode, 0)
|
||||
|
||||
def test_room_mailbox_admission_and_complete_reply_boundaries(self):
|
||||
self.check_case("room.mail")
|
||||
|
||||
def test_old_room_mail_tag_only_response_is_rejected(self):
|
||||
def old(source):
|
||||
branch = extract_braced(source, "if (payload[0] == mesh::ROOM_MAIL_REQUEST_SUBTYPE)")
|
||||
changed = branch.replace("return length ? 4 + length : 0;", "return 4 + length;")
|
||||
self.assertNotEqual(changed, branch)
|
||||
return source.replace(branch, changed, 1)
|
||||
self.assertNotEqual(self.execute("room.mail", room_transform=old).returncode, 0)
|
||||
|
||||
def test_old_room_unbounded_copy_is_rejected(self):
|
||||
def old(source):
|
||||
begin = source.index(" const uint8_t* tbuf = telemetry.getBuffer();")
|
||||
|
||||
Reference in new issue
Block a user