Own the network: details, VPN, enterprise Wi-Fi, and a firewall that can also allow

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-24 16:31:52 -04:00
parent aba2d16ffa
commit b30bf40407
29 changed files with 4452 additions and 241 deletions
@@ -22,18 +22,21 @@ SettingsPage {
Component.onCompleted: Sharing.refresh()
TextRow {
visible: Sharing.lastError !== ""
label: "Sharing needs attention"
detail: Sharing.lastError
value: ""
divider: false
}
SettingsCard {
title: "This machine"
subtitle: "The name other machines see."
// The error belongs to the machine, not to a floating banner above the
// title: a bare row above the first card read as part of the page
// furniture, which is exactly what an error must not do.
TextRow {
width: parent.width
visible: Sharing.lastError !== ""
label: "Sharing needs attention"
detail: Sharing.lastError
value: ""
}
TextFieldRow {
label: "Network name"
detail: "Used for ssh and for anything else that finds this machine by name"
@@ -47,32 +50,37 @@ SettingsPage {
SettingsCard {
title: "Remote login"
subtitle: "Sign in to a terminal on this machine over SSH."
subtitle: Sharing.remoteLoginOn
? "Sign in to a terminal on this machine with: ssh " + Sharing.networkName
: "Sign in to a terminal on this machine over SSH."
// Port and the password-sign-in claim used to be two rows of their own
// below this one. They describe this switch rather than standing beside
// it, so they read as its detail line -- and the card is three rows
// shorter for saying the same things.
//
// "Keys only" is reported from sshd's configuration rather than assumed:
// claiming it on a machine that actually accepts passwords would be a
// security claim this page cannot back up.
SwitchRow {
label: "Allow remote login"
detail: Sharing.remoteLogin?.installed === true
? (Sharing.remoteLoginOn
? "Running, and starts automatically at boot"
: "Not running")
? "OpenSSH · port " + String(Sharing.remoteLogin?.port ?? "22")
+ " · password sign-in: " + Sharing.passwordLoginSummary().toLowerCase()
+ (Sharing.remoteLoginOn ? " · starts at boot" : "")
: "OpenSSH server is not installed"
checked: Sharing.remoteLoginOn
enabled: !Sharing.busy && Sharing.remoteLogin?.installed === true
divider: Sharing.remoteLoginOn
onToggled: value => Sharing.setRemoteLogin(value)
}
TextRow {
visible: Sharing.remoteLoginOn
label: "Connect with"
detail: "From another machine on your network"
value: "ssh " + Sharing.networkName
}
TextRow {
visible: Sharing.remoteLoginOn && Sharing.remoteSessions.length === 0
label: "Nobody is signed in"
label: "Nobody is signed in remotely"
detail: "Remote login is on, and no one is connected from another machine."
value: ""
divider: false
}
Repeater {
@@ -80,30 +88,14 @@ SettingsPage {
delegate: TextRow {
required property var modelData
required property int index
width: parent.width
label: String(modelData.user ?? "") + " is signed in from " + String(modelData.from ?? "")
detail: "Since " + String(modelData.since ?? "") + " · " + String(modelData.line ?? "")
value: ""
divider: index < Sharing.remoteSessions.length - 1
}
}
TextRow {
visible: Sharing.remoteLoginOn
label: "Port"
detail: "Where the SSH server is listening"
value: String(Sharing.remoteLogin?.port ?? "22")
}
// Reported from the configuration rather than assumed. Saying "keys
// only" on a machine that actually accepts passwords would be a
// security claim this page cannot back up.
TextRow {
visible: Sharing.remoteLoginOn
label: "Password sign-in"
detail: Sharing.passwordLoginSummary()
value: ""
divider: false
}
}
SettingsCard {
@@ -113,11 +105,12 @@ SettingsPage {
SwitchRow {
label: "Allow remote desktop"
detail: Sharing.remoteDesktop?.available === true
? (Sharing.remoteDesktopOn
? "Running for your session"
? "RDP · port " + String(Sharing.remoteDesktop?.port ?? "3389") + " · "
+ (Sharing.remoteDesktopOn
? "running for your session"
: (Sharing.remoteDesktop?.hasCredentials === true
? "Not running"
: "Set a username and password before turning this on"))
? "not running"
: "set a username and password before turning this on"))
: "Remote desktop support is not installed"
checked: Sharing.remoteDesktopOn
enabled: !Sharing.busy
@@ -149,12 +142,16 @@ SettingsPage {
// terminal, never into this page. grdctl prompts for it on a terminal
// and crashes without one, and passing it as an argument would publish
// it through /proc to every process on this machine.
//
// The row says why rather than naming the mechanism: "opens kitty" is
// an implementation detail, and the reason -- the password never passes
// through Panama -- is the part worth reading.
ActionRow {
visible: Sharing.remoteDesktop?.available === true
label: "Credentials"
detail: Sharing.remoteDesktop?.hasCredentials === true
? "Stored in the login keyring · setting new ones opens a terminal to type into"
: "None stored yet · remote desktop cannot be turned on without them"
? "Stored in the login keyring · set in a terminal so the password never passes through Panama"
: "None stored yet · set in a terminal so the password never passes through Panama"
action: "Set…"
enabled: !Sharing.busy
onTriggered: Sharing.setRdpCredentials(Quickshell.env("USER") || "")
@@ -176,11 +173,15 @@ SettingsPage {
title: "File and media sharing"
subtitle: "Sharing folders and media needs software this machine does not necessarily have."
// Not a switch, because there is nothing behind it. Naming what
// installing Samba would unlock is the difference between a dead row
// and an answer -- the panel this replaces shows a switch that silently
// does nothing.
TextRow {
label: "Share folders on the network"
detail: Sharing.fileSharing?.installed === true
? "Samba is installed"
: "Needs Samba, which is not installed. Settings does not install software."
? "Samba is installed, so folders can be published to Windows, macOS and Linux machines alike"
: "Samba is not installed — install it and this becomes a switch. Settings does not install software."
value: Sharing.fileSharing?.installed === true ? "Available" : "Not installed"
}