Bug: app cannot authenticate when device-local auth is enabled (EM06P, fw 2.1.13) — Digest is MD5-only, device requires SHA-256
Setting up an EM06P on Homey Pro (Early 2023, fw 13.4.1-rc.3), app v2.0.10. Device paired fine, but the parent device immediately went Device unreachable and all six channel devices stayed at null (expected — channels don’t poll, they get data from the parent).
The device was reachable the whole time. The cause is the Digest implementation in lib/RefossApi.js.
1. Device info works — no auth needed, and it advertises auth is on
$ curl -s http://<device-ip>/rpc/Refoss.DeviceInfo.Get
{"name":"Refoss Smart Energy Monitor","model":"em06p",
"dev_id":"refoss-em06p-c4e7ae******","api_ver":"1.0",
"fw_ver":"2.1.13","hw_ver":"2.0.0","auth_en":true}
2. Data endpoint returns 401, and the challenge asks for SHA-256
$ curl -s -i http://<device-ip>/rpc/Refoss.Status.Get
HTTP/1.1 401 Unauthorized
Www-Authenticate: Digest qop="auth", realm="refoss-em06p-c4e7ae******",
nonce="1786889468", algorithm=SHA-256
Server: RefossHTTP/1.0.0
3. Why the app can never satisfy it — lib/RefossApi.js:
js
function md5(str) {
return crypto.createHash('md5').update(str).digest('hex');
}
function buildDigestHeader({ username, password, method, path, challenge, nc, cnonce }) {
const { realm, nonce, qop, opaque, algorithm } = challenge;
const ha1 = (algorithm || '').toUpperCase() === 'MD5-SESS'
? md5(`${md5(`${username}:${realm}:${password}`)}:${nonce}:${cnonce}`)
: md5(`${username}:${realm}:${password}`);
const ha2 = md5(`${method}:${path}`);
...
}
Every hash is MD5; there is no SHA-256 branch. So the response digest is always wrong for this firmware and the retry after 401 fails permanently — the user just sees Device unreachable with no hint that it’s an auth problem.
Second, smaller issue in the same path — the challenge parser only accepts quoted values:
js
const re = /(\w+)="([^"]+)"/g;
The device sends algorithm=SHA-256 unquoted, so algorithm is never even parsed. Both qop="auth" and realm="..." are quoted and do parse, which is why this goes unnoticed.
Suggested fix: pick the hash function from the challenge (MD5, MD5-sess, SHA-256, SHA-256-sess) instead of hardcoding MD5, and relax the parser to accept unquoted parameter values. RFC 7616 §3.3.
Workaround: disable local authentication on the device in the Refoss app. auth_en becomes false, Refoss.Status.Get returns 200 and everything works — all six channels report immediately. Obviously not ideal, since it leaves the RPC API (including Em.Config.Set) open to anyone on the LAN.
One request while you’re in there: it would help a lot if the poll failure surfaced the underlying error. Device unreachable. Check IP address and network connection. sent me looking at the network for a while, when the device was answering 401 the entire time.