Browse Source

wip: Initial commit

master
ptrcnull 2 years ago
commit
ab2ddeed87
  1. 3
      go.mod
  2. 26
      main.go
  3. 49
      server/conn_wrapper.go
  4. 95
      server/server.go
  5. 16
      test.js

3
go.mod

@ -0,0 +1,3 @@
module tgmail
go 1.15

26
main.go

@ -0,0 +1,26 @@
package main
import (
"log"
"net"
"tgmail/server"
)
func main() {
l, err := net.Listen("tcp", "0.0.0.0:2525")
if err != nil {
panic(err)
}
defer l.Close()
log.Println("Listening!")
for {
c, err := l.Accept()
if err != nil {
log.Println(err)
return
}
go server.Handle(c)
}
}

49
server/conn_wrapper.go

@ -0,0 +1,49 @@
package server
import (
"bufio"
"log"
"net"
"strconv"
"strings"
)
type wrapper struct {
net.Conn
r *bufio.Reader
}
func (w *wrapper) cmd(code int64, msgs ...string) error {
for i, msg := range msgs {
sep := "-"
if i == len(msgs)-1 {
sep = " "
}
err := w.send(strconv.FormatInt(code, 10) + sep + msg)
if err != nil {
return err
}
}
return nil
}
func (w *wrapper) send(message string) error {
log.Println("+", message)
// fuck some MTAs
_, err := w.Write([]byte(message + "\r\n"))
return err
}
func (w *wrapper) recv() (string, error) {
if w.r == nil {
w.r = bufio.NewReader(w)
}
//log.Println("* recv called")
msg, err := w.r.ReadString('\n')
if err != nil {
return "", err
}
msg = strings.TrimRight(msg, " \t\r\n")
log.Println("-", msg)
return msg, nil
}

95
server/server.go

@ -0,0 +1,95 @@
package server
import (
"bytes"
"io/ioutil"
"log"
"net"
"net/mail"
"strings"
)
const response = "uwu"
func Handle(conn net.Conn) {
c := wrapper{Conn: conn}
log.Println("Connection received from", c.RemoteAddr().String())
c.cmd(220, response+" ESMTP")
for {
msg, err := c.recv()
if err != nil {
log.Println(err)
c.Close()
return
}
cmd := strings.ToUpper(strings.Split(msg, " ")[0])
if cmd == "EHLO" {
c.cmd(250,
response,
"8BITMIME",
"SMTPUTF8",
"SIZE 104857600")
continue
}
if cmd == "DATA" {
c.cmd(354, response)
data, err := readContent(c)
if err != nil {
log.Println(err)
c.Close()
return
}
go handleMessage(data)
continue
}
if cmd == "QUIT" {
c.cmd(221, response)
c.Close()
break
}
c.cmd(250, response)
}
c.Close()
}
func readContent(c wrapper) (string, error) {
data := ""
for {
msg, err := c.recv()
if err != nil {
return "", err
}
if msg == "." {
break
}
data += msg + "\r\n"
}
c.cmd(250, response)
return data, nil
}
func handleMessage(data string) {
msg, err := mail.ReadMessage(bytes.NewReader([]byte(data)))
if err != nil {
log.Println(err)
return
}
body, err := ioutil.ReadAll(msg.Body)
if err != nil {
log.Println(err)
return
}
log.Println("FROM: ", msg.Header.Get("From"))
log.Println(string(body))
}

16
test.js

@ -0,0 +1,16 @@
const net = require('net')
const server = net.createServer(c => {
console.log('Connected')
c.on('data', d => {
console.log('data', d.toString())
})
c.on('end', () => {
console.log('client disconnected')
})
c.write('220 uwu ESMTP\n')
})
server.listen(2525, () => {
console.log('works')
})
Loading…
Cancel
Save