Update alert PSK handling to accept both base64 and hex formats
Enhanced the CLI command for setting the alert PSK to support both base64 (24/44 chars) and hex (32/64 chars) formats. This change allows for greater flexibility in key input, accommodating the mobile app's "share" output. Updated error messages for clarity and ensured that previously derived hashtags are cleared when a new PSK is set. Relevant adjustments made in CommonCLI and MQTT implementation documentation.
This commit is contained in:
1 parent
6a3ed5d430
commit
a865d0a303
2 files changed
+50
-19
No files matched your search
@@ -714,7 +714,7 @@ A "recovered" message is sent once when the underlying connection comes back. Af
|
||||
| Setting | Default | Notes |
|
||||
|---------|---------|-------|
|
||||
| `alert` | `off` | Master enable for automatic fault alerts |
|
||||
| `alert.psk` | *(unset)* | Private base64 PSK (24 or 44 chars). The active channel key. |
|
||||
| `alert.psk` | *(unset)* | Private channel secret. Accepts either base64 (24 or 44 chars, like `BaseChatMesh::addChannel`) or hex (32 or 64 chars, like the mobile app's "Share Channel" output). Stored internally as base64. |
|
||||
| `alert.hashtag` | *(unset)* | Informational only; set via `set alert.hashtag` to pre-derive `alert.psk` from `sha256("#name")[0..15]`. Cleared when `alert.psk` is set directly. |
|
||||
| `alert.region` | *(unset)* | Optional region name; overrides the repeater's `default_scope` for alert sends only. Empty = use `default_scope`. Looked up lazily via `RegionMap`; unknown names silently fall back to `default_scope`. |
|
||||
| `alert.wifi` | `30` (min) | 0 disables WiFi alerts |
|
||||
@@ -734,7 +734,7 @@ Get:
|
||||
|
||||
Set:
|
||||
- `set alert on` / `set alert off`
|
||||
- `set alert.psk <base64>` — 24-char (16-byte) or 44-char (32-byte) base64; rejects banned channels (Public, `#test`, `#bot`). Clears `alert.hashtag` since the new key is operator-supplied.
|
||||
- `set alert.psk <secret>` — 24-/44-char base64 **or** 32-/64-char hex (16- or 32-byte secret); rejects banned channels (Public, `#test`, `#bot`). Clears `alert.hashtag` since the new key is operator-supplied. The mobile app's "share" output is hex; either format is accepted.
|
||||
- `set alert.psk` (no argument) — clears both `alert.psk` and `alert.hashtag`
|
||||
- `set alert.hashtag <name>` — derives the 16-byte key from `sha256("#name")` *once*, stores it as `alert.psk`, and remembers the hashtag for `get alert.hashtag`. `#` prefix is added if omitted (so `alerts` and `#alerts` are equivalent). Refuses banned hashtag names.
|
||||
- `set alert.hashtag` (no argument) — clears both `alert.psk` and `alert.hashtag`
|
||||
@@ -765,7 +765,7 @@ Anyone running a companion app and subscribed to the `#ops-alerts` hashtag chann
|
||||
Generate a 16-byte random PSK and base64-encode it (24 chars), or use the companion app's "Add channel" feature to create one and copy the secret. Then:
|
||||
|
||||
```bash
|
||||
set alert.psk <your_24_or_44_char_base64_psk>
|
||||
set alert.psk <secret> # base64 (24/44 chars) or hex (32/64 chars) — mobile "share" works as-is
|
||||
set alert.wifi 10
|
||||
set alert.mqtt 60
|
||||
set alert on
|
||||
|
||||
+47
-16
@@ -1631,23 +1631,54 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
strcpy(reply, "Error: PSK too long (max 47 chars)");
|
||||
} else if (val[0] == '#') {
|
||||
strcpy(reply, "Error: use 'set alert.hashtag' for hashtag channels");
|
||||
} else if (len != 24 && len != 44) {
|
||||
// Quick character-count check before storing; AlertReporter will redo the
|
||||
// full base64 decode and reject anything that doesn't yield 16 or 32 bytes.
|
||||
strcpy(reply, "Error: PSK must be 24 chars (16-byte) or 44 chars (32-byte) base64");
|
||||
} else if (const char* banned = alertReporterBannedChannelMatchB64(val)) {
|
||||
// Refuse any key on the banned channel list (Public PSK, well-known
|
||||
// auto-responder hashtags like #test/#bot, etc.). Fault alerts on those
|
||||
// channels would spam every node in the area.
|
||||
sprintf(reply, "Error: refusing banned channel '%s'; pick a private key or hashtag", banned);
|
||||
} else {
|
||||
StrHelper::strncpy(_prefs->alert_psk_b64, val, sizeof(_prefs->alert_psk_b64));
|
||||
// The new PSK is operator-supplied, so any previously-derived hashtag
|
||||
// name is no longer accurate provenance — drop it.
|
||||
_prefs->alert_hashtag[0] = '\0';
|
||||
savePrefs();
|
||||
_callbacks->onAlertConfigChanged();
|
||||
strcpy(reply, "OK - alert.psk updated");
|
||||
// Accept either:
|
||||
// - base64: 24 chars (16-byte secret) or 44 chars (32-byte secret) —
|
||||
// the format `BaseChatMesh::addChannel` already expects.
|
||||
// - hex: 32 chars (16-byte secret) or 64 chars (32-byte secret) —
|
||||
// what the MeshCore mobile app's "share" button emits for both
|
||||
// private channels and hashtag channels.
|
||||
// Hex input is converted to base64 once at CLI time so the on-disk
|
||||
// representation (and AlertReporter's decode path) stays unchanged.
|
||||
char canonical_b64[48];
|
||||
const char* store = nullptr;
|
||||
|
||||
if (len == 32 || len == 64) {
|
||||
bool all_hex = true;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (!mesh::Utils::isHexChar(val[i])) { all_hex = false; break; }
|
||||
}
|
||||
if (all_hex) {
|
||||
uint8_t raw[32];
|
||||
int raw_len = (int)(len / 2);
|
||||
if (mesh::Utils::fromHex(raw, raw_len, val)) {
|
||||
size_t b64_len = alert_encode_base64(raw, (size_t)raw_len, canonical_b64, sizeof(canonical_b64));
|
||||
if (b64_len > 0 && b64_len < sizeof(_prefs->alert_psk_b64)) {
|
||||
store = canonical_b64;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!store && (len == 24 || len == 44)) {
|
||||
store = val;
|
||||
}
|
||||
|
||||
if (!store) {
|
||||
strcpy(reply, "Error: PSK must be 32/64 hex chars or 24/44 chars base64 (16- or 32-byte secret)");
|
||||
} else if (const char* banned = alertReporterBannedChannelMatchB64(store)) {
|
||||
// Refuse any key on the banned channel list (Public PSK, well-known
|
||||
// auto-responder hashtags like #test/#bot, etc.). Fault alerts on
|
||||
// those channels would spam every node in the area.
|
||||
sprintf(reply, "Error: refusing banned channel '%s'; pick a private key or hashtag", banned);
|
||||
} else {
|
||||
StrHelper::strncpy(_prefs->alert_psk_b64, store, sizeof(_prefs->alert_psk_b64));
|
||||
// The new PSK is operator-supplied, so any previously-derived hashtag
|
||||
// name is no longer accurate provenance — drop it.
|
||||
_prefs->alert_hashtag[0] = '\0';
|
||||
savePrefs();
|
||||
_callbacks->onAlertConfigChanged();
|
||||
strcpy(reply, "OK - alert.psk updated");
|
||||
}
|
||||
}
|
||||
} else if (memcmp(config, "alert.hashtag", 13) == 0 && (config[13] == 0 || config[13] == ' ')) {
|
||||
const char* val = (config[13] == ' ') ? &config[14] : "";
|
||||
|
||||
Reference in new issue
Block a user