screen: fix MD5 rotation schedule and send root username

Two bugs found via the weston journal (issue #92):

1. MD5 rotation index used (j>>2 & 3) for the round number, which
   cycles every 4 steps instead of every 16. Verified against RFC 1321
   test vectors: md5("") was 7a1dce5b... instead of d41d8cd9... — the
   derived AES key was wrong, so the server decrypted the credentials
   to garbage. Fixed to j>>4.

2. weston's vnc_handle_auth calls getpwnam(username) and requires
   pw_uid == weston's own uid before PAM is consulted. We sent an empty
   username, which fails outright ("VNC: wrong user"). weston runs as
   root, so send username "root"; the empty password still passes via
   pam_permit.so on the weston-remote-access service.

Fixes #92
This commit is contained in:
iris 2026-05-20 21:47:27 +02:00
parent a95ca22b49
commit c10b4e26ef

View file

@ -242,7 +242,9 @@ canvas { display: block; cursor: default; }
: j<48 ? [bb^cc^dd, (3*j+5)%16] : j<48 ? [bb^cc^dd, (3*j+5)%16]
: [cc^(bb|(~dd)), (7*j)%16]; : [cc^(bb|(~dd)), (7*j)%16];
f = add(add(aa, f), add(m[i+g], T[j])); f = add(add(aa, f), add(m[i+g], T[j]));
[aa,dd,cc,bb] = [dd, cc, bb, add(bb, r(f, S[(j%4)+((j>>2&3)*4)]))]; // Rotation amount: round = j>>4 (changes every 16 steps),
// position-in-round = j%4. S is laid out as 4 rounds × 4.
[aa,dd,cc,bb] = [dd, cc, bb, add(bb, r(f, S[(j%4)+((j>>4)*4)]))];
} }
[a,b2,c,d] = [add(a,aa), add(b2,bb), add(c,cc), add(d,dd)]; [a,b2,c,d] = [add(a,aa), add(b2,bb), add(c,cc), add(d,dd)];
} }
@ -419,8 +421,15 @@ canvas { display: block; cursor: default; }
const aesKey = md5(sharedBytes); const aesKey = md5(sharedBytes);
dbg('Apple-DH: shared MD5 key=' + hex(aesKey)); dbg('Apple-DH: shared MD5 key=' + hex(aesKey));
// Credentials: 64 bytes username (zeroed) + 64 bytes password (zeroed) // Credentials: 64 bytes username + 64 bytes password.
const creds = new Uint8Array(128); // empty username + empty password // weston's vnc_handle_auth (libweston/backend-vnc/vnc.c) does
// getpwnam(username) and requires pw_uid == weston's own uid
// BEFORE PAM is ever consulted — an empty/garbage username is
// rejected outright. weston runs as root, so the username must
// be "root". The password stays empty; pam_permit.so on the
// weston-remote-access PAM service accepts it.
const creds = new Uint8Array(128);
creds.set(new TextEncoder().encode('root'), 0);
const encCreds = await aes128ecb(aesKey, creds); const encCreds = await aes128ecb(aesKey, creds);
// Send: encrypted_creds + client_pub // Send: encrypted_creds + client_pub