fix: apply hub-managed GRD credentials at boot
This commit is contained in:
@@ -3,6 +3,9 @@ from pathlib import Path
|
|||||||
|
|
||||||
|
|
||||||
RDP_NIX = Path(__file__).resolve().parents[2] / "modules" / "rdp.nix"
|
RDP_NIX = Path(__file__).resolve().parents[2] / "modules" / "rdp.nix"
|
||||||
|
USERNAME_READ = "USERNAME=\"$(tr -d '\\n' < \"$USERNAME_FILE\")\""
|
||||||
|
USERNAME_LENGTH_GUARD = "if [ \"''${#USERNAME}\" -gt 32 ]; then"
|
||||||
|
SHORT_PASSWORD_GUARD = 'if [ "\'\'${#PASSWORD}" -lt 8 ]; then'
|
||||||
|
|
||||||
|
|
||||||
def _section(source: str, start: str, end: str) -> str:
|
def _section(source: str, start: str, end: str) -> str:
|
||||||
@@ -45,7 +48,9 @@ class RdpModuleBootSetupTests(unittest.TestCase):
|
|||||||
self.assertIn('"gnome-remote-desktop-configuration.service"', self.setup_service)
|
self.assertIn('"gnome-remote-desktop-configuration.service"', self.setup_service)
|
||||||
self.assertNotIn("RemainAfterExit", self.setup_service)
|
self.assertNotIn("RemainAfterExit", self.setup_service)
|
||||||
self.assertIn('TimeoutStartSec = "2min";', self.setup_service)
|
self.assertIn('TimeoutStartSec = "2min";', self.setup_service)
|
||||||
self.assertIn('timeout --kill-after=5s 15s', self.setup_service)
|
self.assertIn('timeout --kill-after=5s 10s', self.setup_service)
|
||||||
|
self.assertIn('echo "grdctl command timed out: $*" >&2', self.setup_service)
|
||||||
|
self.assertIn('echo "grdctl command failed (exit $rc): $*" >&2', self.setup_service)
|
||||||
|
|
||||||
def test_setup_runs_grdctl_as_gnome_remote_desktop_user(self):
|
def test_setup_runs_grdctl_as_gnome_remote_desktop_user(self):
|
||||||
self.assertIn("runuser -u gnome-remote-desktop -- \\", self.setup_service)
|
self.assertIn("runuser -u gnome-remote-desktop -- \\", self.setup_service)
|
||||||
@@ -54,20 +59,30 @@ class RdpModuleBootSetupTests(unittest.TestCase):
|
|||||||
def test_hub_files_are_the_source_of_truth_for_username_and_password(self):
|
def test_hub_files_are_the_source_of_truth_for_username_and_password(self):
|
||||||
self.assertIn('DEFAULT_USERNAME="sovran"', self.setup_service)
|
self.assertIn('DEFAULT_USERNAME="sovran"', self.setup_service)
|
||||||
self.assertIn('if [ ! -f "$USERNAME_FILE" ]; then', self.setup_service)
|
self.assertIn('if [ ! -f "$USERNAME_FILE" ]; then', self.setup_service)
|
||||||
self.assertIn("USERNAME=\"$(tr -d '\\n' < \"$USERNAME_FILE\")\"", self.setup_service)
|
self.assertIn(USERNAME_READ, self.setup_service)
|
||||||
|
self.assertIn(USERNAME_LENGTH_GUARD, self.setup_service)
|
||||||
|
self.assertIn('case "$USERNAME" in', self.setup_service)
|
||||||
|
self.assertIn('[A-Za-z_][A-Za-z0-9_-]*)', self.setup_service)
|
||||||
|
self.assertIn("RDP username is too long (''${#USERNAME} characters, maximum 32)", self.setup_service)
|
||||||
|
self.assertIn("RDP username must start with a letter or underscore and contain only letters, numbers, underscores, and hyphens", self.setup_service)
|
||||||
self.assertIn('if [ ! -f "$PASSWORD_FILE" ]; then', self.setup_service)
|
self.assertIn('if [ ! -f "$PASSWORD_FILE" ]; then', self.setup_service)
|
||||||
self.assertIn('PASSWORD="$(tr -d \'\\n\' < "$PASSWORD_FILE")"', self.setup_service)
|
self.assertIn("tr -d '\\n'", self.setup_service)
|
||||||
|
self.assertIn('"$PASSWORD_FILE"', self.setup_service)
|
||||||
|
self.assertIn(SHORT_PASSWORD_GUARD, self.setup_service)
|
||||||
|
self.assertIn("RDP password is too short (''${#PASSWORD} characters, minimum 8)", self.setup_service)
|
||||||
self.assertIn('grdctl_system rdp set-credentials "$USERNAME" "$PASSWORD"', self.setup_service)
|
self.assertIn('grdctl_system rdp set-credentials "$USERNAME" "$PASSWORD"', self.setup_service)
|
||||||
self.assertNotIn('grdctl --system rdp set-credentials sovran "$PASSWORD"', self.setup_service)
|
self.assertNotIn('grdctl --system rdp set-credentials sovran "$PASSWORD"', self.setup_service)
|
||||||
|
|
||||||
def test_secure_permissions_are_enforced_for_state_and_secret_files(self):
|
def test_secure_permissions_are_enforced_for_state_and_secret_files(self):
|
||||||
self.assertIn('"d /var/lib/gnome-remote-desktop/tls 0700', self.source)
|
self.assertIn('"d /var/lib/gnome-remote-desktop/tls 0700', self.source)
|
||||||
self.assertIn('chmod 700 \\', self.setup_service)
|
self.assertIn("chmod 700", self.setup_service)
|
||||||
self.assertIn('chmod 600 "$USERNAME_FILE"', self.setup_service)
|
self.assertIn('chmod 600 "$USERNAME_FILE"', self.setup_service)
|
||||||
self.assertIn('chmod 600 "$PASSWORD_FILE"', self.setup_service)
|
self.assertIn('chmod 600 "$PASSWORD_FILE"', self.setup_service)
|
||||||
self.assertIn('chmod 600 "$CRED_FILE"', self.setup_service)
|
self.assertIn('chmod 600 "$CRED_FILE"', self.setup_service)
|
||||||
self.assertIn('chmod 600 "$TLS_DIR/rdp-tls.key"', self.setup_service)
|
self.assertIn('chmod 600 "$TLS_DIR/rdp-tls.key"', self.setup_service)
|
||||||
self.assertIn('chmod 644 "$TLS_DIR/rdp-tls.crt"', self.setup_service)
|
self.assertIn('chmod 644 "$TLS_DIR/rdp-tls.crt"', self.setup_service)
|
||||||
|
self.assertIn('LOCAL_IP="$(hostname -I | awk \'{print $1}\')"', self.setup_service)
|
||||||
|
self.assertIn('LOCAL_IP="127.0.0.1"', self.setup_service)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
+34
-2
@@ -61,9 +61,22 @@ lib.mkIf config.sovran_systemsOS.features.rdp {
|
|||||||
DEFAULT_USERNAME="sovran"
|
DEFAULT_USERNAME="sovran"
|
||||||
|
|
||||||
grdctl_system() {
|
grdctl_system() {
|
||||||
timeout --kill-after=5s 15s \
|
local rc=0
|
||||||
|
|
||||||
|
if timeout --kill-after=5s 10s \
|
||||||
runuser -u gnome-remote-desktop -- \
|
runuser -u gnome-remote-desktop -- \
|
||||||
grdctl --system "$@"
|
grdctl --system "$@"; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
rc=$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$rc" -eq 124 ] || [ "$rc" -eq 137 ]; then
|
||||||
|
echo "grdctl command timed out: $*" >&2
|
||||||
|
fi
|
||||||
|
echo "grdctl command failed (exit $rc): $*" >&2
|
||||||
|
|
||||||
|
return "$rc"
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdir -p "$STATE_DIR/.local/share/gnome-remote-desktop" "$TLS_DIR"
|
mkdir -p "$STATE_DIR/.local/share/gnome-remote-desktop" "$TLS_DIR"
|
||||||
@@ -104,6 +117,18 @@ lib.mkIf config.sovran_systemsOS.features.rdp {
|
|||||||
USERNAME="$DEFAULT_USERNAME"
|
USERNAME="$DEFAULT_USERNAME"
|
||||||
printf '%s\n' "$USERNAME" > "$USERNAME_FILE"
|
printf '%s\n' "$USERNAME" > "$USERNAME_FILE"
|
||||||
fi
|
fi
|
||||||
|
if [ "''${#USERNAME}" -gt 32 ]; then
|
||||||
|
echo "RDP username is too long (''${#USERNAME} characters, maximum 32): $USERNAME from $USERNAME_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
case "$USERNAME" in
|
||||||
|
[A-Za-z_][A-Za-z0-9_-]*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "RDP username must start with a letter or underscore and contain only letters, numbers, underscores, and hyphens: $USERNAME from $USERNAME_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
chown gnome-remote-desktop:gnome-remote-desktop "$USERNAME_FILE"
|
chown gnome-remote-desktop:gnome-remote-desktop "$USERNAME_FILE"
|
||||||
chmod 600 "$USERNAME_FILE"
|
chmod 600 "$USERNAME_FILE"
|
||||||
|
|
||||||
@@ -115,10 +140,17 @@ lib.mkIf config.sovran_systemsOS.features.rdp {
|
|||||||
echo "RDP password file is empty: $PASSWORD_FILE" >&2
|
echo "RDP password file is empty: $PASSWORD_FILE" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [ "''${#PASSWORD}" -lt 8 ]; then
|
||||||
|
echo "RDP password is too short (''${#PASSWORD} characters, minimum 8): $PASSWORD_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
chown gnome-remote-desktop:gnome-remote-desktop "$PASSWORD_FILE"
|
chown gnome-remote-desktop:gnome-remote-desktop "$PASSWORD_FILE"
|
||||||
chmod 600 "$PASSWORD_FILE"
|
chmod 600 "$PASSWORD_FILE"
|
||||||
|
|
||||||
LOCAL_IP="$(hostname -I | awk '{print $1}')"
|
LOCAL_IP="$(hostname -I | awk '{print $1}')"
|
||||||
|
if [ -z "$LOCAL_IP" ]; then
|
||||||
|
LOCAL_IP="127.0.0.1"
|
||||||
|
fi
|
||||||
|
|
||||||
cat > "$CRED_FILE" <<EOF
|
cat > "$CRED_FILE" <<EOF
|
||||||
========================================
|
========================================
|
||||||
|
|||||||
Reference in New Issue
Block a user