added automatic latest firmware spoofing
This commit is contained in:
@@ -89,3 +89,28 @@ behavior that still needs manual testing.
|
||||
state in the handoff.
|
||||
- Do not commit generated binaries, OpenWrt build output, runtime state, logs, or
|
||||
captured protocol payloads.
|
||||
|
||||
## Environment pitfalls and shared discoveries
|
||||
|
||||
- In this workspace, the Codex `apply_patch` helper is currently unusable. It
|
||||
fails with `bwrap: No permissions to create a new namespace`, including when
|
||||
invoked from an approved command outside the normal sandbox. Do not spend time
|
||||
retrying it or tracing its symlink after seeing this known error.
|
||||
- For repository edits, use `git apply --recount` with a focused unified diff as
|
||||
the fallback. `--recount` avoids failures caused by manually miscounted hunk
|
||||
lengths. Review the resulting `git diff` and run `git diff --check` afterward.
|
||||
Preserve unrelated worktree changes exactly as with any other editing method.
|
||||
- Ordinary read-only commands may fail with the same `bwrap` namespace error.
|
||||
When the command is safe and required, rerun it using the environment's normal
|
||||
escalation/approval mechanism instead of investigating the namespace setup.
|
||||
|
||||
Agents must preserve useful environment knowledge for later agents. When a new
|
||||
pitfall or workaround is verified to be deterministic or repeatedly encountered,
|
||||
add a short entry to this section before handoff. Keep these entries actionable
|
||||
and specific: include the recognizable failure, the confirmed workaround, and
|
||||
any validation required afterward.
|
||||
|
||||
Do not record transient command failures, guesses, lengthy logs, credentials,
|
||||
auth keys, host secrets, or details that only apply to a single task. If a
|
||||
discovery could weaken safety controls or requires broader permissions, report
|
||||
it to the user instead of documenting a bypass.
|
||||
|
||||
@@ -8,6 +8,7 @@ Daemon that makes an OpenWrt router appear as a UniFi AP to UniFi Network contro
|
||||
| --- | --- | --- |
|
||||
| **L2 Discovery** | UDP broadcast + multicast every 10s | `announce.c` → port 10001 |
|
||||
| **Adoption** | AES-128-CBC handshake with the controller | `inform.c` → `handle_response()` |
|
||||
| **Firmware spoofing** | Persists and reports the target version requested by an upgrade | `inform.c` → `handle_response()` |
|
||||
| **WiFi Config** | Creates WiFi networks from the controller via UCI | `wlan.c` → `wlan_apply_config()` |
|
||||
| **Band Steering** | 802.11k/v Neighbor Reports + BSS Transition | `wlan.c` → `apply_vap()` |
|
||||
| **Fast Roaming** | 802.11r FT with mobility_domain derived from MAC | `wlan.c` → `apply_vap()` |
|
||||
@@ -99,6 +100,10 @@ Daemon settings live in `/etc/openuf/openuf.conf`. Adoption and controller state
|
||||
are persisted separately in `/etc/openuf/state.json`; do not copy that file
|
||||
between devices because it contains the device authentication key.
|
||||
|
||||
Because UniFi firmware cannot run on the OpenWrt host, an upgrade request does
|
||||
not download or install its image. Instead, openUF saves the requested firmware
|
||||
version in `state.json` and reports it in subsequent inform packets.
|
||||
|
||||
---
|
||||
|
||||
## Glossary
|
||||
|
||||
+28
-1
@@ -575,7 +575,12 @@ static char *build_payload(const openuf_state_t *st,
|
||||
}
|
||||
|
||||
char fw_version[64];
|
||||
snprintf(fw_version, sizeof(fw_version), "%s%s", m->fw_pre, m->fw_ver);
|
||||
if (st->firmware_version[0])
|
||||
snprintf(fw_version, sizeof(fw_version), "%s",
|
||||
st->firmware_version);
|
||||
else
|
||||
snprintf(fw_version, sizeof(fw_version), "%s%s",
|
||||
m->fw_pre, m->fw_ver);
|
||||
|
||||
char inform_url_buf[256];
|
||||
if (st->inform_url[0])
|
||||
@@ -812,6 +817,28 @@ static void handle_response(openuf_state_t *st,
|
||||
|
||||
LOG("Handling response type: %s", type);
|
||||
|
||||
/* An OpenWrt host cannot install UniFi firmware. Acknowledge the
|
||||
* controller's request by reporting its target version from now on. */
|
||||
if (!strcmp(type, "upgrade")) {
|
||||
if (json_object_object_get_ex(resp, "version", &v) &&
|
||||
json_object_is_type(v, json_type_string)) {
|
||||
const char *version = json_object_get_string(v);
|
||||
size_t len = strlen(version);
|
||||
if (len > 0 && len < sizeof(st->firmware_version)) {
|
||||
snprintf(st->firmware_version,
|
||||
sizeof(st->firmware_version), "%s", version);
|
||||
state_save(st);
|
||||
LOG("Firmware upgrade spoofed; now reporting version=%s",
|
||||
st->firmware_version);
|
||||
strcpy(action_out, "upgrade-spoofed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG("Ignoring upgrade response without a valid version");
|
||||
strcpy(action_out, "upgrade-invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
/* ── noop ────────────────────────────────────────────────────── */
|
||||
if (!strcmp(type, "noop")) {
|
||||
strcpy(action_out, "noop");
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@
|
||||
void inform_set_debug_level(int level);
|
||||
|
||||
/* Send one inform cycle.
|
||||
* Updates *st in place (adopted flag, auth key, inform_url, cfgversion).
|
||||
* Updates *st in place (adoption, controller config, and spoofed firmware).
|
||||
* Returns 0 on success, -1 on error (sets err_out[0..127]). */
|
||||
int inform_send(openuf_state_t *st,
|
||||
const uf_model_t *model,
|
||||
|
||||
@@ -68,6 +68,7 @@ void state_load(openuf_state_t *st)
|
||||
LOAD_STR (authkey, "authkey");
|
||||
LOAD_STR (inform_url, "inform_url");
|
||||
LOAD_STR (cfgversion, "cfgversion");
|
||||
LOAD_STR (firmware_version, "firmware_version");
|
||||
LOAD_BOOL(config_applied, "config_applied");
|
||||
LOAD_INT (config_schema, "config_schema");
|
||||
LOAD_BOOL(use_aes_gcm, "use_aes_gcm");
|
||||
@@ -112,6 +113,7 @@ int state_save(const openuf_state_t *st)
|
||||
json_object_object_add(root, "authkey", json_object_new_string(st->authkey));
|
||||
json_object_object_add(root, "inform_url", json_object_new_string(st->inform_url));
|
||||
json_object_object_add(root, "cfgversion", json_object_new_string(st->cfgversion));
|
||||
json_object_object_add(root, "firmware_version", json_object_new_string(st->firmware_version));
|
||||
json_object_object_add(root, "config_applied", json_object_new_boolean(st->config_applied));
|
||||
json_object_object_add(root, "config_schema", json_object_new_int(st->config_schema));
|
||||
json_object_object_add(root, "use_aes_gcm", json_object_new_boolean(st->use_aes_gcm));
|
||||
|
||||
@@ -10,6 +10,7 @@ typedef struct {
|
||||
char authkey[64];
|
||||
char inform_url[256];
|
||||
char cfgversion[32];
|
||||
char firmware_version[64];
|
||||
bool config_applied;
|
||||
int config_schema;
|
||||
bool use_aes_gcm;
|
||||
|
||||
Reference in New Issue
Block a user