Compare commits

...

1 Commits

Author SHA1 Message Date
aoife cassidy
fde4ee9ccc
add DNS checker and run against suspicious hosts 2025-11-22 02:35:59 +01:00

View File

@ -3,11 +3,15 @@ package main
import (
"bytes"
"database/sql"
"errors"
"fmt"
"io"
"log"
"net"
"os"
"path"
"regexp"
"slices"
"strings"
"time"
@ -110,6 +114,46 @@ func (c *character) Say(msg string) string {
strings.TrimSpace(msg))
}
// TODO: move this into an admin-editable world-unreadable file somewhere
var suspiciousHosts = []string{
"mx1.cock.li",
"mx2.cock.li",
}
var ErrNoSuchDomain = errors.New("no host found for email address")
var ErrNoSuchMailserver = errors.New("no mail server found for email address")
// DigMX does some grubbing around to attempt to find valid email hosts, and
// then runs then through [net.LookupMX] and returns their mailserver domains.
// may return [ErrNoSuchDomain] or [ErrNoSuchMailserver].
func DigMX(raw string) (domains []string, err error) {
re := regexp.MustCompile(`@[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)+\b`) // good enough
candidates := re.FindAllString(raw, -1)
// the error checking tries to be very generous: if anything comes up
// positive we will throw no errors and just assume the rest was a fluke.
ok := false
for _, host := range candidates {
records, e := net.LookupMX(host[1:])
if e != nil {
err = ErrNoSuchDomain
}
if len(records) == 0 {
err = ErrNoSuchMailserver
} else {
ok = true
for _, record := range records {
domains = append(domains, record.Host)
}
}
}
if ok {
return domains, nil
}
return
}
func main() {
logFile := path.Join(logDir, fmt.Sprintf("%d", time.Now().Unix()))
logF, err := os.Create(logFile)
@ -201,9 +245,23 @@ func _main(l *log.Logger, db *sql.DB) error {
`),
"i'm sorry, before going further could you share an email with me?",
newCharacter("wire guy", "a lil homonculus made of discarded computer cables"),
func(s *scene) { su.Email = string(s.Input.Bytes()) },
func(s *scene) {
su.Email = string(s.Input.Bytes())
if records, err := DigMX(su.Email); err != nil {
for _, record := range records {
if slices.Contains(suspiciousHosts, record) {
su.Notes = append(su.Notes, models.SignupNote{
Author: "dns",
Content: fmt.Sprintf("email address has suspicious host %s", record),
SignupID: su.ID,
})
}
}
}
},
func(s *scene, tv *tview.TextView, msg string) {
// TODO could check and see if it's email shaped and admonish if not
// NOTE(nbsp): DigMX call can see if email is invalid but this isn't used yet
trimmed := strings.TrimSpace(msg)
fmt.Fprintln(tv, s.Host.Say(fmt.Sprintf("I heard '%s'. Is that right? if so, /nod", trimmed)))
}),