init: pristine aerc 0.20.0 source
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package cryptoutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"git.sr.ht/~rjarry/aerc/app"
|
||||
"git.sr.ht/~rjarry/aerc/lib/rfc822"
|
||||
"github.com/emersion/go-message/mail"
|
||||
)
|
||||
|
||||
func Cleartext(r io.Reader, header mail.Header) ([]byte, error) {
|
||||
msg, err := app.CryptoProvider().Decrypt(
|
||||
rfc822.NewCRLFReader(r), app.DecryptKeys)
|
||||
if err != nil {
|
||||
return nil, errors.New("decrypt error")
|
||||
}
|
||||
full, err := createMessage(header, msg.Body)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to create decrypted message")
|
||||
}
|
||||
return full, nil
|
||||
}
|
||||
|
||||
func createMessage(header mail.Header, body io.Reader) ([]byte, error) {
|
||||
e, err := rfc822.ReadMessage(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// copy the header values from the "decrypted body". This should set
|
||||
// the correct content type.
|
||||
hf := e.Header.Fields()
|
||||
for hf.Next() {
|
||||
header.Set(hf.Key(), hf.Value())
|
||||
}
|
||||
|
||||
ctype, params, err := header.ContentType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// in case there remains a multipart/{encrypted,signed} content type,
|
||||
// manually correct them to multipart/mixed as a fallback.
|
||||
ct := strings.ToLower(ctype)
|
||||
if strings.Contains(ct, "multipart/encrypted") ||
|
||||
strings.Contains(ct, "multipart/signed") {
|
||||
delete(params, "protocol")
|
||||
delete(params, "micalg")
|
||||
header.SetContentType("multipart/mixed", params)
|
||||
}
|
||||
|
||||
// a SingleInlineWriter is sufficient since the "decrypted body"
|
||||
// already contains the proper boundaries of the parts; we just want to
|
||||
// combine it with the headers.
|
||||
var message bytes.Buffer
|
||||
w, err := mail.CreateSingleInlineWriter(&message, header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := io.Copy(w, e.Body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w.Close()
|
||||
|
||||
return message.Bytes(), nil
|
||||
}
|
||||
Reference in New Issue
Block a user