This is the main dovel repository, it has the Go code to run dovel SMTP server.
Author: bmayer3 (bmayer@sibros.tech)
Date: Sun Feb 12 20:17:52 2023 -0300
Parent: 881b4b4
Added dkim support
commit 8d0b023b0457c8bfcc9c2fa4ca077ea5b74a410e Author: bmayer3 <bmayer@sibros.tech> Date: Sun Feb 12 20:17:52 2023 -0300 Added dkim support diff --git a/cmd/dovel/main.go b/cmd/dovel/main.go index f7076b4..32aafda 100644 --- a/cmd/dovel/main.go +++ b/cmd/dovel/main.go @@ -1,7 +1,11 @@ package main import ( + "crypto" + "crypto/x509" "encoding/json" + "encoding/pem" + "io/ioutil" "log" "net/http" "os" @@ -21,8 +25,9 @@ var ( defaultConfig = config.Config{ WebPort: &defaultPort, Server: config.ServerConfig{ - Domain: "m.blmayer.dev", - Address: ":2525", + DKIMKeyPath: "dkim.priv", + Domain: "mail.blmayer.dev", + Address: ":2525", Inboxes: []config.InboxConfig{ { Domain: "localhost", @@ -33,11 +38,11 @@ var ( }, }, } - b = backend.Backend{Handlers: map[string]config.Handler{}} + cfg config.Config + b = backend.Backend{Handlers: map[string]config.Handler{}} ) func main() { - var cfg config.Config configPath := ".dovel-config.json" configFile, err := os.Open(configPath) if err != nil { @@ -47,6 +52,25 @@ func main() { json.NewDecoder(configFile).Decode(&cfg) } + // load kdim key + if cfg.Server.DKIMKeyPath != "" { + key, err := ioutil.ReadFile(cfg.Server.DKIMKeyPath) + if err != nil { + panic(err) + } + + block, _ := pem.Decode(key) + if block == nil { + panic("no PEM data found") + } + privKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + panic(err) + } + b.PrivateKey = privKey.(crypto.Signer) + println("loaded dkim private key") + } + for _, hand := range cfg.Server.Inboxes { switch hand.Handler { case "gwi":
commit 8d0b023b0457c8bfcc9c2fa4ca077ea5b74a410e Author: bmayer3 <bmayer@sibros.tech> Date: Sun Feb 12 20:17:52 2023 -0300 Added dkim support diff --git a/config/config.go b/config/config.go index 6ec40d7..48fa959 100644 --- a/config/config.go +++ b/config/config.go @@ -36,6 +36,5 @@ type ServerConfig struct { Address string Domain string Inboxes []InboxConfig - DKIMPrivKey string - DKIMPubKey string + DKIMKeyPath string }
commit 8d0b023b0457c8bfcc9c2fa4ca077ea5b74a410e Author: bmayer3 <bmayer@sibros.tech> Date: Sun Feb 12 20:17:52 2023 -0300 Added dkim support diff --git a/go.mod b/go.mod index 9e87fd6..f159123 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module blmayer.dev/x/dovel go 1.19 require ( + github.com/OfimaticSRL/parsemail v0.0.0-20230123231945-3a41f46bbfa4 + github.com/emersion/go-msgauth v0.6.6 github.com/emersion/go-smtp v0.15.0 github.com/go-git/go-git/v5 v5.4.2 github.com/marcospgmelo/parsemail v1.3.1-0.20201020162348-38663e9311e7 @@ -10,7 +12,6 @@ require ( require ( github.com/Microsoft/go-winio v0.6.0 // indirect - github.com/OfimaticSRL/parsemail v0.0.0-20230123231945-3a41f46bbfa4 // indirect github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect github.com/cloudflare/circl v1.3.0 // indirect
commit 8d0b023b0457c8bfcc9c2fa4ca077ea5b74a410e Author: bmayer3 <bmayer@sibros.tech> Date: Sun Feb 12 20:17:52 2023 -0300 Added dkim support diff --git a/go.sum b/go.sum index 84f9db6..a59b1a1 100644 --- a/go.sum +++ b/go.sum @@ -20,10 +20,17 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/emersion/go-message v0.11.2/go.mod h1:C4jnca5HOTo4bGN9YdqNQM9sITuT3Y0K6bSUw9RklvY= +github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4= +github.com/emersion/go-milter v0.3.3/go.mod h1:ablHK0pbLB83kMFBznp/Rj8aV+Kc3jw8cxzzmCNLIOY= +github.com/emersion/go-msgauth v0.6.6 h1:buv5lL8v/3v4RpHnQFS2IPhE3nxSRX+AxnrEJbDbHhA= +github.com/emersion/go-msgauth v0.6.6/go.mod h1:A+/zaz9bzukLM6tRWRgJ3BdrBi+TFKTvQ3fGMFOI9SM= 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.15.0 h1:3+hMGMGrqP/lqd7qoxZc1hTU8LY8gHV9RFGWlqSDmP8= github.com/emersion/go-smtp v0.15.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= +github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U= +github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= @@ -59,6 +66,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/marcospgmelo/parsemail v1.3.1-0.20201020162348-38663e9311e7 h1:KlXrFiVXXvxkEmHWmHErAxzBL7ynvJvzdLr8ZZRgYbc= github.com/marcospgmelo/parsemail v1.3.1-0.20201020162348-38663e9311e7/go.mod h1:bzTPHUEfHfbAxgj0nNHBAEH50bbKSkSuNVx8HEpO+5A= +github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -77,6 +85,7 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -87,6 +96,7 @@ golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= @@ -113,6 +123,7 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
commit 8d0b023b0457c8bfcc9c2fa4ca077ea5b74a410e Author: bmayer3 <bmayer@sibros.tech> Date: Sun Feb 12 20:17:52 2023 -0300 Added dkim support diff --git a/interfaces/backend/backend.go b/interfaces/backend/backend.go index 323fee8..c6b8d50 100644 --- a/interfaces/backend/backend.go +++ b/interfaces/backend/backend.go @@ -5,6 +5,7 @@ package backend import ( "bytes" + "crypto" "fmt" "io" "mime/multipart" @@ -17,6 +18,7 @@ import ( "blmayer.dev/x/dovel/config" "blmayer.dev/x/dovel/interfaces" "github.com/OfimaticSRL/parsemail" + "github.com/emersion/go-msgauth/dkim" "github.com/emersion/go-smtp" ) @@ -81,7 +83,8 @@ func (s Session) Logout() error { } type Backend struct { - Handlers map[string]config.Handler + Handlers map[string]config.Handler + PrivateKey crypto.Signer } func (b Backend) NewSession(_ *smtp.Conn) (smtp.Session, error) { @@ -98,6 +101,7 @@ func (b Backend) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, erro func (b Backend) SendHandler(saveFunction func(e interfaces.Email, b []byte) error) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + println("backend sending email") if err := r.ParseMultipartForm(20 * 1024 * 1024); err != nil { println("form error: " + err.Error()) http.Error(w, "form error"+err.Error(), http.StatusNotAcceptable) @@ -172,6 +176,17 @@ func (b Backend) SendHandler(saveFunction func(e interfaces.Email, b []byte) err } form.Close() + // dkim + payload := bytes.Buffer{} + options := &dkim.SignOptions{ + Domain: "mail.blmayer.dev", + Selector: "dkim", + Signer: b.PrivateKey, + } + if err := dkim.Sign(&payload, &body, options); err != nil { + println("failed to sign body:", err.Error()) + } + // dns mx for email for _, to := range email.To { addr := strings.Split(to, "@") @@ -193,7 +208,7 @@ func (b Backend) SendHandler(saveFunction func(e interfaces.Email, b []byte) err nil, email.From, []string{to}, - &body, + &payload, ) if err != nil { println("sendMail error: " + err.Error())
commit 8d0b023b0457c8bfcc9c2fa4ca077ea5b74a410e Author: bmayer3 <bmayer@sibros.tech> Date: Sun Feb 12 20:17:52 2023 -0300 Added dkim support diff --git a/interfaces/file/file.go b/interfaces/file/file.go index 5123671..9ffc14a 100644 --- a/interfaces/file/file.go +++ b/interfaces/file/file.go @@ -79,6 +79,7 @@ func (f FileHandler) IndexHandler() http.HandlerFunc { func (f FileHandler) SendHandler(b backend.Backend) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + println("file handling send email") user, pass, _ := r.BasicAuth() if user != "x" || pass != f.password { w.Header().Add("WWW-Authenticate", "Basic") @@ -86,7 +87,7 @@ func (f FileHandler) SendHandler(b backend.Backend) http.HandlerFunc { return } - b.SendHandler(f.SaveSent) + b.SendHandler(f.SaveSent)(w, r) } }
commit 8d0b023b0457c8bfcc9c2fa4ca077ea5b74a410e Author: bmayer3 <bmayer@sibros.tech> Date: Sun Feb 12 20:17:52 2023 -0300 Added dkim support diff --git a/www/compose.html b/www/compose.html index 18621a6..fb6523e 100644 --- a/www/compose.html +++ b/www/compose.html @@ -1,15 +1,20 @@ {{template "head.html"}} -<p>// <b>composing</b></p> +<p><b>composing</b></p> <form action=/out method=post enctype=multipart/form-data> - // From: <input name=from placeholder="___________" {{if .inbox}}value="{{index .inbox 0}}"{{end}}><br> - // To: <input name=to placeholder="________"><br> - // CC: <input name=cc placeholder="________"><br> - // CCo: <input name=cco placeholder="________"><br> - // Subject: <input name=subject placeholder="_________" {{if .subj}}value="{{index .subj 0}}"{{end}}><br> - // Body:<br><br> - <textarea name=body rows="7" cols="50" placeholder="________"></textarea><br> + <label for="from">From: </label> + <input name=from {{if .inbox}}value="{{index .inbox 0}}"{{end}}><br> + <label>To: </label> + <input name=to><br> + <label>CC: </label> + <input name=cc><br> + <label>CCo: </label> + <input name=cco><br> + <label>Subject: </label> + <input name=subject {{if .subj}}value="{{index .subj 0}}"{{end}}><br> + Body:<br><br> + <field><textarea name=body rows="7" cols="50"></textarea><br></field> <br> - // <input type=submit value=send> + <input type=submit value=send> </form>
commit 8d0b023b0457c8bfcc9c2fa4ca077ea5b74a410e Author: bmayer3 <bmayer@sibros.tech> Date: Sun Feb 12 20:17:52 2023 -0300 Added dkim support diff --git a/www/style-min.html b/www/style-min.html index df86487..8f21fdd 100644 --- a/www/style-min.html +++ b/www/style-min.html @@ -10,8 +10,10 @@ color:#f0f } input, textarea { + flex-grow: 1; background: #000; border: none; + border-bottom: 1px solid #0f0; color: #0f0; font-family: monospace; } @@ -20,5 +22,10 @@ cursor: pointer; color: #f0f; } + label { + display: inline-block; + min-width: 80; + } + </style>