diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-07-02 21:52:07 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-07-02 21:52:07 +0900 |
| commit | 82561d62b66f17c05604e87f18187bb3a91f00d2 (patch) | |
| tree | c1543f85b4458b7d5cb2cf7b1baa9dee318debfe /system/dbus/proxy.go | |
| parent | eec021cc4b4eb42bc9c8311755826828bfba1996 (diff) | |
system: move system access packages
These packages loosely belong in the "system" package and "system" provides high level wrappers for all of them.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'system/dbus/proxy.go')
| -rw-r--r-- | system/dbus/proxy.go | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/system/dbus/proxy.go b/system/dbus/proxy.go new file mode 100644 index 00000000..cc0af1ea --- /dev/null +++ b/system/dbus/proxy.go @@ -0,0 +1,117 @@ +package dbus + +import ( + "context" + "fmt" + "io" + "os/exec" + "sync" + "syscall" + + "git.gensokyo.uk/security/hakurei/helper" +) + +// ProxyName is the file name or path to the proxy program. +// Overriding ProxyName will only affect Proxy instance created after the change. +var ProxyName = "xdg-dbus-proxy" + +type BadInterfaceError struct { + Interface string + Segment string +} + +func (e *BadInterfaceError) Error() string { + return fmt.Sprintf("bad interface string %q in %s bus configuration", e.Interface, e.Segment) +} + +// Proxy holds the state of a xdg-dbus-proxy process, and should never be copied. +type Proxy struct { + helper helper.Helper + ctx context.Context + + cancel context.CancelCauseFunc + cause func() error + + final *Final + output io.Writer + useSandbox bool + + name string + CmdF func(any) + + CommandContext func(ctx context.Context) (cmd *exec.Cmd) + FilterF func([]byte) []byte + + mu, pmu sync.RWMutex +} + +func (p *Proxy) String() string { + if p == nil { + return "(invalid dbus proxy)" + } + + p.mu.RLock() + defer p.mu.RUnlock() + + if p.helper != nil { + return p.helper.String() + } + + return "(unused dbus proxy)" +} + +// Final describes the outcome of a proxy configuration. +type Final struct { + Session, System ProxyPair + // parsed upstream address + SessionUpstream, SystemUpstream []AddrEntry + io.WriterTo +} + +// Finalise creates a checked argument writer for [Proxy]. +func Finalise(sessionBus, systemBus ProxyPair, session, system *Config) (final *Final, err error) { + if session == nil && system == nil { + return nil, syscall.EBADE + } + + var args []string + if session != nil { + if err = session.checkInterfaces("session"); err != nil { + return + } + args = append(args, session.Args(sessionBus)...) + } + if system != nil { + if err = system.checkInterfaces("system"); err != nil { + return + } + args = append(args, system.Args(systemBus)...) + } + + final = &Final{Session: sessionBus, System: systemBus} + + final.WriterTo, err = helper.NewCheckedArgs(args) + if err != nil { + return + } + + if session != nil { + final.SessionUpstream, err = Parse([]byte(final.Session[0])) + if err != nil { + return + } + } + if system != nil { + final.SystemUpstream, err = Parse([]byte(final.System[0])) + if err != nil { + return + } + } + + return +} + +// New returns a new instance of [Proxy]. +func New(ctx context.Context, final *Final, output io.Writer) *Proxy { + return &Proxy{name: ProxyName, ctx: ctx, final: final, output: output, useSandbox: true} +} |
