From 2f676c9d6e7baac289409cbcabde5b6e53b32ec3 Mon Sep 17 00:00:00 2001 From: Ophestra Umiker Date: Wed, 18 Dec 2024 15:50:46 +0900 Subject: fst: rename from fipc Signed-off-by: Ophestra Umiker --- fipc/config.go | 242 ----------------------------------------- fst/config.go | 242 +++++++++++++++++++++++++++++++++++++++++ fst/shared.go | 18 +++ internal/app/app.go | 20 ++-- internal/app/app_nixos_test.go | 13 +-- internal/app/app_pd_test.go | 15 ++- internal/app/app_test.go | 6 +- internal/app/export_test.go | 3 +- internal/app/id.go | 17 --- internal/app/seal.go | 16 +-- internal/state/state.go | 6 +- main.go | 10 +- 12 files changed, 304 insertions(+), 304 deletions(-) delete mode 100644 fipc/config.go create mode 100644 fst/config.go create mode 100644 fst/shared.go delete mode 100644 internal/app/id.go diff --git a/fipc/config.go b/fipc/config.go deleted file mode 100644 index 472d22f6..00000000 --- a/fipc/config.go +++ /dev/null @@ -1,242 +0,0 @@ -package fipc - -import ( - "errors" - - "git.ophivana.moe/security/fortify/dbus" - "git.ophivana.moe/security/fortify/helper/bwrap" - "git.ophivana.moe/security/fortify/internal/linux" - "git.ophivana.moe/security/fortify/internal/system" -) - -const fTmp = "/fortify" - -// Config is used to seal an *App -type Config struct { - // D-Bus application ID - ID string `json:"id"` - // value passed through to the child process as its argv - Command []string `json:"command"` - - // child confinement configuration - Confinement ConfinementConfig `json:"confinement"` -} - -// ConfinementConfig defines fortified child's confinement -type ConfinementConfig struct { - // numerical application id, determines uid in the init namespace - AppID int `json:"app_id"` - // list of supplementary groups to inherit - Groups []string `json:"groups"` - // passwd username in the sandbox, defaults to chronos - Username string `json:"username,omitempty"` - // home directory in sandbox, empty for outer - Inner string `json:"home_inner"` - // home directory in init namespace - Outer string `json:"home"` - // bwrap sandbox confinement configuration - Sandbox *SandboxConfig `json:"sandbox"` - - // reference to a system D-Bus proxy configuration, - // nil value disables system bus proxy - SystemBus *dbus.Config `json:"system_bus,omitempty"` - // reference to a session D-Bus proxy configuration, - // nil value makes session bus proxy assume built-in defaults - SessionBus *dbus.Config `json:"session_bus,omitempty"` - - // child capability enablements - Enablements system.Enablements `json:"enablements"` -} - -// SandboxConfig describes resources made available to the sandbox. -type SandboxConfig struct { - // unix hostname within sandbox - Hostname string `json:"hostname,omitempty"` - // userns availability within sandbox - UserNS bool `json:"userns,omitempty"` - // share net namespace - Net bool `json:"net,omitempty"` - // share all devices - Dev bool `json:"dev,omitempty"` - // do not run in new session - NoNewSession bool `json:"no_new_session,omitempty"` - // map target user uid to privileged user uid in the user namespace - MapRealUID bool `json:"map_real_uid"` - // direct access to wayland socket - DirectWayland bool `json:"direct_wayland,omitempty"` - - // final environment variables - Env map[string]string `json:"env"` - // sandbox host filesystem access - Filesystem []*FilesystemConfig `json:"filesystem"` - // symlinks created inside the sandbox - Link [][2]string `json:"symlink"` - // automatically set up /etc symlinks - AutoEtc bool `json:"auto_etc"` - // paths to override by mounting tmpfs over them - Override []string `json:"override"` -} - -type FilesystemConfig struct { - // mount point in sandbox, same as src if empty - Dst string `json:"dst,omitempty"` - // host filesystem path to make available to sandbox - Src string `json:"src"` - // write access - Write bool `json:"write,omitempty"` - // device access - Device bool `json:"dev,omitempty"` - // exit if unable to share - Must bool `json:"require,omitempty"` -} - -// Bwrap returns the address of the corresponding bwrap.Config to s. -// Note that remaining tmpfs entries must be queued by the caller prior to launch. -func (s *SandboxConfig) Bwrap(os linux.System) (*bwrap.Config, error) { - if s == nil { - return nil, errors.New("nil sandbox config") - } - - var uid int - if !s.MapRealUID { - uid = 65534 - } else { - uid = os.Geteuid() - } - - conf := (&bwrap.Config{ - Net: s.Net, - UserNS: s.UserNS, - Hostname: s.Hostname, - Clearenv: true, - SetEnv: s.Env, - NewSession: !s.NoNewSession, - DieWithParent: true, - AsInit: true, - - // initialise map - Chmod: make(bwrap.ChmodConfig), - }). - SetUID(uid).SetGID(uid). - Procfs("/proc"). - Tmpfs(fTmp, 4*1024) - - if !s.Dev { - conf.DevTmpfs("/dev").Mqueue("/dev/mqueue") - } else { - conf.Bind("/dev", "/dev", false, true, true) - } - - if !s.AutoEtc { - conf.Dir("/etc") - } - - for _, c := range s.Filesystem { - if c == nil { - continue - } - src := c.Src - dest := c.Dst - if c.Dst == "" { - dest = c.Src - } - conf.Bind(src, dest, !c.Must, c.Write, c.Device) - } - - for _, l := range s.Link { - conf.Symlink(l[0], l[1]) - } - - if s.AutoEtc { - conf.Bind("/etc", fTmp+"/etc") - - // link host /etc contents to prevent passwd/group from being overwritten - if d, err := os.ReadDir("/etc"); err != nil { - return nil, err - } else { - for _, ent := range d { - name := ent.Name() - switch name { - case "passwd": - case "group": - - case "mtab": - conf.Symlink("/proc/mounts", "/etc/"+name) - default: - conf.Symlink(fTmp+"/etc/"+name, "/etc/"+name) - } - } - } - } - - return conf, nil -} - -// Template returns a fully populated instance of Config. -func Template() *Config { - return &Config{ - ID: "org.chromium.Chromium", - Command: []string{ - "chromium", - "--ignore-gpu-blocklist", - "--disable-smooth-scrolling", - "--enable-features=UseOzonePlatform", - "--ozone-platform=wayland", - }, - Confinement: ConfinementConfig{ - AppID: 9, - Groups: []string{"video"}, - Username: "chronos", - Outer: "/var/lib/persist/home/org.chromium.Chromium", - Inner: "/var/lib/fortify", - Sandbox: &SandboxConfig{ - Hostname: "localhost", - UserNS: true, - Net: true, - NoNewSession: true, - MapRealUID: true, - Dev: true, - DirectWayland: false, - // example API credentials pulled from Google Chrome - // DO NOT USE THESE IN A REAL BROWSER - Env: map[string]string{ - "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY", - "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com", - "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT", - }, - Filesystem: []*FilesystemConfig{ - {Src: "/nix/store"}, - {Src: "/run/current-system"}, - {Src: "/run/opengl-driver"}, - {Src: "/var/db/nix-channels"}, - {Src: "/home/chronos", Write: true, Must: true}, - {Src: "/dev/dri", Device: true}, - }, - Link: [][2]string{{"/run/user/65534", "/run/user/150"}}, - AutoEtc: true, - Override: []string{"/var/run/nscd"}, - }, - SystemBus: &dbus.Config{ - See: nil, - Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"}, - Own: nil, - Call: nil, - Broadcast: nil, - Log: false, - Filter: true, - }, - SessionBus: &dbus.Config{ - See: nil, - Talk: []string{"org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver", - "org.freedesktop.secrets", "org.kde.kwalletd5", "org.kde.kwalletd6", "org.gnome.SessionManager"}, - Own: []string{"org.chromium.Chromium.*", "org.mpris.MediaPlayer2.org.chromium.Chromium.*", - "org.mpris.MediaPlayer2.chromium.*"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Log: false, - Filter: true, - }, - Enablements: system.EWayland.Mask() | system.EDBus.Mask() | system.EPulse.Mask(), - }, - } -} diff --git a/fst/config.go b/fst/config.go new file mode 100644 index 00000000..b1a2240b --- /dev/null +++ b/fst/config.go @@ -0,0 +1,242 @@ +package fst + +import ( + "errors" + + "git.ophivana.moe/security/fortify/dbus" + "git.ophivana.moe/security/fortify/helper/bwrap" + "git.ophivana.moe/security/fortify/internal/linux" + "git.ophivana.moe/security/fortify/internal/system" +) + +const fTmp = "/fortify" + +// Config is used to seal an *App +type Config struct { + // D-Bus application ID + ID string `json:"id"` + // value passed through to the child process as its argv + Command []string `json:"command"` + + // child confinement configuration + Confinement ConfinementConfig `json:"confinement"` +} + +// ConfinementConfig defines fortified child's confinement +type ConfinementConfig struct { + // numerical application id, determines uid in the init namespace + AppID int `json:"app_id"` + // list of supplementary groups to inherit + Groups []string `json:"groups"` + // passwd username in the sandbox, defaults to chronos + Username string `json:"username,omitempty"` + // home directory in sandbox, empty for outer + Inner string `json:"home_inner"` + // home directory in init namespace + Outer string `json:"home"` + // bwrap sandbox confinement configuration + Sandbox *SandboxConfig `json:"sandbox"` + + // reference to a system D-Bus proxy configuration, + // nil value disables system bus proxy + SystemBus *dbus.Config `json:"system_bus,omitempty"` + // reference to a session D-Bus proxy configuration, + // nil value makes session bus proxy assume built-in defaults + SessionBus *dbus.Config `json:"session_bus,omitempty"` + + // child capability enablements + Enablements system.Enablements `json:"enablements"` +} + +// SandboxConfig describes resources made available to the sandbox. +type SandboxConfig struct { + // unix hostname within sandbox + Hostname string `json:"hostname,omitempty"` + // userns availability within sandbox + UserNS bool `json:"userns,omitempty"` + // share net namespace + Net bool `json:"net,omitempty"` + // share all devices + Dev bool `json:"dev,omitempty"` + // do not run in new session + NoNewSession bool `json:"no_new_session,omitempty"` + // map target user uid to privileged user uid in the user namespace + MapRealUID bool `json:"map_real_uid"` + // direct access to wayland socket + DirectWayland bool `json:"direct_wayland,omitempty"` + + // final environment variables + Env map[string]string `json:"env"` + // sandbox host filesystem access + Filesystem []*FilesystemConfig `json:"filesystem"` + // symlinks created inside the sandbox + Link [][2]string `json:"symlink"` + // automatically set up /etc symlinks + AutoEtc bool `json:"auto_etc"` + // paths to override by mounting tmpfs over them + Override []string `json:"override"` +} + +type FilesystemConfig struct { + // mount point in sandbox, same as src if empty + Dst string `json:"dst,omitempty"` + // host filesystem path to make available to sandbox + Src string `json:"src"` + // write access + Write bool `json:"write,omitempty"` + // device access + Device bool `json:"dev,omitempty"` + // exit if unable to share + Must bool `json:"require,omitempty"` +} + +// Bwrap returns the address of the corresponding bwrap.Config to s. +// Note that remaining tmpfs entries must be queued by the caller prior to launch. +func (s *SandboxConfig) Bwrap(os linux.System) (*bwrap.Config, error) { + if s == nil { + return nil, errors.New("nil sandbox config") + } + + var uid int + if !s.MapRealUID { + uid = 65534 + } else { + uid = os.Geteuid() + } + + conf := (&bwrap.Config{ + Net: s.Net, + UserNS: s.UserNS, + Hostname: s.Hostname, + Clearenv: true, + SetEnv: s.Env, + NewSession: !s.NoNewSession, + DieWithParent: true, + AsInit: true, + + // initialise map + Chmod: make(bwrap.ChmodConfig), + }). + SetUID(uid).SetGID(uid). + Procfs("/proc"). + Tmpfs(fTmp, 4*1024) + + if !s.Dev { + conf.DevTmpfs("/dev").Mqueue("/dev/mqueue") + } else { + conf.Bind("/dev", "/dev", false, true, true) + } + + if !s.AutoEtc { + conf.Dir("/etc") + } + + for _, c := range s.Filesystem { + if c == nil { + continue + } + src := c.Src + dest := c.Dst + if c.Dst == "" { + dest = c.Src + } + conf.Bind(src, dest, !c.Must, c.Write, c.Device) + } + + for _, l := range s.Link { + conf.Symlink(l[0], l[1]) + } + + if s.AutoEtc { + conf.Bind("/etc", fTmp+"/etc") + + // link host /etc contents to prevent passwd/group from being overwritten + if d, err := os.ReadDir("/etc"); err != nil { + return nil, err + } else { + for _, ent := range d { + name := ent.Name() + switch name { + case "passwd": + case "group": + + case "mtab": + conf.Symlink("/proc/mounts", "/etc/"+name) + default: + conf.Symlink(fTmp+"/etc/"+name, "/etc/"+name) + } + } + } + } + + return conf, nil +} + +// Template returns a fully populated instance of Config. +func Template() *Config { + return &Config{ + ID: "org.chromium.Chromium", + Command: []string{ + "chromium", + "--ignore-gpu-blocklist", + "--disable-smooth-scrolling", + "--enable-features=UseOzonePlatform", + "--ozone-platform=wayland", + }, + Confinement: ConfinementConfig{ + AppID: 9, + Groups: []string{"video"}, + Username: "chronos", + Outer: "/var/lib/persist/home/org.chromium.Chromium", + Inner: "/var/lib/fortify", + Sandbox: &SandboxConfig{ + Hostname: "localhost", + UserNS: true, + Net: true, + NoNewSession: true, + MapRealUID: true, + Dev: true, + DirectWayland: false, + // example API credentials pulled from Google Chrome + // DO NOT USE THESE IN A REAL BROWSER + Env: map[string]string{ + "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY", + "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com", + "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT", + }, + Filesystem: []*FilesystemConfig{ + {Src: "/nix/store"}, + {Src: "/run/current-system"}, + {Src: "/run/opengl-driver"}, + {Src: "/var/db/nix-channels"}, + {Src: "/home/chronos", Write: true, Must: true}, + {Src: "/dev/dri", Device: true}, + }, + Link: [][2]string{{"/run/user/65534", "/run/user/150"}}, + AutoEtc: true, + Override: []string{"/var/run/nscd"}, + }, + SystemBus: &dbus.Config{ + See: nil, + Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"}, + Own: nil, + Call: nil, + Broadcast: nil, + Log: false, + Filter: true, + }, + SessionBus: &dbus.Config{ + See: nil, + Talk: []string{"org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver", + "org.freedesktop.secrets", "org.kde.kwalletd5", "org.kde.kwalletd6", "org.gnome.SessionManager"}, + Own: []string{"org.chromium.Chromium.*", "org.mpris.MediaPlayer2.org.chromium.Chromium.*", + "org.mpris.MediaPlayer2.chromium.*"}, + Call: map[string]string{"org.freedesktop.portal.*": "*"}, + Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, + Log: false, + Filter: true, + }, + Enablements: system.EWayland.Mask() | system.EDBus.Mask() | system.EPulse.Mask(), + }, + } +} diff --git a/fst/shared.go b/fst/shared.go new file mode 100644 index 00000000..39544863 --- /dev/null +++ b/fst/shared.go @@ -0,0 +1,18 @@ +// Package fst exports shared fortify types. +package fst + +import ( + "crypto/rand" + "encoding/hex" +) + +type ID [16]byte + +func (a *ID) String() string { + return hex.EncodeToString(a[:]) +} + +func NewAppID(id *ID) error { + _, err := rand.Read(id[:]) + return err +} diff --git a/internal/app/app.go b/internal/app/app.go index 5cb1ddf8..4c6ae9e1 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -5,13 +5,13 @@ import ( "sync/atomic" "git.ophivana.moe/security/fortify/cmd/fshim/ipc/shim" - "git.ophivana.moe/security/fortify/fipc" + "git.ophivana.moe/security/fortify/fst" "git.ophivana.moe/security/fortify/internal/linux" ) type App interface { // ID returns a copy of App's unique ID. - ID() ID + ID() fst.ID // Start sets up the system and starts the App. Start() error // Wait waits for App's process to exit and reverts system setup. @@ -19,7 +19,7 @@ type App interface { // WaitErr returns error returned by the underlying wait syscall. WaitErr() error - Seal(config *fipc.Config) error + Seal(config *fst.Config) error String() string } @@ -28,7 +28,7 @@ type app struct { ct *appCt // application unique identifier - id *ID + id *fst.ID // operating system interface os linux.System // shim process manager @@ -41,7 +41,7 @@ type app struct { lock sync.RWMutex } -func (a *app) ID() ID { +func (a *app) ID() fst.ID { return *a.id } @@ -70,18 +70,18 @@ func (a *app) WaitErr() error { func New(os linux.System) (App, error) { a := new(app) - a.id = new(ID) + a.id = new(fst.ID) a.os = os - return a, newAppID(a.id) + return a, fst.NewAppID(a.id) } // appCt ensures its wrapped val is only accessed once type appCt struct { - val *fipc.Config + val *fst.Config done *atomic.Bool } -func (a *appCt) Unwrap() *fipc.Config { +func (a *appCt) Unwrap() *fst.Config { if !a.done.Load() { defer a.done.Store(true) return a.val @@ -89,7 +89,7 @@ func (a *appCt) Unwrap() *fipc.Config { panic("attempted to access config reference twice") } -func newAppCt(config *fipc.Config) (ct *appCt) { +func newAppCt(config *fst.Config) (ct *appCt) { ct = new(appCt) ct.done = new(atomic.Bool) ct.val = config diff --git a/internal/app/app_nixos_test.go b/internal/app/app_nixos_test.go index 1d92ece8..1a716cc5 100644 --- a/internal/app/app_nixos_test.go +++ b/internal/app/app_nixos_test.go @@ -3,24 +3,23 @@ package app_test import ( "git.ophivana.moe/security/fortify/acl" "git.ophivana.moe/security/fortify/dbus" - "git.ophivana.moe/security/fortify/fipc" + "git.ophivana.moe/security/fortify/fst" "git.ophivana.moe/security/fortify/helper/bwrap" - "git.ophivana.moe/security/fortify/internal/app" "git.ophivana.moe/security/fortify/internal/system" ) var testCasesNixos = []sealTestCase{ { "nixos chromium direct wayland", new(stubNixOS), - &fipc.Config{ + &fst.Config{ ID: "org.chromium.Chromium", Command: []string{"/nix/store/yqivzpzzn7z5x0lq9hmbzygh45d8rhqd-chromium-start"}, - Confinement: fipc.ConfinementConfig{ + Confinement: fst.ConfinementConfig{ AppID: 1, Groups: []string{}, Username: "u0_a1", Outer: "/var/lib/persist/module/fortify/0/1", - Sandbox: &fipc.SandboxConfig{ + Sandbox: &fst.SandboxConfig{ UserNS: true, Net: true, MapRealUID: true, DirectWayland: true, Env: nil, - Filesystem: []*fipc.FilesystemConfig{ + Filesystem: []*fst.FilesystemConfig{ {Src: "/bin", Must: true}, {Src: "/usr/bin", Must: true}, {Src: "/nix/store", Must: true}, {Src: "/run/current-system", Must: true}, {Src: "/sys/block"}, {Src: "/sys/bus"}, {Src: "/sys/class"}, {Src: "/sys/dev"}, {Src: "/sys/devices"}, @@ -49,7 +48,7 @@ var testCasesNixos = []sealTestCase{ Enablements: system.EWayland.Mask() | system.EDBus.Mask() | system.EPulse.Mask(), }, }, - app.ID{ + fst.ID{ 0x8e, 0x2c, 0x76, 0xb0, 0x66, 0xda, 0xbe, 0x57, 0x4c, 0xf0, 0x73, 0xbd, diff --git a/internal/app/app_pd_test.go b/internal/app/app_pd_test.go index 3a551805..af4b5056 100644 --- a/internal/app/app_pd_test.go +++ b/internal/app/app_pd_test.go @@ -3,24 +3,23 @@ package app_test import ( "git.ophivana.moe/security/fortify/acl" "git.ophivana.moe/security/fortify/dbus" - "git.ophivana.moe/security/fortify/fipc" + "git.ophivana.moe/security/fortify/fst" "git.ophivana.moe/security/fortify/helper/bwrap" - "git.ophivana.moe/security/fortify/internal/app" "git.ophivana.moe/security/fortify/internal/system" ) var testCasesPd = []sealTestCase{ { "nixos permissive defaults no enablements", new(stubNixOS), - &fipc.Config{ + &fst.Config{ Command: make([]string, 0), - Confinement: fipc.ConfinementConfig{ + Confinement: fst.ConfinementConfig{ AppID: 0, Username: "chronos", Outer: "/home/chronos", }, }, - app.ID{ + fst.ID{ 0x4a, 0x45, 0x0b, 0x65, 0x96, 0xd7, 0xbc, 0x15, 0xbd, 0x01, 0x78, 0x0e, @@ -191,10 +190,10 @@ var testCasesPd = []sealTestCase{ }, { "nixos permissive defaults chromium", new(stubNixOS), - &fipc.Config{ + &fst.Config{ ID: "org.chromium.Chromium", Command: []string{"/run/current-system/sw/bin/zsh", "-c", "exec chromium "}, - Confinement: fipc.ConfinementConfig{ + Confinement: fst.ConfinementConfig{ AppID: 9, Groups: []string{"video"}, Username: "chronos", @@ -233,7 +232,7 @@ var testCasesPd = []sealTestCase{ Enablements: system.EWayland.Mask() | system.EDBus.Mask() | system.EPulse.Mask(), }, }, - app.ID{ + fst.ID{ 0xeb, 0xf0, 0x83, 0xd1, 0xb1, 0x75, 0x91, 0x17, 0x82, 0xd4, 0x13, 0x36, diff --git a/internal/app/app_test.go b/internal/app/app_test.go index 21db1860..b60295fc 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "git.ophivana.moe/security/fortify/fipc" + "git.ophivana.moe/security/fortify/fst" "git.ophivana.moe/security/fortify/helper/bwrap" "git.ophivana.moe/security/fortify/internal/app" "git.ophivana.moe/security/fortify/internal/linux" @@ -16,8 +16,8 @@ import ( type sealTestCase struct { name string os linux.System - config *fipc.Config - id app.ID + config *fst.Config + id fst.ID wantSys *system.I wantBwrap *bwrap.Config } diff --git a/internal/app/export_test.go b/internal/app/export_test.go index 56eb4a31..90886e13 100644 --- a/internal/app/export_test.go +++ b/internal/app/export_test.go @@ -1,12 +1,13 @@ package app import ( + "git.ophivana.moe/security/fortify/fst" "git.ophivana.moe/security/fortify/helper/bwrap" "git.ophivana.moe/security/fortify/internal/linux" "git.ophivana.moe/security/fortify/internal/system" ) -func NewWithID(id ID, os linux.System) App { +func NewWithID(id fst.ID, os linux.System) App { a := new(app) a.id = &id a.os = os diff --git a/internal/app/id.go b/internal/app/id.go deleted file mode 100644 index 6ca48312..00000000 --- a/internal/app/id.go +++ /dev/null @@ -1,17 +0,0 @@ -package app - -import ( - "crypto/rand" - "encoding/hex" -) - -type ID [16]byte - -func (a *ID) String() string { - return hex.EncodeToString(a[:]) -} - -func newAppID(id *ID) error { - _, err := rand.Read(id[:]) - return err -} diff --git a/internal/app/seal.go b/internal/app/seal.go index b01befc1..d71553a2 100644 --- a/internal/app/seal.go +++ b/internal/app/seal.go @@ -9,7 +9,7 @@ import ( "strconv" "git.ophivana.moe/security/fortify/dbus" - "git.ophivana.moe/security/fortify/fipc" + "git.ophivana.moe/security/fortify/fst" "git.ophivana.moe/security/fortify/internal/fmsg" "git.ophivana.moe/security/fortify/internal/linux" "git.ophivana.moe/security/fortify/internal/state" @@ -60,7 +60,7 @@ type appSeal struct { } // Seal seals the app launch context -func (a *app) Seal(config *fipc.Config) error { +func (a *app) Seal(config *fst.Config) error { a.lock.Lock() defer a.lock.Unlock() @@ -148,7 +148,7 @@ func (a *app) Seal(config *fipc.Config) error { fmsg.VPrintln("sandbox configuration not supplied, PROCEED WITH CAUTION") // permissive defaults - conf := &fipc.SandboxConfig{ + conf := &fst.SandboxConfig{ UserNS: true, Net: true, NoNewSession: true, @@ -158,7 +158,7 @@ func (a *app) Seal(config *fipc.Config) error { if d, err := a.os.ReadDir("/"); err != nil { return err } else { - b := make([]*fipc.FilesystemConfig, 0, len(d)) + b := make([]*fst.FilesystemConfig, 0, len(d)) for _, ent := range d { p := "/" + ent.Name() switch p { @@ -170,7 +170,7 @@ func (a *app) Seal(config *fipc.Config) error { case "/etc": default: - b = append(b, &fipc.FilesystemConfig{Src: p, Write: true, Must: true}) + b = append(b, &fst.FilesystemConfig{Src: p, Write: true, Must: true}) } } conf.Filesystem = append(conf.Filesystem, b...) @@ -179,7 +179,7 @@ func (a *app) Seal(config *fipc.Config) error { if d, err := a.os.ReadDir("/run"); err != nil { return err } else { - b := make([]*fipc.FilesystemConfig, 0, len(d)) + b := make([]*fst.FilesystemConfig, 0, len(d)) for _, ent := range d { name := ent.Name() switch name { @@ -187,7 +187,7 @@ func (a *app) Seal(config *fipc.Config) error { case "dbus": default: p := "/run/" + name - b = append(b, &fipc.FilesystemConfig{Src: p, Write: true, Must: true}) + b = append(b, &fst.FilesystemConfig{Src: p, Write: true, Must: true}) } } conf.Filesystem = append(conf.Filesystem, b...) @@ -199,7 +199,7 @@ func (a *app) Seal(config *fipc.Config) error { } // bind GPU stuff if config.Confinement.Enablements.Has(system.EX11) || config.Confinement.Enablements.Has(system.EWayland) { - conf.Filesystem = append(conf.Filesystem, &fipc.FilesystemConfig{Src: "/dev/dri", Device: true}) + conf.Filesystem = append(conf.Filesystem, &fst.FilesystemConfig{Src: "/dev/dri", Device: true}) } config.Confinement.Sandbox = conf diff --git a/internal/state/state.go b/internal/state/state.go index bb23932a..cf345aad 100644 --- a/internal/state/state.go +++ b/internal/state/state.go @@ -3,7 +3,7 @@ package state import ( "time" - "git.ophivana.moe/security/fortify/fipc" + "git.ophivana.moe/security/fortify/fst" ) type Store interface { @@ -27,11 +27,11 @@ type Backend interface { // State is the on-disk format for a fortified process's state information type State struct { // fortify instance id - ID [16]byte `json:"instance"` + ID fst.ID `json:"instance"` // child process PID value PID int `json:"pid"` // sealed app configuration - Config *fipc.Config `json:"config"` + Config *fst.Config `json:"config"` // process start time Time time.Time diff --git a/main.go b/main.go index 3087cd54..e3914356 100644 --- a/main.go +++ b/main.go @@ -12,7 +12,7 @@ import ( "text/tabwriter" "git.ophivana.moe/security/fortify/dbus" - "git.ophivana.moe/security/fortify/fipc" + "git.ophivana.moe/security/fortify/fst" "git.ophivana.moe/security/fortify/internal" "git.ophivana.moe/security/fortify/internal/app" "git.ophivana.moe/security/fortify/internal/fmsg" @@ -103,7 +103,7 @@ func main() { fmt.Println(license) fmsg.Exit(0) case "template": // print full template configuration - if s, err := json.MarshalIndent(fipc.Template(), "", " "); err != nil { + if s, err := json.MarshalIndent(fst.Template(), "", " "); err != nil { fmsg.Fatalf("cannot generate template: %v", err) panic("unreachable") } else { @@ -130,7 +130,7 @@ func main() { fmsg.Fatal("app requires at least 1 argument") } - config := new(fipc.Config) + config := new(fst.Config) if f, err := os.Open(args[1]); err != nil { fmsg.Fatalf("cannot access config file %q: %s", args[1], err) panic("unreachable") @@ -180,7 +180,7 @@ func main() { _ = set.Parse(args[1:]) // initialise config from flags - config := &fipc.Config{ + config := &fst.Config{ ID: fid, Command: set.Args(), } @@ -276,7 +276,7 @@ func main() { panic("unreachable") } -func runApp(config *fipc.Config) { +func runApp(config *fst.Config) { if os.SdBooted() { fmsg.VPrintln("system booted with systemd as init system") } -- cgit v1.3.1