diff options
author | Moritz Poldrack <git@moritz.sh> | 2023-03-04 10:56:47 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-03-07 00:13:03 +0100 |
commit | d3dea73aa53791a94f86c31689a10880fabeb84c (patch) | |
tree | ae815295162ff7431d47fd16a2e74d0cb8465222 /lib/ipc | |
parent | c6a08b1003a2cb02d86002541ead0f9b38db1beb (diff) | |
download | aerc-d3dea73aa53791a94f86c31689a10880fabeb84c.tar.gz |
ipc: allow triggering internal commands via IPC
In order to make automation easier, it's useful to be able to send
commands to aerc via IPC. This can be done by calling the aerc binary
followed by a colon and the command to run. For example:
aerc :read && aerc :remark && aerc :archive month
Security to ensure no malicious commands are run is deferred to the
user. By default the socket is only writable by the user. This is
considered sufficient as the potential harm an attacker gaining
write-access to a user's session can cause is significantly greater than
"can delete some emails".
To ensure users with an according threat model, it is possible to
disable command IPC. mailto-handling is unaffected even though it works
over IPC as it is absolutely non-destructive.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'lib/ipc')
-rw-r--r-- | lib/ipc/handler.go | 1 | ||||
-rw-r--r-- | lib/ipc/receive.go | 14 |
2 files changed, 15 insertions, 0 deletions
diff --git a/lib/ipc/handler.go b/lib/ipc/handler.go index fb8f0e06..c00acd63 100644 --- a/lib/ipc/handler.go +++ b/lib/ipc/handler.go @@ -5,4 +5,5 @@ import "net/url" type Handler interface { Mailto(addr *url.URL) error Mbox(source string) error + Command(args []string) error } diff --git a/lib/ipc/receive.go b/lib/ipc/receive.go index 0745e3d6..12df3411 100644 --- a/lib/ipc/receive.go +++ b/lib/ipc/receive.go @@ -11,6 +11,7 @@ import ( "sync/atomic" "time" + "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/log" "github.com/kyoh86/xdg" ) @@ -116,6 +117,19 @@ func (as *AercServer) handleMessage(req *Request) *Response { if err != nil { return &Response{Error: err.Error()} } + case strings.HasPrefix(req.Arguments[0], ":"): + if config.General.DisableIPC { + return &Response{ + Error: "command rejected: IPC is disabled", + } + } + + req.Arguments[0] = strings.TrimPrefix(req.Arguments[0], ":") + err := as.handler.Command(req.Arguments) + if err != nil { + return &Response{Error: err.Error()} + } + default: return &Response{Error: "command not understood"} } |