Files
honeydany/app/services/imap.go
T

62 lines
2.3 KiB
Go

package services
import (
"bufio"
"net"
"strings"
"time"
)
func NewIMAPHandler(log LoggerFunc) Handler {
return func(conn net.Conn) {
defer conn.Close()
remote := conn.RemoteAddr().String()
_, _ = conn.Write([]byte("* OK IMAP4rev1 Service Ready\r\n"))
conn.SetDeadline(time.Now().Add(2 * time.Minute))
scanner := bufio.NewScanner(conn)
selected := false
mailbox := "INBOX"
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" { continue }
parts := strings.Fields(line)
if len(parts) < 2 { continue }
tag := parts[0]
cmd := strings.ToUpper(parts[1])
switch cmd {
case "LOGIN":
if len(parts) >= 4 {
user := strings.Trim(parts[2], "\"")
pass := strings.Trim(parts[3], "\"")
log(Record{Timestamp: Now(), RemoteAddr: remoteIP(remote), RemotePort: remotePort(remote), Service: "imap", Details: map[string]string{"event":"login_attempt","username":user,"password":pass}})
}
_, _ = conn.Write([]byte(tag + " OK LOGIN completed\r\n"))
case "CAPABILITY":
_, _ = conn.Write([]byte("* CAPABILITY IMAP4rev1 AUTH=PLAIN IDLE\r\n"))
_, _ = conn.Write([]byte(tag + " OK CAPABILITY completed\r\n"))
case "NOOP":
_, _ = conn.Write([]byte(tag + " OK NOOP completed\r\n"))
case "SELECT", "EXAMINE":
if len(parts) >= 3 { mailbox = strings.Trim(parts[2], "\"") }
selected = true
// fake mailbox with 2 messages
_, _ = conn.Write([]byte("* 2 EXISTS\r\n"))
_, _ = conn.Write([]byte("* OK [UIDVALIDITY 1] UIDs valid\r\n"))
_, _ = conn.Write([]byte(tag + " OK [READ-WRITE] SELECT completed (" + mailbox + ")\r\n"))
log(Record{Timestamp: Now(), RemoteAddr: remoteIP(remote), RemotePort: remotePort(remote), Service: "imap", Details: map[string]string{"event":"select","mailbox":mailbox}})
case "FETCH":
if !selected { _, _ = conn.Write([]byte(tag + " BAD No mailbox selected\r\n")); continue }
// minimal fake fetch
_, _ = conn.Write([]byte("* 1 FETCH (FLAGS (\\Seen) RFC822.SIZE 1234)\r\n"))
_, _ = conn.Write([]byte(tag + " OK FETCH completed\r\n"))
case "LOGOUT":
_, _ = conn.Write([]byte("* BYE IMAP4rev1 Server logging out\r\n"))
_, _ = conn.Write([]byte(tag + " OK LOGOUT completed\r\n"))
return
default:
_, _ = conn.Write([]byte(tag + " BAD Command not recognized\r\n"))
}
}
}
}