diff options
| author | Ophestra <cat@gensokyo.uk> | 2024-12-26 13:21:49 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2024-12-26 13:21:49 +0900 |
| commit | e0e2f40e84a5a63a2ea220a0974ac56e6a52c48a (patch) | |
| tree | b72d376060f6f01235924dbf8d3a03f9f21ed08f /cmd/fpkg/start.go | |
| parent | bf8094c6cad12926e65aaa78d02ef414d3ece3da (diff) | |
cmd/fpkg: app bundle helper
This helper program creates fortify configuration for running an application bundle. The activate action wraps a home-manager activation package and ensures each generation gets activated once.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'cmd/fpkg/start.go')
| -rw-r--r-- | cmd/fpkg/start.go | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/cmd/fpkg/start.go b/cmd/fpkg/start.go new file mode 100644 index 00000000..498a3f35 --- /dev/null +++ b/cmd/fpkg/start.go @@ -0,0 +1,92 @@ +package main + +import ( + "flag" + "path" + + "git.gensokyo.uk/security/fortify/fst" + "git.gensokyo.uk/security/fortify/internal/fmsg" +) + +func actionStart(args []string) { + set := flag.NewFlagSet("start", flag.ExitOnError) + var dropShell bool + set.BoolVar(&dropShell, "s", false, "Drop to a shell on activation") + + // Ignore errors; set is set for ExitOnError. + _ = set.Parse(args) + + args = set.Args() + + if len(args) < 1 { + fmsg.Fatal("invalid argument") + } + id := args[0] + pathSet := pathSetByApp(id) + app := loadBundleInfo(pathSet.metaPath, func() {}) + + if app.ID != id { + fmsg.Fatalf("app %q claims to have identifier %q", id, app.ID) + } + + command := make([]string, 1, len(args)) + if !dropShell { + command[0] = app.Launcher + } else { + command[0] = shell + } + command = append(command, args[1:]...) + + config := &fst.Config{ + ID: app.ID, + Command: command, + Confinement: fst.ConfinementConfig{ + AppID: app.AppID, + Groups: app.Groups, + Username: "fortify", + Inner: path.Join("/data/data", app.ID), + Outer: pathSet.homeDir, + Sandbox: &fst.SandboxConfig{ + Hostname: formatHostname(app.Name), + UserNS: app.UserNS, + Net: app.Net, + Dev: app.Dev, + NoNewSession: app.NoNewSession || dropShell, + MapRealUID: app.MapRealUID, + DirectWayland: app.DirectWayland, + Filesystem: []*fst.FilesystemConfig{ + {Src: path.Join(pathSet.nixPath, "store"), Dst: "/nix/store", Must: true}, + {Src: pathSet.metaPath, Dst: path.Join(fst.Tmp, "app"), Must: true}, + {Src: "/etc/resolv.conf"}, + {Src: "/sys/block"}, + {Src: "/sys/bus"}, + {Src: "/sys/class"}, + {Src: "/sys/dev"}, + {Src: "/sys/devices"}, + }, + Link: [][2]string{ + {app.CurrentSystem, "/run/current-system"}, + {"/run/current-system/sw/bin", "/bin"}, + {"/run/current-system/sw/bin", "/usr/bin"}, + }, + Etc: path.Join(pathSet.cacheDir, "etc"), + AutoEtc: true, + }, + ExtraPerms: []*fst.ExtraPermConfig{ + {Path: dataHome, Execute: true}, + {Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true}, + }, + SystemBus: app.SystemBus, + SessionBus: app.SessionBus, + Enablements: app.Enablements, + }, + } + + if app.GPU { + config.Confinement.Sandbox.Filesystem = append(config.Confinement.Sandbox.Filesystem, + &fst.FilesystemConfig{Src: "/dev/dri", Device: true}) + } + + fortifyApp(config, func() {}) + fmsg.Exit(0) +} |
