Implement first version of signature collector
This commit is contained in:
parent
2d45c99a89
commit
dccb3ba50b
4 changed files with 283 additions and 22 deletions
141
mime.go
141
mime.go
|
|
@ -6,10 +6,117 @@ import (
|
|||
"net/textproto"
|
||||
"io/ioutil"
|
||||
"bytes"
|
||||
"mimeparser"
|
||||
"proton/pmmime"
|
||||
"io"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
)
|
||||
|
||||
func parseMIME(mimeBody string) (body *mimeparser.BodyCollector, atts, attHeaders []string, err error) {
|
||||
|
||||
|
||||
func DecodePart(partReader io.Reader, header textproto.MIMEHeader) (decodedPart io.Reader) {
|
||||
decodedPart = pmmime.DecodeContentEncoding(partReader, header.Get("Content-Transfer-Encoding"))
|
||||
if decodedPart == nil {
|
||||
log.Warnf("Unsupported Content-Transfer-Encoding '%v'", header.Get("Content-Transfer-Encoding"))
|
||||
decodedPart = partReader
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ======================== Attachments Collector ==============
|
||||
// Collect contents of all attachment parts and return
|
||||
// them as a string
|
||||
|
||||
type SignatureCollector struct {
|
||||
target pmmime.VisitAcceptor
|
||||
signature string
|
||||
}
|
||||
|
||||
func NewSignatureCollector(targetAccepter pmmime.VisitAcceptor) *SignatureCollector {
|
||||
return &SignatureCollector{
|
||||
target: targetAccepter,
|
||||
}
|
||||
}
|
||||
|
||||
func getMultipartParts(r io.Reader, params map[string]string) (parts []io.Reader, headers []textproto.MIMEHeader, err error) {
|
||||
mr := multipart.NewReader(r, params["boundary"])
|
||||
parts = []io.Reader{}
|
||||
headers = []textproto.MIMEHeader{}
|
||||
var p *multipart.Part
|
||||
for {
|
||||
p, err = mr.NextPart()
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
b, _ := ioutil.ReadAll(p)
|
||||
buffer := bytes.NewBuffer(b)
|
||||
|
||||
parts = append(parts, buffer)
|
||||
headers = append(headers, p.Header)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (sc *SignatureCollector) Accept(part io.Reader, header textproto.MIMEHeader, hasPlainSibling bool, isFirst, isLast bool) (err error) {
|
||||
parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||
if parentMediaType == "multipart/signed" {
|
||||
var multiparts []io.Reader
|
||||
var multipartHeaders []textproto.MIMEHeader
|
||||
if multiparts, multipartHeaders, err = getMultipartParts(part, params); err != nil {
|
||||
return
|
||||
} else {
|
||||
hasPlainChild := false
|
||||
for _, header := range multipartHeaders {
|
||||
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||
if mediaType == "text/plain" {
|
||||
hasPlainChild = true
|
||||
}
|
||||
}
|
||||
if len(multiparts) != 2 {
|
||||
// Invalid multipart/signed format just pass along
|
||||
for i, p := range multiparts {
|
||||
if err = sc.target.Accept(p, multipartHeaders[i], hasPlainChild, true, true); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
// actual multipart/signed format
|
||||
err = sc.target.Accept(multiparts[0], multipartHeaders[0], hasPlainChild, true, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
partData, _ := ioutil.ReadAll(multiparts[1])
|
||||
decodedPart := pmmime.DecodeContentEncoding(bytes.NewReader(partData), header.Get("Content-Transfer-Encoding"))
|
||||
buffer, err := ioutil.ReadAll(decodedPart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buffer, err = pmmime.DecodeCharset(buffer, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sc.signature = string(buffer)
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
sc.target.Accept(part, header, hasPlainSibling, isFirst, isLast)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (ac SignatureCollector) GetSignature() string {
|
||||
return ac.signature
|
||||
}
|
||||
|
||||
|
||||
func ParseMIME(mimeBody string) (body *pmmime.BodyCollector, atts, attHeaders []string, err error) {
|
||||
|
||||
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
|
||||
if err != nil {
|
||||
|
|
@ -19,10 +126,12 @@ func parseMIME(mimeBody string) (body *mimeparser.BodyCollector, atts, attHeader
|
|||
h := textproto.MIMEHeader(mm.Header)
|
||||
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
||||
|
||||
printAccepter := mimeparser.NewMIMEPrinter()
|
||||
bodyCollector := mimeparser.NewBodyCollector(printAccepter)
|
||||
attachmentsCollector := mimeparser.NewAttachmentsCollector(bodyCollector)
|
||||
err = mimeparser.VisitAll(bytes.NewReader(mmBodyData), h, attachmentsCollector)
|
||||
printAccepter := pmmime.NewMIMEPrinter()
|
||||
bodyCollector := pmmime.NewBodyCollector(printAccepter)
|
||||
attachmentsCollector := pmmime.NewAttachmentsCollector(bodyCollector)
|
||||
mimeVisitor := pmmime.NewMimeVisitor(attachmentsCollector)
|
||||
signatureCollector := NewSignatureCollector(mimeVisitor)
|
||||
err = pmmime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
|
||||
|
||||
body = bodyCollector
|
||||
atts = attachmentsCollector.GetAttachments()
|
||||
|
|
@ -31,7 +140,7 @@ func parseMIME(mimeBody string) (body *mimeparser.BodyCollector, atts, attHeader
|
|||
return
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
// define call back interface
|
||||
type MIMECallbacks interface {
|
||||
|
|
@ -42,16 +151,16 @@ type MIMECallbacks interface {
|
|||
}
|
||||
|
||||
func (o *OpenPGP) decryptMIMEMessage(encryptedText string, verifierKey string, privateKeys []byte,
|
||||
passphrase string, callbacks MIMECallbacks, verifyTime int64) (verifier int, err error) {
|
||||
decsignverify, error := o.DecryptMessageVerifyPrivbinkeys(encryptedText, verifierKey, privateKeys, passphrase, verifyTime)
|
||||
if (error != nil) {
|
||||
return 0, error
|
||||
passphrase string, callbacks MIMECallbacks, verifyTime int64) (verifier int, err error) {
|
||||
decsignverify, err := o.DecryptMessageVerifyPrivbinkeys(encryptedText, verifierKey, privateKeys, passphrase, verifyTime)
|
||||
if (err != nil) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
body, attachments, attachmentHeaders, error := parseMIME(decsignverify.Plaintext
|
||||
if (error != nil) {
|
||||
return 0, error
|
||||
})
|
||||
body, attachments, attachmentHeaders, err := parseMIME(decsignverify.Plaintext)
|
||||
if (err != nil) {
|
||||
return 0, err
|
||||
}
|
||||
bodyContent, bodyMimeType := body.GetBody()
|
||||
callbacks.onBody(bodyContent, bodyMimeType)
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
|
|
@ -62,4 +171,4 @@ func (o *OpenPGP) decryptMIMEMessage(encryptedText string, verifierKey string, p
|
|||
// Todo verify the signature included in the attachment
|
||||
|
||||
return verifier, nil
|
||||
}
|
||||
}*/
|
||||
Loading…
Add table
Add a link
Reference in a new issue