diff --git a/CHANGELOG.md b/CHANGELOG.md index fa6cd4f..088dd9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## Unreleased ## Added - Reply to XEP-0092 software version requests. +- Add support for PLUS variants of SCRAM authentification mechanisms (requires go-xmpp fork). +- Add pinning of last used authentification mechanism if a SCRAM mechanism was used. ## [v0.6.2] 2023-09-29 ### Changed diff --git a/connect.go b/connect.go index 80bd184..65eec9d 100644 --- a/connect.go +++ b/connect.go @@ -9,7 +9,7 @@ import ( "net" "strings" - "github.com/mdosch/go-xmpp" // BSD-3-Clause + "github.com/mdosch/go-xmpp" // BSD-3-Clause "salsa.debian.org/mdosch/xmppsrv" // BSD-2-Clause ) diff --git a/go.mod b/go.mod index fddc852..9c7b4f1 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/ProtonMail/gopenpgp/v2 v2.7.4 github.com/beevik/etree v1.2.0 github.com/gabriel-vasile/mimetype v1.4.3 - github.com/mdosch/go-xmpp v0.0.2-0.20231102200754-c72f24ac2925 + github.com/mdosch/go-xmpp v0.0.2-0.20231102202634-0867a2d90d2f github.com/pborman/getopt/v2 v2.1.0 salsa.debian.org/mdosch/xmppsrv v0.2.5 ) diff --git a/go.sum b/go.sum index c309186..38c86b3 100644 --- a/go.sum +++ b/go.sum @@ -16,12 +16,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/mdosch/go-xmpp v0.0.2-0.20231102200145-ed497e83c73f h1:f6RpAnO9HMoFwjDOe6YMxZBdEH8KHwnWAwNWy71TnY4= -github.com/mdosch/go-xmpp v0.0.2-0.20231102200145-ed497e83c73f/go.mod h1:WfXW1cCXjSvg8Le5XQc6r+ONLXjHoKyUgTucb4jfaAU= -github.com/mdosch/go-xmpp v0.0.2-0.20231102200702-306dda69d03f h1:+rHm93PVQOcm8uIuzGt83XsBoiaPXFzApEsWZluCl4Q= -github.com/mdosch/go-xmpp v0.0.2-0.20231102200702-306dda69d03f/go.mod h1:WfXW1cCXjSvg8Le5XQc6r+ONLXjHoKyUgTucb4jfaAU= -github.com/mdosch/go-xmpp v0.0.2-0.20231102200754-c72f24ac2925 h1:ndBO84uPCo0+wtQRq/LnRfW0jZFZX5E3ZUnUgvl5LT8= -github.com/mdosch/go-xmpp v0.0.2-0.20231102200754-c72f24ac2925/go.mod h1:WfXW1cCXjSvg8Le5XQc6r+ONLXjHoKyUgTucb4jfaAU= +github.com/mdosch/go-xmpp v0.0.2-0.20231102202634-0867a2d90d2f h1:03GBYbzfYQv+rnxk5mhLkj0XKbJZfozuLJloGWICO/k= +github.com/mdosch/go-xmpp v0.0.2-0.20231102202634-0867a2d90d2f/go.mod h1:WfXW1cCXjSvg8Le5XQc6r+ONLXjHoKyUgTucb4jfaAU= github.com/pborman/getopt/v2 v2.1.0 h1:eNfR+r+dWLdWmV8g5OlpyrTYHkhVNxHBdN2cCrJmOEA= github.com/pborman/getopt/v2 v2.1.0/go.mod h1:4NtW75ny4eBw9fO1bhtNdYTlZKYX5/tBLtsOpwKIKd0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/handlemechanisminfo.go b/handlemechanisminfo.go new file mode 100644 index 0000000..23c5cb3 --- /dev/null +++ b/handlemechanisminfo.go @@ -0,0 +1,72 @@ +// Copyright Martin Dosch. +// Use of this source code is governed by the BSD-2-clause +// license that can be found in the LICENSE file. + +package main + +import ( + "errors" + "fmt" + "os" + "os/user" + "strings" +) + +func findPinFilePath(username string) (string, error) { + osDataDir := os.Getenv("$XDG_DATA_HOME") + if osDataDir == "" { + // Get the current user. + curUser, err := user.Current() + if err != nil { + return strError, fmt.Errorf("findConfig: failed to get current user: %w", err) + } + // Get home directory. + home := curUser.HomeDir + if home == "" { + return strError, errors.New("no home directory found") + } + osDataDir = home + "/.local/share/" + } + authPinFilePath := osDataDir + "/go-sendxmpp/" + username + "/" + + return authPinFilePath, nil +} + +// Opens the auth mechanism pin file and returns the value. +func parsePinFile(user string) (string, error) { + // Find auth pin file + authPinFile, err := findPinFilePath(user) + if err != nil { + return "", err + } + + // Read file. + m, err := os.ReadFile(authPinFile + "authmechanism") + if err != nil { + return "", err + } + // Strip trailing newline. + mechanism := strings.TrimSuffix(string(m), "\n") + + return mechanism, nil +} + +// Writes the used mechanism to the auth pin file. +func writePinFile(mechanism string, user string) error { + // Find auth pin file + authPinFilePath, err := findPinFilePath(user) + if err != nil { + return err + } + if _, err = os.Stat(authPinFilePath); os.IsNotExist(err) { + err = os.MkdirAll(authPinFilePath, defaultDirRights) + if err != nil { + return fmt.Errorf("writePinFile: could not create folder for auth pin file: %w", err) + } + } + err = os.WriteFile(authPinFilePath+"authmechanism", []byte(mechanism+"\n"), 0o400) + if err != nil { + return err + } + return nil +} diff --git a/httpupload.go b/httpupload.go index a471bd4..eb46634 100644 --- a/httpupload.go +++ b/httpupload.go @@ -17,7 +17,7 @@ import ( "github.com/beevik/etree" // BSD-2-clause "github.com/gabriel-vasile/mimetype" // MIT License - "github.com/mdosch/go-xmpp" // BSD-3-Clause + "github.com/mdosch/go-xmpp" // BSD-3-Clause ) func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, filePath string) string { diff --git a/main.go b/main.go index c3619b9..67f1ef0 100644 --- a/main.go +++ b/main.go @@ -18,7 +18,7 @@ import ( "time" "github.com/ProtonMail/gopenpgp/v2/crypto" // MIT License - "github.com/mdosch/go-xmpp" // BSD-3-Clause + "github.com/mdosch/go-xmpp" // BSD-3-Clause "github.com/pborman/getopt/v2" // BSD-3-Clause ) @@ -229,6 +229,12 @@ func main() { os.Exit(0) } + // Check whether an authentification mechanism is pinned. + authMech, err := parsePinFile(user) + if err != nil { + log.Println("couldn't open authentification pin file:", err) + } + // Set XMPP connection options. options := xmpp.Options{ Host: server, @@ -246,6 +252,7 @@ func main() { StartTLS: !*flagDirectTLS, Debug: *flagDebug, TLSConfig: &tlsConfig, + Mechanism: authMech, } // Read message from file. @@ -292,6 +299,14 @@ func main() { if err != nil { log.Fatal(err) } + // If no authentification mechanism is pinned and a SCRAM mechanism is + // used, write the used mechanism to the pin file. + if authMech == "" && strings.HasPrefix(client.Mechanism, "SCRAM") { + err = writePinFile(client.Mechanism, user) + if err != nil { + log.Println("could not write authentification mechanism pin file:", err) + } + } iqc := make(chan xmpp.IQ, defaultBufferSize) msgc := make(chan xmpp.Chat, defaultBufferSize) diff --git a/ox.go b/ox.go index 375db4d..170d161 100644 --- a/ox.go +++ b/ox.go @@ -16,7 +16,7 @@ import ( "github.com/ProtonMail/gopenpgp/v2/crypto" // MIT License "github.com/beevik/etree" // BSD-2-clause - "github.com/mdosch/go-xmpp" // BSD-3-Clause + "github.com/mdosch/go-xmpp" // BSD-3-Clause ) func oxDeleteNodes(jid string, client *xmpp.Client, iqc chan xmpp.IQ) error { diff --git a/stanzahandling.go b/stanzahandling.go index 2ef3667..8f60e63 100644 --- a/stanzahandling.go +++ b/stanzahandling.go @@ -10,7 +10,7 @@ import ( "log" "runtime" - "github.com/beevik/etree" // BSD-2-clause + "github.com/beevik/etree" // BSD-2-clause "github.com/mdosch/go-xmpp" // BSD-3-Clause )