Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package go-sendxmpp for openSUSE:Factory 
checked in at 2024-11-26 20:56:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/go-sendxmpp (Old)
 and      /work/SRC/openSUSE:Factory/.go-sendxmpp.new.28523 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "go-sendxmpp"

Tue Nov 26 20:56:05 2024 rev:20 rq:1226437 version:0.12.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/go-sendxmpp/go-sendxmpp.changes  2024-10-27 
11:26:57.386586362 +0100
+++ /work/SRC/openSUSE:Factory/.go-sendxmpp.new.28523/go-sendxmpp.changes       
2024-11-26 20:56:35.192147701 +0100
@@ -1,0 +2,22 @@
+Tue Nov 26 07:44:14 UTC 2024 - Michael Vetter <mvet...@suse.com>
+
+- Update to 0.12.1:
+  Changed:
+  * Print error instead of quitting if a message of type error is received.
+  * Allow upload of multiple files.
+  Added:
+  * Add flag --suppress-root-warning to suppress the warning when go-sendxmpp 
is used by the root user.
+
+-------------------------------------------------------------------
+Tue Nov 26 07:43:44 UTC 2024 - Michael Vetter <mvet...@suse.com>
+
+- Update to 0.12.0:
+  Added:
+  * Add possibility to look up direct TLS connection endpoint via hostmeta2 
(requires xmppsrv >= 0.3.3).
+  * Add flag --allow-plain to allow PLAIN authentication (requires go-xmpp >= 
0.2.5).
+  Changed:
+  * Disable PLAIN authentication per default.
+  * Disable PLAIN authentication after first use of a SCRAM auth mechanism 
(overrides --allow-plain) (requires
+    go-xmpp >= 0.2.5).
+
+-------------------------------------------------------------------

Old:
----
  go-sendxmpp-0.11.4.tar.gz

New:
----
  go-sendxmpp-0.12.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ go-sendxmpp.spec ++++++
--- /var/tmp/diff_new_pack.PhhjDq/_old  2024-11-26 20:56:38.620290109 +0100
+++ /var/tmp/diff_new_pack.PhhjDq/_new  2024-11-26 20:56:38.636290774 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           go-sendxmpp
-Version:        0.11.4
+Version:        0.12.1
 Release:        0
 Summary:        A little tool to send messages to an XMPP contact or MUC
 License:        BSD-2-Clause

++++++ _service ++++++
--- /var/tmp/diff_new_pack.PhhjDq/_old  2024-11-26 20:56:38.916302406 +0100
+++ /var/tmp/diff_new_pack.PhhjDq/_new  2024-11-26 20:56:38.964304400 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://salsa.debian.org/mdosch/go-sendxmpp.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v0.11.4</param>
+    <param name="revision">v0.12.1</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">disable</param>
     <param name="versionrewrite-pattern">v(.*)</param>

++++++ go-sendxmpp-0.11.4.tar.gz -> go-sendxmpp-0.12.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/CHANGELOG.md 
new/go-sendxmpp-0.12.1/CHANGELOG.md
--- old/go-sendxmpp-0.11.4/CHANGELOG.md 2024-10-26 00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/CHANGELOG.md 2024-11-17 18:54:38.000000000 +0100
@@ -1,8 +1,25 @@
 # Changelog
 
+## [v0.12.1] 2024-11-17
+### Changed
+- Print error instead of quitting if a message of type error is received.
+- Allow upload of multiple files.
+
+### Added
+- Add flag `--suppress-root-warning` to suppress the warning when go-sendxmpp 
is used by the root user.
+
+## [v0.12.0] 2024-11-03
+### Added
+- Add possibility to look up direct TLS connection endpoint via hostmeta2 
(requires xmppsrv >= 0.3.3).
+- Add flag `--allow-plain` to allow PLAIN authentication (requires go-xmpp >= 
0.2.5).
+
+### Changed
+- Disable PLAIN authentication per default.
+- Disable PLAIN authentication after first use of a SCRAM auth mechanism 
(overrides `--allow-plain`) (requires go-xmpp >= 0.2.5).
+
 ## [v0.11.4] 2024-10-26
 ### Changed
-- Fix bug in SCRAM-SHA-256-PLUS (via go-xmpp >= 0.2.4).
+- Fix bug in SCRAM-SHA-256-PLUS auth (via go-xmpp >= 0.2.4).
 
 ## [v0.11.3] 2024-10-25
 ### Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/README.md 
new/go-sendxmpp-0.12.1/README.md
--- old/go-sendxmpp-0.11.4/README.md    2024-10-26 00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/README.md    2024-11-17 18:54:38.000000000 +0100
@@ -75,8 +75,9 @@
 the account details via command line options:
 
 ```plain
-Usage: go-sendxmpp [-cdilnt] [-a value] [--fast-off] [-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] [--ssdp-off] [-s value] 
[--timeout value] [--tls-version value] [-u value] [--version] [recipients…]
+Usage: go-sendxmpp [-cdilnt] [-a value] [--allow-plain] [--fast-off] [-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] [--ssdp-off] [-s value] 
[--suppress-root-warning] [--timeout value] [--tls-version value] [-u value] 
[--version] [recipients…]
  -a, --alias=value  Set alias/nicknamefor chatrooms.
+     --allow-plain  Allow PLAIN authentication.
  -c, --chatroom     Send message to a chatroom.
  -d, --debug        Show debugging info.
      --fast-off     Disable XEP-0484: Fast Authentication Streamlining Tokens.
@@ -85,7 +86,7 @@
      --headline     Send message as type headline.
      --help         Show help.
  -h, --http-upload=value
-                    Send a file via http-upload.
+                    Send a file via http-upload. Can be invoked several times 
to upload multiple files.
  -i, --interactive  Interactive mode (for use with e.g. 'tail -f').
  -j, --jserver=value
                     XMPP server address.
@@ -118,8 +119,10 @@
      --scram-mech-pinning=value
                     Enforce the use of a certain SCRAM authentication 
mechanism.
      --ssdp-off     Disable XEP-0474: SASL SCRAM Downgrade Protection.
-      -s, --subject=value
+ -s, --subject=value
                     Set message subject.
+     --suppress-root-warning
+                    Suppress warning when run as root.
      --timeout=value
                     Connection timeout in seconds. [10]
  -t, --tls          Use direct TLS.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/authpinning.go 
new/go-sendxmpp-0.12.1/authpinning.go
--- old/go-sendxmpp-0.11.4/authpinning.go       1970-01-01 01:00:00.000000000 
+0100
+++ new/go-sendxmpp-0.12.1/authpinning.go       2024-11-17 18:54:38.000000000 
+0100
@@ -0,0 +1,42 @@
+package main
+
+import (
+       "fmt"
+       "os"
+       "strings"
+)
+
+func findAuthPinFilePath(username string) (string, error) {
+       dataPath, err := getDataPath(fsFriendlyJid(username))
+       if err != nil {
+               return strEmpty, fmt.Errorf("findAuthPinFilePath: %v", err)
+       }
+       return fmt.Sprintf("%sauthpin", dataPath), nil
+}
+
+func parseAuthPinFile(username string) (bool, error) {
+       // Find auth pin file.
+       authPinFile, err := findAuthPinFilePath(username)
+       if err != nil {
+               return false, fmt.Errorf("authPinFile: %v", err)
+       }
+       // Read file.
+       f, err := os.ReadFile(authPinFile)
+       if err != nil {
+               return false, fmt.Errorf("authPinFile: %v", err)
+       }
+       // Strip trailing newline.
+       content := strings.TrimSuffix(string(f), "\n")
+       noPLAIN := content == "noPLAIN"
+       return noPLAIN, nil
+}
+
+func writeAuthPinFile(username string) error {
+       // Find auth pin file.
+       authPinFile, err := findAuthPinFilePath(username)
+       if err != nil {
+               return fmt.Errorf("authPinFile: %v", err)
+       }
+       err = os.WriteFile(authPinFile, []byte("noPLAIN\n"), 0o400)
+       return err
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/connect.go 
new/go-sendxmpp-0.12.1/connect.go
--- old/go-sendxmpp-0.11.4/connect.go   2024-10-26 00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/connect.go   2024-11-17 18:54:38.000000000 +0100
@@ -17,9 +17,10 @@
 func connect(options xmpp.Options, directTLS bool) (*xmpp.Client, error) {
        proxy := os.Getenv("HTTP_PROXY")
        server := options.User[strings.Index(options.User, "@")+1:]
-       // Look up SRV records if server is not specified manually.
+       // Look up SRV records or hostmeta2 if server is not specified manually.
        if options.Host == "" {
-               // Don't do SRV look ups if proxy is set.
+               // Don't do SRV or hostmeta2 look ups if proxy is set.
+               // TODO: 2024-10-30: Support hostmeta2 look ups using proxy.
                if proxy == "" {
                        // Look up xmpp-client SRV records.
                        srvMixed, err := xmppsrv.LookupClient(server)
@@ -47,6 +48,22 @@
                                        }
                                }
                        }
+                       // Look up hostmeta2 file.
+                       hm2, httpStatus, err := xmppsrv.LookupHostmeta2(server)
+                       if httpStatus != 404 && err != nil {
+                               for _, link := range hm2.Links {
+                                       if link.Rel == nsC2SdTLS {
+                                               options.NoTLS = false
+                                               options.StartTLS = false
+                                               options.Host = 
net.JoinHostPort(link.Sni, fmt.Sprint(link.Port))
+                                               // Connect to server
+                                               client, err := 
options.NewClient()
+                                               if err == nil {
+                                                       return client, nil
+                                               }
+                                       }
+                               }
+                       }
                }
        }
        _, port, _ := net.SplitHostPort(options.Host)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/const.go 
new/go-sendxmpp-0.12.1/const.go
--- old/go-sendxmpp-0.11.4/const.go     2024-10-26 00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/const.go     2024-11-17 18:54:38.000000000 +0100
@@ -5,7 +5,7 @@
 package main
 
 const (
-       version = "0.11.4"
+       version = "0.12.1"
        // defaults
        defaultBufferSize      = 100
        defaultConfigColumnSep = 2
@@ -24,6 +24,7 @@
        defaultTLS12           = 12
        defaultTLS13           = 13
        // namespace
+       nsC2SdTLS      = "urn:xmpp:alt-connections:tls"
        nsDiscoInfo    = "http://jabber.org/protocol/disco#info";
        nsDiscoItems   = "http://jabber.org/protocol/disco#items";
        nsEme          = "urn:xmpp:eme:0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/go.mod 
new/go-sendxmpp-0.12.1/go.mod
--- old/go-sendxmpp-0.11.4/go.mod       2024-10-26 00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/go.mod       2024-11-17 18:54:38.000000000 +0100
@@ -5,22 +5,22 @@
 toolchain go1.22.7
 
 require (
-       github.com/ProtonMail/gopenpgp/v2 v2.8.0-beta.0
+       github.com/ProtonMail/gopenpgp/v2 v2.8.0
        github.com/beevik/etree v1.4.1
        github.com/gabriel-vasile/mimetype v1.4.6
        github.com/google/uuid v1.6.0
        github.com/pborman/getopt/v2 v2.1.0
-       github.com/xmppo/go-xmpp v0.2.4
-       golang.org/x/crypto v0.28.0
-       salsa.debian.org/mdosch/xmppsrv v0.3.2
+       github.com/xmppo/go-xmpp v0.2.5
+       golang.org/x/crypto v0.29.0
+       salsa.debian.org/mdosch/xmppsrv v0.3.3
 )
 
 require (
-       github.com/ProtonMail/go-crypto v1.1.0-beta.0 // indirect
+       github.com/ProtonMail/go-crypto v1.1.2 // indirect
        github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // 
indirect
        github.com/cloudflare/circl v1.5.0 // indirect
        github.com/pkg/errors v0.9.1 // indirect
-       golang.org/x/net v0.30.0 // indirect
-       golang.org/x/sys v0.26.0 // indirect
-       golang.org/x/text v0.19.0 // indirect
+       golang.org/x/net v0.31.0 // indirect
+       golang.org/x/sys v0.27.0 // indirect
+       golang.org/x/text v0.20.0 // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/go.sum 
new/go-sendxmpp-0.12.1/go.sum
--- old/go-sendxmpp-0.11.4/go.sum       2024-10-26 00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/go.sum       2024-11-17 18:54:38.000000000 +0100
@@ -1,9 +1,9 @@
-github.com/ProtonMail/go-crypto v1.1.0-beta.0 
h1:9ZLo7gzqEbrSakeRM4L0jaHMuZSLrjoYBIdIwcBr4C4=
-github.com/ProtonMail/go-crypto v1.1.0-beta.0/go.mod 
h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
+github.com/ProtonMail/go-crypto v1.1.2 
h1:A7JbD57ThNqh7XjmHE+PXpQ3Dqt3BrSAC0AL0Go3KS0=
+github.com/ProtonMail/go-crypto v1.1.2/go.mod 
h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
 github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f 
h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k=
 github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod 
h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=
-github.com/ProtonMail/gopenpgp/v2 v2.8.0-beta.0 
h1:tTiGHVwjTCVhgA2hod0OyVncfCK3l2j3tApi7tKW07s=
-github.com/ProtonMail/gopenpgp/v2 v2.8.0-beta.0/go.mod 
h1:M2xITH7IEPDrcxzmYtFmpypFMISvUV+DXuG8nBqfqf8=
+github.com/ProtonMail/gopenpgp/v2 v2.8.0 
h1:WvMv3CMcFsqKSM4/Qf8sf3tgyQkzDqQmoSE49bnBuP4=
+github.com/ProtonMail/gopenpgp/v2 v2.8.0/go.mod 
h1:qb2GUSnmA9ipBW5GVtCtEhkummSlqs2A8Ar3S0HBgSY=
 github.com/beevik/etree v1.4.1 h1:PmQJDDYahBGNKDcpdX8uPy1xRCwoCGVUiW669MEirVI=
 github.com/beevik/etree v1.4.1/go.mod 
h1:gPNJNaBGVZ9AwsidazFZyygnd+0pAU38N4D+WemwKNs=
 github.com/cloudflare/circl v1.5.0 
h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
@@ -22,21 +22,21 @@
 github.com/pmezard/go-difflib v1.0.0/go.mod 
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/testify v1.7.0 
h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/xmppo/go-xmpp v0.2.4 h1:2ed1qnYUAKsooL3kphniIWmqBjz8IB8cmzyGB/WdAXo=
-github.com/xmppo/go-xmpp v0.2.4/go.mod 
h1:b24GAaIpOqpxK7vYpZsMo11ReZ1qMBu3DPjkZXcqSpw=
+github.com/xmppo/go-xmpp v0.2.5 h1:6ILGfT6vnWek3f4+SdM0bUV/lRx67dvBCsCVNIVBUb0=
+github.com/xmppo/go-xmpp v0.2.5/go.mod 
h1:b24GAaIpOqpxK7vYpZsMo11ReZ1qMBu3DPjkZXcqSpw=
 github.com/yuin/goldmark v1.4.13/go.mod 
h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod 
h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
-golang.org/x/crypto v0.28.0/go.mod 
h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
+golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
+golang.org/x/crypto v0.29.0/go.mod 
h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod 
h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod 
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod 
h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod 
h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
-golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
+golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
+golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -46,8 +46,8 @@
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
-golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
+golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -56,8 +56,8 @@
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
-golang.org/x/text v0.19.0/go.mod 
h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
+golang.org/x/text v0.20.0/go.mod 
h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod 
h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod 
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod 
h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@@ -65,5 +65,5 @@
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c 
h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod 
h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-salsa.debian.org/mdosch/xmppsrv v0.3.2 
h1:c83iqkp/GnsPYqQ12dTw8MQBzI+Dtw9mQOFSuL3GjaQ=
-salsa.debian.org/mdosch/xmppsrv v0.3.2/go.mod 
h1:udWXnWFa9zkcyN9YSB/u44BCnnRDpeQ0eDy3MVLjHZQ=
+salsa.debian.org/mdosch/xmppsrv v0.3.3 
h1:F8FGyw1Q1LkAs/UbIXd6Obd33q2CKWrIxxrzvuLSVuM=
+salsa.debian.org/mdosch/xmppsrv v0.3.3/go.mod 
h1:udWXnWFa9zkcyN9YSB/u44BCnnRDpeQ0eDy3MVLjHZQ=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/httpupload.go 
new/go-sendxmpp-0.12.1/httpupload.go
--- old/go-sendxmpp-0.11.4/httpupload.go        2024-10-26 00:54:13.000000000 
+0200
+++ new/go-sendxmpp-0.12.1/httpupload.go        2024-11-17 18:54:38.000000000 
+0100
@@ -22,52 +22,27 @@
        "github.com/xmppo/go-xmpp"           // BSD-3-Clause
 )
 
-func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, 
filePath string,
+func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, jserver string, 
filePaths []string,
        timeout time.Duration,
-) (string, error) {
+) (urls []string, err error) {
        var uploadComponent string
        var maxFileSize int64
        var iqDiscoItemsXMLQuery, iqDiscoInfoXMLQuery *etree.Element
 
-       // Get file size
-       fileInfo, err := os.Stat(filePath)
-       if err != nil {
-               return "", err
-       }
-       fileSize := fileInfo.Size()
-
-       // Read file
-       buffer, err := readFile(filePath)
-       if err != nil {
-               return "", err
-       }
-
-       // Get mime type
-       mimeType := mimetype.Detect(buffer.Bytes()).String()
-       var mimeTypeEscaped bytes.Buffer
-       xml.Escape(&mimeTypeEscaped, []byte(mimeType))
-
-       // Get file name
-       fileName := filepath.Base(filePath)
-       // Just use alphanumerical and some special characters for now
-       // to work around https://github.com/xmppo/go-xmpp/issues/132
-       reg := regexp.MustCompile(`[^a-zA-Z0-9\+\-\_\.]+`)
-       fileNameEscaped := reg.ReplaceAllString(fileName, "_")
-
        // Query server for disco#items
        iqContent, err := sendIQ(client, iqc, jserver, "get",
                "<query xmlns='http://jabber.org/protocol/disco#items'/>")
        if err != nil {
-               return "", err
+               return urls, err
        }
        iqDiscoItemsXML := etree.NewDocument()
        err = iqDiscoItemsXML.ReadFromBytes(iqContent.Query)
        if err != nil {
-               return "", err
+               return urls, err
        }
        iqDiscoItemsXMLQuery = iqDiscoItemsXML.SelectElement("query")
        if iqDiscoItemsXMLQuery == nil {
-               return "", fmt.Errorf("http-upload: no query element in disco 
items reply")
+               return urls, fmt.Errorf("http-upload: no query element in disco 
items reply")
        }
        iqDiscoItemsXMLItems := iqDiscoItemsXMLQuery.SelectElements("item")
 
@@ -80,11 +55,11 @@
                iqDiscoInfoReqXMLQuery.CreateAttr("xmlns", nsDiscoInfo)
                iqdi, err := iqDiscoInfoReqXML.WriteToString()
                if err != nil {
-                       return "", err
+                       return urls, err
                }
                iqDiscoInfo, err := sendIQ(client, iqc, jid.Value, "get", iqdi)
                if err != nil {
-                       return "", err
+                       return urls, err
                }
                if iqDiscoInfo.Type != strResult {
                        continue
@@ -92,7 +67,7 @@
                iqDiscoInfoXML := etree.NewDocument()
                err = iqDiscoInfoXML.ReadFromBytes(iqDiscoInfo.Query)
                if err != nil {
-                       return "", err
+                       return urls, err
                }
                iqDiscoInfoXMLQuery = iqDiscoInfoXML.SelectElement("query")
                if iqDiscoInfoXMLQuery == nil {
@@ -117,7 +92,7 @@
                }
        }
        if uploadComponent == "" {
-               return "", fmt.Errorf("http-upload: no http upload component 
found")
+               return urls, fmt.Errorf("http-upload: no http upload component 
found")
        }
        iqDiscoInfoXMLX := iqDiscoInfoXMLQuery.SelectElements("x")
        for _, r := range iqDiscoInfoXMLX {
@@ -142,114 +117,143 @@
                                if prevFieldVal.Text() == nsHTTPUpload {
                                        maxFileSize, err = 
strconv.ParseInt(curFieldVal.Text(), 10, 64)
                                        if err != nil {
-                                               return "", 
fmt.Errorf("http-upload: error while checking server maximum http upload file 
size")
+                                               return urls, 
fmt.Errorf("http-upload: error while checking server maximum http upload file 
size")
                                        }
                                }
                        }
                }
        }
-       // Check if the file size doesn't exceed the maximum file size of the 
http upload
-       // component if a maximum file size is reported, if not just continue 
and hope for
-       // the best.
-       if maxFileSize != 0 {
-               if fileSize > maxFileSize {
-                       return "", fmt.Errorf("http-upload: file size %s MiB is 
larger than the maximum file size allowed (%s MiB)",
-                               strconv.FormatInt(fileSize/1024/1024, 10), 
strconv.FormatInt(maxFileSize/1024/1024, 10))
+
+       for _, filePath := range filePaths {
+               // Get file size
+               fileInfo, err := os.Stat(filePath)
+               if err != nil {
+                       return urls, err
                }
-       }
+               fileSize := fileInfo.Size()
 
-       request := etree.NewDocument()
-       request.WriteSettings.AttrSingleQuote = true
-       requestReq := request.CreateElement("request")
-       requestReq.CreateAttr("xmlns", nsHTTPUpload)
-       requestReq.CreateAttr("filename", fileNameEscaped)
-       requestReq.CreateAttr("size", fmt.Sprint(fileSize))
-       requestReq.CreateAttr("content-type", mimeType)
-       r, err := request.WriteToString()
-       if err != nil {
-               return "", err
-       }
+               // Read file
+               buffer, err := readFile(filePath)
+               if err != nil {
+                       return urls, err
+               }
 
-       // Request http upload slot
-       uploadSlot, err := sendIQ(client, iqc, uploadComponent, "get", r)
-       if err != nil {
-               return "", err
-       }
-       if uploadSlot.Type != strResult {
-               return "", fmt.Errorf("http-upload: error while requesting 
upload slot")
-       }
-       iqHTTPUploadSlotXML := etree.NewDocument()
-       err = iqHTTPUploadSlotXML.ReadFromBytes(uploadSlot.Query)
-       if err != nil {
-               return "", err
-       }
-       iqHTTPUploadSlotXMLSlot := iqHTTPUploadSlotXML.SelectElement("slot")
-       if iqHTTPUploadSlotXMLSlot == nil {
-               return "", fmt.Errorf("http-upload: no slot element")
-       }
-       iqHTTPUploadSlotXMLPut := iqHTTPUploadSlotXMLSlot.SelectElement("put")
-       if iqHTTPUploadSlotXMLPut == nil {
-               return "", fmt.Errorf("http-upload: no put element")
-       }
-       iqHTTPUploadSlotXMLPutURL := iqHTTPUploadSlotXMLPut.SelectAttr("url")
-       if iqHTTPUploadSlotXMLPutURL == nil {
-               return "", fmt.Errorf("http-upload: no url attribute")
-       }
-       if !strings.HasPrefix(iqHTTPUploadSlotXMLPutURL.Value, "https://";) {
-               return "", fmt.Errorf("http-upload: upload slot does not 
provide https")
-       }
-       // Upload file
-       httpTransport := &http.Transport{
-               IdleConnTimeout:     timeout,
-               TLSHandshakeTimeout: timeout,
-       }
-       proxyEnv := os.Getenv("HTTP_PROXY")
-       if proxyEnv != "" {
-               proxyURL, err := url.Parse(proxyEnv)
+               // Get mime type
+               mimeType := mimetype.Detect(buffer.Bytes()).String()
+               var mimeTypeEscaped bytes.Buffer
+               xml.Escape(&mimeTypeEscaped, []byte(mimeType))
+
+               // Get file name
+               fileName := filepath.Base(filePath)
+               // Just use alphanumerical and some special characters for now
+               // to work around https://github.com/xmppo/go-xmpp/issues/132
+               reg := regexp.MustCompile(`[^a-zA-Z0-9\+\-\_\.]+`)
+               fileNameEscaped := reg.ReplaceAllString(fileName, "_")
+
+               // Check if the file size doesn't exceed the maximum file size 
of the http upload
+               // component if a maximum file size is reported, if not just 
continue and hope for
+               // the best.
+               if maxFileSize != 0 {
+                       if fileSize > maxFileSize {
+                               return urls, fmt.Errorf("http-upload: file size 
%s MiB is larger than the maximum file size allowed (%s MiB)",
+                                       strconv.FormatInt(fileSize/1024/1024, 
10), strconv.FormatInt(maxFileSize/1024/1024, 10))
+                       }
+               }
+
+               request := etree.NewDocument()
+               request.WriteSettings.AttrSingleQuote = true
+               requestReq := request.CreateElement("request")
+               requestReq.CreateAttr("xmlns", nsHTTPUpload)
+               requestReq.CreateAttr("filename", fileNameEscaped)
+               requestReq.CreateAttr("size", fmt.Sprint(fileSize))
+               requestReq.CreateAttr("content-type", mimeType)
+               r, err := request.WriteToString()
                if err != nil {
-                       return "", err
+                       return urls, err
                }
-               httpTransport.Proxy = http.ProxyURL(proxyURL)
-       }
-       httpClient := &http.Client{Transport: httpTransport}
-       req, err := http.NewRequest(http.MethodPut, 
iqHTTPUploadSlotXMLPutURL.Value,
-               buffer)
-       if err != nil {
-               return "", err
-       }
-       req.Header.Set("Content-Type", mimeTypeEscaped.String())
-       iqHTTPUploadSlotXMLPutHeaders := 
iqHTTPUploadSlotXMLPut.SelectElements("header")
-       for _, h := range iqHTTPUploadSlotXMLPutHeaders {
-               name := h.SelectAttr("name")
-               if name == nil {
-                       continue
+
+               // Request http upload slot
+               uploadSlot, err := sendIQ(client, iqc, uploadComponent, "get", 
r)
+               if err != nil {
+                       return urls, err
                }
-               switch name.Value {
-               case "Authorization", "Cookie", "Expires":
-                       req.Header.Set(name.Value, h.Text())
+               if uploadSlot.Type != strResult {
+                       return urls, fmt.Errorf("http-upload: error while 
requesting upload slot")
+               }
+               iqHTTPUploadSlotXML := etree.NewDocument()
+               err = iqHTTPUploadSlotXML.ReadFromBytes(uploadSlot.Query)
+               if err != nil {
+                       return urls, err
+               }
+               iqHTTPUploadSlotXMLSlot := 
iqHTTPUploadSlotXML.SelectElement("slot")
+               if iqHTTPUploadSlotXMLSlot == nil {
+                       return urls, fmt.Errorf("http-upload: no slot element")
+               }
+               iqHTTPUploadSlotXMLPut := 
iqHTTPUploadSlotXMLSlot.SelectElement("put")
+               if iqHTTPUploadSlotXMLPut == nil {
+                       return urls, fmt.Errorf("http-upload: no put element")
+               }
+               iqHTTPUploadSlotXMLPutURL := 
iqHTTPUploadSlotXMLPut.SelectAttr("url")
+               if iqHTTPUploadSlotXMLPutURL == nil {
+                       return urls, fmt.Errorf("http-upload: no url attribute")
+               }
+               if !strings.HasPrefix(iqHTTPUploadSlotXMLPutURL.Value, 
"https://";) {
+                       return urls, fmt.Errorf("http-upload: upload slot does 
not provide https")
+               }
+               // Upload file
+               httpTransport := &http.Transport{
+                       IdleConnTimeout:     timeout,
+                       TLSHandshakeTimeout: timeout,
+               }
+               proxyEnv := os.Getenv("HTTP_PROXY")
+               if proxyEnv != "" {
+                       proxyURL, err := url.Parse(proxyEnv)
+                       if err != nil {
+                               return urls, err
+                       }
+                       httpTransport.Proxy = http.ProxyURL(proxyURL)
+               }
+               httpClient := &http.Client{Transport: httpTransport}
+               req, err := http.NewRequest(http.MethodPut, 
iqHTTPUploadSlotXMLPutURL.Value,
+                       buffer)
+               if err != nil {
+                       return urls, err
+               }
+               req.Header.Set("Content-Type", mimeTypeEscaped.String())
+               iqHTTPUploadSlotXMLPutHeaders := 
iqHTTPUploadSlotXMLPut.SelectElements("header")
+               for _, h := range iqHTTPUploadSlotXMLPutHeaders {
+                       name := h.SelectAttr("name")
+                       if name == nil {
+                               continue
+                       }
+                       switch name.Value {
+                       case "Authorization", "Cookie", "Expires":
+                               req.Header.Set(name.Value, h.Text())
+                       }
+               }
+               resp, err := httpClient.Do(req)
+               if err != nil {
+                       return urls, err
+               }
+               // Test for http status code "200 OK" or "201 Created"
+               if resp.StatusCode != 200 && resp.StatusCode != 201 {
+                       return urls, fmt.Errorf("http-upload: upload failed")
                }
-       }
-       resp, err := httpClient.Do(req)
-       if err != nil {
-               return "", err
-       }
-       // Test for http status code "200 OK" or "201 Created"
-       if resp.StatusCode != 200 && resp.StatusCode != 201 {
-               return "", fmt.Errorf("http-upload: upload failed")
-       }
 
-       // Return http link
-       iqHTTPUploadSlotXMLGet := iqHTTPUploadSlotXMLSlot.SelectElement("get")
-       if iqHTTPUploadSlotXMLGet == nil {
-               return "", fmt.Errorf("http-upload: no get element")
-       }
-       iqHTTPUploadSlotXMLGetURL := iqHTTPUploadSlotXMLGet.SelectAttr("url")
-       if iqHTTPUploadSlotXMLGetURL == nil {
-               return "", fmt.Errorf("http-upload: no url attribute")
-       }
-       err = resp.Body.Close()
-       if err != nil {
-               fmt.Println("http-upload: error while closing http request 
body:", err)
+               // Return http link
+               iqHTTPUploadSlotXMLGet := 
iqHTTPUploadSlotXMLSlot.SelectElement("get")
+               if iqHTTPUploadSlotXMLGet == nil {
+                       return urls, fmt.Errorf("http-upload: no get element")
+               }
+               iqHTTPUploadSlotXMLGetURL := 
iqHTTPUploadSlotXMLGet.SelectAttr("url")
+               if iqHTTPUploadSlotXMLGetURL == nil {
+                       return urls, fmt.Errorf("http-upload: no url attribute")
+               }
+               err = resp.Body.Close()
+               if err != nil {
+                       fmt.Println("http-upload: error while closing http 
request body:", err)
+               }
+               urls = append(urls, iqHTTPUploadSlotXMLGetURL.Value)
        }
-       return iqHTTPUploadSlotXMLGetURL.Value, nil
+       return urls, nil
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/main.go 
new/go-sendxmpp-0.12.1/main.go
--- old/go-sendxmpp-0.11.4/main.go      2024-10-26 00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/main.go      2024-11-17 18:54:38.000000000 +0100
@@ -99,7 +99,7 @@
 
        // Define command line flags.
        flagHelp := getopt.BoolLong("help", 0, "Show help.")
-       flagHTTPUpload := getopt.StringLong("http-upload", 'h', "", "Send a 
file via http-upload.")
+       flagHTTPUpload := getopt.ListLong("http-upload", 'h', "Send a file via 
http-upload. Can be invoked several times to upload multiple files.")
        flagDebug := getopt.BoolLong("debug", 'd', "Show debugging info.")
        flagServer := getopt.StringLong("jserver", 'j', "", "XMPP server 
address.")
        flagUser := getopt.StringLong("username", 'u', "", "Username for XMPP 
account.")
@@ -139,6 +139,8 @@
        flagSSDPOff := getopt.BoolLong("ssdp-off", 0, "Disable XEP-0474: SASL 
SCRAM Downgrade Protection.")
        flagSubject := getopt.StringLong("subject", 's', "", "Set message 
subject.")
        flagFastOff := getopt.BoolLong("fast-off", 0, "Disable XEP-0484: Fast 
Authentication Streamlining Tokens.")
+       flagPLAINAllow := getopt.BoolLong("allow-plain", 0, "Allow PLAIN 
authentication.")
+       flagNoRootWarning := getopt.BoolLong("suppress-root-warning", 0, 
"Suppress warning when run as root.")
 
        // Parse command line flags.
        getopt.Parse()
@@ -160,14 +162,14 @@
                os.Exit(0)
                // Quit if Ox (OpenPGP for XMPP) is requested for unsupported 
operations like
                // groupchat, http-upload or listening.
-       case *flagOx && *flagHTTPUpload != "":
+       case *flagOx && len(*flagHTTPUpload) != 0:
                log.Fatal("No Ox support for http-upload available.")
        case *flagOx && *flagChatroom:
                log.Fatal("No Ox support for chat rooms available.")
-       case *flagHTTPUpload != "" && *flagInteractive:
+       case len(*flagHTTPUpload) != 0 && *flagInteractive:
                log.Fatal("Interactive mode and http upload can't" +
                        " be used at the same time.")
-       case *flagHTTPUpload != "" && *flagMessageFile != "":
+       case len(*flagHTTPUpload) != 0 && *flagMessageFile != "":
                log.Fatal("You can't send a message while using" +
                        " http upload.")
        case *flagOx && *flagOOBFile != "":
@@ -179,7 +181,7 @@
        }
 
        // Print a warning if go-sendxmpp is run by the user root on 
non-windows systems.
-       if runtime.GOOS != "windows" {
+       if runtime.GOOS != "windows" && !*flagNoRootWarning {
                // Get the current user.
                currUser, err := osUser.Current()
                if err != nil {
@@ -307,6 +309,10 @@
 
        resource := "go-sendxmpp." + getShortID()
 
+       // Check whether PLAIN authentication is disabled.
+       pinNoPLAIN, _ := parseAuthPinFile(user)
+       noPLAIN := pinNoPLAIN || !*flagPLAINAllow
+
        // Set XMPP connection options.
        options := xmpp.Options{
                Host:        server,
@@ -331,6 +337,7 @@
                Fast:          !*flagFastOff,
                FastToken:     fast.Token,
                FastMechanism: fast.Mechanism,
+               NoPLAIN:       noPLAIN,
        }
 
        // Read message from file.
@@ -343,7 +350,7 @@
 
        // Skip reading message if '-i' or '--interactive' is set to work with 
e.g. 'tail -f'.
        // Also for listening mode and Ox key handling.
-       if !*flagInteractive && !*flagListen && *flagHTTPUpload == "" &&
+       if !*flagInteractive && !*flagListen && len(*flagHTTPUpload) == 0 &&
                !*flagOxDeleteNodes && *flagOxImportPrivKey == "" &&
                !*flagOxGenPrivKeyX25519 && !*flagOxGenPrivKeyRSA && 
*flagOOBFile == "" &&
                message == "" {
@@ -368,7 +375,7 @@
        // Exit if message is empty.
        if message == "" && !*flagInteractive && !*flagListen && 
!*flagOxGenPrivKeyRSA &&
                !*flagOxGenPrivKeyX25519 && *flagOxImportPrivKey == "" &&
-               !*flagOxDeleteNodes && *flagHTTPUpload == "" && *flagOOBFile == 
"" {
+               !*flagOxDeleteNodes && len(*flagHTTPUpload) == 0 && 
*flagOOBFile == "" {
                os.Exit(0)
        }
 
@@ -406,6 +413,15 @@
                        fmt.Println(err)
                }
        }
+       // If authentication is not yet pinned to not use PLAIN and a SCRAM 
mechanism is
+       // used, write the auth pin file.
+       if !pinNoPLAIN && (strings.HasPrefix(client.Mechanism, "SCRAM") ||
+               strings.HasPrefix(client.Mechanism, "HT")) {
+               err = writeAuthPinFile(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)
        ctx, cancel := context.WithCancel(context.Background())
@@ -497,9 +513,10 @@
                }
        }
 
-       if *flagHTTPUpload != "" {
-               message, err = httpUpload(client, iqc, tlsConfig.ServerName,
-                       *flagHTTPUpload, timeout)
+       var uploadMessages []string
+       if len(*flagHTTPUpload) != 0 {
+               uploadMessages, err = httpUpload(client, iqc,
+                       tlsConfig.ServerName, *flagHTTPUpload, timeout)
                if err != nil {
                        cancel()
                        closeAndExit(client, err)
@@ -702,19 +719,21 @@
                }
        default:
                for _, recipient := range recipients {
-                       if message == "" {
+                       if message == "" && len(uploadMessages) == 0 {
                                break
                        }
                        switch {
-                       case *flagHTTPUpload != "":
-                               _, err = client.Send(xmpp.Chat{
-                                       Remote: recipient.Jid,
-                                       Type:   msgType, Ooburl: message, Text: 
message,
-                                       Subject: *flagSubject,
-                               })
-                               if err != nil {
-                                       fmt.Println("Couldn't send message to",
-                                               recipient.Jid)
+                       case len(*flagHTTPUpload) != 0:
+                               for _, message = range uploadMessages {
+                                       _, err = client.Send(xmpp.Chat{
+                                               Remote: recipient.Jid,
+                                               Type:   msgType, Ooburl: 
message, Text: message,
+                                               Subject: *flagSubject,
+                                       })
+                                       if err != nil {
+                                               fmt.Println("Couldn't send 
message to",
+                                                       recipient.Jid)
+                                       }
                                }
                        // (Hopefully) temporary workaround due to go-xmpp 
choking on URL encoding.
                        // Once this is fixed in the lib the http-upload case 
above can be reused.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/man/go-sendxmpp.1 
new/go-sendxmpp-0.12.1/man/go-sendxmpp.1
--- old/go-sendxmpp-0.11.4/man/go-sendxmpp.1    2024-10-26 00:54:13.000000000 
+0200
+++ new/go-sendxmpp-0.12.1/man/go-sendxmpp.1    2024-11-17 18:54:38.000000000 
+0100
@@ -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" "June 2024" ""
+.TH "GO\-SENDXMPP" "1" "November 2024" ""
 .SH "NAME"
 \fBgo\-sendxmpp\fR \- A tool to send messages to an XMPP contact or MUC\.
 .SH "SYNOPSIS"
-\fBgo\-sendxmpp [\-cdilnt] [\-a value] [\-\-fast\-off] [\-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] [\-\-ssdp\-off] [\-s value] 
[\-\-timeout value] [\-\-tls\-version value] [\-u value] [\-\-version] 
[recipients…]\fR
+\fBgo\-sendxmpp [\-cdilnt] [\-a value] [\-\-fast\-off] [\-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] 
[\-\-allow\-plain] [\-\-raw] [\-\-scram\-mech\-pinning value] [\-\-ssdp\-off] 
[\-s value] [\-\-suppress\-root\-warning] [\-\-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 \fBsendxmpp\fR\.
 .br
@@ -33,7 +33,7 @@
 Show help\.
 .TP
 \fB\-h\fR, \fB\-\-http\-upload=\fR[\fIvalue\fR]
-Send a file via http\-upload\.
+Send a file via http\-upload\. Can be invoked several times to upload multiple 
files\.
 .TP
 \fB\-i\fR, \fB\-\-interactive\fR
 Interactive mode (for use with e\.g\. \fBtail \-f\fR)\.
@@ -83,11 +83,14 @@
 \fB\-p\fR, \fB\-\-password\fR=[\fIvalue\fR]
 Password for XMPP account\.
 .TP
+\fB\-\-allow\-plain\fR
+Allow PLAIN authentication\. Note that this setting has no effect if there was 
a successful connection using a SCRAM authentication mechanism before\. In that 
case PLAIN is not allowed to prevent downgrades by a man\-in\-the\-middle 
attack\.
+.TP
 \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=[<value>]\fR
-Enforce the use of a certain SCRAM authentication mechanism\. Currently 
go\-sendxmpp supports \fBSCRAM\-SHA\-1\fR, \fBSCRAM\-SHA\-1\-PLUS\fR, 
\fBSCRAM\-SHA\-256\fR, \fBSCRAM\-SHA\-256\-PLUS\fR, \fBSCRAM\-SHA\-512\fR and 
\fBSCRAM\-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)\.
+Enforce the use of a certain SCRAM authentication mechanism\. Currently 
go\-sendxmpp supports \fBSCRAM\-SHA\-1\fR, \fBSCRAM\-SHA\-1\-PLUS\fR, 
\fBSCRAM\-SHA\-256\fR, \fBSCRAM\-SHA\-256\-PLUS\fR, \fBSCRAM\-SHA\-512\fR and 
\fBSCRAM\-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 and requires a SCRAM authentication mechanism)\.
 .TP
 \fB\-\-ssdp\-off\fR
 Disable XEP\-0474: SASL SCRAM Downgrade Protection\.
@@ -95,6 +98,9 @@
 \fB\-s\fR, \fB\-\-subject\fR=[\fIvalue\fR]
 Set message subject\.
 .TP
+\fB\-\-suppress\-root\-warning\fR
+Suppress warning when run as root\.
+.TP
 \fB\-\-timeout=\fR[\fIvalue\fR]
 Connection timeout in seconds\. (Default: 10)
 .TP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/man/go-sendxmpp.1.html 
new/go-sendxmpp-0.12.1/man/go-sendxmpp.1.html
--- old/go-sendxmpp-0.11.4/man/go-sendxmpp.1.html       2024-10-26 
00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/man/go-sendxmpp.1.html       2024-11-17 
18:54:38.000000000 +0100
@@ -83,8 +83,8 @@
 
 <p><code>go-sendxmpp [-cdilnt] [-a value] [--fast-off] [-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] 
[--ssdp-off] [-s value] [--timeout value]
-[--tls-version value] [-u value] [--version] [recipients…]</code></p>
+[--ox-passphrase value] [-p value]  [--allow-plain] [--raw] 
[--scram-mech-pinning value] [--ssdp-off] [-s value] [--suppress-root-warning]
+[--timeout value] [--tls-version value] [-u value] [--version] 
[recipients…]</code></p>
 
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 
@@ -119,7 +119,7 @@
 <dd>Show help.</dd>
 <dt>
 <code>-h</code>, <code>--http-upload=</code>[<var>value</var>]</dt>
-<dd>Send a file via http-upload.</dd>
+<dd>Send a file via http-upload. Can be invoked several times to upload 
multiple files.</dd>
 <dt>
 <code>-i</code>, <code>--interactive</code>
 </dt>
@@ -182,6 +182,10 @@
 <dt>
 <code>-p</code>, <code>--password</code>=[<var>value</var>]</dt>
 <dd>Password for XMPP account.</dd>
+<dt><code>--allow-plain</code></dt>
+<dd>Allow PLAIN authentication. Note that this setting has no effect if there 
was a successful
+connection using a SCRAM authentication mechanism before. In that case PLAIN 
is not allowed
+to prevent downgrades by a man-in-the-middle attack.</dd>
 <dt><code>--raw</code></dt>
 <dd>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 <code>-c</code> and 
go-sendxmpp will join the MUC.</dd>
@@ -190,12 +194,14 @@
 <strong>SCRAM-SHA-1</strong>, <strong>SCRAM-SHA-1-PLUS</strong>, 
<strong>SCRAM-SHA-256</strong>, <strong>SCRAM-SHA-256-PLUS</strong>, 
<strong>SCRAM-SHA-512</strong>
 and <strong>SCRAM-SHA-512-PLUS</strong>. 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).</dd>
+to prevent downgrade attacks (needs server support and requires a SCRAM 
authentication mechanism).</dd>
 <dt><code>--ssdp-off</code></dt>
 <dd>Disable XEP-0474: SASL SCRAM Downgrade Protection.</dd>
 <dt>
 <code>-s</code>, <code>--subject</code>=[<var>value</var>]</dt>
 <dd>Set message subject.</dd>
+<dt><code>--suppress-root-warning</code></dt>
+<dd>Suppress warning when run as root.</dd>
 <dt>
 <code>--timeout=</code>[<var>value</var>]</dt>
 <dd>Connection timeout in seconds. (Default: 10)</dd>
@@ -284,7 +290,7 @@
 
   <ol class='man-decor man-foot man foot'>
     <li class='tl'></li>
-    <li class='tc'>June 2024</li>
+    <li class='tc'>November 2024</li>
     <li class='tr'>go-sendxmpp(1)</li>
   </ol>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/man/go-sendxmpp.1.ronn 
new/go-sendxmpp-0.12.1/man/go-sendxmpp.1.ronn
--- old/go-sendxmpp-0.11.4/man/go-sendxmpp.1.ronn       2024-10-26 
00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/man/go-sendxmpp.1.ronn       2024-11-17 
18:54:38.000000000 +0100
@@ -5,8 +5,8 @@
 
 `go-sendxmpp [-cdilnt] [-a value] [--fast-off] [-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] 
[--ssdp-off] [-s value] [--timeout value]
-[--tls-version value] [-u value] [--version] [recipients…]`
+[--ox-passphrase value] [-p value]  [--allow-plain] [--raw] 
[--scram-mech-pinning value] [--ssdp-off] [-s value] [--suppress-root-warning]
+[--timeout value] [--tls-version value] [-u value] [--version] [recipients…]`
 
 ## DESCRIPTION
 
@@ -41,7 +41,7 @@
 Show help.
 
 * `-h`, `--http-upload=`[<value>]:
-Send a file via http-upload.
+Send a file via http-upload. Can be invoked several times to upload multiple 
files.
 
 * `-i`, `--interactive`:
 Interactive mode (for use with e.g. `tail -f`).
@@ -106,6 +106,11 @@
 * `-p`, `--password`=[<value>]:
 Password for XMPP account.
 
+* `--allow-plain`:
+Allow PLAIN authentication. Note that this setting has no effect if there was 
a successful
+connection using a SCRAM authentication mechanism before. In that case PLAIN 
is not allowed
+to prevent downgrades by a man-in-the-middle attack.
+
 * `--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.
@@ -115,7 +120,7 @@
 **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).
+to prevent downgrade attacks (needs server support and requires a SCRAM 
authentication mechanism).
 
 * `--ssdp-off`:
 Disable XEP-0474: SASL SCRAM Downgrade Protection.
@@ -123,6 +128,9 @@
 * `-s`, `--subject`=[<value>]:
 Set message subject.
 
+* `--suppress-root-warning`:
+Suppress warning when run as root.
+
 * `--timeout=`[<value>]:
 Connection timeout in seconds. (Default: 10)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/man/go-sendxmpp.5 
new/go-sendxmpp-0.12.1/man/go-sendxmpp.5
--- old/go-sendxmpp-0.11.4/man/go-sendxmpp.5    2024-10-26 00:54:13.000000000 
+0200
+++ new/go-sendxmpp-0.12.1/man/go-sendxmpp.5    2024-11-17 18:54:38.000000000 
+0100
@@ -1,6 +1,6 @@
 .\" generated with Ronn-NG/v0.9.1
 .\" http://github.com/apjanke/ronn-ng/tree/0.9.1
-.TH "GO\-SENDXMPP" "5" "October 2023" ""
+.TH "GO\-SENDXMPP" "5" "November 2024" ""
 .SH "NAME"
 \fBgo\-sendxmpp\fR \- A tool to send messages to an XMPP contact or MUC\.
 .SH "LOCATION"
@@ -20,7 +20,7 @@
 .SH "REQUIRED SETTINGS"
 If all necessary settings are supplied as command line arguments no config 
file is needed at all\. Setting \fBjserver\fR and \fBport\fR might not be 
necessary depending on the used server\.
 .br
-You should either use a password manager and the setting \fBeval_password\fR 
or add your password in plaintext to the config file with the setting 
\fBpassword\fR\.
+You should either use a password manager and the setting \fBeval_password\fR 
or add your password in plaintext to the config file with the setting 
\fBpassword\fR\. Please be careful with \fBeval_password\fR as any command put 
there will be executed\.
 .SH "AUTHOR"
 Written by Martin Dosch\.
 .SH "REPORTING BUGS"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/man/go-sendxmpp.5.html 
new/go-sendxmpp-0.12.1/man/go-sendxmpp.5.html
--- old/go-sendxmpp-0.11.4/man/go-sendxmpp.5.html       2024-10-26 
00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/man/go-sendxmpp.5.html       2024-11-17 
18:54:38.000000000 +0100
@@ -95,7 +95,8 @@
 <p>If all necessary settings are supplied as command line arguments no config 
file is needed at all.
 Setting <code>jserver</code> and <code>port</code> might not be necessary 
depending on the used server.  <br>
 You should either use a password manager and the setting 
<code>eval_password</code> or add
-your password in plaintext to the config file with the setting 
<code>password</code>.</p>
+your password in plaintext to the config file with the setting 
<code>password</code>.
+Please be careful with <code>eval_password</code> as any command put there 
will be executed.</p>
 
 <h2 id="AUTHOR">AUTHOR</h2>
 
@@ -116,7 +117,7 @@
 
   <ol class='man-decor man-foot man foot'>
     <li class='tl'></li>
-    <li class='tc'>October 2023</li>
+    <li class='tc'>November 2024</li>
     <li class='tr'>go-sendxmpp(5)</li>
   </ol>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/man/go-sendxmpp.5.ronn 
new/go-sendxmpp-0.12.1/man/go-sendxmpp.5.ronn
--- old/go-sendxmpp-0.11.4/man/go-sendxmpp.5.ronn       2024-10-26 
00:54:13.000000000 +0200
+++ new/go-sendxmpp-0.12.1/man/go-sendxmpp.5.ronn       2024-11-17 
18:54:38.000000000 +0100
@@ -22,6 +22,7 @@
 Setting `jserver` and `port` might not be necessary depending on the used 
server.    
 You should either use a password manager and the setting `eval_password` or add
 your password in plaintext to the config file with the setting `password`.
+Please be careful with `eval_password` as any command put there will be 
executed.
 
 ## AUTHOR
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-0.11.4/stanzahandling.go 
new/go-sendxmpp-0.12.1/stanzahandling.go
--- old/go-sendxmpp-0.11.4/stanzahandling.go    2024-10-26 00:54:13.000000000 
+0200
+++ new/go-sendxmpp-0.12.1/stanzahandling.go    2024-11-17 18:54:38.000000000 
+0100
@@ -6,6 +6,7 @@
 
 import (
        "context"
+       "encoding/xml"
        "fmt"
        "io"
        "log"
@@ -45,6 +46,11 @@
 }
 
 func rcvStanzas(client *xmpp.Client, ctx context.Context, iqc chan xmpp.IQ, 
msgc chan xmpp.Chat) {
+       type messageError struct {
+               XMLName xml.Name `xml:"message-error"`
+               Text    string   `xml:"text"`
+       }
+       var me messageError
        var received interface{}
        r := make(chan interface{}, defaultBufferSize)
        e := make(chan error, defaultBufferSize)
@@ -68,18 +74,28 @@
                case <-ctx.Done():
                        return
                case err := <-e:
-                       if err != nil {
-                               if err != io.EOF {
-                                       closeAndExit(client, err)
-                                       return
-                               }
+                       switch err {
+                       case io.EOF, io.ErrUnexpectedEOF:
+                               return
+                       case nil:
+                               continue
+                       default:
+                               closeAndExit(client, fmt.Errorf("rcvStanzas: 
%v", err))
                                return
                        }
                case received = <-r:
                }
                switch v := received.(type) {
                case xmpp.Chat:
-
+                       if v.Type == "error" {
+                               for _, oe := range v.OtherElem {
+                                       err := 
xml.Unmarshal([]byte("<message-error>"+
+                                               
oe.InnerXML+"</message-error>"), &me)
+                                       if err == nil {
+                                               fmt.Printf("%s: %s\n", 
v.Remote, me.Text)
+                                       }
+                               }
+                       }
                        msgc <- v
                case xmpp.IQ:
                        switch v.Type {

++++++ vendor.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/ProtonMail/go-crypto/openpgp/clearsign/clearsign.go 
new/vendor/github.com/ProtonMail/go-crypto/openpgp/clearsign/clearsign.go
--- old/vendor/github.com/ProtonMail/go-crypto/openpgp/clearsign/clearsign.go   
2024-10-26 19:43:43.000000000 +0200
+++ new/vendor/github.com/ProtonMail/go-crypto/openpgp/clearsign/clearsign.go   
2024-11-26 08:45:58.000000000 +0100
@@ -173,6 +173,7 @@
                b.Plaintext = append(b.Plaintext, line...)
                b.Plaintext = append(b.Plaintext, lf)
        }
+       b.Plaintext = b.Plaintext[:len(b.Plaintext)-1]
 
        // We want to find the extent of the armored data (including any 
newlines at
        // the end).
@@ -359,7 +360,7 @@
 
 // Encode returns a WriteCloser which will clear-sign a message with privateKey
 // and write it to w. If config is nil, sensible defaults are used.
-func Encode(w io.Writer, privateKey *packet.PrivateKey, config *packet.Config, 
headers map[string]string) (plaintext io.WriteCloser, err error) {
+func Encode(w io.Writer, privateKey *packet.PrivateKey, config *packet.Config) 
(plaintext io.WriteCloser, err error) {
        return EncodeMulti(w, []*packet.PrivateKey{privateKey}, config)
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go
 
new/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go
--- 
old/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go
   2024-10-26 19:43:43.000000000 +0200
+++ 
new/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go
   2024-11-26 08:45:58.000000000 +0100
@@ -7,6 +7,7 @@
 import (
        "crypto/cipher"
        "crypto/sha256"
+       "fmt"
        "io"
        "strconv"
 
@@ -63,8 +64,11 @@
 // decryptAead decrypts a V2 SEIPD packet (AEAD) as specified in
 // 
https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
 func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, 
error) {
-       aead, nonce := getSymmetricallyEncryptedAeadInstance(se.Cipher, 
se.Mode, inputKey, se.Salt[:], se.associatedData())
+       if se.Cipher.KeySize() != len(inputKey) {
+               return nil, errors.StructuralError(fmt.Sprintf("invalid session 
key length for cipher: got %d bytes, but expected %d bytes", len(inputKey), 
se.Cipher.KeySize()))
+       }
 
+       aead, nonce := getSymmetricallyEncryptedAeadInstance(se.Cipher, 
se.Mode, inputKey, se.Salt[:], se.associatedData())
        // Carry the first tagLen bytes
        tagLen := se.Mode.TagLength()
        peekedBytes := make([]byte, tagLen)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/ProtonMail/gopenpgp/v2/crypto/signature.go 
new/vendor/github.com/ProtonMail/gopenpgp/v2/crypto/signature.go
--- old/vendor/github.com/ProtonMail/gopenpgp/v2/crypto/signature.go    
2024-10-26 19:43:43.000000000 +0200
+++ new/vendor/github.com/ProtonMail/gopenpgp/v2/crypto/signature.go    
2024-11-26 08:45:58.000000000 +0100
@@ -17,11 +17,15 @@
        "github.com/ProtonMail/gopenpgp/v2/internal"
 )
 
+// allowedHashes stores the allowed OpenPGP hashes that can be used in a
+// message signature hash.
 var allowedHashes = []crypto.Hash{
        crypto.SHA224,
        crypto.SHA256,
        crypto.SHA384,
        crypto.SHA512,
+       crypto.SHA3_256,
+       crypto.SHA3_512,
 }
 
 // SignatureVerificationError is returned from Decrypt and VerifyDetached
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/xmppo/go-xmpp/xmpp.go 
new/vendor/github.com/xmppo/go-xmpp/xmpp.go
--- old/vendor/github.com/xmppo/go-xmpp/xmpp.go 2024-10-26 19:43:43.000000000 
+0200
+++ new/vendor/github.com/xmppo/go-xmpp/xmpp.go 2024-11-26 08:45:58.000000000 
+0100
@@ -46,18 +46,28 @@
 )
 
 const (
-       nsStream       = "http://etherx.jabber.org/streams";
-       nsTLS          = "urn:ietf:params:xml:ns:xmpp-tls"
-       nsSASL         = "urn:ietf:params:xml:ns:xmpp-sasl"
-       nsSASL2        = "urn:xmpp:sasl:2"
-       nsBind         = "urn:ietf:params:xml:ns:xmpp-bind"
-       nsBind2        = "urn:xmpp:bind:0"
-       nsFast         = "urn:xmpp:fast:0"
-       nsSASLCB       = "urn:xmpp:sasl-cb:0"
-       nsClient       = "jabber:client"
-       nsSession      = "urn:ietf:params:xml:ns:xmpp-session"
-       nsStreamLimits = "urn:xmpp:stream-limits:0"
-       Version        = "0.2.4"
+       Version         = "0.2.5-dev"
+       nsStream        = "http://etherx.jabber.org/streams";
+       nsTLS           = "urn:ietf:params:xml:ns:xmpp-tls"
+       nsSASL          = "urn:ietf:params:xml:ns:xmpp-sasl"
+       nsSASL2         = "urn:xmpp:sasl:2"
+       nsBind          = "urn:ietf:params:xml:ns:xmpp-bind"
+       nsBind2         = "urn:xmpp:bind:0"
+       nsFast          = "urn:xmpp:fast:0"
+       nsSASLCB        = "urn:xmpp:sasl-cb:0"
+       nsClient        = "jabber:client"
+       nsSession       = "urn:ietf:params:xml:ns:xmpp-session"
+       nsStreamLimits  = "urn:xmpp:stream-limits:0"
+       scramSHA1       = "SCRAM-SHA-1"
+       scramSHA1Plus   = "SCRAM-SHA-1-PLUS"
+       scramSHA256     = "SCRAM-SHA-256"
+       scramSHA256Plus = "SCRAM-SHA-256-PLUS"
+       scramSHA512     = "SCRAM-SHA-512"
+       scramSHA512Plus = "SCRAM-SHA-512-PLUS"
+       htSHA256Expr    = "HT-SHA-256-EXPR"
+       htSHA256Uniq    = "HT-SHA-256-UNIQ"
+       htSHA256Endp    = "HT-SHA-256-ENDP"
+       htSHA256None    = "HT-SHA-256-NONE"
 )
 
 // Default TLS configuration options
@@ -277,6 +287,9 @@
        // XEP-0484: Fast Authentication Streamlining Tokens
        // Invalidate the current token
        FastInvalidate bool
+
+       // NoPLAIN forbids authentication using plain passwords
+       NoPLAIN bool
 }
 
 // NewClient establishes a new Client connection based on a set of Options.
@@ -451,7 +464,7 @@
                }
        }
 
-       // If the server requires we STARTTLS, attempt to do so.
+       // If the server requires STARTTLS, attempt to do so.
        if f, err = c.startTLSIfRequired(f, o, domain); err != nil {
                return err
        }
@@ -476,7 +489,11 @@
                foundAnonymous := false
                for _, m := range mechSlice {
                        if m == "ANONYMOUS" {
-                               fmt.Fprintf(c.stanzaWriter, "<auth xmlns='%s' 
mechanism='ANONYMOUS' />\n", nsSASL)
+                               if sasl2 {
+                                       fmt.Fprintf(c.stanzaWriter, 
"<authenticate xmlns='%s' mechanism='ANONYMOUS' />\n", nsSASL2)
+                               } else {
+                                       fmt.Fprintf(c.stanzaWriter, "<auth 
xmlns='%s' mechanism='ANONYMOUS' />\n", nsSASL)
+                               }
                                foundAnonymous = true
                                break
                        }
@@ -503,21 +520,22 @@
                        }
                } else {
                        switch {
-                       case slices.Contains(mechSlice, "SCRAM-SHA-512-PLUS") 
&& tlsConnOK:
-                               mechanism = "SCRAM-SHA-512-PLUS"
-                       case slices.Contains(mechSlice, "SCRAM-SHA-256-PLUS") 
&& tlsConnOK:
-                               mechanism = "SCRAM-SHA-256-PLUS"
-                       case slices.Contains(mechSlice, "SCRAM-SHA-1-PLUS") && 
tlsConnOK:
-                               mechanism = "SCRAM-SHA-1-PLUS"
-                       case slices.Contains(mechSlice, "SCRAM-SHA-512"):
-                               mechanism = "SCRAM-SHA-512"
-                       case slices.Contains(mechSlice, "SCRAM-SHA-256"):
-                               mechanism = "SCRAM-SHA-256"
-                       case slices.Contains(mechSlice, "SCRAM-SHA-1"):
-                               mechanism = "SCRAM-SHA-1"
+                       case slices.Contains(mechSlice, scramSHA512Plus) && 
tlsConnOK:
+                               mechanism = scramSHA512Plus
+                       case slices.Contains(mechSlice, scramSHA256Plus) && 
tlsConnOK:
+                               mechanism = scramSHA256Plus
+                       case slices.Contains(mechSlice, scramSHA1Plus) && 
tlsConnOK:
+                               mechanism = scramSHA1Plus
+                       case slices.Contains(mechSlice, scramSHA512):
+                               mechanism = scramSHA512
+                       case slices.Contains(mechSlice, scramSHA256):
+                               mechanism = scramSHA256
+                       case slices.Contains(mechSlice, scramSHA1):
+                               mechanism = scramSHA1
                        case slices.Contains(mechSlice, "X-OAUTH2"):
                                mechanism = "X-OAUTH2"
-                       case slices.Contains(mechSlice, "PLAIN") && tlsConnOK:
+                               // Do not use PLAIN auth if NoPlain is set.
+                       case slices.Contains(mechSlice, "PLAIN") && tlsConnOK 
&& !o.NoPLAIN:
                                mechanism = "PLAIN"
                        }
                }
@@ -586,11 +604,11 @@
                        }
                        var shaNewFn func() hash.Hash
                        switch mechanism {
-                       case "SCRAM-SHA-512", "SCRAM-SHA-512-PLUS":
+                       case scramSHA512, scramSHA512Plus:
                                shaNewFn = sha512.New
-                       case "SCRAM-SHA-256", "SCRAM-SHA-256-PLUS":
+                       case scramSHA256, scramSHA256Plus:
                                shaNewFn = sha256.New
-                       case "SCRAM-SHA-1", "SCRAM-SHA-1-PLUS":
+                       case scramSHA1, scramSHA1Plus:
                                shaNewFn = sha1.New
                        default:
                                return errors.New("unsupported auth mechanism")
@@ -634,14 +652,14 @@
                                        if o.FastToken == "" {
                                                m := 
f.Authentication.Inline.Fast.Mechanism
                                                switch {
-                                               case slices.Contains(m, 
"HT-SHA-256-EXPR") && tls13:
-                                                       mech = "HT-SHA-256-EXPR"
-                                               case slices.Contains(m, 
"HT-SHA-256-UNIQ") && !tls13:
-                                                       mech = "HT-SHA-256-UNIQ"
-                                               case slices.Contains(m, 
"HT-SHA-256-ENDP"):
-                                                       mech = "HT-SHA-256-ENDP"
-                                               case slices.Contains(m, 
"HT-SHA-256-NONE"):
-                                                       mech = "HT-SHA-256-NONE"
+                                               case slices.Contains(m, 
htSHA256Expr) && tls13:
+                                                       mech = htSHA256Expr
+                                               case slices.Contains(m, 
htSHA256Uniq) && !tls13:
+                                                       mech = htSHA256Uniq
+                                               case slices.Contains(m, 
htSHA256Endp):
+                                                       mech = htSHA256Endp
+                                               case slices.Contains(m, 
htSHA256None):
+                                                       mech = htSHA256None
                                                default:
                                                        return 
fmt.Errorf("fast: unsupported auth mechanism %s", m)
                                                }
@@ -655,14 +673,14 @@
                                                tlsState := 
tlsConn.ConnectionState()
                                                mechanism = o.FastMechanism
                                                switch mechanism {
-                                               case "HT-SHA-256-EXPR":
+                                               case htSHA256Expr:
                                                        keyingMaterial, err = 
tlsState.ExportKeyingMaterial("EXPORTER-Channel-Binding", nil, 32)
                                                        if err != nil {
                                                                return err
                                                        }
-                                               case "HT-SHA-256-UNIQ":
+                                               case htSHA256Uniq:
                                                        keyingMaterial = 
tlsState.TLSUnique
-                                               case "HT-SHA-256-ENDP":
+                                               case htSHA256Endp:
                                                        var h hash.Hash
                                                        switch 
tlsState.PeerCertificates[0].SignatureAlgorithm {
                                                        case x509.SHA1WithRSA, 
x509.SHA256WithRSA, x509.ECDSAWithSHA1,
@@ -676,7 +694,7 @@
                                                        
h.Write(tlsState.PeerCertificates[0].Raw)
                                                        keyingMaterial = 
h.Sum(nil)
                                                        h.Reset()
-                                               case "HT-SHA-256-NONE":
+                                               case htSHA256None:
                                                        keyingMaterial = 
[]byte("")
                                                default:
                                                        return 
fmt.Errorf("fast: unsupported auth mechanism %s", mechanism)
@@ -757,14 +775,14 @@
                                if v.Token.Token != "" && v.Token.Token != 
o.FastToken {
                                        m := 
f.Authentication.Inline.Fast.Mechanism
                                        switch {
-                                       case slices.Contains(m, 
"HT-SHA-256-EXPR") && tls13:
-                                               c.Fast.Mechanism = 
"HT-SHA-256-EXPR"
-                                       case slices.Contains(m, 
"HT-SHA-256-UNIQ") && !tls13:
-                                               c.Fast.Mechanism = 
"HT-SHA-256-UNIQ"
-                                       case slices.Contains(m, 
"HT-SHA-256-ENDP"):
-                                               c.Fast.Mechanism = 
"HT-SHA-256-ENDP"
-                                       case slices.Contains(m, 
"HT-SHA-256-NONE"):
-                                               c.Fast.Mechanism = 
"HT-SHA-256-NONE"
+                                       case slices.Contains(m, htSHA256Expr) 
&& tls13:
+                                               c.Fast.Mechanism = htSHA256Expr
+                                       case slices.Contains(m, htSHA256Uniq) 
&& !tls13:
+                                               c.Fast.Mechanism = htSHA256Uniq
+                                       case slices.Contains(m, htSHA256Endp):
+                                               c.Fast.Mechanism = htSHA256Endp
+                                       case slices.Contains(m, htSHA256None):
+                                               c.Fast.Mechanism = htSHA256None
                                        }
                                        c.Fast.Token = v.Token.Token
                                        c.Fast.Expiry, _ = 
time.Parse(time.RFC3339, v.Token.Expiry)
@@ -857,13 +875,13 @@
                        h.Reset()
                        var storedKey []byte
                        switch mechanism {
-                       case "SCRAM-SHA-512", "SCRAM-SHA-512-PLUS":
+                       case scramSHA512, scramSHA512Plus:
                                storedKey512 := sha512.Sum512(clientKey)
                                storedKey = storedKey512[:]
-                       case "SCRAM-SHA-256", "SCRAM-SHA-256-PLUS":
+                       case scramSHA256, scramSHA256Plus:
                                storedKey256 := sha256.Sum256(clientKey)
                                storedKey = storedKey256[:]
-                       case "SCRAM-SHA-1", "SCRAM-SHA-1-PLUS":
+                       case scramSHA1, scramSHA1Plus:
                                storedKey1 := sha1.Sum(clientKey)
                                storedKey = storedKey1[:]
                        }
@@ -923,8 +941,8 @@
                        enc := make([]byte, 
base64.StdEncoding.EncodedLen(len(raw)))
                        base64.StdEncoding.Encode(enc, []byte(raw))
                        if sasl2 {
-                               fmt.Fprintf(c.stanzaWriter, "<auth xmlns='%s' 
mechanism='X-OAUTH2' auth:service='oauth2' "+
-                                       "xmlns:auth='%s'>%s</auth>\n", nsSASL2, 
o.OAuthXmlNs, enc)
+                               fmt.Fprintf(c.stanzaWriter, "<authenticate 
xmlns='%s' mechanism='X-OAUTH2' auth:service='oauth2' "+
+                                       "xmlns:auth='%s'>%s</authenticate>\n", 
nsSASL2, o.OAuthXmlNs, enc)
                        } else {
                                fmt.Fprintf(c.stanzaWriter, "<auth xmlns='%s' 
mechanism='X-OAUTH2' auth:service='oauth2' "+
                                        "xmlns:auth='%s'>%s</auth>\n", nsSASL, 
o.OAuthXmlNs, enc)
@@ -936,7 +954,7 @@
                        enc := make([]byte, 
base64.StdEncoding.EncodedLen(len(raw)))
                        base64.StdEncoding.Encode(enc, []byte(raw))
                        if sasl2 {
-                               fmt.Fprintf(c.conn, "<auth xmlns='%s' 
mechanism='PLAIN'>%s</auth>\n", nsSASL2, enc)
+                               fmt.Fprintf(c.conn, "<authenticate xmlns='%s' 
mechanism='PLAIN'>%s</authenticate>\n", nsSASL2, enc)
                        } else {
                                fmt.Fprintf(c.conn, "<auth xmlns='%s' 
mechanism='PLAIN'>%s</auth>\n", nsSASL, enc)
                        }
@@ -976,14 +994,14 @@
                if v.Token.Token != "" {
                        m := f.Authentication.Inline.Fast.Mechanism
                        switch {
-                       case slices.Contains(m, "HT-SHA-256-EXPR") && tls13:
-                               c.Fast.Mechanism = "HT-SHA-256-EXPR"
-                       case slices.Contains(m, "HT-SHA-256-UNIQ") && !tls13:
-                               c.Fast.Mechanism = "HT-SHA-256-UNIQ"
-                       case slices.Contains(m, "HT-SHA-256-ENDP"):
-                               c.Fast.Mechanism = "HT-SHA-256-ENDP"
-                       case slices.Contains(m, "HT-SHA-256-NONE"):
-                               c.Fast.Mechanism = "HT-SHA-256-NONE"
+                       case slices.Contains(m, htSHA256Expr) && tls13:
+                               c.Fast.Mechanism = htSHA256Expr
+                       case slices.Contains(m, htSHA256Uniq) && !tls13:
+                               c.Fast.Mechanism = htSHA256Uniq
+                       case slices.Contains(m, htSHA256Endp):
+                               c.Fast.Mechanism = htSHA256Endp
+                       case slices.Contains(m, htSHA256None):
+                               c.Fast.Mechanism = htSHA256None
                        }
                        c.Fast.Token = v.Token.Token
                        c.Fast.Expiry, _ = time.Parse(time.RFC3339, 
v.Token.Expiry)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/xmppo/go-xmpp/xmpp_information_query.go 
new/vendor/github.com/xmppo/go-xmpp/xmpp_information_query.go
--- old/vendor/github.com/xmppo/go-xmpp/xmpp_information_query.go       
2024-10-26 19:43:43.000000000 +0200
+++ new/vendor/github.com/xmppo/go-xmpp/xmpp_information_query.go       
2024-11-26 08:45:58.000000000 +0100
@@ -17,12 +17,18 @@
        return c.RawInformationQuery(c.jid, c.domain, reqID, IQTypeGet, 
XMPPNS_DISCO_ITEMS, "")
 }
 
-// Discover information about a node
+// Discover information about a node. Empty node queries info about server 
itself.
 func (c *Client) DiscoverNodeInfo(node string) (string, error) {
        query := fmt.Sprintf("<query xmlns='%s' node='%s'/>", 
XMPPNS_DISCO_INFO, node)
        return c.RawInformation(c.jid, c.domain, "info3", IQTypeGet, query)
 }
 
+// Discover information about given item from given jid.
+func (c *Client) DiscoverInfo(to string) (string, error) {
+       query := fmt.Sprintf("<query xmlns='%s'/>", XMPPNS_DISCO_INFO)
+       return c.RawInformation(c.jid, to, "info3", IQTypeGet, query)
+}
+
 // Discover items that the server exposes
 func (c *Client) DiscoverServerItems() (string, error) {
        return c.DiscoverEntityItems(c.domain)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/crypto/sha3/doc.go 
new/vendor/golang.org/x/crypto/sha3/doc.go
--- old/vendor/golang.org/x/crypto/sha3/doc.go  2024-10-26 19:43:43.000000000 
+0200
+++ new/vendor/golang.org/x/crypto/sha3/doc.go  2024-11-26 08:45:58.000000000 
+0100
@@ -5,6 +5,10 @@
 // Package sha3 implements the SHA-3 fixed-output-length hash functions and
 // the SHAKE variable-output-length hash functions defined by FIPS-202.
 //
+// All types in this package also implement [encoding.BinaryMarshaler],
+// [encoding.BinaryAppender] and [encoding.BinaryUnmarshaler] to marshal and
+// unmarshal the internal state of the hash.
+//
 // Both types of hash function use the "sponge" construction and the Keccak
 // permutation. For a detailed specification see http://keccak.noekeon.org/
 //
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/crypto/sha3/hashes.go 
new/vendor/golang.org/x/crypto/sha3/hashes.go
--- old/vendor/golang.org/x/crypto/sha3/hashes.go       2024-10-26 
19:43:43.000000000 +0200
+++ new/vendor/golang.org/x/crypto/sha3/hashes.go       2024-11-26 
08:45:58.000000000 +0100
@@ -48,33 +48,52 @@
        crypto.RegisterHash(crypto.SHA3_512, New512)
 }
 
+const (
+       dsbyteSHA3   = 0b00000110
+       dsbyteKeccak = 0b00000001
+       dsbyteShake  = 0b00011111
+       dsbyteCShake = 0b00000100
+
+       // rateK[c] is the rate in bytes for Keccak[c] where c is the capacity 
in
+       // bits. Given the sponge size is 1600 bits, the rate is 1600 - c bits.
+       rateK256  = (1600 - 256) / 8
+       rateK448  = (1600 - 448) / 8
+       rateK512  = (1600 - 512) / 8
+       rateK768  = (1600 - 768) / 8
+       rateK1024 = (1600 - 1024) / 8
+)
+
 func new224Generic() *state {
-       return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
+       return &state{rate: rateK448, outputLen: 28, dsbyte: dsbyteSHA3}
 }
 
 func new256Generic() *state {
-       return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
+       return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteSHA3}
 }
 
 func new384Generic() *state {
-       return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
+       return &state{rate: rateK768, outputLen: 48, dsbyte: dsbyteSHA3}
 }
 
 func new512Generic() *state {
-       return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
+       return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteSHA3}
 }
 
 // NewLegacyKeccak256 creates a new Keccak-256 hash.
 //
 // Only use this function if you require compatibility with an existing 
cryptosystem
 // that uses non-standard padding. All other users should use New256 instead.
-func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, 
dsbyte: 0x01} }
+func NewLegacyKeccak256() hash.Hash {
+       return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteKeccak}
+}
 
 // NewLegacyKeccak512 creates a new Keccak-512 hash.
 //
 // Only use this function if you require compatibility with an existing 
cryptosystem
 // that uses non-standard padding. All other users should use New512 instead.
-func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, 
dsbyte: 0x01} }
+func NewLegacyKeccak512() hash.Hash {
+       return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteKeccak}
+}
 
 // Sum224 returns the SHA3-224 digest of the data.
 func Sum224(data []byte) (digest [28]byte) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/crypto/sha3/sha3.go 
new/vendor/golang.org/x/crypto/sha3/sha3.go
--- old/vendor/golang.org/x/crypto/sha3/sha3.go 2024-10-26 19:43:43.000000000 
+0200
+++ new/vendor/golang.org/x/crypto/sha3/sha3.go 2024-11-26 08:45:58.000000000 
+0100
@@ -4,6 +4,15 @@
 
 package sha3
 
+import (
+       "crypto/subtle"
+       "encoding/binary"
+       "errors"
+       "unsafe"
+
+       "golang.org/x/sys/cpu"
+)
+
 // spongeDirection indicates the direction bytes are flowing through the 
sponge.
 type spongeDirection int
 
@@ -14,16 +23,13 @@
        spongeSqueezing
 )
 
-const (
-       // maxRate is the maximum size of the internal buffer. SHAKE-256
-       // currently needs the largest buffer.
-       maxRate = 168
-)
-
 type state struct {
-       // Generic sponge components.
-       a    [25]uint64 // main state of the hash
-       rate int        // the number of bytes of state to use
+       a [1600 / 8]byte // main state of the hash
+
+       // a[n:rate] is the buffer. If absorbing, it's the remaining space to 
XOR
+       // into before running the permutation. If squeezing, it's the remaining
+       // output to produce before running the permutation.
+       n, rate int
 
        // dsbyte contains the "domain separation" bits and the first bit of
        // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
@@ -39,10 +45,6 @@
        //      Extendable-Output Functions (May 2014)"
        dsbyte byte
 
-       i, n    int // storage[i:n] is the buffer, i is only used while 
squeezing
-       storage [maxRate]byte
-
-       // Specific to SHA-3 and SHAKE.
        outputLen int             // the default output size in bytes
        state     spongeDirection // whether the sponge is absorbing or 
squeezing
 }
@@ -61,7 +63,7 @@
                d.a[i] = 0
        }
        d.state = spongeAbsorbing
-       d.i, d.n = 0, 0
+       d.n = 0
 }
 
 func (d *state) clone() *state {
@@ -69,22 +71,25 @@
        return &ret
 }
 
-// permute applies the KeccakF-1600 permutation. It handles
-// any input-output buffering.
+// permute applies the KeccakF-1600 permutation.
 func (d *state) permute() {
-       switch d.state {
-       case spongeAbsorbing:
-               // If we're absorbing, we need to xor the input into the state
-               // before applying the permutation.
-               xorIn(d, d.storage[:d.rate])
-               d.n = 0
-               keccakF1600(&d.a)
-       case spongeSqueezing:
-               // If we're squeezing, we need to apply the permutation before
-               // copying more output.
-               keccakF1600(&d.a)
-               d.i = 0
-               copyOut(d, d.storage[:d.rate])
+       var a *[25]uint64
+       if cpu.IsBigEndian {
+               a = new([25]uint64)
+               for i := range a {
+                       a[i] = binary.LittleEndian.Uint64(d.a[i*8:])
+               }
+       } else {
+               a = (*[25]uint64)(unsafe.Pointer(&d.a))
+       }
+
+       keccakF1600(a)
+       d.n = 0
+
+       if cpu.IsBigEndian {
+               for i := range a {
+                       binary.LittleEndian.PutUint64(d.a[i*8:], a[i])
+               }
        }
 }
 
@@ -92,53 +97,36 @@
 // the multi-bitrate 10..1 padding rule, and permutes the state.
 func (d *state) padAndPermute() {
        // Pad with this instance's domain-separator bits. We know that there's
-       // at least one byte of space in d.buf because, if it were full,
+       // at least one byte of space in the sponge because, if it were full,
        // permute would have been called to empty it. dsbyte also contains the
        // first one bit for the padding. See the comment in the state struct.
-       d.storage[d.n] = d.dsbyte
-       d.n++
-       for d.n < d.rate {
-               d.storage[d.n] = 0
-               d.n++
-       }
+       d.a[d.n] ^= d.dsbyte
        // This adds the final one bit for the padding. Because of the way that
        // bits are numbered from the LSB upwards, the final bit is the MSB of
        // the last byte.
-       d.storage[d.rate-1] ^= 0x80
+       d.a[d.rate-1] ^= 0x80
        // Apply the permutation
        d.permute()
        d.state = spongeSqueezing
-       d.n = d.rate
-       copyOut(d, d.storage[:d.rate])
 }
 
 // Write absorbs more data into the hash's state. It panics if any
 // output has already been read.
-func (d *state) Write(p []byte) (written int, err error) {
+func (d *state) Write(p []byte) (n int, err error) {
        if d.state != spongeAbsorbing {
                panic("sha3: Write after Read")
        }
-       written = len(p)
+
+       n = len(p)
 
        for len(p) > 0 {
-               if d.n == 0 && len(p) >= d.rate {
-                       // The fast path; absorb a full "rate" bytes of input 
and apply the permutation.
-                       xorIn(d, p[:d.rate])
-                       p = p[d.rate:]
-                       keccakF1600(&d.a)
-               } else {
-                       // The slow path; buffer the input until we can fill 
the sponge, and then xor it in.
-                       todo := d.rate - d.n
-                       if todo > len(p) {
-                               todo = len(p)
-                       }
-                       d.n += copy(d.storage[d.n:], p[:todo])
-                       p = p[todo:]
-
-                       // If the sponge is full, apply the permutation.
-                       if d.n == d.rate {
-                               d.permute()
-                       }
+               x := subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
+               d.n += x
+               p = p[x:]
+
+               // If the sponge is full, apply the permutation.
+               if d.n == d.rate {
+                       d.permute()
                }
        }
 
@@ -156,14 +144,14 @@
 
        // Now, do the squeezing.
        for len(out) > 0 {
-               n := copy(out, d.storage[d.i:d.n])
-               d.i += n
-               out = out[n:]
-
                // Apply the permutation if we've squeezed the sponge dry.
-               if d.i == d.rate {
+               if d.n == d.rate {
                        d.permute()
                }
+
+               x := copy(out, d.a[d.n:d.rate])
+               d.n += x
+               out = out[x:]
        }
 
        return
@@ -183,3 +171,74 @@
        dup.Read(hash)
        return append(in, hash...)
 }
+
+const (
+       magicSHA3   = "sha\x08"
+       magicShake  = "sha\x09"
+       magicCShake = "sha\x0a"
+       magicKeccak = "sha\x0b"
+       // magic || rate || main state || n || sponge direction
+       marshaledSize = len(magicSHA3) + 1 + 200 + 1 + 1
+)
+
+func (d *state) MarshalBinary() ([]byte, error) {
+       return d.AppendBinary(make([]byte, 0, marshaledSize))
+}
+
+func (d *state) AppendBinary(b []byte) ([]byte, error) {
+       switch d.dsbyte {
+       case dsbyteSHA3:
+               b = append(b, magicSHA3...)
+       case dsbyteShake:
+               b = append(b, magicShake...)
+       case dsbyteCShake:
+               b = append(b, magicCShake...)
+       case dsbyteKeccak:
+               b = append(b, magicKeccak...)
+       default:
+               panic("unknown dsbyte")
+       }
+       // rate is at most 168, and n is at most rate.
+       b = append(b, byte(d.rate))
+       b = append(b, d.a[:]...)
+       b = append(b, byte(d.n), byte(d.state))
+       return b, nil
+}
+
+func (d *state) UnmarshalBinary(b []byte) error {
+       if len(b) != marshaledSize {
+               return errors.New("sha3: invalid hash state")
+       }
+
+       magic := string(b[:len(magicSHA3)])
+       b = b[len(magicSHA3):]
+       switch {
+       case magic == magicSHA3 && d.dsbyte == dsbyteSHA3:
+       case magic == magicShake && d.dsbyte == dsbyteShake:
+       case magic == magicCShake && d.dsbyte == dsbyteCShake:
+       case magic == magicKeccak && d.dsbyte == dsbyteKeccak:
+       default:
+               return errors.New("sha3: invalid hash state identifier")
+       }
+
+       rate := int(b[0])
+       b = b[1:]
+       if rate != d.rate {
+               return errors.New("sha3: invalid hash state function")
+       }
+
+       copy(d.a[:], b)
+       b = b[len(d.a):]
+
+       n, state := int(b[0]), spongeDirection(b[1])
+       if n > d.rate {
+               return errors.New("sha3: invalid hash state")
+       }
+       d.n = n
+       if state != spongeAbsorbing && state != spongeSqueezing {
+               return errors.New("sha3: invalid hash state")
+       }
+       d.state = state
+
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/crypto/sha3/shake.go 
new/vendor/golang.org/x/crypto/sha3/shake.go
--- old/vendor/golang.org/x/crypto/sha3/shake.go        2024-10-26 
19:43:43.000000000 +0200
+++ new/vendor/golang.org/x/crypto/sha3/shake.go        2024-11-26 
08:45:58.000000000 +0100
@@ -16,9 +16,12 @@
 // [2] https://doi.org/10.6028/NIST.SP.800-185
 
 import (
+       "bytes"
        "encoding/binary"
+       "errors"
        "hash"
        "io"
+       "math/bits"
 )
 
 // ShakeHash defines the interface to hash functions that support
@@ -50,41 +53,33 @@
        initBlock []byte
 }
 
-// Consts for configuring initial SHA-3 state
-const (
-       dsbyteShake  = 0x1f
-       dsbyteCShake = 0x04
-       rate128      = 168
-       rate256      = 136
-)
+func bytepad(data []byte, rate int) []byte {
+       out := make([]byte, 0, 9+len(data)+rate-1)
+       out = append(out, leftEncode(uint64(rate))...)
+       out = append(out, data...)
+       if padlen := rate - len(out)%rate; padlen < rate {
+               out = append(out, make([]byte, padlen)...)
+       }
+       return out
+}
 
-func bytepad(input []byte, w int) []byte {
-       // leftEncode always returns max 9 bytes
-       buf := make([]byte, 0, 9+len(input)+w)
-       buf = append(buf, leftEncode(uint64(w))...)
-       buf = append(buf, input...)
-       padlen := w - (len(buf) % w)
-       return append(buf, make([]byte, padlen)...)
-}
-
-func leftEncode(value uint64) []byte {
-       var b [9]byte
-       binary.BigEndian.PutUint64(b[1:], value)
-       // Trim all but last leading zero bytes
-       i := byte(1)
-       for i < 8 && b[i] == 0 {
-               i++
-       }
-       // Prepend number of encoded bytes
-       b[i-1] = 9 - i
-       return b[i-1:]
+func leftEncode(x uint64) []byte {
+       // Let n be the smallest positive integer for which 2^(8n) > x.
+       n := (bits.Len64(x) + 7) / 8
+       if n == 0 {
+               n = 1
+       }
+       // Return n || x with n as a byte and x an n bytes in big-endian order.
+       b := make([]byte, 9)
+       binary.BigEndian.PutUint64(b[1:], x)
+       b = b[9-n-1:]
+       b[0] = byte(n)
+       return b
 }
 
 func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash {
        c := cshakeState{state: &state{rate: rate, outputLen: outputLen, 
dsbyte: dsbyte}}
-
-       // leftEncode returns max 9 bytes
-       c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
+       c.initBlock = make([]byte, 0, 9+len(N)+9+len(S)) // leftEncode returns 
max 9 bytes
        c.initBlock = append(c.initBlock, leftEncode(uint64(len(N))*8)...)
        c.initBlock = append(c.initBlock, N...)
        c.initBlock = append(c.initBlock, leftEncode(uint64(len(S))*8)...)
@@ -111,6 +106,30 @@
        return c.clone()
 }
 
+func (c *cshakeState) MarshalBinary() ([]byte, error) {
+       return c.AppendBinary(make([]byte, 0, marshaledSize+len(c.initBlock)))
+}
+
+func (c *cshakeState) AppendBinary(b []byte) ([]byte, error) {
+       b, err := c.state.AppendBinary(b)
+       if err != nil {
+               return nil, err
+       }
+       b = append(b, c.initBlock...)
+       return b, nil
+}
+
+func (c *cshakeState) UnmarshalBinary(b []byte) error {
+       if len(b) <= marshaledSize {
+               return errors.New("sha3: invalid hash state")
+       }
+       if err := c.state.UnmarshalBinary(b[:marshaledSize]); err != nil {
+               return err
+       }
+       c.initBlock = bytes.Clone(b[marshaledSize:])
+       return nil
+}
+
 // NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
 // Its generic security strength is 128 bits against all attacks if at
 // least 32 bytes of its output are used.
@@ -126,11 +145,11 @@
 }
 
 func newShake128Generic() *state {
-       return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
+       return &state{rate: rateK256, outputLen: 32, dsbyte: dsbyteShake}
 }
 
 func newShake256Generic() *state {
-       return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
+       return &state{rate: rateK512, outputLen: 64, dsbyte: dsbyteShake}
 }
 
 // NewCShake128 creates a new instance of cSHAKE128 variable-output-length 
ShakeHash,
@@ -143,7 +162,7 @@
        if len(N) == 0 && len(S) == 0 {
                return NewShake128()
        }
-       return newCShake(N, S, rate128, 32, dsbyteCShake)
+       return newCShake(N, S, rateK256, 32, dsbyteCShake)
 }
 
 // NewCShake256 creates a new instance of cSHAKE256 variable-output-length 
ShakeHash,
@@ -156,7 +175,7 @@
        if len(N) == 0 && len(S) == 0 {
                return NewShake256()
        }
-       return newCShake(N, S, rate256, 64, dsbyteCShake)
+       return newCShake(N, S, rateK512, 64, dsbyteCShake)
 }
 
 // ShakeSum128 writes an arbitrary-length digest of data into hash.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/crypto/sha3/xor.go 
new/vendor/golang.org/x/crypto/sha3/xor.go
--- old/vendor/golang.org/x/crypto/sha3/xor.go  2024-10-26 19:43:43.000000000 
+0200
+++ new/vendor/golang.org/x/crypto/sha3/xor.go  1970-01-01 01:00:00.000000000 
+0100
@@ -1,40 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sha3
-
-import (
-       "crypto/subtle"
-       "encoding/binary"
-       "unsafe"
-
-       "golang.org/x/sys/cpu"
-)
-
-// xorIn xors the bytes in buf into the state.
-func xorIn(d *state, buf []byte) {
-       if cpu.IsBigEndian {
-               for i := 0; len(buf) >= 8; i++ {
-                       a := binary.LittleEndian.Uint64(buf)
-                       d.a[i] ^= a
-                       buf = buf[8:]
-               }
-       } else {
-               ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
-               subtle.XORBytes(ab[:], ab[:], buf)
-       }
-}
-
-// copyOut copies uint64s to a byte buffer.
-func copyOut(d *state, b []byte) {
-       if cpu.IsBigEndian {
-               for i := 0; len(b) >= 8; i++ {
-                       binary.LittleEndian.PutUint64(b, d.a[i])
-                       b = b[8:]
-               }
-       } else {
-               ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
-               copy(b, ab[:])
-       }
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/net/html/doc.go 
new/vendor/golang.org/x/net/html/doc.go
--- old/vendor/golang.org/x/net/html/doc.go     2024-10-26 19:43:43.000000000 
+0200
+++ new/vendor/golang.org/x/net/html/doc.go     2024-11-26 08:45:58.000000000 
+0100
@@ -78,16 +78,11 @@
        if err != nil {
                // ...
        }
-       var f func(*html.Node)
-       f = func(n *html.Node) {
+       for n := range doc.Descendants() {
                if n.Type == html.ElementNode && n.Data == "a" {
                        // Do something with n...
                }
-               for c := n.FirstChild; c != nil; c = c.NextSibling {
-                       f(c)
-               }
        }
-       f(doc)
 
 The relevant specifications include:
 https://html.spec.whatwg.org/multipage/syntax.html and
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/net/html/iter.go 
new/vendor/golang.org/x/net/html/iter.go
--- old/vendor/golang.org/x/net/html/iter.go    1970-01-01 01:00:00.000000000 
+0100
+++ new/vendor/golang.org/x/net/html/iter.go    2024-11-26 08:45:58.000000000 
+0100
@@ -0,0 +1,56 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.23
+
+package html
+
+import "iter"
+
+// Ancestors returns an iterator over the ancestors of n, starting with 
n.Parent.
+//
+// Mutating a Node or its parents while iterating may have unexpected results.
+func (n *Node) Ancestors() iter.Seq[*Node] {
+       _ = n.Parent // eager nil check
+
+       return func(yield func(*Node) bool) {
+               for p := n.Parent; p != nil && yield(p); p = p.Parent {
+               }
+       }
+}
+
+// ChildNodes returns an iterator over the immediate children of n,
+// starting with n.FirstChild.
+//
+// Mutating a Node or its children while iterating may have unexpected results.
+func (n *Node) ChildNodes() iter.Seq[*Node] {
+       _ = n.FirstChild // eager nil check
+
+       return func(yield func(*Node) bool) {
+               for c := n.FirstChild; c != nil && yield(c); c = c.NextSibling {
+               }
+       }
+
+}
+
+// Descendants returns an iterator over all nodes recursively beneath
+// n, excluding n itself. Nodes are visited in depth-first preorder.
+//
+// Mutating a Node or its descendants while iterating may have unexpected 
results.
+func (n *Node) Descendants() iter.Seq[*Node] {
+       _ = n.FirstChild // eager nil check
+
+       return func(yield func(*Node) bool) {
+               n.descendants(yield)
+       }
+}
+
+func (n *Node) descendants(yield func(*Node) bool) bool {
+       for c := range n.ChildNodes() {
+               if !yield(c) || !c.descendants(yield) {
+                       return false
+               }
+       }
+       return true
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/net/html/node.go 
new/vendor/golang.org/x/net/html/node.go
--- old/vendor/golang.org/x/net/html/node.go    2024-10-26 19:43:43.000000000 
+0200
+++ new/vendor/golang.org/x/net/html/node.go    2024-11-26 08:45:58.000000000 
+0100
@@ -38,6 +38,10 @@
 // that it looks like "a<b" rather than "a&lt;b". For element nodes, DataAtom
 // is the atom for Data, or zero if Data is not a known tag name.
 //
+// Node trees may be navigated using the link fields (Parent,
+// FirstChild, and so on) or a range loop over iterators such as
+// [Node.Descendants].
+//
 // An empty Namespace implies a "http://www.w3.org/1999/xhtml"; namespace.
 // Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML";, and
 // "svg" is short for "http://www.w3.org/2000/svg";.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s 
new/vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s
--- old/vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s 1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s 2024-11-26 
08:45:58.000000000 +0100
@@ -0,0 +1,17 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin && amd64 && gc
+
+#include "textflag.h"
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+       JMP     libc_sysctl(SB)
+GLOBL  ·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA   ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_sysctlbyname_trampoline<>(SB),NOSPLIT,$0-0
+       JMP     libc_sysctlbyname(SB)
+GLOBL  ·libc_sysctlbyname_trampoline_addr(SB), RODATA, $8
+DATA   ·libc_sysctlbyname_trampoline_addr(SB)/8, 
$libc_sysctlbyname_trampoline<>(SB)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go 
new/vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go
--- old/vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go   1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go   2024-11-26 
08:45:58.000000000 +0100
@@ -0,0 +1,61 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin && amd64 && gc
+
+package cpu
+
+// darwinSupportsAVX512 checks Darwin kernel for AVX512 support via sysctl
+// call (see issue 43089). It also restricts AVX512 support for Darwin to
+// kernel version 21.3.0 (MacOS 12.2.0) or later (see issue 49233).
+//
+// Background:
+// Darwin implements a special mechanism to economize on thread state when
+// AVX512 specific registers are not in use. This scheme minimizes state when
+// preempting threads that haven't yet used any AVX512 instructions, but adds
+// special requirements to check for AVX512 hardware support at runtime (e.g.
+// via sysctl call or commpage inspection). See issue 43089 and link below for
+// full background:
+// 
https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.1.10/osfmk/i386/fpu.c#L214-L240
+//
+// Additionally, all versions of the Darwin kernel from 19.6.0 through 21.2.0
+// (corresponding to MacOS 10.15.6 - 12.1) have a bug that can cause corruption
+// of the AVX512 mask registers (K0-K7) upon signal return. For this reason
+// AVX512 is considered unsafe to use on Darwin for kernel versions prior to
+// 21.3.0, where a fix has been confirmed. See issue 49233 for full background.
+func darwinSupportsAVX512() bool {
+       return darwinSysctlEnabled([]byte("hw.optional.avx512f\x00")) && 
darwinKernelVersionCheck(21, 3, 0)
+}
+
+// Ensure Darwin kernel version is at least major.minor.patch, avoiding 
dependencies
+func darwinKernelVersionCheck(major, minor, patch int) bool {
+       var release [256]byte
+       err := darwinOSRelease(&release)
+       if err != nil {
+               return false
+       }
+
+       var mmp [3]int
+       c := 0
+Loop:
+       for _, b := range release[:] {
+               switch {
+               case b >= '0' && b <= '9':
+                       mmp[c] = 10*mmp[c] + int(b-'0')
+               case b == '.':
+                       c++
+                       if c > 2 {
+                               return false
+                       }
+               case b == 0:
+                       break Loop
+               default:
+                       return false
+               }
+       }
+       if c != 2 {
+               return false
+       }
+       return mmp[0] > major || mmp[0] == major && (mmp[1] > minor || mmp[1] 
== minor && mmp[2] >= patch)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go 
new/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
--- old/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go       2024-10-26 
19:43:43.000000000 +0200
+++ new/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go       2024-11-26 
08:45:58.000000000 +0100
@@ -6,10 +6,10 @@
 
 package cpu
 
-// cpuid is implemented in cpu_x86.s for gc compiler
+// cpuid is implemented in cpu_gc_x86.s for gc compiler
 // and in cpu_gccgo.c for gccgo.
 func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
 
-// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
+// xgetbv with ecx = 0 is implemented in cpu_gc_x86.s for gc compiler
 // and in cpu_gccgo.c for gccgo.
 func xgetbv() (eax, edx uint32)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_gc_x86.s 
new/vendor/golang.org/x/sys/cpu/cpu_gc_x86.s
--- old/vendor/golang.org/x/sys/cpu/cpu_gc_x86.s        1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/golang.org/x/sys/cpu/cpu_gc_x86.s        2024-11-26 
08:45:58.000000000 +0100
@@ -0,0 +1,26 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (386 || amd64 || amd64p32) && gc
+
+#include "textflag.h"
+
+// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
+TEXT ·cpuid(SB), NOSPLIT, $0-24
+       MOVL eaxArg+0(FP), AX
+       MOVL ecxArg+4(FP), CX
+       CPUID
+       MOVL AX, eax+8(FP)
+       MOVL BX, ebx+12(FP)
+       MOVL CX, ecx+16(FP)
+       MOVL DX, edx+20(FP)
+       RET
+
+// func xgetbv() (eax, edx uint32)
+TEXT ·xgetbv(SB), NOSPLIT, $0-8
+       MOVL $0, CX
+       XGETBV
+       MOVL AX, eax+0(FP)
+       MOVL DX, edx+4(FP)
+       RET
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go 
new/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
--- old/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go    2024-10-26 
19:43:43.000000000 +0200
+++ new/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go    2024-11-26 
08:45:58.000000000 +0100
@@ -23,9 +23,3 @@
        gccgoXgetbv(&a, &d)
        return a, d
 }
-
-// gccgo doesn't build on Darwin, per:
-// https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gcc.rb#L76
-func darwinSupportsAVX512() bool {
-       return false
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go 
new/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
--- old/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go  2024-10-26 
19:43:43.000000000 +0200
+++ new/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go  2024-11-26 
08:45:58.000000000 +0100
@@ -110,7 +110,6 @@
        ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
        ARM64.HasDIT = isSet(hwCap, hwcap_DIT)
 
-
        // HWCAP2 feature bits
        ARM64.HasSVE2 = isSet(hwCap2, hwcap2_SVE2)
        ARM64.HasI8MM = isSet(hwCap2, hwcap2_I8MM)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_other_x86.go 
new/vendor/golang.org/x/sys/cpu/cpu_other_x86.go
--- old/vendor/golang.org/x/sys/cpu/cpu_other_x86.go    1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/golang.org/x/sys/cpu/cpu_other_x86.go    2024-11-26 
08:45:58.000000000 +0100
@@ -0,0 +1,11 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 || amd64p32 || (amd64 && (!darwin || !gc))
+
+package cpu
+
+func darwinSupportsAVX512() bool {
+       panic("only implemented for gc && amd64 && darwin")
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_x86.go 
new/vendor/golang.org/x/sys/cpu/cpu_x86.go
--- old/vendor/golang.org/x/sys/cpu/cpu_x86.go  2024-10-26 19:43:43.000000000 
+0200
+++ new/vendor/golang.org/x/sys/cpu/cpu_x86.go  2024-11-26 08:45:58.000000000 
+0100
@@ -92,10 +92,8 @@
                osSupportsAVX = isSet(1, eax) && isSet(2, eax)
 
                if runtime.GOOS == "darwin" {
-                       // Darwin doesn't save/restore AVX-512 mask registers 
correctly across signal handlers.
-                       // Since users can't rely on mask register contents, 
let's not advertise AVX-512 support.
-                       // See issue 49233.
-                       osSupportsAVX512 = false
+                       // Darwin requires special AVX512 checks, see 
cpu_darwin_x86.go
+                       osSupportsAVX512 = osSupportsAVX && 
darwinSupportsAVX512()
                } else {
                        // Check if OPMASK and ZMM registers have OS support.
                        osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && 
isSet(6, eax) && isSet(7, eax)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_x86.s 
new/vendor/golang.org/x/sys/cpu/cpu_x86.s
--- old/vendor/golang.org/x/sys/cpu/cpu_x86.s   2024-10-26 19:43:43.000000000 
+0200
+++ new/vendor/golang.org/x/sys/cpu/cpu_x86.s   1970-01-01 01:00:00.000000000 
+0100
@@ -1,26 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build (386 || amd64 || amd64p32) && gc
-
-#include "textflag.h"
-
-// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
-TEXT ·cpuid(SB), NOSPLIT, $0-24
-       MOVL eaxArg+0(FP), AX
-       MOVL ecxArg+4(FP), CX
-       CPUID
-       MOVL AX, eax+8(FP)
-       MOVL BX, ebx+12(FP)
-       MOVL CX, ecx+16(FP)
-       MOVL DX, edx+20(FP)
-       RET
-
-// func xgetbv() (eax, edx uint32)
-TEXT ·xgetbv(SB),NOSPLIT,$0-8
-       MOVL $0, CX
-       XGETBV
-       MOVL AX, eax+0(FP)
-       MOVL DX, edx+4(FP)
-       RET
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go 
new/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go
--- old/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go    1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go    2024-11-26 
08:45:58.000000000 +0100
@@ -0,0 +1,98 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Minimal copy of x/sys/unix so the cpu package can make a
+// system call on Darwin without depending on x/sys/unix.
+
+//go:build darwin && amd64 && gc
+
+package cpu
+
+import (
+       "syscall"
+       "unsafe"
+)
+
+type _C_int int32
+
+// adapted from unix.Uname() at x/sys/unix/syscall_darwin.go L419
+func darwinOSRelease(release *[256]byte) error {
+       // from x/sys/unix/zerrors_openbsd_amd64.go
+       const (
+               CTL_KERN       = 0x1
+               KERN_OSRELEASE = 0x2
+       )
+
+       mib := []_C_int{CTL_KERN, KERN_OSRELEASE}
+       n := unsafe.Sizeof(*release)
+
+       return sysctl(mib, &release[0], &n, nil, 0)
+}
+
+type Errno = syscall.Errno
+
+var _zero uintptr // Single-word zero for use when we need a valid pointer to 
0 bytes.
+
+// from x/sys/unix/zsyscall_darwin_amd64.go L791-807
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen 
uintptr) error {
+       var _p0 unsafe.Pointer
+       if len(mib) > 0 {
+               _p0 = unsafe.Pointer(&mib[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       if _, _, err := syscall_syscall6(
+               libc_sysctl_trampoline_addr,
+               uintptr(_p0),
+               uintptr(len(mib)),
+               uintptr(unsafe.Pointer(old)),
+               uintptr(unsafe.Pointer(oldlen)),
+               uintptr(unsafe.Pointer(new)),
+               uintptr(newlen),
+       ); err != 0 {
+               return err
+       }
+
+       return nil
+}
+
+var libc_sysctl_trampoline_addr uintptr
+
+// adapted from internal/cpu/cpu_arm64_darwin.go
+func darwinSysctlEnabled(name []byte) bool {
+       out := int32(0)
+       nout := unsafe.Sizeof(out)
+       if ret := sysctlbyname(&name[0], (*byte)(unsafe.Pointer(&out)), &nout, 
nil, 0); ret != nil {
+               return false
+       }
+       return out > 0
+}
+
+//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
+
+var libc_sysctlbyname_trampoline_addr uintptr
+
+// adapted from runtime/sys_darwin.go in the pattern of sysctl() above, as 
defined in x/sys/unix
+func sysctlbyname(name *byte, old *byte, oldlen *uintptr, new *byte, newlen 
uintptr) error {
+       if _, _, err := syscall_syscall6(
+               libc_sysctlbyname_trampoline_addr,
+               uintptr(unsafe.Pointer(name)),
+               uintptr(unsafe.Pointer(old)),
+               uintptr(unsafe.Pointer(oldlen)),
+               uintptr(unsafe.Pointer(new)),
+               uintptr(newlen),
+               0,
+       ); err != 0 {
+               return err
+       }
+
+       return nil
+}
+
+//go:cgo_import_dynamic libc_sysctlbyname sysctlbyname 
"/usr/lib/libSystem.B.dylib"
+
+// Implemented in the runtime package (runtime/sys_darwin.go)
+func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err 
Errno)
+
+//go:linkname syscall_syscall6 syscall.syscall6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt
--- old/vendor/modules.txt      2024-10-26 19:43:43.000000000 +0200
+++ new/vendor/modules.txt      2024-11-26 08:45:58.000000000 +0100
@@ -1,4 +1,4 @@
-# github.com/ProtonMail/go-crypto v1.1.0-beta.0
+# github.com/ProtonMail/go-crypto v1.1.2
 ## explicit; go 1.17
 github.com/ProtonMail/go-crypto/bitcurves
 github.com/ProtonMail/go-crypto/brainpool
@@ -26,7 +26,7 @@
 # github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f
 ## explicit; go 1.12
 github.com/ProtonMail/go-mime
-# github.com/ProtonMail/gopenpgp/v2 v2.8.0-beta.0
+# github.com/ProtonMail/gopenpgp/v2 v2.8.0
 ## explicit; go 1.17
 github.com/ProtonMail/gopenpgp/v2/armor
 github.com/ProtonMail/gopenpgp/v2/constants
@@ -64,10 +64,10 @@
 # github.com/pkg/errors v0.9.1
 ## explicit
 github.com/pkg/errors
-# github.com/xmppo/go-xmpp v0.2.4
+# github.com/xmppo/go-xmpp v0.2.5
 ## explicit; go 1.21.5
 github.com/xmppo/go-xmpp
-# golang.org/x/crypto v0.28.0
+# golang.org/x/crypto v0.29.0
 ## explicit; go 1.20
 golang.org/x/crypto/argon2
 golang.org/x/crypto/blake2b
@@ -76,16 +76,16 @@
 golang.org/x/crypto/pbkdf2
 golang.org/x/crypto/scrypt
 golang.org/x/crypto/sha3
-# golang.org/x/net v0.30.0
+# golang.org/x/net v0.31.0
 ## explicit; go 1.18
 golang.org/x/net/html
 golang.org/x/net/html/atom
 golang.org/x/net/internal/socks
 golang.org/x/net/proxy
-# golang.org/x/sys v0.26.0
+# golang.org/x/sys v0.27.0
 ## explicit; go 1.18
 golang.org/x/sys/cpu
-# golang.org/x/text v0.19.0
+# golang.org/x/text v0.20.0
 ## explicit; go 1.18
 golang.org/x/text/encoding
 golang.org/x/text/encoding/charmap
@@ -104,6 +104,6 @@
 golang.org/x/text/language
 golang.org/x/text/runes
 golang.org/x/text/transform
-# salsa.debian.org/mdosch/xmppsrv v0.3.2
+# salsa.debian.org/mdosch/xmppsrv v0.3.3
 ## explicit; go 1.16
 salsa.debian.org/mdosch/xmppsrv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/salsa.debian.org/mdosch/xmppsrv/CHANGELOG.md 
new/vendor/salsa.debian.org/mdosch/xmppsrv/CHANGELOG.md
--- old/vendor/salsa.debian.org/mdosch/xmppsrv/CHANGELOG.md     2024-10-26 
19:43:43.000000000 +0200
+++ new/vendor/salsa.debian.org/mdosch/xmppsrv/CHANGELOG.md     2024-11-26 
08:45:58.000000000 +0100
@@ -1,7 +1,11 @@
 # Changelog
 
+## [0.3.3] 20224-11-02
+### Added
+- Add host-meta2 look up.
+
 ## [0.3.2] 2024-08-20
-## Added
+###  Added
 - Add constant including version.
 
 ## [0.3.1] 2024-08-18
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/salsa.debian.org/mdosch/xmppsrv/const.go 
new/vendor/salsa.debian.org/mdosch/xmppsrv/const.go
--- old/vendor/salsa.debian.org/mdosch/xmppsrv/const.go 1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/salsa.debian.org/mdosch/xmppsrv/const.go 2024-11-26 
08:45:58.000000000 +0100
@@ -0,0 +1,7 @@
+// 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 xmppsrv
+
+const Version = "0.3.3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/salsa.debian.org/mdosch/xmppsrv/hostmeta2.go 
new/vendor/salsa.debian.org/mdosch/xmppsrv/hostmeta2.go
--- old/vendor/salsa.debian.org/mdosch/xmppsrv/hostmeta2.go     1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/salsa.debian.org/mdosch/xmppsrv/hostmeta2.go     2024-11-26 
08:45:58.000000000 +0100
@@ -0,0 +1,56 @@
+// 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 xmppsrv
+
+import (
+       "encoding/json"
+       "fmt"
+       "io"
+       "net/http"
+)
+
+// The Hostmeta2 type includes all informations from the host meta 2 file of a
+// given server.
+type Hostmeta2 struct {
+       XMPP struct {
+               TTL                 int      `json:"ttl"`
+               PublicKeyPinsSha256 []string `json:"public-key-pins-sha-256"`
+       } `json:"xmpp"`
+       Links []struct {
+               Rel      string   `json:"rel"`
+               Href     string   `json:"href,omitempty"`
+               Ips      []string `json:"ips,omitempty"`
+               Priority int      `json:"priority,omitempty"`
+               Weight   int      `json:"weight,omitempty"`
+               Sni      string   `json:"sni,omitempty"`
+               Ech      string   `json:"ech,omitempty"`
+               Port     int      `json:"port,omitempty"`
+       } `json:"links"`
+}
+
+// LookupHostmeta2 looks up the host meta 2 file for a given server and 
returns the
+// information as Hostmeta2 type and the HTTP status code.
+func LookupHostmeta2(server string) (Hostmeta2, int, error) {
+       // TODO: 20241030: Also make DNS server configurable.
+       httpClient := &http.Client{}
+       resp, err := httpClient.Get("https://"; + server + 
"/.well-known/host-meta.json")
+       if err != nil {
+               return Hostmeta2{}, 0, fmt.Errorf("xmppsrv: host-meta2: failed 
to request host-meta file: %v", err)
+       }
+       if resp.StatusCode == 404 {
+               return Hostmeta2{}, resp.StatusCode, fmt.Errorf("xmppsrv: 
host-meta2: failed to request host-meta2 file: HTTP status 404")
+       }
+       defer resp.Body.Close()
+       body, err := io.ReadAll(resp.Body)
+       if err != nil {
+               return Hostmeta2{}, resp.StatusCode, fmt.Errorf("xmppsrv: 
host-meta2: failed to read http response body: %v", err)
+       }
+       hm2 := Hostmeta2{}
+       err = json.Unmarshal(body, &hm2)
+       if err != nil {
+               return Hostmeta2{}, resp.StatusCode, fmt.Errorf("xmppsrv: 
host-meta2: failed to unmarshal body: %v", err)
+       }
+       return hm2, resp.StatusCode, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/salsa.debian.org/mdosch/xmppsrv/xmppsrv.go 
new/vendor/salsa.debian.org/mdosch/xmppsrv/xmppsrv.go
--- old/vendor/salsa.debian.org/mdosch/xmppsrv/xmppsrv.go       2024-10-26 
19:43:43.000000000 +0200
+++ new/vendor/salsa.debian.org/mdosch/xmppsrv/xmppsrv.go       2024-11-26 
08:45:58.000000000 +0100
@@ -13,11 +13,8 @@
        "net"
        "sort"
        "strings"
-       "time"
 )
 
-const Version = "0.3.2"
-
 // The Config type is used to configure which resolver is used.
 // Set Resolver to an IP address and DoT to false to use the
 // DNS resolver on port 53 on the given IP address.
@@ -428,7 +425,6 @@
 func LookupClient(server string) ([]SRV, error) {
        var records, records2 []SRV
        var err, err2 error
-       rand.Seed(time.Now().UnixNano())
        // Look up xmpp-client SRV
        records, err = getSRV(server, "xmpp-client")
        // Look up xmpps-client SRV records.
@@ -463,7 +459,6 @@
 func (c *Config) LookupClient(server string) ([]SRV, error) {
        var records, records2 []SRV
        var err, err2 error
-       rand.Seed(time.Now().UnixNano())
        switch {
        case c.Resolver == "":
                // Look up xmpp-client SRV
@@ -512,7 +507,6 @@
 // priority and weight.
 func LookupServer(server string) ([]SRV, error) {
        var err, err2 error
-       rand.Seed(time.Now().UnixNano())
        // Look up xmpp-client SRV
        records, err := getSRV(server, "xmpp-server")
        // Look up xmpps-client SRV records.
@@ -547,7 +541,6 @@
 func (c *Config) LookupServer(server string) ([]SRV, error) {
        var records, records2 []SRV
        var err, err2 error
-       rand.Seed(time.Now().UnixNano())
        switch {
        case c.Resolver == "":
                // Look up xmpp-client SRV

Reply via email to