This is the main dovel repository, it has the Go code to run dovel SMTP server.
Author: blmayer (bleemayer@gmail.com)
Date: Sun Jun 18 00:18:20 2023 -0300
Parent: 7b45792
Added initial support for pgp email
commit 5f083f9a3c216fdb8c581aabee8755a21d3669bb
Author: blmayer <bleemayer@gmail.com>
Date: Sun Jun 18 00:18:20 2023 -0300
Added initial support for pgp email
diff --git a/cmd/dovel/web.go b/cmd/dovel/web.go
index 8ef1407..56ad76f 100644
--- a/cmd/dovel/web.go
+++ b/cmd/dovel/web.go
@@ -1,6 +1,7 @@
package main
import (
+ "crypto"
"html/template"
"io"
"net/http"
@@ -152,7 +153,12 @@ func (h webHandler) sendHandler() http.HandlerFunc {
}
}
- err := h.mailer.Send(email)
+ var key crypto.PublicKey
+ if len(fo.Value["key"]) > 0 {
+ key = crypto.BLAKE2b_256
+ }
+
+ err := h.mailer.Send(email, key)
if err != nil {
println("send error: " + err.Error())
http.Error(w, "send error"+err.Error(), http.StatusInternalServerError)
commit 5f083f9a3c216fdb8c581aabee8755a21d3669bb
Author: blmayer <bleemayer@gmail.com>
Date: Sun Jun 18 00:18:20 2023 -0300
Added initial support for pgp email
diff --git a/config/config.go b/config/config.go
index 0e23958..667a948 100644
--- a/config/config.go
+++ b/config/config.go
@@ -14,6 +14,7 @@ type Config struct {
type InboxConfig struct {
Domain string
DKIMKeyPath string
+ PrivateKey string
Templates string
Handler string
Root string
commit 5f083f9a3c216fdb8c581aabee8755a21d3669bb
Author: blmayer <bleemayer@gmail.com>
Date: Sun Jun 18 00:18:20 2023 -0300
Added initial support for pgp email
diff --git a/go.mod b/go.mod
index b1cd6af..abe3f0f 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,9 @@ require (
require (
github.com/Microsoft/go-winio v0.6.0 // indirect
- github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
+ github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310 // indirect
+ github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect
+ github.com/ProtonMail/gopenpgp/v2 v2.7.1 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/cloudflare/circl v1.3.2 // indirect
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead // indirect
@@ -21,10 +23,13 @@ require (
github.com/go-git/go-billy/v5 v5.4.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
+ github.com/tv42/zbase32 v0.0.0-20220222190657-f76a9fc892fa // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
- golang.org/x/tools v0.3.0 // indirect
+ golang.org/x/text v0.8.0 // indirect
+ golang.org/x/tools v0.6.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)
commit 5f083f9a3c216fdb8c581aabee8755a21d3669bb
Author: blmayer <bleemayer@gmail.com>
Date: Sun Jun 18 00:18:20 2023 -0300
Added initial support for pgp email
diff --git a/go.sum b/go.sum
index b2aa81f..ceb8cbf 100644
--- a/go.sum
+++ b/go.sum
@@ -8,6 +8,12 @@ github.com/OfimaticSRL/parsemail v0.0.0-20230215211201-e1c318cd177f/go.mod h1:Me
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
+github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310 h1:dGAdTcqheKrQ/TW76sAcmO2IorwXplUw2inPkOzykbw=
+github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
+github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k=
+github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=
+github.com/ProtonMail/gopenpgp/v2 v2.7.1 h1:Awsg7MPc2gD3I7IFac2qE3Gdls0lZW8SzrFZ3k1oz0s=
+github.com/ProtonMail/gopenpgp/v2 v2.7.1/go.mod h1:/BU5gfAVwqyd8EfC3Eu7zmuhwYQpKs+cGD8M//iiaxs=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
@@ -85,6 +91,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
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=
+github.com/tv42/zbase32 v0.0.0-20220222190657-f76a9fc892fa h1:2EwhXkNkeMjX9iFYGWLPQLPhw9O58BhnYgtYKeqybcY=
+github.com/tv42/zbase32 v0.0.0-20220222190657-f76a9fc892fa/go.mod h1:is48sjgBanWcA5CQrPBu9Y5yABY/T2awj/zI65bq704=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
@@ -102,6 +110,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -109,10 +119,12 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -130,6 +142,7 @@ golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -137,19 +150,24 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
commit 5f083f9a3c216fdb8c581aabee8755a21d3669bb
Author: blmayer <bleemayer@gmail.com>
Date: Sun Jun 18 00:18:20 2023 -0300
Added initial support for pgp email
diff --git a/interfaces/file/file.go b/interfaces/file/file.go
index 40e2b74..30024e5 100644
--- a/interfaces/file/file.go
+++ b/interfaces/file/file.go
@@ -21,11 +21,14 @@ import (
"blmayer.dev/x/dovel/config"
"blmayer.dev/x/dovel/interfaces"
+ "blmayer.dev/x/dovel/util/wkd"
"blmayer.dev/x/vault"
"github.com/OfimaticSRL/parsemail"
"github.com/emersion/go-msgauth/dkim"
+
+ "github.com/ProtonMail/gopenpgp/v2/helper"
)
// FileHandler is used to configure the file email handler.
@@ -111,7 +114,7 @@ func (f FileHandler) SaveSent(email interfaces.Email) error {
return nil
}
-func (f FileHandler) Send(mail interfaces.Email) error {
+func (f FileHandler) Send(mail interfaces.Email, opts interfaces.Opt) error {
mail.ID = fmt.Sprintf("%d@%s", mail.Date.Unix(), f.domain)
body := bytes.Buffer{}
@@ -131,16 +134,6 @@ func (f FileHandler) Send(mail interfaces.Email) error {
body.WriteString("Subject: " + mail.Subject + "\r\n")
body.WriteString("Content-Type: multipart/mixed; boundary=" + form.Boundary() + "\r\n\r\n")
- text, err := form.CreatePart(
- map[string][]string{
- "Content-Type": {"text/plain; charset=\"UTF-8\""},
- },
- )
- if err != nil {
- return err
- }
- text.Write([]byte(mail.Body))
-
for name, fi := range mail.Attachments {
part, err := form.CreateFormFile(name, name)
if err != nil {
@@ -150,19 +143,6 @@ func (f FileHandler) Send(mail interfaces.Email) error {
part.Write(fi.Data)
}
- form.Close()
-
- // dkim
- payload := bytes.Buffer{}
- options := &dkim.SignOptions{
- Domain: f.domain,
- Selector: "dkim",
- Signer: f.privateKey,
- }
- if err := dkim.Sign(&payload, &body, options); err != nil {
- println("failed to sign body:", err.Error())
- }
- mail.Raw = payload.Bytes()
for _, to := range mail.To {
// dns mx for email
@@ -175,6 +155,51 @@ func (f FileHandler) Send(mail interfaces.Email) error {
return err
}
+ // grab public key if wanted
+ if opts.Encrypt {
+ key, err := wkd.FetchPGPKey(addr[0], addr[1])
+ if err != nil {
+ println("error fetching key", err)
+ } else {
+ text, err := form.CreatePart(
+ map[string][]string{
+ "Content-Type": {"application/pgp-encrypted"},
+ },
+ )
+ if err != nil {
+ return err
+ }
+ cypher, err := helper.EncryptMessageArmored(key, mail.Body)
+ if err != nil {
+ return err
+ }
+ text.Write([]byte(cypher))
+ }
+ } else {
+ text, err := form.CreatePart(
+ map[string][]string{
+ "Content-Type": {"text/plain; charset=\"UTF-8\""},
+ },
+ )
+ if err != nil {
+ return err
+ }
+ text.Write([]byte(mail.Body))
+ }
+ form.Close()
+
+ // dkim
+ payload := bytes.Buffer{}
+ options := &dkim.SignOptions{
+ Domain: f.domain,
+ Selector: "dkim",
+ Signer: f.privateKey,
+ }
+ if err := dkim.Sign(&payload, &body, options); err != nil {
+ println("failed to sign body:", err.Error())
+ }
+ mail.Raw = payload.Bytes()
+
server := mxs[0].Host + ":smtp"
err = smtp.SendMail(
server,
commit 5f083f9a3c216fdb8c581aabee8755a21d3669bb
Author: blmayer <bleemayer@gmail.com>
Date: Sun Jun 18 00:18:20 2023 -0300
Added initial support for pgp email
diff --git a/interfaces/main.go b/interfaces/main.go
index d618b6b..6cee223 100644
--- a/interfaces/main.go
+++ b/interfaces/main.go
@@ -60,6 +60,10 @@ type Attachment struct {
Data []byte
}
+type Opt struct {
+ Encrypt bool
+}
+
type Email struct {
Headers map[string][]string
ID string
commit 5f083f9a3c216fdb8c581aabee8755a21d3669bb
Author: blmayer <bleemayer@gmail.com>
Date: Sun Jun 18 00:18:20 2023 -0300
Added initial support for pgp email
diff --git a/www/assets/manifest.json b/www/assets/manifest.json
index e63f7ca..59ade4c 100644
--- a/www/assets/manifest.json
+++ b/www/assets/manifest.json
@@ -5,6 +5,7 @@
{
"src": "/assets/icon.png",
"type": "image/png",
+ "purpose": "maskable",
"sizes": "512x512"
}
],