From 5303a0901c5a4c0eae797308a12b0a17059de852 Mon Sep 17 00:00:00 2001 From: Martin Dosch Date: Mon, 8 Jan 2024 21:11:56 +0100 Subject: [PATCH] Add support for XEP-0474. --- CHANGELOG.md | 4 +++ README.md | 3 ++ handlemechanisminfo.go | 72 ------------------------------------------ main.go | 14 ++------ man/go-sendxmpp.1 | 9 +++--- man/go-sendxmpp.1.html | 27 +++++++--------- man/go-sendxmpp.1.ronn | 25 +++++++-------- 7 files changed, 36 insertions(+), 118 deletions(-) delete mode 100644 handlemechanisminfo.go diff --git a/CHANGELOG.md b/CHANGELOG.md index f260e62..44913d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # Changelog ## Unreleased +### Added +- Add no parameter `--scram-mech-pinning`. + ### Changed - Refuse to upload a file if upload slot doesn't provide https. +- Use XEP-0474 instead of SCRAM mechanism pinning to prevent downgrade attacks (requires go-xmpp commit TODO). ## [v0.7.0] 2023-11-11 ### Added diff --git a/README.md b/README.md index 7f34655..5bf38bf 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ the account details via command line options: ```plain Usage: go-sendxmpp [-cdilnt] [-a value] [-f value] [--headline] [--help] [-h value] [-j value] [-m value] [--muc-password value] [--oob-file value] [--ox] [--ox-delete-nodes] [--ox-genprivkey-rsa] [--ox-genprivkey-x25519] [--ox-import-privkey value] [--ox-passphrase value] [-p value] [--raw] [--timeout value] [--tls-version value] [-u value] [--version] [recipients…] +Usage: go-sendxmpp [-cdilnt] [-a value] [-f value] [--headline] [--help] [-h value] [-j value] [-m value] [--muc-password value] [--oob-file value] [--ox] [--ox-delete-nodes] [--ox-genprivkey-rsa] [--ox-genprivkey-x25519] [--ox-import-privkey value] [--ox-passphrase value] [-p value] [--raw] [--scram-mech-pinning value] [--timeout value] [--tls-version value] [-u value] [--version] [recipients…] -a, --alias=value Set alias/nicknamefor chatrooms. -c, --chatroom Send message to a chatroom. -d, --debug Show debugging info. @@ -114,6 +115,8 @@ Usage: go-sendxmpp [-cdilnt] [-a value] [-f value] [--headline] [--help] [-h val -p, --password=value Password for XMPP account. --raw Send raw XML. + --scram-mech-pinning=value + Enforce the use of a certain SCRAM authentication mechanism. --timeout=value Connection timeout in seconds. [10] -t, --tls Use direct TLS. diff --git a/handlemechanisminfo.go b/handlemechanisminfo.go deleted file mode 100644 index 23c5cb3..0000000 --- a/handlemechanisminfo.go +++ /dev/null @@ -1,72 +0,0 @@ -// 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/main.go b/main.go index df0cdff..d6e7c18 100644 --- a/main.go +++ b/main.go @@ -122,6 +122,7 @@ func main() { flagOxDeleteNodes := getopt.BoolLong("ox-delete-nodes", 0, "Delete existing OpenPGP nodes on the server.") flagOOBFile := getopt.StringLong("oob-file", 0, "", "URL to send a file as out of band data.") flagHeadline := getopt.BoolLong("headline", 0, "Send message as type headline.") + flagSCRAMPinning := getopt.StringLong("scram-mech-pinning", 0, "", "Enforce the use of a certain SCRAM authentication mechanism.") // Parse command line flags. getopt.Parse() @@ -229,9 +230,6 @@ func main() { os.Exit(0) } - // Check whether an authentication mechanism is pinned. - authMech, _ := parsePinFile(user) - // Set XMPP connection options. options := xmpp.Options{ Host: server, @@ -249,7 +247,7 @@ func main() { StartTLS: !*flagDirectTLS, Debug: *flagDebug, TLSConfig: &tlsConfig, - Mechanism: authMech, + Mechanism: *flagSCRAMPinning, } // Read message from file. @@ -296,14 +294,6 @@ func main() { if err != nil { log.Fatal(err) } - // If no authentication 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 authentication mechanism pin file:", err) - } - } iqc := make(chan xmpp.IQ, defaultBufferSize) msgc := make(chan xmpp.Chat, defaultBufferSize) diff --git a/man/go-sendxmpp.1 b/man/go-sendxmpp.1 index 3bfdde4..dc50f95 100644 --- a/man/go-sendxmpp.1 +++ b/man/go-sendxmpp.1 @@ -1,10 +1,10 @@ .\" generated with Ronn-NG/v0.9.1 .\" http://github.com/apjanke/ronn-ng/tree/0.9.1 -.TH "GO\-SENDXMPP" "1" "November 2023" "" +.TH "GO\-SENDXMPP" "1" "January 2024" "" .SH "NAME" \fBgo\-sendxmpp\fR \- A tool to send messages to an XMPP contact or MUC\. .SH "SYNOPSIS" -\fBgo\-sendxmpp\fR [\-cdilnt] [\-a value] [\-f value] [\-\-headline] [\-\-help] [\-h value] [\-j value] [\-m value] [\-\-muc\-password value] [\-\-oob\-file value] [\-\-ox] [\-\-ox\-delete\-nodes] [\-\-ox\-genprivkey\-rsa] [\-\-ox\-genprivkey\-x25519] [\-\-ox\-import\-privkey value] [\-\-ox\-passphrase value] [\-p value] [\-\-raw] [\-\-timeout value] [\-\-tls\-version value] [\-u value] [\-\-version] [recipients…] +\fBgo\-sendxmpp [\-cdilnt] [\-a value] [\-f value] [\-\-headline] [\-\-help] [\-h value] [\-j value] [\-m value] [\-\-muc\-password value] [\-\-oob\-file value] [\-\-ox] [\-\-ox\-delete\-nodes] [\-\-ox\-genprivkey\-rsa] [\-\-ox\-genprivkey\-x25519] [\-\-ox\-import\-privkey value] [\-\-ox\-passphrase value] [\-p value] [\-\-raw] [\-\-scram\-mech\-pinning value] [\-\-timeout value] [\-\-tls\-version value] [\-u value] [\-\-version] [recipients…]\fR .SH "DESCRIPTION" A tool to send messages to an XMPP contact or MUC inspired by (but not as powerful as) \fBsendxmpp\fR\. .br @@ -86,6 +86,9 @@ Password for XMPP account\. \fB\-\-raw\fR Send raw XML\. To send raw XML to a contact as normal chat message no contact must be specified\. To send raw XML to a MUC you have to specify the MUC via \fB\-c\fR and go\-sendxmpp will join the MUC\. .TP +\fB\-\-scram\-mech\-pinning=[]\fR +Enforce the use of a certain SCRAM authentication mechanism\. Currently go\-sendxmpp supports \fISCRAM\-SHA\-1\fR, \fISCRAM\-SHA\-1\-PLUS\fR, \fISCRAM\-SHA\-256\fR, \fISCRAM\-SHA\-256\-PLUS\fR, \fISCRAM\-SHA\-512\fR and \fISCRAM\-SHA\-512\-PLUS\fR\. You should know what you are doing when using this setting and make sure the chosen mechanism is supported by the server\. If not set go\-sendxmpp will use XEP\-0474 to prevent downgrade attacks (needs server support)\. +.TP \fB\-\-timeout=\fR[\fIvalue\fR] Connection timeout in seconds\. (Default: 10) .TP @@ -97,8 +100,6 @@ Username for XMPP account (JID)\. .TP \fB\-\-version\fR Show version information\. -.SH "SCRAM" -Go\-sendxmpp supports \fBSalted Challenge Response Authentication Mechanism\fR (SCRAM)\. If go\-sendxmpp successfully connects using SCRAM it will create a file \fB~/\.local/share/go\-sendxmpp/[your_jid]/authmechanism\fR containing the name of the used mechanism\. It will read this file and use the same mechanism for future connections and fail if it is not available\. This is to protect against downgrades by a \fBMachine In The Middle\fR (MITM)\. If you want to upgrade to another mechanism (e\.g\. if SCRAM\-SHA\-1\-PLUS gets available for your server that previously only supported SCRAM\-SHA\-1) you have to manually edit the file\. It is not recommended to delete the file and let go\-sendxmpp recreate it as this would make it vulnerable to downgrade attacks for the next connection attempt\. .SH "SHELL COMPLETIONS" .SS "ZSH" There are no shell completions yet (contributions welcome) but for zsh it is possible to automatically create completions from \fB\-\-help\fR which might work good enough\. diff --git a/man/go-sendxmpp.1.html b/man/go-sendxmpp.1.html index 2779c81..56edb31 100644 --- a/man/go-sendxmpp.1.html +++ b/man/go-sendxmpp.1.html @@ -57,7 +57,6 @@ SYNOPSIS DESCRIPTION OPTIONS - SCRAM SHELL COMPLETIONS CHAT AUTHOR @@ -80,7 +79,10 @@

SYNOPSIS

-

go-sendxmpp [-cdilnt] [-a value] [-f value] [--headline] [--help] [-h value] [-j value] [-m value] [--muc-password value] [--oob-file value] [--ox] [--ox-delete-nodes] [--ox-genprivkey-rsa] [--ox-genprivkey-x25519] [--ox-import-privkey value] [--ox-passphrase value] [-p value] [--raw] [--timeout value] [--tls-version value] [-u value] [--version] [recipients…]

+

go-sendxmpp [-cdilnt] [-a value] [-f value] [--headline] [--help] [-h value] [-j value] [-m value] [--muc-password value] +[--oob-file value] [--ox] [--ox-delete-nodes] [--ox-genprivkey-rsa] [--ox-genprivkey-x25519] [--ox-import-privkey value] +[--ox-passphrase value] [-p value] [--raw] [--scram-mech-pinning value] [--timeout value] [--tls-version value] [-u value] +[--version] [recipients…]

DESCRIPTION

@@ -182,6 +184,12 @@ it might be imported using --ox-import-privkey.
--raw
Send raw XML. To send raw XML to a contact as normal chat message no contact must be specified. To send raw XML to a MUC you have to specify the MUC via -c and go-sendxmpp will join the MUC.
+
--scram-mech-pinning=[<value>]
+
Enforce the use of a certain SCRAM authentication mechanism. Currently go-sendxmpp supports +SCRAM-SHA-1, SCRAM-SHA-1-PLUS, SCRAM-SHA-256, SCRAM-SHA-256-PLUS, SCRAM-SHA-512 +and SCRAM-SHA-512-PLUS. You should know what you are doing when using this setting and +make sure the chosen mechanism is supported by the server. If not set go-sendxmpp will use XEP-0474 +to prevent downgrade attacks (needs server support).
--timeout=[value]
Connection timeout in seconds. (Default: 10)
@@ -196,19 +204,6 @@ To send raw XML to a MUC you have to specify the MUC via -c and go-
Show version information.
-

SCRAM

- -

Go-sendxmpp supports Salted Challenge Response Authentication Mechanism (SCRAM). -If go-sendxmpp successfully connects using SCRAM it will create a file -~/.local/share/go-sendxmpp/[your_jid]/authmechanism containing the name of the -used mechanism. It will read this file and use the same mechanism for future connections -and fail if it is not available. This is to protect against downgrades by a -Machine In The Middle (MITM). If you want to upgrade to another mechanism (e.g. -if SCRAM-SHA-1-PLUS gets available for your server that previously only supported -SCRAM-SHA-1) you have to manually edit the file. It is not recommended to delete -the file and let go-sendxmpp recreate it as this would make it vulnerable to downgrade -attacks for the next connection attempt.

-

SHELL COMPLETIONS

ZSH

@@ -246,7 +241,7 @@ License: BSD 2-clause License

  1. -
  2. November 2023
  3. +
  4. January 2024
  5. go-sendxmpp(1)
diff --git a/man/go-sendxmpp.1.ronn b/man/go-sendxmpp.1.ronn index b052759..02470a6 100644 --- a/man/go-sendxmpp.1.ronn +++ b/man/go-sendxmpp.1.ronn @@ -3,7 +3,10 @@ go-sendxmpp(1) -- A tool to send messages to an XMPP contact or MUC. ## SYNOPSIS -`go-sendxmpp` [-cdilnt] [-a value] [-f value] [--headline] [--help] [-h value] [-j value] [-m value] [--muc-password value] [--oob-file value] [--ox] [--ox-delete-nodes] [--ox-genprivkey-rsa] [--ox-genprivkey-x25519] [--ox-import-privkey value] [--ox-passphrase value] [-p value] [--raw] [--timeout value] [--tls-version value] [-u value] [--version] [recipients…] +`go-sendxmpp [-cdilnt] [-a value] [-f value] [--headline] [--help] [-h value] [-j value] [-m value] [--muc-password value] +[--oob-file value] [--ox] [--ox-delete-nodes] [--ox-genprivkey-rsa] [--ox-genprivkey-x25519] [--ox-import-privkey value] +[--ox-passphrase value] [-p value] [--raw] [--scram-mech-pinning value] [--timeout value] [--tls-version value] [-u value] +[--version] [recipients…]` ## DESCRIPTION @@ -107,6 +110,13 @@ Password for XMPP account. Send raw XML. To send raw XML to a contact as normal chat message no contact must be specified. To send raw XML to a MUC you have to specify the MUC via `-c` and go-sendxmpp will join the MUC. +* `--scram-mech-pinning=[]`: +Enforce the use of a certain SCRAM authentication mechanism. Currently go-sendxmpp supports +*SCRAM-SHA-1*, *SCRAM-SHA-1-PLUS*, *SCRAM-SHA-256*, *SCRAM-SHA-256-PLUS*, *SCRAM-SHA-512* +and *SCRAM-SHA-512-PLUS*. You should know what you are doing when using this setting and +make sure the chosen mechanism is supported by the server. If not set go-sendxmpp will use XEP-0474 +to prevent downgrade attacks (needs server support). + * `--timeout=`[]: Connection timeout in seconds. (Default: 10) @@ -119,19 +129,6 @@ Username for XMPP account (JID). * `--version`: Show version information. -## SCRAM - -Go-sendxmpp supports **Salted Challenge Response Authentication Mechanism** (SCRAM). -If go-sendxmpp successfully connects using SCRAM it will create a file -`~/.local/share/go-sendxmpp/[your_jid]/authmechanism` containing the name of the -used mechanism. It will read this file and use the same mechanism for future connections -and fail if it is not available. This is to protect against downgrades by a -**Machine In The Middle** (MITM). If you want to upgrade to another mechanism (e.g. -if SCRAM-SHA-1-PLUS gets available for your server that previously only supported -SCRAM-SHA-1) you have to manually edit the file. It is not recommended to delete -the file and let go-sendxmpp recreate it as this would make it vulnerable to downgrade -attacks for the next connection attempt. - ## SHELL COMPLETIONS ### ZSH