Merge branch 'develop' into codex/packet-auth-policy
Resolve conflicts against the NodeDB signer/key primitives (#11050) and the admin-key PKI decrypt budget (#11100). - NodeDB: drop this branch's hasSeenXeddsaSigner in favour of develop's isKnownXeddsaSigner. They answer the same question, but develop's reads the dedicated warm signer bit (warmSignerOf) rather than the WarmProtected category, and TrafficManagementModule already depends on it. Keep develop's copyPublicKey/copyPublicKeyAuthoritative, isVerifiedSignerForKey and commitRemoteKey/KeyCommitTrust. - checkXeddsaReceivePolicy: keep this branch's Strict/Balanced/Compatible policy, which is a superset of develop's balanced-only downgrade gate, and call isKnownXeddsaSigner from it. develop's !pki_encrypted term is dropped because the policy returns early for PKI packets before that check. - perhapsDecode: keep develop's key resolution (NodeDB then pending-key, only for real PKI candidates) plus its admin-key token bucket, and re-apply this branch's pkiAttempted flag feeding the DECODE_OPAQUE verdict. Keep both passesRoutingAuthGate and adminKeyFallbackAllowed/Refund. - test_A17: model eviction the way NodeDB actually does it, passing the warm signer bit as well as the XeddsaSigner category, since isKnownXeddsaSigner reads the former. Native suite: 38 suites, 743/743 cases, no sanitizer findings.
This commit is contained in:
@@ -593,6 +593,37 @@ void test_receiveEmptyDataFromProxy(void)
|
||||
TEST_ASSERT_TRUE(mockRouter->packets_.empty());
|
||||
}
|
||||
|
||||
// Text must be read as text: data.size aliases the string's first bytes, so reading it regardless
|
||||
// of the variant let a client name a length of up to PB_SIZE_MAX. There is no delivery control for
|
||||
// this variant: an encoded ServiceEnvelope always contains NUL, so text can never carry one.
|
||||
void test_receiveTextVariantFromProxyIsNotReadAsBytes(void)
|
||||
{
|
||||
meshtastic_MqttClientProxyMessage message = meshtastic_MqttClientProxyMessage_init_default;
|
||||
snprintf(message.topic, sizeof(message.topic), "msh/2/e/test/!87654321");
|
||||
message.which_payload_variant = meshtastic_MqttClientProxyMessage_text_tag;
|
||||
// data.size would read these as the largest length a pb_size_t can name.
|
||||
memset(message.payload_variant.text, 0xFF, sizeof(message.payload_variant.text) - 1);
|
||||
message.payload_variant.text[sizeof(message.payload_variant.text) - 1] = '\0';
|
||||
|
||||
mqtt->onClientProxyReceive(message);
|
||||
|
||||
TEST_ASSERT_TRUE(mockRouter->packets_.empty());
|
||||
}
|
||||
|
||||
// A proxy message with no payload variant set must be ignored rather than read as bytes.
|
||||
void test_receiveNoVariantFromProxyIsIgnored(void)
|
||||
{
|
||||
meshtastic_MqttClientProxyMessage message = meshtastic_MqttClientProxyMessage_init_default;
|
||||
snprintf(message.topic, sizeof(message.topic), "msh/2/e/test/!87654321");
|
||||
message.which_payload_variant = 0;
|
||||
memset(message.payload_variant.data.bytes, 0xFF, sizeof(message.payload_variant.data.bytes));
|
||||
message.payload_variant.data.size = sizeof(message.payload_variant.data.bytes);
|
||||
|
||||
mqtt->onClientProxyReceive(message);
|
||||
|
||||
TEST_ASSERT_TRUE(mockRouter->packets_.empty());
|
||||
}
|
||||
|
||||
// Packets should be ignored if downlink is not enabled.
|
||||
void test_receiveWithoutChannelDownlink(void)
|
||||
{
|
||||
@@ -1116,6 +1147,8 @@ void setup()
|
||||
RUN_TEST(test_receiveDecodedProto);
|
||||
RUN_TEST(test_receiveDecodedProtoFromProxy);
|
||||
RUN_TEST(test_receiveEmptyDataFromProxy);
|
||||
RUN_TEST(test_receiveTextVariantFromProxyIsNotReadAsBytes);
|
||||
RUN_TEST(test_receiveNoVariantFromProxyIsIgnored);
|
||||
RUN_TEST(test_receiveWithoutChannelDownlink);
|
||||
RUN_TEST(test_receiveEncryptedPKITopicToUs);
|
||||
RUN_TEST(test_receiveIgnoresOwnPublishedMessages);
|
||||
|
||||
Reference in New Issue
Block a user