aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/setuid/app.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-04-12 10:54:24 +0900
committerOphestra <cat@gensokyo.uk>2025-04-12 10:54:24 +0900
commit0d7c1a9a4356614f035225aeb24e66421879a99b (patch)
treec490cfd0f75fbf0218045e277812fb5b6173d4e3 /internal/app/setuid/app.go
parentae6f5ede1928c9d0a2d480b6a924914e8599529f (diff)
app: rename app implementation package
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/setuid/app.go')
-rw-r--r--internal/app/setuid/app.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/internal/app/setuid/app.go b/internal/app/setuid/app.go
new file mode 100644
index 00000000..472d06ea
--- /dev/null
+++ b/internal/app/setuid/app.go
@@ -0,0 +1,82 @@
+package setuid
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "sync"
+
+ "git.gensokyo.uk/security/fortify/fst"
+ "git.gensokyo.uk/security/fortify/internal/fmsg"
+ "git.gensokyo.uk/security/fortify/internal/sys"
+)
+
+func New(ctx context.Context, os sys.State) (fst.App, error) {
+ a := new(app)
+ a.sys = os
+ a.ctx = ctx
+
+ id := new(fst.ID)
+ err := fst.NewAppID(id)
+ a.id = newID(id)
+
+ return a, err
+}
+
+func MustNew(ctx context.Context, os sys.State) fst.App {
+ a, err := New(ctx, os)
+ if err != nil {
+ log.Fatalf("cannot create app: %v", err)
+ }
+ return a
+}
+
+type app struct {
+ id *stringPair[fst.ID]
+ sys sys.State
+ ctx context.Context
+
+ *outcome
+ mu sync.RWMutex
+}
+
+func (a *app) ID() fst.ID { a.mu.RLock(); defer a.mu.RUnlock(); return a.id.unwrap() }
+
+func (a *app) String() string {
+ if a == nil {
+ return "(invalid app)"
+ }
+
+ a.mu.RLock()
+ defer a.mu.RUnlock()
+
+ if a.outcome != nil {
+ if a.outcome.user.uid == nil {
+ return fmt.Sprintf("(sealed app %s with invalid uid)", a.id)
+ }
+ return fmt.Sprintf("(sealed app %s as uid %s)", a.id, a.outcome.user.uid)
+ }
+
+ return fmt.Sprintf("(unsealed app %s)", a.id)
+}
+
+func (a *app) Seal(config *fst.Config) (fst.SealedApp, error) {
+ a.mu.Lock()
+ defer a.mu.Unlock()
+
+ if a.outcome != nil {
+ panic("app sealed twice")
+ }
+ if config == nil {
+ return nil, fmsg.WrapError(ErrConfig,
+ "attempted to seal app with nil config")
+ }
+
+ seal := new(outcome)
+ seal.id = a.id
+ err := seal.finalise(a.ctx, a.sys, config)
+ if err == nil {
+ a.outcome = seal
+ }
+ return seal, err
+}