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.
241 lines
7.4 KiB
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
|
|
}
|