aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMoritz Poldrack <git@moritz.sh>2023-03-04 10:56:47 +0100
committerRobin Jarry <robin@jarry.cc>2023-03-07 00:13:03 +0100
commitd3dea73aa53791a94f86c31689a10880fabeb84c (patch)
treeae815295162ff7431d47fd16a2e74d0cb8465222 /lib
parentc6a08b1003a2cb02d86002541ead0f9b38db1beb (diff)
downloadaerc-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')
-rw-r--r--lib/ipc/handler.go1
-rw-r--r--lib/ipc/receive.go14
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"}
}