Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PKI channel for MQTT #4464

Merged
merged 2 commits into from
Aug 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions src/mqtt/MQTT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
LOG_INFO("Ignoring downlink message we originally sent.\n");
} else {
// Find channel by channel_id and check downlink_enabled
if (strcmp(e.channel_id, channels.getGlobalId(ch.index)) == 0 && e.packet && ch.settings.downlink_enabled) {
if ((strcmp(e.channel_id, "PKI") && e.packet) ||
(strcmp(e.channel_id, channels.getGlobalId(ch.index)) == 0 && e.packet && ch.settings.downlink_enabled)) {
LOG_INFO("Received MQTT topic %s, len=%u\n", topic, length);
meshtastic_MeshPacket *p = packetPool.allocCopy(*e.packet);
p->via_mqtt = true; // Mark that the packet was received via MQTT
Expand All @@ -161,8 +162,11 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
p->channel = ch.index;
}

// PKI messages get accepted even if we can't decrypt
if (router && p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag && p->channel == 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to check for (strcmp(e.channel_id, "PKI") to avoid not decrypting when you happen to have a channel hash of 0.

Also, I think here we want to check whether the to and from are in our NodeDB to avoid routing PKI messages for nodes that do not talk via your channels.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest change to 2.5 branch fixes all of this, except checking for to/from. I'm still pondering that one.

router->enqueueReceivedMessage(p);
// ignore messages if we don't have the channel key
if (router && perhapsDecode(p))
else if (router && perhapsDecode(p))
router->enqueueReceivedMessage(p);
else
packetPool.release(p);
Expand Down Expand Up @@ -377,6 +381,11 @@ void MQTT::sendSubscriptions()
#endif // ARCH_NRF52
}
}
#if !MESHTASTIC_EXCLUDE_PKI
std::string topic = cryptTopic + "PKI/#";
LOG_INFO("Subscribing to %s\n", topic.c_str());
pubSub.subscribe(topic.c_str(), 1);
jp-bennett marked this conversation as resolved.
Show resolved Hide resolved
#endif
#endif
}

Expand Down Expand Up @@ -452,8 +461,12 @@ void MQTT::publishQueuedMessages()
meshtastic_ServiceEnvelope *env = mqttQueue.dequeuePtr(0);
static uint8_t bytes[meshtastic_MeshPacket_size + 64];
size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env);

std::string topic = cryptTopic + env->channel_id + "/" + owner.id;
std::string topic;
if (env->packet->pki_encrypted) {
topic = cryptTopic + "PKI/" + owner.id;
} else {
topic = cryptTopic + env->channel_id + "/" + owner.id;
}
LOG_INFO("publish %s, %u bytes from queue\n", topic.c_str(), numBytes);

publish(topic.c_str(), bytes, numBytes, false);
Expand All @@ -463,7 +476,12 @@ void MQTT::publishQueuedMessages()
// handle json topic
auto jsonString = MeshPacketSerializer::JsonSerialize(env->packet);
if (jsonString.length() != 0) {
std::string topicJson = jsonTopic + env->channel_id + "/" + owner.id;
std::string topicJson;
if (env->packet->pki_encrypted) {
topicJson = jsonTopic + "PKI/" + owner.id;
} else {
topicJson = jsonTopic + env->channel_id + "/" + owner.id;
}
LOG_INFO("JSON publish message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(),
jsonString.c_str());
publish(topicJson.c_str(), jsonString.c_str(), false);
Expand Down Expand Up @@ -513,8 +531,12 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
static uint8_t bytes[meshtastic_MeshPacket_size + 64];
size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, env);

std::string topic = cryptTopic + channelId + "/" + owner.id;
std::string topic;
if (mp.pki_encrypted) {
jp-bennett marked this conversation as resolved.
Show resolved Hide resolved
topic = cryptTopic + "PKI/" + owner.id;
} else {
topic = cryptTopic + channelId + "/" + owner.id;
}
LOG_DEBUG("MQTT Publish %s, %u bytes\n", topic.c_str(), numBytes);

publish(topic.c_str(), bytes, numBytes, false);
Expand All @@ -524,7 +546,12 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
// handle json topic
auto jsonString = MeshPacketSerializer::JsonSerialize((meshtastic_MeshPacket *)&mp_decoded);
if (jsonString.length() != 0) {
std::string topicJson = jsonTopic + channelId + "/" + owner.id;
std::string topicJson;
if (mp.pki_encrypted) {
topicJson = jsonTopic + "PKI/" + owner.id;
} else {
topicJson = jsonTopic + channelId + "/" + owner.id;
}
LOG_INFO("JSON publish message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(),
jsonString.c_str());
publish(topicJson.c_str(), jsonString.c_str(), false);
Expand Down
Loading