You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-sendxmpp/oxstanzas.go

241 lines
7.4 KiB
Go

package main
import (
"encoding/base64"
"errors"
"strings"
"time"
"github.com/ProtonMail/gopenpgp/v2/crypto" // MIT License
"github.com/beevik/etree" // BSD-2-clause
)
func oxNodeListRequest() (string, error) {
nodeListRequest := etree.NewDocument()
query := nodeListRequest.CreateElement("query")
query.CreateAttr("xmlns", nsDiscoItems)
nlr, err := nodeListRequest.WriteToString()
if err != nil {
return nlr, err
}
return nlr, nil
}
func oxNodeListReply(iqReply []byte) ([]string, error) {
var nodes []string
nodeListReply := etree.NewDocument()
err := nodeListReply.ReadFromBytes(iqReply)
if err != nil {
return nodes, err
}
query := nodeListReply.SelectElement("query")
if query == nil {
return nodes, errors.New("error parsing iq reply")
}
items := query.SelectElements("item")
if items == nil {
return nodes, errors.New("error parsing iq reply")
}
for _, item := range items {
node := item.SelectAttr("node")
if node == nil {
continue
}
if !strings.Contains(node.Value, nsOx) {
continue
}
nodes = append(nodes, node.Value)
}
return nodes, nil
}
func oxDeleteNodeRequest(node string) (string, error) {
deleteNodeRequest := etree.NewDocument()
pubsub := deleteNodeRequest.CreateElement("pubsub")
pubsub.CreateAttr("xmlns", nsPubsubOwner)
delete := pubsub.CreateElement("delete")
delete.CreateAttr("node", node)
dnr, err := deleteNodeRequest.WriteToString()
if err != nil {
return dnr, err
}
return dnr, nil
}
func oxParseSignCrypt(message string) (oxSigncrypt, error) {
var output oxSigncrypt
doc := etree.NewDocument()
err := doc.ReadFromString(message)
if err != nil {
return output, err
}
signcrypt := doc.SelectElement("signcrypt")
if signcrypt == nil {
return output, errors.New("ox: no signcrypt element")
}
to := signcrypt.SelectElement("to")
if to == nil {
return output, errors.New("ox: no to element")
}
jid := to.SelectAttr("jid")
if jid == nil {
return output, errors.New("ox: no jid attribute")
}
output.jid = jid.Value
timestamp := signcrypt.SelectElement("time")
if timestamp == nil {
return output, errors.New("ox: no time element")
}
stamp := timestamp.SelectAttr("stamp")
if stamp == nil {
return output, errors.New("ox: no stamp attribute")
}
output.stamp = stamp.Value
payload := signcrypt.SelectElement("payload")
if payload == nil {
return output, errors.New("ox: no payload element")
}
body := payload.SelectElement("body")
if body == nil {
return output, errors.New("ox: no body element")
}
output.body = body.Text()
return output, nil
}
func oxPublishPubKeyRequest(pubKeyBase64 string, fingerprint string,
keyCreated string) (string, error) {
root := etree.NewDocument()
pubsub := root.CreateElement("pubsub")
pubsub.CreateAttr("xmlns", nsPubsub)
publish := pubsub.CreateElement("publish")
publish.CreateAttr("node", nsOxPubKeys+":"+fingerprint)
item := publish.CreateElement("item")
item.CreateAttr("id", keyCreated)
pubkey := item.CreateElement("pubkey")
pubkey.CreateAttr("xmlns", nsOx)
data := pubkey.CreateElement("data")
data.CreateText(pubKeyBase64)
publishoptions := pubsub.CreateElement("publish-options")
x := publishoptions.CreateElement("x")
x.CreateAttr("xmlns", nsJabberData)
x.CreateAttr("type", "submit")
field := x.CreateElement("field")
field.CreateAttr("var", "FORM_TYPE")
field.CreateAttr("type", "hidden")
value := field.CreateElement("value")
value.CreateText(pubsubPubOptions)
field = x.CreateElement("field")
field.CreateAttr("var", "pubsub#access_model")
value = field.CreateElement("value")
value.CreateText("open")
output, err := root.WriteToString()
if err != nil {
return output, err
}
return output, nil
}
func oxPublishPubKeyListRequest(fingerprint string, keyCreated string) (string, error) {
root := etree.NewDocument()
pubsub := root.CreateElement("pubsub")
pubsub.CreateAttr("xmlns", nsPubsub)
publish := pubsub.CreateElement("publish")
publish.CreateAttr("node", nsOxPubKeys)
item := publish.CreateElement("item")
pubkeyslist := item.CreateElement("public-keys-list")
pubkeyslist.CreateAttr("xmlns", nsOx)
pubkeymeta := pubkeyslist.CreateElement("pubkey-metadata")
pubkeymeta.CreateAttr("v4-fingerprint", fingerprint)
pubkeymeta.CreateAttr("date", keyCreated)
publishoptions := pubsub.CreateElement("publish-options")
x := publishoptions.CreateElement("x")
x.CreateAttr("xmlns", nsJabberData)
x.CreateAttr("type", "submit")
field := x.CreateElement("field")
field.CreateAttr("var", "FORM_TYPE")
field.CreateAttr("type", "hidden")
value := field.CreateElement("value")
value.CreateText(pubsubPubOptions)
field = x.CreateElement("field")
field.CreateAttr("var", "pubsub#access_model")
value = field.CreateElement("value")
value.CreateText("open")
output, err := root.WriteToString()
if err != nil {
return output, err
}
return output, nil
}
func oxRecvPubKeysRequest(fingerprint string) (string, error) {
opkr := etree.NewDocument()
opkrPs := opkr.CreateElement("pubsub")
opkrPs.CreateAttr("xmlns", nsPubsub)
opkrPsItems := opkrPs.CreateElement("items")
opkrPsItems.CreateAttr("node", nsOxPubKeys+":"+fingerprint)
opkrPsItems.CreateAttr("max_items", "1")
output, err := opkr.WriteToString()
if err != nil {
return output, err
}
return output, nil
}
func oxGetPubKeyRingRequest() (string, error) {
oxPubKeyListReq := etree.NewDocument()
oxPubKeyListReqPs := oxPubKeyListReq.CreateElement("pubsub")
oxPubKeyListReqPs.CreateAttr("xmlns", nsPubsub)
oxPubKeyListReqPsItems := oxPubKeyListReqPs.CreateElement("items")
oxPubKeyListReqPsItems.CreateAttr("node", nsOxPubKeys)
oxPubKeyListReqPsItems.CreateAttr("max_items", "1")
output, err := oxPubKeyListReq.WriteToString()
if err != nil {
return output, err
}
return output, err
}
func oxCryptMessage(recipient string, message string) (string, error) {
oxCryptMessage := etree.NewDocument()
oxCryptMessageSc := oxCryptMessage.CreateElement("signcrypt")
oxCryptMessageSc.CreateAttr("xmlns", nsOx)
oxCryptMessageScTo := oxCryptMessageSc.CreateElement("to")
oxCryptMessageScTo.CreateAttr("jid", recipient)
oxCryptMessageScTime := oxCryptMessageSc.CreateElement("time")
oxCryptMessageScTime.CreateAttr("stamp", time.Now().UTC().Format("2006-01-02T15:04:05Z"))
oxCryptMessageScRpad := oxCryptMessageSc.CreateElement("rpad")
oxCryptMessageScRpad.CreateText(getRpad(len(message)))
oxCryptMessageScPayload := oxCryptMessageSc.CreateElement("payload")
oxCryptMessageScPayloadBody := oxCryptMessageScPayload.CreateElement("body")
oxCryptMessageScPayloadBody.CreateAttr("xmlns", nsJabberClient)
oxCryptMessageScPayloadBody.CreateText(message)
output, err := oxCryptMessage.WriteToString()
if err != nil {
return output, err
}
return output, nil
}
func oxMessage(recipient string, pgpMessage *crypto.PGPMessage) (string, error) {
om := etree.NewDocument()
omMessage := om.CreateElement("message")
omMessage.CreateAttr("to", recipient)
omMessage.CreateAttr("id", getID())
omMessageStore := omMessage.CreateElement("store")
omMessageStore.CreateAttr("xmlns", nsHints)
omMessageEme := omMessage.CreateElement("encryption")
omMessageEme.CreateAttr("xmlns", nsEme)
omMessageEme.CreateAttr("namespace", nsOx)
omMessageOpgp := omMessage.CreateElement("openpgp")
omMessageOpgp.CreateAttr("xmlns", nsOx)
omMessageOpgp.CreateText(base64.StdEncoding.EncodeToString(pgpMessage.Data))
omMessageBody := omMessage.CreateElement("body")
omMessageBody.CreateText(oxAltBody)
output, err := om.WriteToString()
if err != nil {
return output, err
}
return output, nil
}