feat: the room may use the church Wi-Fi and may not read its password
These are shared computers in rooms full of people, and in a stock Plasma
desktop "use the network" and "read the network's password" are much
closer together than they look.
Measured on Debian 13 with NetworkManager 1.52 and Plasma 6.3:
* org.freedesktop.NetworkManager.settings.modify.own ships as "yes" for
an active session — no prompt, no administrator. It covers any
connection whose connection.permissions names that user, and a Wi-Fi
network added from the desktop is created exactly that way. So a
password a teacher types in is readable by the next person to sit
down.
* the applet offers "Show Network's QR Code" on every saved wireless
connection, and the QR code contains the pre-shared key.
* that action, and the "Configure…" beside it, are contextual actions in
ConnectionItem.qml and do NOT consult
authorizeControlModule("kcm_networkmanagement"). The Kiosk key gates
the toolbar button only. Hiding buttons was never going to be the
answer.
Every one of those paths ends at NetworkManager's GetSecrets, so that is
where this is answered. A polkit rule refuses settings.modify.own,
settings.modify.system, both wifi.share actions and the machine-wide
settings, for the classroom user by name.
Deliberately NOT refused: network-control, wifi.scan and the
enable/disable actions. None returns a secret, and they are what
connecting and seeing a network are made of. Automatic reconnection does
not go through polkit at all — NetworkManager does it as root — so nothing
here can stop the room coming back on the network after a reboot, which is
the property that matters most on a Sunday.
An administrator's account and root are untouched, and the override route
is the same one the sleep rule has.
classroom-wifi is the other half, and it is a requirement rather than a
convenience: it provisions the church Wi-Fi as a SYSTEM connection, with
no connection.permissions, psk-flags=0 and a 0600 root:root file. A
connection the machine owns is one nobody in the room can read. Verified
against real NetworkManager in the lab — the classroom account gets
"Permission denied" on the file, "--" from nmcli and "Insufficient
privileges" from GetSecrets, while autoconnect stays on.
There is deliberately no teacher-facing join dialog. Anything that lets
the room add a connection lets the room own it, and an owned connection is
a readable one; docs/networking.md says so rather than leaving it to be
rediscovered.
The rule is plain JavaScript, so the test evaluates it with polkit's
objects stubbed and asserts both halves: which actions come back NO, and
which are left alone. What it cannot test is the last mile — polkit
resolves a subject through logind and a container has no graphical seat
session, so every check there is denied for reasons unrelated to this
rule. That one is a physical check, and it is written down as one.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7f4a122900
commit
bf7b959893
@@ -32,6 +32,22 @@ action/help_report_bug=false
|
||||
action/help_about_kde=false
|
||||
action/help_contents=false
|
||||
|
||||
# The network applet reads this one before it draws its own settings
|
||||
# button and its "Configure Network Connections…" entry — see
|
||||
# main.qml, which calls
|
||||
# KAuthorized.authorizeControlModule("kcm_networkmanagement").
|
||||
#
|
||||
# This is only the first of two layers, and on its own it would be
|
||||
# security theatre. The applet ALSO puts "Show Network's QR Code" and
|
||||
# "Configure…" on every saved wireless connection as contextual actions,
|
||||
# and neither of those consults this key — measured on Plasma 6.3. The QR
|
||||
# code contains the pre-shared key. What actually refuses them is the
|
||||
# polkit rule in org.ekklesia.classroom.network.rules, which answers at
|
||||
# NetworkManager rather than in a menu. This key is here so that a teacher
|
||||
# is not shown doors that will not open.
|
||||
[KDE Control Module Restrictions][$i]
|
||||
kcm_networkmanagement=false
|
||||
|
||||
# Not immutable. Marking this group [$i] froze the colour scheme so hard
|
||||
# that `classroom-theme light` changed the running session and then lost
|
||||
# the change at the next start — measured. These are defaults for a room
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// The classroom user cannot be shown a saved Wi-Fi password.
|
||||
//
|
||||
// These are shared computers in rooms full of people. The account a
|
||||
// teacher uses must be able to USE the church's Wi-Fi and must never be
|
||||
// able to READ its password, and those two are much closer together in a
|
||||
// stock desktop than they look.
|
||||
//
|
||||
// WHY THIS IS NOT DONE IN THE PANEL.
|
||||
//
|
||||
// Plasma's network applet offers "Show Network's QR Code" on every saved
|
||||
// wireless connection — a contextual action in ConnectionItem.qml — and
|
||||
// that QR code contains the pre-shared key in plain text. Next to it is
|
||||
// "Configure…", which opens the connection editor. Neither is covered by
|
||||
// the Kiosk key that hides the applet's own settings button: measured,
|
||||
// authorizeControlModule("kcm_networkmanagement") gates the toolbar entry
|
||||
// and not those two.
|
||||
//
|
||||
// So hiding buttons cannot be the answer. Every one of those paths ends
|
||||
// at the same place — NetworkManager's GetSecrets over D-Bus — and polkit
|
||||
// is where that is answered once, for the applet, the editor, nmcli, a
|
||||
// future Plasma version and anything else that asks.
|
||||
//
|
||||
// WHAT IS REFUSED, AND WHAT IS DELIBERATELY NOT.
|
||||
//
|
||||
// Refused: reading or changing stored connections, and the two sharing
|
||||
// actions that exist to hand the password to somebody.
|
||||
//
|
||||
// settings.modify.own is the one that matters most and is the easiest to
|
||||
// miss. Debian ships it as "yes" — no authentication at all — and it
|
||||
// applies to any connection whose connection.permissions names this user.
|
||||
// A Wi-Fi network added from the desktop is created that way by default,
|
||||
// so a password typed in by a teacher would be readable by the next
|
||||
// person to sit down. This is why the church's Wi-Fi must be provisioned
|
||||
// as a SYSTEM connection by an administrator; see classroom-wifi.
|
||||
//
|
||||
// Not refused: network-control, wifi.scan and the enable/disable actions.
|
||||
// Those are what connecting to a network and seeing that it is there are
|
||||
// made of, and none of them returns a secret. Automatic reconnection does
|
||||
// not go through polkit at all — NetworkManager does it as root — so
|
||||
// nothing here can stop the room coming back on the network after a
|
||||
// reboot.
|
||||
//
|
||||
// Scoped to the classroom user by name. A technician's account and root
|
||||
// are untouched, which is what keeps the machine serviceable: an
|
||||
// administrator on SSH can still read, edit and add connections normally.
|
||||
//
|
||||
// To lift this for maintenance, drop a file of the same name into
|
||||
// /etc/polkit-1/rules.d/, which polkit reads ahead of this one.
|
||||
|
||||
polkit.addRule(function (action, subject) {
|
||||
if (subject.user !== "classroom") {
|
||||
return polkit.Result.NOT_HANDLED;
|
||||
}
|
||||
|
||||
var refused = [
|
||||
// Reading or writing the secrets of a connection this user owns.
|
||||
// Debian's default for this is "yes".
|
||||
"org.freedesktop.NetworkManager.settings.modify.own",
|
||||
// The same for a connection belonging to the system. Debian asks
|
||||
// for an administrator password here; the classroom has no
|
||||
// administrator standing at it, and a prompt a teacher cannot
|
||||
// answer is worse than no menu entry.
|
||||
"org.freedesktop.NetworkManager.settings.modify.system",
|
||||
// Handing the password to somebody: the QR code, and the open
|
||||
// network equivalent.
|
||||
"org.freedesktop.NetworkManager.wifi.share.protected",
|
||||
"org.freedesktop.NetworkManager.wifi.share.open",
|
||||
// Machine-wide settings a classroom has no business changing.
|
||||
"org.freedesktop.NetworkManager.settings.modify.hostname",
|
||||
"org.freedesktop.NetworkManager.settings.modify.global-dns",
|
||||
"org.freedesktop.NetworkManager.reload",
|
||||
"org.freedesktop.NetworkManager.checkpoint-rollback",
|
||||
];
|
||||
|
||||
for (var i = 0; i < refused.length; i++) {
|
||||
if (action.id === refused[i]) {
|
||||
polkit.log(
|
||||
"ekklesia-classroom: refusing " + action.id +
|
||||
" for the classroom user"
|
||||
);
|
||||
return polkit.Result.NO;
|
||||
}
|
||||
}
|
||||
|
||||
return polkit.Result.NOT_HANDLED;
|
||||
});
|
||||
Reference in New Issue
Block a user