Skip to content

Commit

Permalink
Add option to preserve private key for factory reset (config) (#4679)
Browse files Browse the repository at this point in the history
* Add option to preserve private key for factory reset (config)

* Typo fix

* Copy the key in the right direction, and set the size.

* Don't set the key size back to 0 right after setting it to 32.

* Set the key size before using it to do a memcpy.

* Use the right key_size for backing up private_key

* Don't factoryReset() for a missing nodeDB

* Disable Bluetooth in AdminModule when resetting device settings or nodeDB to avoid race

* Add checks for valid objects before deinit bluetooth

* Add disableBluetooth to handleSetConfig, handleSetModuleConfig, and commit settings

---------

Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
  • Loading branch information
thebentern and jp-bennett authored Sep 11, 2024
1 parent 1ba4f6e commit 9ac0e26
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 9 deletions.
23 changes: 17 additions & 6 deletions src/mesh/NodeDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
#endif
// second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState();
installDefaultConfig();
installDefaultConfig(!eraseBleBonds); // Also preserve the private key if we're not erasing BLE bonds
installDefaultModuleConfig();
installDefaultChannels();
// third, write everything to disk
Expand All @@ -268,8 +268,13 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
return true;
}

void NodeDB::installDefaultConfig()
void NodeDB::installDefaultConfig(bool preserveKey = false)
{
uint8_t private_key_temp[32];
bool shouldPreserveKey = preserveKey && config.has_security && config.security.private_key.size > 0;
if (shouldPreserveKey) {
memcpy(private_key_temp, config.security.private_key.bytes, config.security.private_key.size);
}
LOG_INFO("Installing default LocalConfig\n");
memset(&config, 0, sizeof(meshtastic_LocalConfig));
config.version = DEVICESTATE_CUR_VER;
Expand Down Expand Up @@ -310,8 +315,14 @@ void NodeDB::installDefaultConfig()
#else
config.security.admin_key[0].size = 0;
#endif
if (shouldPreserveKey) {
config.security.private_key.size = 32;
memcpy(config.security.private_key.bytes, private_key_temp, config.security.private_key.size);
printBytes("Restored key", config.security.private_key.bytes, config.security.private_key.size);
} else {
config.security.private_key.size = 0;
}
config.security.public_key.size = 0;
config.security.private_key.size = 0;
#ifdef PIN_GPS_EN
config.position.gps_en_gpio = PIN_GPS_EN;
#endif
Expand Down Expand Up @@ -714,7 +725,7 @@ void NodeDB::loadFromDisk()
//} else {
if (devicestate.version < DEVICESTATE_MIN_VER) {
LOG_WARN("Devicestate %d is old, discarding\n", devicestate.version);
factoryReset();
installDefaultDeviceState();
} else {
LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d\n", devicestate.version,
devicestate.node_db_lite.size());
Expand All @@ -730,7 +741,7 @@ void NodeDB::loadFromDisk()
} else {
if (config.version < DEVICESTATE_MIN_VER) {
LOG_WARN("config %d is old, discarding\n", config.version);
installDefaultConfig();
installDefaultConfig(true);
} else {
LOG_INFO("Loaded saved config version %d\n", config.version);
}
Expand Down Expand Up @@ -1043,7 +1054,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
if (p.public_key.size > 0) {
printBytes("Incoming Pubkey: ", p.public_key.bytes, 32);
if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one
LOG_INFO("Public Key set for node, not updateing!\n");
LOG_INFO("Public Key set for node, not updating!\n");
// we copy the key into the incoming packet, to prevent overwrite
memcpy(p.public_key.bytes, info->user.public_key.bytes, 32);
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/mesh/NodeDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ class NodeDB
void cleanupMeshDB();

/// Reinit device state from scratch (not loading from disk)
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(bool preserveKey),
installDefaultModuleConfig();

/// write to flash
/// @return true if the save was successful
Expand Down
23 changes: 22 additions & 1 deletion src/modules/AdminModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,22 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
break;
}
case meshtastic_AdminMessage_factory_reset_config_tag: {
disableBluetooth();
LOG_INFO("Initiating factory config reset\n");
nodeDB->factoryReset();
LOG_INFO("Factory config reset finished, rebooting soon.\n");
reboot(DEFAULT_REBOOT_SECONDS);
break;
}
case meshtastic_AdminMessage_factory_reset_device_tag: {
disableBluetooth();
LOG_INFO("Initiating full factory reset\n");
nodeDB->factoryReset(true);
reboot(DEFAULT_REBOOT_SECONDS);
break;
}
case meshtastic_AdminMessage_nodedb_reset_tag: {
disableBluetooth();
LOG_INFO("Initiating node-db reset\n");
nodeDB->resetNodes();
reboot(DEFAULT_REBOOT_SECONDS);
Expand All @@ -209,6 +213,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
break;
}
case meshtastic_AdminMessage_commit_edit_settings_tag: {
disableBluetooth();
LOG_INFO("Committing transaction for edited settings\n");
hasOpenEditTransaction = false;
saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
Expand Down Expand Up @@ -559,12 +564,16 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)

break;
}
if (requiresReboot) {
disableBluetooth();
}

saveChanges(changes, requiresReboot);
}

void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
{
disableBluetooth();
switch (c.which_payload_variant) {
case meshtastic_ModuleConfig_mqtt_tag:
LOG_INFO("Setting module config: MQTT\n");
Expand Down Expand Up @@ -636,7 +645,6 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
moduleConfig.paxcounter = c.payload_variant.paxcounter;
break;
}

saveChanges(SEGMENT_MODULECONFIG);
}

Expand Down Expand Up @@ -1031,3 +1039,16 @@ bool AdminModule::messageIsRequest(meshtastic_AdminMessage *r)
else
return false;
}

void disableBluetooth()
{
#if HAS_BLUETOOTH
#ifdef ARCH_ESP32
if (nimbleBluetooth)
nimbleBluetooth->deinit();
#elif defined(ARCH_NRF52)
if (nrf52Bluetooth)
nrf52Bluetooth->shutdown();
#endif
#endif
}
4 changes: 3 additions & 1 deletion src/modules/AdminModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,6 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>, public Obser
bool messageIsRequest(meshtastic_AdminMessage *r);
};

extern AdminModule *adminModule;
extern AdminModule *adminModule;

void disableBluetooth();

0 comments on commit 9ac0e26

Please sign in to comment.