fix access checks; fix duplicate metadata message; better email sanitization

This commit is contained in:
Aine
2024-02-05 21:49:30 +02:00
parent 32b80191a3
commit 0bd2fc525e
4 changed files with 38 additions and 27 deletions

View File

@@ -22,14 +22,24 @@ func parseMXIDpatterns(patterns []string, defaultPattern string) ([]*regexp.Rege
return mxidwc.ParsePatterns(patterns)
}
func (b *Bot) allowUsers(actorID id.UserID) bool {
if len(b.allowedUsers) != 0 {
if !mxidwc.Match(actorID.String(), b.allowedUsers) {
return false
}
func (b *Bot) allowUsers(actorID id.UserID, targetRoomID id.RoomID) bool {
// first, check if it's an allowed user
if mxidwc.Match(actorID.String(), b.allowedUsers) {
return true
}
return true
// second, check if it's an admin (admin may not fit the allowed users pattern)
if b.allowAdmin(actorID, targetRoomID) {
return true
}
// then, check if it's the owner (same as above)
cfg, err := b.cfg.GetRoom(targetRoomID)
if err == nil && cfg.Owner() == actorID.String() {
return true
}
return false
}
func (b *Bot) allowAnyone(_ id.UserID, _ id.RoomID) bool {
@@ -37,7 +47,7 @@ func (b *Bot) allowAnyone(_ id.UserID, _ id.RoomID) bool {
}
func (b *Bot) allowOwner(actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(actorID) {
if !b.allowUsers(actorID, targetRoomID) {
return false
}
cfg, err := b.cfg.GetRoom(targetRoomID)
@@ -59,7 +69,7 @@ func (b *Bot) allowAdmin(actorID id.UserID, _ id.RoomID) bool {
}
func (b *Bot) allowSend(actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(actorID) {
if !b.allowUsers(actorID, targetRoomID) {
return false
}
@@ -73,7 +83,7 @@ func (b *Bot) allowSend(actorID id.UserID, targetRoomID id.RoomID) bool {
}
func (b *Bot) allowReply(actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(actorID) {
if !b.allowUsers(actorID, targetRoomID) {
return false
}

View File

@@ -3,7 +3,9 @@ package bot
import (
"context"
"errors"
"fmt"
"strings"
"time"
"gitlab.com/etke.cc/linkpearl"
"maunium.net/go/mautrix/event"
@@ -71,7 +73,7 @@ func (b *Bot) Sendmail(eventID id.EventID, from, to, data string) (bool, error)
return false, err
}
log.Warn().Err(err).Msg("email delivery succeeded")
log.Info().Msg("email delivery succeeded")
return false, nil
}
@@ -202,7 +204,7 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
}
evt := &event.Event{
ID: threadID + "-autoreply",
ID: id.EventID(fmt.Sprintf("%s-autoreply-%s", threadID, time.Now().UTC().Format("20060102T150405Z"))),
RoomID: roomID,
Content: event.Content{
Parsed: &event.MessageEventContent{
@@ -256,17 +258,17 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
queued, err = b.Sendmail(evt.ID, meta.From, to, data)
if queued {
b.log.Info().Err(err).Str("from", meta.From).Str("to", to).Msg("email has been queued")
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg, "Autoreply has been sent (queued)")
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg, "Autoreply has been sent to "+to+" (queued)")
continue
}
if err != nil {
b.Error(ctx, "cannot send email: %v", err)
b.Error(ctx, "cannot send email to %q: %v", to, err)
continue
}
}
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg, "Autoreply has been sent")
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg, "Autoreply has been sent to "+to)
}
}
func (b *Bot) canReply(ctx context.Context) bool {
@@ -345,12 +347,12 @@ func (b *Bot) SendEmailReply(ctx context.Context) {
}
if err != nil {
b.Error(ctx, "cannot send email: %v", err)
b.Error(ctx, "cannot send email to %q: %v", to, err)
continue
}
}
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg)
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg)
}
}
type parentEmail struct {
@@ -420,7 +422,7 @@ func (e *parentEmail) fixtofrom(newSenderMailbox string, domains []string) strin
func (e *parentEmail) calculateRecipients(from string, forwardedFrom []string) {
recipients := map[string]struct{}{}
recipients[e.From] = struct{}{}
recipients[email.Address(e.From)] = struct{}{}
for _, addr := range strings.Split(email.Address(e.To), ",") {
recipients[addr] = struct{}{}
@@ -436,7 +438,7 @@ func (e *parentEmail) calculateRecipients(from string, forwardedFrom []string) {
rcpts := make([]string, 0, len(recipients))
for rcpt := range recipients {
rcpts = append(rcpts, rcpt)
rcpts = append(rcpts, email.Address(rcpt))
}
e.Recipients = rcpts
@@ -486,10 +488,10 @@ func (b *Bot) getParentEmail(evt *event.Event, newFromMailbox string) *parentEma
return parent
}
parent.From = linkpearl.EventField[string](&parentEvt.Content, eventFromKey)
parent.To = linkpearl.EventField[string](&parentEvt.Content, eventToKey)
parent.CC = linkpearl.EventField[string](&parentEvt.Content, eventCcKey)
parent.RcptTo = linkpearl.EventField[string](&parentEvt.Content, eventRcptToKey)
parent.From = email.Address(linkpearl.EventField[string](&parentEvt.Content, eventFromKey))
parent.To = email.Address(linkpearl.EventField[string](&parentEvt.Content, eventToKey))
parent.CC = email.Address(linkpearl.EventField[string](&parentEvt.Content, eventCcKey))
parent.RcptTo = email.Address(linkpearl.EventField[string](&parentEvt.Content, eventRcptToKey))
parent.InReplyTo = linkpearl.EventField[string](&parentEvt.Content, eventMessageIDkey)
parent.References = linkpearl.EventField[string](&parentEvt.Content, eventReferencesKey)
senderEmail := parent.fixtofrom(newFromMailbox, b.domains)

View File

@@ -3,7 +3,6 @@ package bot
import (
"context"
"gitlab.com/etke.cc/go/mxidwc"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
)
@@ -33,7 +32,7 @@ func (b *Bot) initSync() {
// joinPermit is called by linkpearl when processing "invite" events and deciding if rooms should be auto-joined or not
func (b *Bot) joinPermit(evt *event.Event) bool {
if !mxidwc.Match(evt.Sender.String(), b.allowedUsers) {
if !b.allowUsers(evt.Sender, evt.RoomID) {
b.log.Debug().Str("userID", evt.Sender.String()).Msg("Rejecting room invitation from unallowed user")
return false
}

View File

@@ -55,7 +55,7 @@ func (s *incomingSession) Mail(from string, opts smtp.MailOptions) error {
s.ban(s.addr)
return ErrBanned
}
s.from = from
s.from = email.Address(from)
s.log.Debug().Str("from", from).Any("options", opts).Msg("incoming mail")
return nil
}