list

server

This is the main dovel repository, it has the Go code to run dovel SMTP server.

curl https://dovel.email/server.tar tar

5f083f9

Author: blmayer (bleemayer@gmail.com)

Date: Sun Jun 18 00:18:20 2023 -0300

Parent: 7b45792

Added initial support for pgp email

Diff

cmd/dovel/web.go

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)

config/config.go

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

go.mod

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
 )

go.sum

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=

interfaces/file/file.go

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,

interfaces/main.go

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

www/assets/manifest.json

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"
 		}
 	],