add DNS checker and run against suspicious hosts

This commit is contained in:
aoife cassidy 2025-11-22 02:35:59 +01:00
parent f5a389d6cb
commit b80c5cd8cc
No known key found for this signature in database
GPG Key ID: 7184AC1C9835CE48

View File

@ -3,11 +3,15 @@ package main
import ( import (
"bytes" "bytes"
"database/sql" "database/sql"
"errors"
"fmt" "fmt"
"io" "io"
"log" "log"
"net"
"os" "os"
"path" "path"
"regexp"
"slices"
"strings" "strings"
"time" "time"
@ -110,6 +114,45 @@ func (c *character) Say(msg string) string {
strings.TrimSpace(msg)) 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
} else 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() { func main() {
logFile := path.Join(logDir, fmt.Sprintf("%d", time.Now().Unix())) logFile := path.Join(logDir, fmt.Sprintf("%d", time.Now().Unix()))
logF, err := os.Create(logFile) logF, err := os.Create(logFile)
@ -201,9 +244,23 @@ func _main(l *log.Logger, db *sql.DB) error {
`), `),
"i'm sorry, before going further could you share an email with me?", "i'm sorry, before going further could you share an email with me?",
newCharacter("wire guy", "a lil homonculus made of discarded computer cables"), 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) { func(s *scene, tv *tview.TextView, msg string) {
// TODO could check and see if it's email shaped and admonish if not // 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) trimmed := strings.TrimSpace(msg)
fmt.Fprintln(tv, s.Host.Say(fmt.Sprintf("I heard '%s'. Is that right? if so, /nod", trimmed))) fmt.Fprintln(tv, s.Host.Say(fmt.Sprintf("I heard '%s'. Is that right? if so, /nod", trimmed)))
}), }),