diff options
Diffstat (limited to 'internal/app/start.go')
| -rw-r--r-- | internal/app/start.go | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/internal/app/start.go b/internal/app/start.go index 02fad973..ed34b7c2 100644 --- a/internal/app/start.go +++ b/internal/app/start.go @@ -2,11 +2,16 @@ package app import ( "errors" + "fmt" "os" "os/exec" + "path" + "path/filepath" "strconv" "time" + "git.ophivana.moe/cat/fortify/helper" + "git.ophivana.moe/cat/fortify/internal/shim" "git.ophivana.moe/cat/fortify/internal/state" "git.ophivana.moe/cat/fortify/internal/verbose" ) @@ -14,6 +19,8 @@ import ( type ( // ProcessError encapsulates errors returned by starting *exec.Cmd ProcessError BaseError + // ShimError encapsulates errors returned by shim.ServeConfig. + ShimError BaseError ) // Start starts the fortified child @@ -21,12 +28,30 @@ func (a *app) Start() error { a.lock.Lock() defer a.lock.Unlock() + // resolve exec paths + e := [2]string{helper.BubblewrapName} + if len(a.seal.command) > 0 { + e[1] = a.seal.command[0] + } + for i, n := range e { + if len(n) == 0 { + continue + } + if filepath.Base(n) == n { + if s, err := exec.LookPath(n); err == nil { + e[i] = s + } else { + return (*ProcessError)(wrapError(err, fmt.Sprintf("cannot find %q in PATH: %v", n, err))) + } + } + } + if err := a.seal.sys.commit(); err != nil { return err } // select command builder - var commandBuilder func() (args []string) + var commandBuilder func(shimEnv string) (args []string) switch a.seal.launchOption { case LaunchMethodSudo: commandBuilder = a.commandBuilderSudo @@ -37,15 +62,30 @@ func (a *app) Start() error { } // configure child process - a.cmd = exec.Command(a.seal.toolPath, commandBuilder()...) + confSockPath := path.Join(a.seal.share, "shim") + a.cmd = exec.Command(a.seal.toolPath, commandBuilder(shim.EnvShim+"="+confSockPath)...) a.cmd.Env = []string{} a.cmd.Stdin = os.Stdin a.cmd.Stdout = os.Stdout a.cmd.Stderr = os.Stderr a.cmd.Dir = a.seal.RunDirPath - // start child process - verbose.Println("starting main process:", a.cmd) + if wls, err := shim.ServeConfig(confSockPath, &shim.Payload{ + Argv: a.seal.command, + Env: a.seal.env, + Exec: e, + Bwrap: a.seal.bwrap, + WL: a.seal.wlDone != nil, + + Verbose: verbose.Get(), + }, a.seal.wl, a.seal.wlDone); err != nil { + return (*ShimError)(wrapError(err, "cannot listen on shim socket:", err)) + } else { + a.wayland = wls + } + + // start shim + verbose.Println("starting shim as target user:", a.cmd) if err := a.cmd.Start(); err != nil { return (*ProcessError)(wrapError(err, "cannot start process:", err)) } @@ -62,11 +102,11 @@ func (a *app) Start() error { } // register process state - var e = new(StateStoreError) - e.Inner, e.DoErr = a.seal.store.Do(func(b state.Backend) { - e.InnerErr = b.Save(&sd) + var err = new(StateStoreError) + err.Inner, err.DoErr = a.seal.store.Do(func(b state.Backend) { + err.InnerErr = b.Save(&sd) }) - return e.equiv("cannot save process state:", e) + return err.equiv("cannot save process state:", e) } // StateStoreError is returned for a failed state save @@ -146,6 +186,14 @@ func (a *app) Wait() (int, error) { verbose.Println("process", strconv.Itoa(a.cmd.Process.Pid), "exited with exit code", r) + // close wayland connection + if a.wayland != nil { + close(a.seal.wlDone) + if err := a.wayland.Close(); err != nil { + fmt.Println("fortify: cannot close wayland connection:", err) + } + } + // update store and revert app setup transaction e := new(StateStoreError) e.Inner, e.DoErr = a.seal.store.Do(func(b state.Backend) { @@ -187,7 +235,9 @@ func (a *app) Wait() (int, error) { ct = append(ct, i) } } - verbose.Println("will revert operations tagged", ct, "as no remaining launchers hold these enablements") + if len(ct) > 0 { + verbose.Println("will revert operations tagged", ct, "as no remaining launchers hold these enablements") + } } if err := a.seal.sys.revert(tags); err != nil { |
