diff --git a/go.mod b/go.mod index 464246a..0c519f7 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module tgmail go 1.15 + +require git.ddd.rip/ptrcnull/telegram v0.0.4 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..041b70f --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +git.ddd.rip/ptrcnull/telegram v0.0.4 h1:b4VaLAdIUuEFG5DRM+JzfLEVoe4tdHhrgxtmoF2UJOQ= +git.ddd.rip/ptrcnull/telegram v0.0.4/go.mod h1:SSSKvfhw7mDx/8UPoLdtP9J74z2/pXccHnKzdi16nLA= diff --git a/main.go b/main.go index c981f7f..ab0211e 100644 --- a/main.go +++ b/main.go @@ -1,13 +1,19 @@ package main import ( + "git.ddd.rip/ptrcnull/telegram" "log" "net" + "os" "tgmail/server" ) func main() { - l, err := net.Listen("tcp", "0.0.0.0:2525") + server.Tg = telegram.Client{ + Token: os.Getenv("TELEGRAM_TOKEN"), + } + + l, err := net.Listen("tcp", "0.0.0.0:25") if err != nil { panic(err) } @@ -21,6 +27,7 @@ func main() { log.Println(err) return } + log.Println("UwU") go server.Handle(c) } } diff --git a/server/server.go b/server/server.go index c6b0856..69f3661 100644 --- a/server/server.go +++ b/server/server.go @@ -2,15 +2,25 @@ package server import ( "bytes" + "encoding/json" + "git.ddd.rip/ptrcnull/telegram" + "io" "io/ioutil" "log" + "mime" + "mime/multipart" + "mime/quotedprintable" "net" + "net/http" "net/mail" "strings" ) const response = "uwu" +var Tg telegram.Client +const chatId = "456311800" + func Handle(conn net.Conn) { c := wrapper{Conn: conn} log.Println("Connection received from", c.RemoteAddr().String()) @@ -77,6 +87,59 @@ func readContent(c wrapper) (string, error) { return data, nil } +type Header interface { + Get(key string) string +} + +func readTextBody(header Header, body io.Reader) (string, error) { + log.Println("reading text body") + var bodyBytes []byte + var err error + + if header.Get("Content-Transfer-Encoding") == "quoted-printable" { + bodyBytes, err = ioutil.ReadAll(quotedprintable.NewReader(body)) + } else { + bodyBytes, err = ioutil.ReadAll(body) + } + + log.Println("ended reading text body") + return string(bodyBytes), err +} + +func readMultipartBody(msg *mail.Message, boundary string) (string, error) { + r := multipart.NewReader(msg.Body, boundary) + body := "" + for { + part, err := r.NextPart() + if err == io.EOF { + break + } + if err != nil { + log.Println("error parsing multipart:", err) + break + } + mimetype, _, err := mime.ParseMediaType(part.Header.Get("Content-Type")) + if err != nil { + log.Println("error parsing multipart mimetype:", err) + continue + } + + if mimetype == "text/plain" { + body, err = readTextBody(part.Header, part) + if err != nil { + log.Println("error reading text body from multipart:", err) + } + } else if mimetype == "text/html" && body == "" { + body, err = readTextBody(part.Header, part) + if err != nil { + log.Println("error reading html body from multipart:", err) + } + } + } + return body, nil +} + + func handleMessage(data string) { msg, err := mail.ReadMessage(bytes.NewReader([]byte(data))) if err != nil { @@ -84,12 +147,47 @@ func handleMessage(data string) { return } - body, err := ioutil.ReadAll(msg.Body) + res := "New mail!" + res += "\nFrom: " + msg.Header.Get("From") + res += "\nTo: " + msg.Header.Get("To") + mimetype, mimeparams, err := mime.ParseMediaType(msg.Header.Get("Content-Type")) if err != nil { log.Println(err) return } + + log.Println("handling email with content-type", mimetype) + + var body string + if strings.HasPrefix(mimetype, "text/") { + body, err = readTextBody(msg.Header, msg.Body) + } else if strings.HasPrefix(mimetype, "multipart/") { + body, err = readMultipartBody(msg, mimeparams["boundary"]) + } else { + body = "check console for more info" + } - log.Println("FROM: ", msg.Header.Get("From")) - log.Println(string(body)) + if err != nil { + log.Println("reading body failed:", err) + return + } + if len(body) > 1000 { + // curl 'https://bin.ddd.rip/documents' --compressed -H 'Content-Type: application/json; charset=utf-8' -H 'X-Requested-With: XMLHttpRequest' -H 'Origin: https://bin.ddd.rip' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: https://bin.ddd.rip/' -H 'TE: Trailers' --data-raw dupa + log.Println("mail too long, uploading to hastebin") + res, err := http.Post("https://bin.ddd.rip/documents", "text/plain", bytes.NewReader([]byte(body))) + if err != nil { + body = "error uploading email: " + err.Error() + } else { + var response map[string]string + json.NewDecoder(res.Body).Decode(&response) + body = "https://bin.ddd.rip/" + response["key"] + } + } + res += "\n\n" + body + + log.Println("sending telegram message") + _, err = Tg.SendMessage(chatId, res) + if err != nil { + log.Println(err) + } }