Initial SMTP server

This commit is contained in:
Caleb Gardner
2024-02-27 08:57:07 -06:00
parent 9d6ad83ef8
commit 33ee0c76b3
4 changed files with 122 additions and 1 deletions
+108
View File
@@ -0,0 +1,108 @@
package main
import (
"crypto/tls"
"flag"
"io"
"log"
"time"
smtp "github.com/emersion/go-smtp"
)
func startSMTPServer() {
keyPath := flag.Arg(1)
if keyPath == "" {
log.Println("No argument given for key files. smtp signing off...")
quitChan <- "smtp arg"
return
}
tlsCert, err := tls.LoadX509KeyPair(keyPath+"/fullchain.pem", keyPath+"/key.pem")
if err != nil {
log.Println("Error while loading tls certificate:", err)
quitChan <- "smtp err"
return
}
cfg := &tls.Config{Certificates: []tls.Certificate{tlsCert}}
serv := smtp.NewServer(&SMTPBackend{
tlsConfig: cfg,
})
serv.Network = "tcp"
serv.Addr = ":587"
serv.TLSConfig = cfg
serv.Domain = "darkstorm.tech"
serv.WriteTimeout = 10 * time.Second
serv.ReadTimeout = 10 * time.Second
serv.MaxMessageBytes = 1024 * 1024
serv.AllowInsecureAuth = true
serv.MaxRecipients = 2
err = serv.ListenAndServeTLS()
log.Println("Error while serving smtp:", err)
quitChan <- "smtp err"
}
type SMTPBackend struct {
tlsConfig *tls.Config
}
func (b *SMTPBackend) NewSession(c *smtp.Conn) (smtp.Session, error) {
return NewSession(b.tlsConfig, c.Server().Addr)
}
type SMTPSession struct {
tlsConfig *tls.Config
client *smtp.Client
addr string
}
func NewSession(tlsConfig *tls.Config, addr string) (*SMTPSession, error) {
client, err := smtp.DialTLS(addr, tlsConfig)
if err != nil {
return nil, err
}
return &SMTPSession{
tlsConfig: tlsConfig,
client: client,
addr: addr,
}, nil
}
func (s *SMTPSession) Reset() {
var err error
s.client, err = smtp.DialTLS(s.addr, s.tlsConfig)
if err != nil {
log.Println("Error while resetting smtp session:", err)
}
}
func (s *SMTPSession) Logout() error {
return s.client.Quit()
}
func (s *SMTPSession) AuthPlain(username, password string) error {
//TODO
return nil
}
func (s *SMTPSession) Mail(from string, opts *smtp.MailOptions) error {
return s.client.Mail(from, opts)
}
func (s *SMTPSession) Rcpt(to string, opts *smtp.RcptOptions) error {
return s.client.Rcpt(to, opts)
}
func (s *SMTPSession) Data(r io.Reader) error {
wrt, err := s.client.Data()
if err != nil {
log.Println("Error while writing smtp data:", err)
return err
}
_, err = io.Copy(wrt, r)
if err != nil {
log.Println("Error while writing smtp data:", err)
return err
}
wrt.Close()
return nil
}
+3
View File
@@ -11,7 +11,10 @@ require (
go.mongodb.org/mongo-driver v1.13.1 go.mongodb.org/mongo-driver v1.13.1
) )
require github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
require ( require (
github.com/emersion/go-smtp v0.20.2
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/klauspost/compress v1.17.6 // indirect github.com/klauspost/compress v1.17.6 // indirect
+4
View File
@@ -16,6 +16,10 @@ github.com/CalebQ42/swassistant-backend v0.2.1 h1:DqBx1pvPgMOE7LbzxvSoasH83FDgGL
github.com/CalebQ42/swassistant-backend v0.2.1/go.mod h1:WY+3UvzBcTUoZMtYCVhNWfFW/Cx3lBActCJfk+EUD0s= github.com/CalebQ42/swassistant-backend v0.2.1/go.mod h1:WY+3UvzBcTUoZMtYCVhNWfFW/Cx3lBActCJfk+EUD0s=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-smtp v0.20.2 h1:peX42Qnh5Q0q3vrAnRy43R/JwTnnv75AebxbkTL7Ia4=
github.com/emersion/go-smtp v0.20.2/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+6
View File
@@ -13,6 +13,7 @@ func main() {
flag.Parse() flag.Parse()
go linker() go linker()
go webserver(*mongoStr) go webserver(*mongoStr)
go startSMTPServer()
for failure := <-quitChan; ; failure = <-quitChan { for failure := <-quitChan; ; failure = <-quitChan {
switch failure { switch failure {
case "tcp conf": case "tcp conf":
@@ -23,6 +24,11 @@ func main() {
continue continue
case "web err": case "web err":
go websiteRestart(*mongoStr) go websiteRestart(*mongoStr)
case "smtp arg":
continue
case "smtp err":
//TODO: restart smtp server
continue
} }
} }
} }