Browse Source

Basic 2017 demo for Le Figaro, hardly updated.

Frédéric G. Marand 1 year ago
commit
87997669c2
9 changed files with 199 additions and 0 deletions
  1. 8 0
      .idea/.gitignore
  2. 8 0
      .idea/modules.xml
  3. 9 0
      .idea/smtpd.iml
  4. 48 0
      cmd/smtpd.go
  5. 92 0
      envelope.go
  6. 12 0
      fixtures/simple.eml
  7. 10 0
      go.mod
  8. 6 0
      go.sum
  9. 6 0
      message.go

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/smtpd.iml" filepath="$PROJECT_DIR$/.idea/smtpd.iml" />
+    </modules>
+  </component>
+</project>

+ 9 - 0
.idea/smtpd.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 48 - 0
cmd/smtpd.go

@@ -0,0 +1,48 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"log"
+
+	"code.osinet.fr/fgm/smtpd"
+
+	baseSmtpd "github.com/bradfitz/go-smtpd/smtpd"
+)
+
+func onNewConnection(c baseSmtpd.Connection) error {
+	var err error
+	log.Printf("New connection from %v\n", c.Addr())
+	network := c.Addr().Network()
+	if network != "tcp" {
+		err = fmt.Errorf("unsupported network: %v", network)
+	}
+	return err
+}
+
+func onNewMail(c baseSmtpd.Connection, addr baseSmtpd.MailAddress) (baseSmtpd.Envelope, error) {
+	var err error
+	e := smtpd.DemoEnvelope{
+		SmtpNetwork: c.Addr().Network(),
+		SmtpRemote:  c.Addr().String(),
+		MailFrom:    addr,
+	}
+	return &e, err
+}
+
+func main() {
+	var addr string
+	flag.StringVar(&addr, "addr", ":25", "The address on which to listen.")
+	flag.Parse()
+
+	s := baseSmtpd.Server{
+		Addr:            addr,
+		OnNewConnection: onNewConnection,
+		OnNewMail:       onNewMail,
+	}
+
+	err := s.ListenAndServe()
+	if err != nil {
+		log.Fatalf("ListenAndServe: %v\n", err)
+	}
+}

+ 92 - 0
envelope.go

@@ -0,0 +1,92 @@
+package smtpd
+
+import (
+	"io"
+	"net/mail"
+	"strings"
+
+	baseSmtpd "github.com/bradfitz/go-smtpd/smtpd"
+	"github.com/go-xweb/log"
+)
+
+type DemoEnvelope struct {
+	SmtpNetwork string                `json:"-"`
+	SmtpRemote  string                `json:"-"`
+	MailFrom    baseSmtpd.MailAddress `json:"mail_from"`
+	RcptTo      baseSmtpd.MailAddress `json:"rcpt_to"`
+	Lines       strings.Builder       `json:"lines"`
+}
+
+func (d *DemoEnvelope) AddRecipient(rcpt baseSmtpd.MailAddress) error {
+	log.Printf("Inbound email from %s for %s", d.MailFrom.Email(), rcpt)
+	d.RcptTo = rcpt
+	return nil
+}
+
+func (d *DemoEnvelope) BeginData() error {
+	d.Lines = strings.Builder{}
+	return nil
+}
+
+func (d *DemoEnvelope) Write(line []byte) error {
+	d.Lines.Write(line)
+	return nil
+}
+
+func (d *DemoEnvelope) Close() error {
+	msg, err := d.Parse()
+	if err == nil {
+		d.Handle(*msg)
+	}
+	return nil
+}
+
+func (d DemoEnvelope) Handle(message mail.Message) {
+	//for i, h := range message.Header {
+	//	first := h[0]
+	//	if len(h[1:]) > 0 {
+	//		log.Printf("%-10s %s(+more)\n", i, first)
+	//	} else {
+	//		log.Printf("%-10s %s\n", i, first)
+	//	}
+	//}
+	parser := mail.AddressParser{}
+
+	from, err := parser.Parse(message.Header.Get("From"))
+	if err != nil {
+		log.Errorf("Error parsing From: header: %v\n", err)
+		from = &mail.Address{}
+	}
+	if from.Name == "" {
+		from.Name = "(no From name)"
+	}
+
+	to, err := parser.Parse(message.Header.Get("To"))
+	if err != nil {
+		log.Errorf("Error parsing To: header: %v\n", err)
+		to = &mail.Address{}
+	}
+	if to.Name == "" {
+		to.Name = "(no To name)"
+	}
+
+	subject := message.Header.Get("Subject")
+	body, err := io.ReadAll(message.Body)
+	if err != nil {
+		log.Errorf("Error reading body: %v", err)
+	}
+	log.Printf("From:    %-20s (%s)\n", from.Name, from.Address)
+	log.Printf("To:      %-20s (%s)\n", to.Name, to.Address)
+	log.Printf("Subject: %s\n", subject)
+	log.Printf("Message:\n%s\n", string(body))
+}
+
+func (d DemoEnvelope) Parse() (*mail.Message, error) {
+	reader := strings.NewReader(d.Lines.String())
+	message, err := mail.ReadMessage(reader)
+	if err != nil {
+		log.Errorf("Error reading submitted message: %v", err)
+		return &mail.Message{}, err
+	}
+	return message, nil
+}

+ 12 - 0
fixtures/simple.eml

@@ -0,0 +1,12 @@
+HELO demo
+MAIL FROM:<mailfrom@example.com>
+RCPT TO:<mailto@example.com>
+DATA
+From: <from@example.com>
+To: <to@example.com>
+Subject: Simple subject
+
+Plain content.
+Two lines of it.
+.
+QUIT

+ 10 - 0
go.mod

@@ -0,0 +1,10 @@
+module code.osinet.fr/fgm/smtpd
+
+go 1.19
+
+require (
+	github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625
+	github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e
+)
+
+require github.com/mattn/go-sqlite3 v1.14.16 // indirect

+ 6 - 0
go.sum

@@ -0,0 +1,6 @@
+github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625 h1:ckJgFhFWywOx+YLEMIJsTb+NV6NexWICk5+AMSuz3ss=
+github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
+github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e h1:xmffs7hgrWpAOcquZrdlWpAEaAdlI9myaYcUUmhIP7k=
+github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e/go.mod h1:ASmYUSBf32lWkkNVX/pnOU4MLuUQpFH4qYHvWHt/l0w=
+github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
+github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=

+ 6 - 0
message.go

@@ -0,0 +1,6 @@
+package smtpd
+
+
+type Message struct {
+
+}