Wrap and unwrap errors.

errwrp
Martin Dosch 12 months ago
parent ea4b1a7de4
commit a912408d16
No known key found for this signature in database
GPG Key ID: 52A57CFCE13D657D

@ -5,6 +5,7 @@
package main
import (
"errors"
"fmt"
"net"
"strings"
@ -33,7 +34,7 @@ func connect(options xmpp.Options, directTLS bool) (*xmpp.Client, error) {
options.Host = net.JoinHostPort(adr.Target, fmt.Sprint(adr.Port))
// Connect to server
client, err := options.NewClient()
if err == nil {
if errors.Unwrap(err) == nil {
return client, nil
}
}
@ -52,7 +53,7 @@ func connect(options xmpp.Options, directTLS bool) (*xmpp.Client, error) {
}
// Connect to server
client, err := options.NewClient()
if err == nil {
if errors.Unwrap(err) == nil {
return client, nil
}
return client, fmt.Errorf("failed to connect to server: %w", err)

@ -7,6 +7,7 @@ package main
import (
"bytes"
"crypto/rand"
"errors"
"fmt"
"log"
"math/big"
@ -33,16 +34,16 @@ func validURI(s string) (*url.URL, error) {
func readFile(path string) (*bytes.Buffer, error) {
file, err := os.Open(path)
if err != nil {
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("readFile: %w", err)
}
buffer := new(bytes.Buffer)
_, err = buffer.ReadFrom(file)
if err != nil {
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("readFile: %w", err)
}
err = file.Close()
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("error while closing file:", err)
}
return buffer, nil
@ -55,7 +56,7 @@ func getRpad(messageLength int) string {
rpad := make([]rune, length)
for i := range rpad {
randInt, err := rand.Int(rand.Reader, max)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
rpad[i] = rpadRunes[randInt.Int64()]
@ -66,7 +67,7 @@ func getRpad(messageLength int) string {
func getID() string {
id := make([]byte, defaultIDBytes)
_, err := rand.Read(id)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
return fmt.Sprintf("%x-%x-%x", id[0:4], id[4:8], id[8:])
@ -75,7 +76,7 @@ func getID() string {
func getShortID() string {
id := make([]byte, defaultShortIDBytes)
_, err := rand.Read(id)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
return fmt.Sprintf("%x", id[0:4])

@ -7,6 +7,7 @@ package main
import (
"bytes"
"encoding/xml"
"errors"
"fmt"
"log"
"net/http"
@ -28,14 +29,14 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
// Get file size
fileInfo, err := os.Stat(filePath)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
fileSize := fileInfo.Size()
// Read file
buffer, err := readFile(filePath)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
@ -54,12 +55,12 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
// Query server for disco#items
iqContent, err := sendIQ(client, iqc, jserver, "get",
"<query xmlns='http://jabber.org/protocol/disco#items'/>")
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
iqDiscoItemsXML := etree.NewDocument()
err = iqDiscoItemsXML.ReadFromBytes(iqContent.Query)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
iqDiscoItemsXMLQuery := iqDiscoItemsXML.SelectElement("query")
@ -76,11 +77,11 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
iqDiscoInfoReqXMLQuery := iqDiscoInfoReqXML.CreateElement("query")
iqDiscoInfoReqXMLQuery.CreateAttr("xmlns", nsDiscoInfo)
iqdi, err := iqDiscoInfoReqXML.WriteToString()
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
iqDiscoInfo, err := sendIQ(client, iqc, jid.Value, "get", iqdi)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
if iqDiscoInfo.Type != strResult {
@ -88,7 +89,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
}
iqDiscoInfoXML := etree.NewDocument()
err = iqDiscoInfoXML.ReadFromBytes(iqDiscoInfo.Query)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
iqDiscoInfoXMLQuery := iqDiscoInfoXML.SelectElement("query")
@ -133,7 +134,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
}
if varAttr.Value == "max-file-size" && prevFieldVal.Text() == nsHTTPUpload {
maxFileSize, err = strconv.ParseInt(curFieldVal.Text(), 10, 64)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal("error while checking server maximum http upload file size.")
}
}
@ -158,13 +159,13 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
requestReq.CreateAttr("size", fmt.Sprint(fileSize))
requestReq.CreateAttr("content-type", mimeType)
r, err := request.WriteToString()
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
// Request http upload slot
uploadSlot, err := sendIQ(client, iqc, uploadComponent, "get", r)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
if uploadSlot.Type != strResult {
@ -172,7 +173,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
}
iqHTTPUploadSlotXML := etree.NewDocument()
err = iqHTTPUploadSlotXML.ReadFromBytes(uploadSlot.Query)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
iqHTTPUploadSlotXMLSlot := iqHTTPUploadSlotXML.SelectElement("slot")
@ -192,7 +193,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
httpClient := &http.Client{}
req, err := http.NewRequest(http.MethodPut, iqHTTPUploadSlotXMLPutURL.Value,
buffer)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
req.Header.Set("Content-Type", mimeTypeEscaped.String())
@ -208,7 +209,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
}
}
resp, err := httpClient.Do(req)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
// Test for http status code "200 OK" or "201 Created"
@ -226,7 +227,7 @@ func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ,
log.Fatal("http-upload: no url attribute")
}
err = resp.Body.Close()
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("error while closing http request body:", err)
}
return iqHTTPUploadSlotXMLGetURL.Value

@ -44,7 +44,7 @@ func readMessage(messageFilePath string) (string, error) {
// Open message file.
file, err := os.Open(messageFilePath)
if err != nil {
if errors.Unwrap(err) != nil {
return output, fmt.Errorf("readMessage: %w", err)
}
scanner := bufio.NewScanner(file)
@ -58,13 +58,13 @@ func readMessage(messageFilePath string) (string, error) {
}
if err := scanner.Err(); errors.Unwrap(err) != nil {
if err != io.EOF {
if errors.Unwrap(err) != io.EOF {
return "", fmt.Errorf("readMessage: %w", err)
}
}
err = file.Close()
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("error while closing file:", err)
}
@ -167,7 +167,7 @@ func main() {
if *flagUser == "" || *flagPassword == "" {
// Read configuration from file.
config, err := parseConfig(*flagFile)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal("Error parsing ", *flagFile, ": ", err)
}
// Set connection options according to config.
@ -266,7 +266,7 @@ func main() {
// Read message from file.
if *flagMessageFile != "" {
message, err = readMessage(*flagMessageFile)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
}
@ -287,7 +287,7 @@ func main() {
}
if err := scanner.Err(); err != nil {
if err != io.EOF {
if errors.Unwrap(err) != io.EOF {
log.Fatal(err)
}
}
@ -304,7 +304,7 @@ func main() {
// Connect to server.
client, err := connect(options, *flagDirectTLS)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
@ -317,7 +317,7 @@ func main() {
re.Jid = r
if *flagOx {
re.OxKeyRing, err = oxGetPublicKeyRing(client, iqc, r)
if err != nil {
if errors.Unwrap(err) != nil {
re.OxKeyRing = nil
fmt.Println("ox: error fetching key for", r+":", err)
}
@ -328,7 +328,7 @@ func main() {
// Check that all recipient JIDs are valid.
for i, recipient := range recipients {
validatedJid, err := MarshalJID(recipient.Jid)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
recipients[i].Jid = validatedJid
@ -337,52 +337,52 @@ func main() {
switch {
case *flagOxGenPrivKeyX25519:
validatedOwnJid, err := MarshalJID(user)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
err = oxGenPrivKey(validatedOwnJid, client, iqc, *flagOxPassphrase, "x25519")
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
os.Exit(0)
case *flagOxGenPrivKeyRSA:
validatedOwnJid, err := MarshalJID(user)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
err = oxGenPrivKey(validatedOwnJid, client, iqc, *flagOxPassphrase, "rsa")
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
os.Exit(0)
case *flagOxImportPrivKey != "":
validatedOwnJid, err := MarshalJID(user)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
err = oxImportPrivKey(validatedOwnJid, *flagOxImportPrivKey,
client, iqc)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
os.Exit(0)
case *flagOxDeleteNodes:
validatedOwnJid, err := MarshalJID(user)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
err = oxDeleteNodes(validatedOwnJid, client, iqc)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
os.Exit(0)
case *flagOx:
validatedOwnJid, err := MarshalJID(user)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
oxPrivKey, err = oxGetPrivKey(validatedOwnJid, *flagOxPassphrase)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
}
@ -397,7 +397,7 @@ func main() {
message = validUTF8(*flagOOBFile)
// Check if the URI is valid.
uri, err := validURI(message)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
message = uri.String()
@ -416,7 +416,7 @@ func main() {
} else {
_, err = client.JoinMUCNoHistory(recipient.Jid, alias)
}
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
}
@ -428,7 +428,7 @@ func main() {
}
// Send raw XML
_, err = client.SendOrg(message + "\n")
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
case *flagInteractive:
@ -436,7 +436,7 @@ func main() {
reader := bufio.NewReader(os.Stdin)
for {
message, err = reader.ReadString('\n')
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal("failed to read from stdin")
}
@ -453,13 +453,13 @@ func main() {
}
oxMessage, err := oxEncrypt(client, oxPrivKey,
recipient.Jid, recipient.OxKeyRing, message)
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("Ox: couldn't encrypt to",
recipient.Jid)
continue
}
_, err = client.SendOrg(oxMessage + "\n")
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
default:
@ -467,7 +467,7 @@ func main() {
Remote: recipient.Jid,
Type: msgType, Text: message,
})
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
}
@ -480,7 +480,7 @@ func main() {
switch {
case isOxMsg(v) && *flagOx:
msg, t, err := oxDecrypt(v, client, iqc, user, oxPrivKey)
if err != nil {
if errors.Unwrap(err) != nil {
log.Println(err)
continue
}
@ -553,7 +553,7 @@ func main() {
Remote: recipient.Jid,
Type: msgType, Ooburl: message, Text: message,
})
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("Couldn't send message to",
recipient.Jid)
}
@ -563,7 +563,7 @@ func main() {
_, err = client.SendOrg("<message to='" + recipient.Jid + "' type='" +
msgType + "'><body>" + message + "</body><x xmlns='jabber:x:oob'><url>" +
message + "</url></x></message>")
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("Couldn't send message to",
recipient.Jid)
}
@ -573,12 +573,12 @@ func main() {
}
oxMessage, err := oxEncrypt(client, oxPrivKey,
recipient.Jid, recipient.OxKeyRing, message)
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("Ox: couldn't encrypt to", recipient.Jid)
continue
}
_, err = client.SendOrg(oxMessage + "\n")
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
default:
@ -586,7 +586,7 @@ func main() {
Remote: recipient.Jid,
Type: msgType, Text: message,
})
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
}

277
ox.go

@ -27,17 +27,17 @@ func oxDeleteNodes(jid string, client *xmpp.Client,
query := nodeListRequest.CreateElement("query")
query.CreateAttr("xmlns", nsDiscoItems)
nlr, err := nodeListRequest.WriteToString()
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxDeleteNodes: failed to create node list request %w", err)
}
iqReply, err := sendIQ(client, iqc, jid, "get", nlr)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxDeleteNodes: failure with node list request iq: %w", err)
}
nodeListReply := etree.NewDocument()
err = nodeListReply.ReadFromBytes(iqReply.Query)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxDeleteNodes: failed to read node list reply iq: %w", err)
}
query = nodeListReply.SelectElement("query")
if query == nil {
@ -62,11 +62,11 @@ func oxDeleteNodes(jid string, client *xmpp.Client,
del := pubsub.CreateElement("delete")
del.CreateAttr("node", node.Value)
dnr, err := deleteNodeRequest.WriteToString()
if err != nil {
if errors.Unwrap(err) != nil {
continue
}
_, err = sendIQ(client, iqc, jid, "set", dnr)
if err != nil {
if errors.Unwrap(err) != nil {
continue
}
}
@ -82,7 +82,7 @@ func oxDecrypt(m xmpp.Chat, client *xmpp.Client, iqc chan xmpp.IQ,
for _, r := range m.OtherElem {
if r.XMLName.Space == nsOx {
cryptMsgByte, err = base64.StdEncoding.DecodeString(r.InnerXML)
if err != nil {
if errors.Unwrap(err) != nil {
return strError, time.Now(), err
}
break
@ -90,22 +90,22 @@ func oxDecrypt(m xmpp.Chat, client *xmpp.Client, iqc chan xmpp.IQ,
}
oxMsg := crypto.NewPGPMessage(cryptMsgByte)
keyRing, err := crypto.NewKeyRing(oxPrivKey)
if err != nil {
if errors.Unwrap(err) != nil {
return strError, time.Now(), err
}
senderKeyRing, err := oxGetPublicKeyRing(client, iqc, sender)
if err != nil {
if errors.Unwrap(err) != nil {
return strError, time.Now(), err
}
decryptMsg, err := keyRing.Decrypt(oxMsg, senderKeyRing, crypto.GetUnixTime())
if err != nil {
if errors.Unwrap(err) != nil {
return strError, time.Now(), err
}
// Remove invalid code points.
message := validUTF8(string(decryptMsg.Data))
doc := etree.NewDocument()
err = doc.ReadFromString(message)
if err != nil {
if errors.Unwrap(err) != nil {
return strError, time.Now(), err
}
signcrypt := doc.SelectElement("signcrypt")
@ -132,7 +132,7 @@ func oxDecrypt(m xmpp.Chat, client *xmpp.Client, iqc chan xmpp.IQ,
return strError, time.Now(), errors.New("ox: no stamp attribute")
}
msgStamp, err := time.Parse("2006-01-02T15:04:05Z0700", stamp.Value)
if err != nil {
if errors.Unwrap(err) != nil {
return strError, time.Now(), err
}
payload := signcrypt.SelectElement("payload")
@ -160,20 +160,20 @@ func oxImportPrivKey(jid string, privKeyLocation string, client *xmpp.Client,
) error {
xmppURI := "xmpp:" + jid
buffer, err := readFile(privKeyLocation)
if err != nil {
if errors.Unwrap(err) != nil {
return err
}
key, err := crypto.NewKey(buffer.Bytes())
if err != nil {
if errors.Unwrap(err) != nil {
key, err = crypto.NewKeyFromArmored(buffer.String())
if err != nil {
if errors.Unwrap(err) != nil {
keyDecoded, err := base64.StdEncoding.DecodeString(buffer.String())
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxImportPrivKey: failed to import private key: %w", err)
}
key, err = crypto.NewKey(keyDecoded)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxImportPrivKey: failed to import private key: %w", err)
}
}
}
@ -182,36 +182,36 @@ func oxImportPrivKey(jid string, privKeyLocation string, client *xmpp.Client,
return errors.New("Key identity is not " + xmppURI)
}
pk, err := key.GetPublicKey()
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxImportPrivKey: failed to get public key associated to private key: %w", err)
}
pubKey, err := crypto.NewKey(pk)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxImportPrivKey: failed to get public key associated to private key: %w", err)
}
fingerprint := strings.ToUpper(pubKey.GetFingerprint())
_, err = oxRecvPublicKeys(client, iqc, jid, fingerprint)
if err != nil {
if errors.Unwrap(err) != nil {
err = oxPublishPubKey(jid, client, iqc, pubKey)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxImportPrivKey: failed to publish public key: %w", err)
}
}
location, err := oxGetPrivKeyLoc(jid)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxImportPrivKey: failed to determine private key location: %w", err)
}
keySerialized, err := key.Serialize()
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxImportPrivKey: failed to serialize private key: %w", err)
}
err = oxStoreKey(location,
base64.StdEncoding.EncodeToString(keySerialized))
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
pubKeyRing, err := oxGetPublicKeyRing(client, iqc, jid)
if err == nil {
if errors.Unwrap(err) == nil {
pubKeys := pubKeyRing.GetKeys()
for _, r := range pubKeys {
if strings.ToUpper(r.GetFingerprint()) == fingerprint {
@ -220,8 +220,8 @@ func oxImportPrivKey(jid string, privKeyLocation string, client *xmpp.Client,
}
}
err = oxPublishPubKey(jid, client, iqc, pubKey)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxImportPrivKey: failed to publish public key: %w", err)
}
return nil
}
@ -232,8 +232,8 @@ func oxPublishPubKey(jid string, client *xmpp.Client, iqc chan xmpp.IQ,
keyCreated := time.Now().UTC().Format("2006-01-02T15:04:05Z")
fingerprint := strings.ToUpper(pubKey.GetFingerprint())
keySerialized, err := pubKey.Serialize()
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxPublishPubKey: failed to serialize pubkey: %w", err)
}
pubKeyBase64 := base64.StdEncoding.EncodeToString(keySerialized)
root := etree.NewDocument()
@ -262,23 +262,23 @@ func oxPublishPubKey(jid string, client *xmpp.Client, iqc chan xmpp.IQ,
value = field.CreateElement("value")
value.CreateText("open")
xmlstring, err := root.WriteToString()
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxPublishPubKey: failed to create publish public key iq xml: %w", err)
}
iqReply, err := sendIQ(client, iqc, jid, "set", xmlstring)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxPublishPubKey: iq failure publishing public key: %w", err)
}
if iqReply.Type != strResult {
return errors.New("error while publishing public key")
}
ownPubKeyRingFromPubsub, err := oxRecvPublicKeys(client, iqc, jid, fingerprint)
if err != nil {
if errors.Unwrap(err) != nil {
return errors.New("couldn't successfully verify public key upload")
}
ownPubKeyFromPubsub := ownPubKeyRingFromPubsub.GetKeys()[0]
ownPubKeyFromPubsubSerialized, err := ownPubKeyFromPubsub.Serialize()
if err != nil {
if errors.Unwrap(err) != nil {
return errors.New("couldn't successfully verify public key upload")
}
if pubKeyBase64 != base64.StdEncoding.EncodeToString(ownPubKeyFromPubsubSerialized) {
@ -310,12 +310,12 @@ func oxPublishPubKey(jid string, client *xmpp.Client, iqc chan xmpp.IQ,
value = field.CreateElement("value")
value.CreateText("open")
xmlstring, err = root.WriteToString()
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxPublishPubKey: failed to create xml for iq to publish public key list: %w", err)
}
iqReply, err = sendIQ(client, iqc, jid, "set", xmlstring)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxPublishPubKey: iq failure publishing public key list: %w", err)
}
if iqReply.Type != strResult {
return errors.New("couldn't publish public key list")
@ -337,19 +337,19 @@ func oxGetPrivKeyLoc(jid string) (string, error) {
dataDir = homeDir + "/.local/share"
default:
homeDir, err = os.UserHomeDir()
if err != nil {
return strError, err
if errors.Unwrap(err) != nil {
return strError, fmt.Errorf("oxGetPrivKeyLoc: failed to determine user dir: %w", err)
}
if homeDir == "" {
return strError, err
return strError, errors.New("oxGetPrivKeyLoc: received empty string for home directory")
}
dataDir = homeDir + "/.local/share"
}
dataDir += "/go-sendxmpp/oxprivkeys/"
if _, err = os.Stat(dataDir); os.IsNotExist(err) {
err = os.MkdirAll(dataDir, defaultDirRights)
if err != nil {
return strError, err
if errors.Unwrap(err) != nil {
return strError, fmt.Errorf("oxGetPrivKeyLoc: could not create folder for private keys: %w", err)
}
}
dataFile := dataDir + base64.StdEncoding.EncodeToString([]byte(jid))
@ -370,19 +370,19 @@ func oxGetPubKeyLoc(fingerprint string) (string, error) {
dataDir = homeDir + "/.local/share"
default:
homeDir, err = os.UserHomeDir()
if err != nil {
return strError, err
if errors.Unwrap(err) != nil {
return strError, fmt.Errorf("oxGetPubKeyLoc: failed to determine user dir: %w", err)
}
if homeDir == "" {
return strError, err
return strError, errors.New("oxGetPubKeyLoc: received empty string for home directory")
}
dataDir = homeDir + "/.local/share"
}
dataDir += "/go-sendxmpp/oxpubkeys/"
if _, err = os.Stat(dataDir); os.IsNotExist(err) {
err = os.MkdirAll(dataDir, defaultDirRights)
if err != nil {
return strError, err
if errors.Unwrap(err) != nil {
return strError, fmt.Errorf("oxGetPubKeyLoc: could not create folder for public keys: %w", err)
}
}
dataFile := dataDir + fingerprint
@ -391,31 +391,31 @@ func oxGetPubKeyLoc(fingerprint string) (string, error) {
func oxGetPrivKey(jid string, passphrase string) (*crypto.Key, error) {
dataFile, err := oxGetPrivKeyLoc(jid)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
keyBuffer, err := readFile(dataFile)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
keyString := keyBuffer.String()
decodedPrivKey, err := base64.StdEncoding.DecodeString(keyString)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPrivKey: failed to decode private key: %w", err)
}
key, err := crypto.NewKey(decodedPrivKey)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPrivKey: failed to decode private key: %w", err)
}
if passphrase != "" {
key, err = key.Unlock([]byte(passphrase))
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal("Ox: couldn't unlock private key.")
}
}
isLocked, err := key.IsLocked()
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPrivKey: failed to check whether private key is locked: %w", err)
}
if isLocked {
log.Fatal("Ox: private key is locked.")
@ -429,8 +429,8 @@ func oxGetPrivKey(jid string, passphrase string) (*crypto.Key, error) {
func oxStoreKey(location string, key string) error {
var file *os.File
file, err := os.Create(location)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxStoreKey: failed to create key location: %w", err)
}
if runtime.GOOS != "windows" {
_ = file.Chmod(os.FileMode(defaultFileRights))
@ -438,11 +438,11 @@ func oxStoreKey(location string, key string) error {
_ = file.Chmod(os.FileMode(defaultFileRightsWin))
}
_, err = file.Write([]byte(key))
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxStoreKey: failed to write key to file: %w", err)
}
err = file.Close()
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("error while closing file:", err)
}
return nil
@ -453,39 +453,39 @@ func oxGenPrivKey(jid string, client *xmpp.Client, iqc chan xmpp.IQ,
) error {
xmppURI := "xmpp:" + jid
key, err := crypto.GenerateKey(xmppURI, "", keyType, defaultRSABits)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxGenPrivKey: failed to generate private key: %w", err)
}
if passphrase != "" {
key, err = key.Lock([]byte(passphrase))
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxGenPrivKey: failed to lock key with passphrase: %w", err)
}
}
keySerialized, err := key.Serialize()
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxGenPrivKey: failed to serialize private key: %w", err)
}
location, err := oxGetPrivKeyLoc(jid)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxGenPrivKey: failed to get private key location: %w", err)
}
err = oxStoreKey(location,
base64.StdEncoding.EncodeToString(keySerialized))
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
decodedPubKey, err := key.GetPublicKey()
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxGenPrivKey: failed to decode public key: %w", err)
}
pubKey, err := crypto.NewKey(decodedPubKey)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxGenPrivKey: failed to decode public key: %w", err)
}
err = oxPublishPubKey(jid, client, iqc, pubKey)
if err != nil {
return err
if errors.Unwrap(err) != nil {
return fmt.Errorf("oxGenPrivKey: failed to publish public key: %w", err)
}
return nil
}
@ -501,12 +501,12 @@ func oxRecvPublicKeys(client *xmpp.Client, iqc chan xmpp.IQ, recipient string,
opkrPsItems.CreateAttr("node", nsOxPubKeys+":"+fingerprint)
opkrPsItems.CreateAttr("max_items", "1")
opkrString, err := opkr.WriteToString()
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxRecvPublicKeys: failed to generate xml for public key request: %w", err)
}
oxPublicKey, err := sendIQ(client, iqc, recipient, "get", opkrString)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxRecvPublicKeys: iq error requesting public keys: %w", err)
}
if oxPublicKey.Type != strResult {
return nil, errors.New("error while requesting public key for " +
@ -514,12 +514,12 @@ func oxRecvPublicKeys(client *xmpp.Client, iqc chan xmpp.IQ, recipient string,
}
oxPublicKeyXML := etree.NewDocument()
err = oxPublicKeyXML.ReadFromBytes(oxPublicKey.Query)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxRecvPublicKeys: failed parsing iq reply to public key request: %w", err)
}
keyring, err := crypto.NewKeyRing(nil)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxRecvPublicKeys: failed reading public key: %w", err)
}
oxPublicKeyXMLPubsub := oxPublicKeyXML.SelectElement("pubsub")
if oxPublicKeyXMLPubsub == nil {
@ -543,19 +543,19 @@ func oxRecvPublicKeys(client *xmpp.Client, iqc chan xmpp.IQ, recipient string,
continue
}
decodedPubKey, err := base64.StdEncoding.DecodeString(data.Text())
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxRecvPublicKeys: failed to decode public key: %w", err)
}
key, err := crypto.NewKey(decodedPubKey)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxRecvPublicKeys: failed to decode public key: %w", err)
}
if key.IsExpired() {
return nil, errors.New("Key is expired: " + fingerprint)
}
err = keyring.AddKey(key)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxRecvPublicKeys: failed adding public key to keyring: %w", err)
}
}
return keyring, nil
@ -565,8 +565,8 @@ func oxGetPublicKeyRing(client *xmpp.Client, iqc chan xmpp.IQ,
recipient string,
) (*crypto.KeyRing, error) {
publicKeyRing, err := crypto.NewKeyRing(nil)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to create a new keyring: %w", err)
}
oxPubKeyListReq := etree.NewDocument()
@ -577,11 +577,11 @@ func oxGetPublicKeyRing(client *xmpp.Client, iqc chan xmpp.IQ,
oxPubKeyListReqPsItems.CreateAttr("node", nsOxPubKeys)
oxPubKeyListReqPsItems.CreateAttr("max_items", "1")
opkl, err := oxPubKeyListReq.WriteToString()
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
oxPublicKeyList, err := sendIQ(client, iqc, recipient, "get", opkl)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
if oxPublicKeyList.Type != strResult {
@ -590,14 +590,14 @@ func oxGetPublicKeyRing(client *xmpp.Client, iqc chan xmpp.IQ,
}
oxPubKeyListXML := etree.NewDocument()
err = oxPubKeyListXML.ReadFromBytes(oxPublicKeyList.Query)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to parse answer to public key list request: %w", err)
}
pubKeyRingID := "none"
newestKey, err := time.Parse(time.RFC3339, "1900-01-01T00:00:00Z")
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to set time for newest key to 1900-01-01: %w", err)
}
oxPubKeyListXMLPubsub := oxPubKeyListXML.SelectElement("pubsub")
@ -627,8 +627,8 @@ func oxGetPublicKeyRing(client *xmpp.Client, iqc chan xmpp.IQ,
continue
}
keyDate, err := time.Parse(time.RFC3339, date.Value)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to parse time stamp for key: %w", err)
}
if keyDate.After(newestKey) {
newestKey = keyDate
@ -640,18 +640,18 @@ func oxGetPublicKeyRing(client *xmpp.Client, iqc chan xmpp.IQ,
}
pubKeyRingLocation, err := oxGetPubKeyLoc(pubKeyRingID)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to get public key ring location: %w", err)
}
pubKeyReadXML := etree.NewDocument()
err = pubKeyReadXML.ReadFromFile(pubKeyRingLocation)
if err == nil {
if errors.Unwrap(err) == nil {
date := pubKeyReadXML.SelectElement("date")
if date != nil {
savedKeysDate, err := time.Parse(time.RFC3339, date.Text())
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to parse time for saved key: %w", err)
}
if !savedKeysDate.Before(newestKey) {
pubKeys := pubKeyReadXML.SelectElements("pubkey")
@ -660,17 +660,17 @@ func oxGetPublicKeyRing(client *xmpp.Client, iqc chan xmpp.IQ,
}
for _, r := range pubKeys {
keyByte, err := base64.StdEncoding.DecodeString(r.Text())
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to decode saved key: %w", err)
}
key, err := crypto.NewKey(keyByte)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to parse saved key: %w", err)
}
if !key.IsExpired() {
err = publicKeyRing.AddKey(key)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to add key to public keyring: %w", err)
}
}
}
@ -681,26 +681,23 @@ func oxGetPublicKeyRing(client *xmpp.Client, iqc chan xmpp.IQ,
}
}
pubKeyRing, err := oxRecvPublicKeys(client, iqc, recipient, pubKeyRingID)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to get public keyring: %w", err)
}
pubKeySaveXML := etree.NewDocument()
date := pubKeySaveXML.CreateElement("date")
date.SetText(newestKey.Format(time.RFC3339))
for _, key := range pubKeyRing.GetKeys() {
keySerialized, err := key.Serialize()
if err != nil {
return nil, err
}
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to serialize key: %w", err)
}
saveKey := pubKeySaveXML.CreateElement("pubkey")
saveKey.SetText(base64.StdEncoding.EncodeToString(keySerialized))
}
err = pubKeySaveXML.WriteToFile(pubKeyRingLocation)
if err != nil {
return nil, err
if errors.Unwrap(err) != nil {
return nil, fmt.Errorf("oxGetPublicKeyRing: failed to create xml for saving public key: %w", err)
}
return pubKeyRing, nil
}
@ -712,13 +709,13 @@ func oxEncrypt(client *xmpp.Client, oxPrivKey *crypto.Key,
return "", nil
}
privKeyRing, err := crypto.NewKeyRing(oxPrivKey)
if err != nil {
return strError, err
if errors.Unwrap(err) != nil {
return strError, fmt.Errorf("oxEncrypt: failed to create private keyring: %w", err)
}
ownJid := strings.Split(client.JID(), "/")[0]
if recipient != ownJid {
opk, err := oxPrivKey.GetPublicKey()
if err == nil {
if errors.Unwrap(err) == nil {
ownKey, _ := crypto.NewKey(opk)
_ = keyRing.AddKey(ownKey)
}
@ -738,13 +735,13 @@ func oxEncrypt(client *xmpp.Client, oxPrivKey *crypto.Key,
oxCryptMessageScPayloadBody.CreateAttr("xmlns", nsJabberClient)
oxCryptMessageScPayloadBody.CreateText(message)
ocm, err := oxCryptMessage.WriteToString()
if err != nil {
return strError, err
if errors.Unwrap(err) != nil {
return strError, fmt.Errorf("oxEncrypt: failed to create xml for ox crypt message: %w", err)
}
plainMessage := crypto.NewPlainMessage([]byte(ocm))
pgpMessage, err := keyRing.Encrypt(plainMessage, privKeyRing)
if err != nil {
return strError, err
if errors.Unwrap(err) != nil {
return strError, fmt.Errorf("oxEncrypt: failed to create pgp message: %w", err)
}
om := etree.NewDocument()
om.WriteSettings.AttrSingleQuote = true
@ -762,8 +759,8 @@ func oxEncrypt(client *xmpp.Client, oxPrivKey *crypto.Key,
omMessageBody := omMessage.CreateElement("body")
omMessageBody.CreateText(oxAltBody)
oms, err := om.WriteToString()
if err != nil {
return strError, err
if errors.Unwrap(err) != nil {
return strError, fmt.Errorf("oxEncrypt: failed to create xml for ox message: %w", err)
}
return oms, nil

@ -20,8 +20,8 @@ import (
func findConfig() (string, error) {
// Get the current user.
curUser, err := user.Current()
if err != nil {
return "", err
if errors.Unwrap(err) != nil {
return "", fmt.Errorf("findConfig: failed to get current user: %w", err)
}
// Get home directory.
home := curUser.HomeDir
@ -41,7 +41,7 @@ func findConfig() (string, error) {
for _, r := range configFiles {
// Check that the config file is existing.
_, err := os.Stat(r)
if err == nil {
if errors.Unwrap(err) == nil {
return r, nil
}
}
@ -62,7 +62,7 @@ func parseConfig(configPath string) (configuration, error) {
// Get systems user config path.
if configPath == "" {
configPath, err = findConfig()
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
}
@ -70,7 +70,7 @@ func parseConfig(configPath string) (configuration, error) {
// Only check file permissions if we are not running on windows.
if runtime.GOOS != "windows" {
info, err := os.Stat(configPath)
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
// Check for file permissions. Must be 600, 640, 440 or 400.
@ -84,8 +84,8 @@ func parseConfig(configPath string) (configuration, error) {
// Open config file.
file, err := os.Open(configPath)
if err != nil {
return output, err
if errors.Unwrap(err) != nil {
return output, fmt.Errorf("parseConfig: failed to open config file: %w", err)
}
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
@ -111,7 +111,7 @@ func parseConfig(configPath string) (configuration, error) {
shell = "/bin/sh"
}
out, err := exec.Command(shell, "-c", row[1]).Output()
if err != nil {
if errors.Unwrap(err) != nil {
log.Fatal(err)
}
output.password = string(out)
@ -144,19 +144,19 @@ func parseConfig(configPath string) (configuration, error) {
}
}
err = file.Close()
if err != nil {
if errors.Unwrap(err) != nil {
fmt.Println("error closing file:", err)
}
// Check if the username is a valid JID
output.username, err = MarshalJID(output.username)
if err != nil {
if errors.Unwrap(err) != nil {
// Check whether only the local part was used by appending an @ and the
// server part.
output.username = output.username + "@" + output.jserver
// Check if the username is a valid JID now
output.username, err = MarshalJID(output.username)
if err != nil {
if errors.Unwrap(err) != nil {
return output, errors.New("invalid username/JID: " + output.username)
}
}

@ -5,6 +5,8 @@
package main
import (
"errors"
"fmt"
"log"
"github.com/beevik/etree" // BSD-2-clause
@ -20,8 +22,8 @@ func sendIQ(client *xmpp.Client, iqc chan xmpp.IQ, target string,
go getIQ(id, c, iqc)
_, err := client.RawInformation(client.JID(), target, id,
iQtype, content+"\n")
if err != nil {
return iq, err
if errors.Unwrap(err) != nil {
return iq, fmt.Errorf("sendIQ: failed to send iq: %w", err)
}
iq = <-c
return iq, nil
@ -42,7 +44,7 @@ func getIQ(id string, c chan xmpp.IQ,
func rcvStanzas(client *xmpp.Client, iqc chan xmpp.IQ, msgc chan xmpp.Chat) {
for {
received, err := client.Recv()
if err != nil {
if errors.Unwrap(err) != nil {
log.Println(err)
}
switch v := received.(type) {
@ -54,7 +56,7 @@ func rcvStanzas(client *xmpp.Client, iqc chan xmpp.IQ, msgc chan xmpp.Chat) {
var xmlns *etree.Attr
iq := etree.NewDocument()
err = iq.ReadFromBytes(v.Query)
if err != nil {
if errors.Unwrap(err) != nil {
log.Println("Couldn't parse IQ:",
string(v.Query), err)
}
@ -80,9 +82,9 @@ func rcvStanzas(client *xmpp.Client, iqc chan xmpp.IQ, msgc chan xmpp.Chat) {
feat := replyQuery.CreateElement("feature")
feat.CreateAttr("var", nsDiscoInfo)
xmlString, err := root.WriteToString()
if err == nil {
if errors.Unwrap(err) == nil {
_, err = client.SendOrg(xmlString)
if err != nil {
if errors.Unwrap(err) != nil {
log.Println(err)
}
}
@ -99,9 +101,9 @@ func rcvStanzas(client *xmpp.Client, iqc chan xmpp.IQ, msgc chan xmpp.Chat) {
su := errorReply.CreateElement("service-unavailable")
su.CreateAttr("xmlns", nsXMPPStanzas)
xmlString, err := root.WriteToString()
if err == nil {
if errors.Unwrap(err) == nil {
_, err = client.SendOrg(xmlString)
if err != nil {
if errors.Unwrap(err) != nil {
log.Println(err)
}
}
@ -119,9 +121,9 @@ func rcvStanzas(client *xmpp.Client, iqc chan xmpp.IQ, msgc chan xmpp.Chat) {
su := errorReply.CreateElement("service-unavailable")
su.CreateAttr("xmlns", nsXMPPStanzas)
xmlString, err := root.WriteToString()
if err == nil {
if errors.Unwrap(err) == nil {
_, err = client.SendOrg(xmlString)
if err != nil {
if errors.Unwrap(err) != nil {
log.Println(err)
}
}

Loading…
Cancel
Save