xmppo / go-xmpp Goto Github PK
View Code? Open in Web Editor NEWGo XMPP Library (From Yasuhiro Matsumoto and based on the code from Russ Cox)
Home Page: https://golang.org/
License: BSD 3-Clause "New" or "Revised" License
Go XMPP Library (From Yasuhiro Matsumoto and based on the code from Russ Cox)
Home Page: https://golang.org/
License: BSD 3-Clause "New" or "Revised" License
I had the problem, that some messages were not delivered when I closed the connection immediately after sending a message. Adding a waiting time of 100 ms between sending and closing solved this.
In the prosody MUC I was told that I should wait for the closing stream element from the server but I think it would be better to have this integrated directly in this lib.
I have a function where I check for the reply to an IQ:
func getIQ(client *xmpp.Client, id string, c chan xmpp.IQ) {
for {
msg, err := client.Recv()
if err != nil {
log.Fatal(err)
}
switch v := msg.(type) {
case xmpp.IQ:
if v.ID == id {
c <- v
return
}
}
}
}
The problem is that if I get an IQ reply of type='error'
it is not accessible but for type='result'
it works. Can you please make all IQs accessible?
Not sure if anyone would be able to help here however it appears that the issue might be related to this plugin. I'm trying to configure the https://github.com/skburgart/go-vacbot plugin which appears to use the go-xmpp scripts as it is shown under the vendor files however when it attempts to connect to the Ecovacs XMPP server at msg-na.ecouser.net:5223 it fails with "starttls handshake: x509: certificate has expired or is not yet valid". I have downloaded the repository and updated the vendor files with the latest copy of go-xmpp and rebuilt the plugin as an executable file using https://github.com/MnrGreg/homebridge-ecovacs-deebot however it still fails. I cannot for the life of me figure out how to ignore the TLS for XMPP. I went back to the original plugin the GoLang script is based off of which is https://github.com/wpietri/sucks and an issue at wpietri/sucks#62 makes reference to removing pyasn1 and pyasn1-modules from Python as a workaround but cannot find how to do a similar process for these GoLang scripts.
Existing issues are open under the plugins at skburgart/go-vacbot#3 and at MnrGreg/homebridge-ecovacs-deebot#1.
Please add support of XEP-0479: XMPP Compliance Suites 2023: https://xmpp.org/extensions/xep-0479.html
XMPP Compliance Suites:
Which replaces:
Is there option to not check TLS cert in case of SSL or STARTTLS ?
Bind is struct in struct , so check &iq.Bind == nil is wrong, the sub-struct always have some address
var iq clientIQ
if &iq.Bind == nil {
log.Printf("&iq.Bind is nil\n")
} else {
log.Printf("&iq.Bind is not nil\n") // Always printed !
}
Proposed fix:
change in clientIQ definition Bind bindBind to Bind *bindBind, likes:
type clientIQ struct { // info/query
XMLName xml.Name `xml:"jabber:client iq"`
From string `xml:"from,attr"`
ID string `xml:"id,attr"`
To string `xml:"to,attr"`
Type string `xml:"type,attr"` // error, get, result, set
Error *clientError // Pointer to struct instead nested struct
Bind *bindBind // Pointer...
}
And also change checking if the 'bind' field used to:
if iq.Bind == nil {
return errors.New("<iq> result missing <bind>")
}
New version memory usage in Win32,
current version unsafe.Sizeof(clientIQ)=136
after my fix unsafe.Sizeof(clientIQ)=56 (in case <iq query...)
So if optional parts are not present, only nil pointer saved.
By the way, in the sruct changed tags:
previous version was xml:",attr"
, I use xml:"from,attr"
It's important because go xml parser is case sensitive and without the change, did not parse
from, to, type and id
Using a node library I can connect to an olark xmpp client.
With golang and the same credentials I get
(*errors.errorString)(0xc42003c060)(EOF)
The options I'm using are
opts := xmpp.Options{
User: "[email protected]",
Password: "password",
NoTLS: true,
InsecureAllowUnencryptedAuth: true,
}
I've also tried without the NoTLS and InsecureAllowUnencryptedAuth options.
According to [1] ServerName should be used to verify the cert:
// ServerName is used to verify the hostname on the returned // certificates unless InsecureSkipVerify is given. It is also included // in the client's handshake to support virtual hosting unless it is // an IP address. ServerName string
But when I connect to e.g. the server xmpp.example.org:443 with the user [email protected] and set ServerName like the following example I get this error:
2020/04/05 21:04:35 x509: certificate is valid for example.org, [other domains but not xmpp.example.org] not xmpp.example.org
var tlsConfig tls.Config
tlsConfig.ServerName = strings.Split(user, "@")[1]
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "xmpp-client")
// Set XMPP connection options.
options := xmpp.Options{
Host: server,
User: user,
[...]
TLSConfig: &tlsConfig,
}
As I understand the explanation from crypto/tls it should not fail as it should check for example.org and not xmpp.example.org although connecting to xmpp.example.org that's why I suspect the library is ignoring my setting of ServerName
.
When I am using JoinMUCNoHistory to join a MUC the returned status is different from the ones specified here. E.g. after a successful join I got 140
which is not listed there.
Do I have to do some transformation with the status returned from the function?
It is possible to have a XEPs and RFCs support page with version (XEP-XXXX v1.2)?
Examples:
I tried to add SCRAM-SHA-1 auth to go-xmpp and got some working prototype but I need to check the server signature in the body of the success message (see https://wiki.xmpp.org/web/SASL_Authentication_and_SCRAM) but I was not able to access it at https://github.com/mattn/go-xmpp/blob/master/xmpp.go#L465
Can you tell me how to access the body and if it's not yet possible, could you make the body of the success message accessible?
FYI
https://github.com/mattermost/xml-roundtrip-validator/blob/master/advisories/unstable-attributes.md
https://github.com/mattermost/xml-roundtrip-validator/blob/master/advisories/unstable-directives.md
https://github.com/mattermost/xml-roundtrip-validator/blob/master/advisories/unstable-elements.md
Hi i can not get the example to work. It is my fist go project so it is probably me
But when i build i get
./example.go:64: chat.Remote undefined (type interface {} has no field or method Remote)
./example.go:64: chat.Text undefined (type interface {} has no field or method Text)
But if i remove the line
fmt.Println(chat.Remote, fromUTF8(chat.Text))
The client goes online and can revive messages, but not display em.
Any ideas?
Thanks
receiving ping from openfire 4.0.1 with double quote mark but current code check only single quotes
case *clientIQ:
if bytes.Equal(v.Query, []byte(`<ping xmlns='urn:xmpp:ping'/>`)) || bytes.Equal(v.Query, []byte(`<ping xmlns="urn:xmpp:ping"/>`)) {
my code is:
package main
import (
"fmt"
xmpp "github.com/mattn/go-xmpp"
)
const (
server = "talk.google.com:5222"
username = "myusername"
password = "mypassword"
)
func main() {
fmt.Println("hello")
talk, err := xmpp.NewClientNoTLS(server, username, password, true)
fmt.Println("error: " + err.Error())
talk.Send(xmpp.Chat{Remote: "[email protected]", Type: "chat", Text: "hello yangxiao"})
}
and get the result
<stream:stream from="gmail.com" id="0C8386F233123077" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:
xmpp-sasl"><mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism></mechanisms></stream:features>
error: PLAIN authentication is not an option: [X-OAUTH2 X-GOOGLE-TOKEN]
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x39764]
goroutine 1 [running]:
github.com/mattn/go-xmpp.(*Client).Send(0x0, 0x253b10, 0x15, 0x231120, 0x4, ...)
/Users/EnzoYang/src/go_path/src/github.com/mattn/go-xmpp/xmpp.go:398 +0x1b4
main.main()
/Users/EnzoYang/Work/Vagrant/pypy/workspace/GO/src/nagi-notify/gtalk.go:19 +0x238
goroutine 2 [syscall]:
my os is mac os x 10.9, my go version is 1.1.2
Proposed fix:
func (c *Client) init(o *Options) error {
.....
if o.Session {
//if server support session, open it
cookie = getCookie() // generate new id value for session
fmt.Fprintf(c.conn, "<iq type='set' id='%x'><session xmlns='%s'/></iq>", cookie, nsSession)
. . .
IMHO here bug in switch, should be:
func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string) (*streamFeatures, error) {
switch {
case f.StartTLS == nil:
// the server does not support STARTTLS
return f, nil
case f.StartTLS.Required != nil: // the server requires STARTTLS.
case o.StartTLS:
break // the user wants STARTTLS and the server supports it.
default:
return f, nil
}
.......
How ca i get roster items?
Dear maintainer,
go-xmpp doesn't filter illegal sequences like U+0000. Codepoints between U+0000 and U+001F (incl.) except U+0009, U+000A and U+000D should be filtered. For more details please see profanity-im/profanity#1437.
For now I just filter this in my application myself: https://salsa.debian.org/mdosch/go-sendxmpp/-/blob/v0.5.1/main.go#L378-381
I try run example.go from "example" directory, it not receive and not send messages. client.Recv() return err==nil but returned Chat struct is empty. May be it depends on https://code.google.com/p/go/issues/detail?id=3526 ?
PS I use talk.google.com as server
Hi,
We are running a prosody 0.9.12 with TLS enabled. I'm not sure why this error is raised (unknown ciphers maybe?):
2017/02/11 15:04:57 tls: oversized record received with length 28012
I'm not sure how I can debug this SSL/TLS communication.
Calling xmpp.NewClient() from more than one goroutine can cause a data race (exposed by the -race
flag for go test
)
The culprit is at https://github.com/mattn/go-xmpp/blob/master/xmpp.go#L193, that should create a new config based on the shared DefaultConfig variable instead of modifying DefaultConfig.
This can currently be worked-around by using opts.NewClient() instead (and providing a TLSConfig to opts), but it would be good to fix the race as well.
I set notls=true, but I got error as title when I start the example.go.
The root cause is you set InsecureSkipVerify=false when enable tls, but not set InsecureSkipVerify=true when disable tls. Unfortunately, the InsecureSkipVerify default value is false.
To fix this just add a fragment in example.go:
if !*notls {
xmpp.DefaultConfig = tls.Config{
ServerName: serverName(*server),
InsecureSkipVerify: false,
}
} else {
xmpp.DefaultConfig = tls.Config{
ServerName: serverName(*server),
InsecureSkipVerify:true,
}
}
I cannot build go-xmpp
$ 6g -V
6g version release.r58.1 9046
$ make
6g -o go.6 xmpp.go
xmpp.go:53: undefined: strings.SplitN
xmpp.go:58: undefined: strings.SplitN
xmpp.go:88: undefined: strings.SplitN
xmpp.go:123: undefined: strings.SplitN
make: *** [go.6] Error 1
https://github.com/mattn/go-xmpp/blob/8a80c8abe319ccc0e61b63684158bffd1a61ca5a/xmpp.go#L315
I placed a few printfs and the server seems to wait on this line forever. No errors thrown either. When I turn debug ON, I was able to see the tag.
boopathi example(master)> go run example.go -server localhost:5222 -username test@boopathi -password testtest -notls -debug
<?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="boopathi" id="fc88ef3d" xml:lang="en" version="1.0">
SE = {{http://etherx.jabber.org/streams stream} [{{xmlns stream} http://etherx.jabber.org/streams} {{ xmlns} jabber:client} {{ from} boopathi} {{ id} fc88ef3d} {{http://www.w3.org/XML/1998/namespace lang} en} {{ version} 1.0}]}
<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
Mechanism = DIGEST-MD5
<challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cmVhbG09ImJvb3BhdGhpIixub25jZT0iOXM3dTVMYjByd240VFB6TzBJbUJOMjhXN1dyaHAwT1NzamVtbUFhMyIscW9wPSJhdXRoIixjaGFyc2V0PXV0Zi04LGFsZ29yaXRobT1tZDUtc2Vzcw==</challenge>
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cnNwYXV0aD01MTI1YmIwY2JiNzMxMWMyODlkZmIwMTY3Yzc4Nzc2Yg==</success>
Waiting for next message
</stream:stream>
In order to allow matterbridge to spoof the avatar of XMPP users in other chat services, I decided to implement a bit of XEP-0084 (User Avatar) by giving go-xmpp the ability to subscribe to pubsub nodes and request their data.
I have a working implementation which currently contains both my patchsets - PubSub and User Avatar. I will try to get them separated so that I can create two smaller PRs, unless desired otherwise.
I've tested the OAuth mechanism but it seems the implementation is broken.
After a while of testing i got it work with the following changes to xmpp.go
if m == "X-HIPCHAT-OAUTH2" && o.OAuthToken != "" {
mechanism = m
// Oauth authentication: send base64-encoded \x00 token \x00 resource.
raw := "\x00" + o.OAuthToken + "\x00" + o.Resource
enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
base64.StdEncoding.Encode(enc, []byte(raw))
outString := fmt.Sprintf("<auth xmlns='http://hipchat.com' node='http://hipchat.com/client/mac' ver='22' mechanism='oauth2'>%s</auth>", enc)
fmt.Println(outString)
fmt.Fprint(c.conn, outString)
break
}
if m == "PLAIN" && o.Password != "" {
mechanism = m
// Plain authentication: send base64-encoded \x00 user \x00 password.
raw := "\x00" + user + "\x00" + o.Password
enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
base64.StdEncoding.Encode(enc, []byte(raw))
fmt.Fprintf(c.conn, "<auth xmlns='%s' mechanism='PLAIN'>%s</auth>\n", nsSASL, enc)
break
}
now i'm receiving the following output
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl' jid='<jid_number>@chat.btf.hipchat.com/bot||proxy|<myHost>|<number>' api_host='<myHost>' chat_host='chat.btf.hipchat.com' muc_host='conf.btf.hipchat.com' web_host='<myHost>'/>
but the client throws still an error
another implementation of the oauth could be found here
dane/hipchat@74f6164
is anyone using oauth in xmpp?
Two successive Recv's will not succeed. Send'ing and Recv'ing must alternate, which is obviously less than ideal :-).
Hi,When i edit "example.go" notls key to the 「true」 ,then i run the example.go is return 「starttls handshake: x509: certificate signed by unknown authority」,Can you help me to solve it
When I exceed my connection rate with a client, I see the following response stanza being returned by them in debug mode:
<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<temporary-auth-failure/>
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
New connection rate exceeded. Try again later.
</text>
</failure>
However, the error returned by xmpp.NewClient
is simply auth failure: text
which makes it difficult to detect this error programatically.
Implement OpenPGP (xep-0027) to allow encrypted messages. More info can be found here https://xmpp.org/extensions/xep-0027.html
I have a working proof of concept. I'll try to publish a PR if time allows.
hi,
I wasn't able to find them,
could you please suggest something that supports XEP-0124, XEP-0206?
what's I've found is only @SamWhited implementation https://bitbucket.org/mellium/bosh/src
When sending a file via http-upload you usually send the URL in oob and in the message body. But it seems the Ooburl is getting altered (compare oob URL to URL in body):
<body>https://upload.example.org:5281/upload/PBOIXpKDzGecqJzo/&%25%3c%3e.txt</body><x xmlns='jabber:x:oob'><url>https://upload.example.org:5281/upload/PBOIXpKDzGecqJzo/&%3c%!e(MISSING).txt</url></x>
Dunno if this issue is because of the update and recent go version, but reflection seems to fail.
panic: reflect.Value.Addr of unaddressable value
runtime.panic+0xac ~/go/src/pkg/runtime/proc.c:1060
runtime.panic(0x4dfe58, 0xf84017c780)
reflect.Value·Addr+0x7e ~/go/src/pkg/reflect/value.go:388
reflect.Value·Addr(0x537110, 0xf8401cf280, 0x0, 0xf8401cf280, 0x0, ...)
github%2ecom/mattn/go-xmpp.next+0x30b ~/go/src/pkg/github.com/mattn/go-xmpp/xmpp.go:425
github%2ecom/mattn/go-xmpp.next(0xf8401c68c0, 0xf84000de00, 0x591e6c, 0x7475613c0000002d)
github%2ecom/mattn/go-xmpp.*Client·init+0x9c4 ~/go/src/pkg/github.com/mattn/go-xmpp/xmpp.go:171
github%2ecom/mattn/go-xmpp.*Client·init(0xf84019e080, 0x7fff35a80b18, 0xf00000008, 0x7fff35a80b3a, 0x8, ...)
github%2ecom/mattn/go-xmpp.NewClient+0x91b ~/go/src/pkg/github.com/mattn/go-xmpp/xmpp.go:107
github%2ecom/mattn/go-xmpp.NewClient(0x575ec4, 0x6b6c617400000013, 0x7fff35a80b18, 0x17, 0x7fff35a80b3a, ...)
main.main+0xbc /home/jan/dev/go/go-xmpp/example.go:27
Can it possible to create minimal server implementation?
hello! and thank you for this useful repo. I'd like to know whether it would be possible to use this repo to create an XMPP connection with Google's FCM servers.
Unlike the (soon to be obsolete) GCM servers, the FCM servers require some authentication (see: https://firebase.google.com/docs/cloud-messaging/auth-server):
The connection has two important requirements:
You must initiate a Transport Layer Security (TLS) connection. Note that FCM doesn't currently support the STARTTLS extension.
FCM requires a SASL PLAIN authentication mechanism using <your_FCM_Sender_Id>@gcm.googleapis.com (FCM sender ID) and the Server key as the password. These values are available in the Cloud Messaging tab of the Firebase console Settings pane.
and of course, this connection would open over their ports (5235/5236).
is this repo FCM-ready? if not, roughly what are the required changes?
i edit server is talk.l.gfan.com,that it tell me an local error:
/go-xmpp/example$ go run example.go
talk.l.gfan.com:5222,[email protected]
2012/04/01 11:30:13 local error: record overflow
exit status 1
but i use talk.google.com:443,got PLAIN error.
2012/04/01 11:28:26 PLAIN authentication is not an option: []
exit status 1
I want to make a basic roster management. Now i can get the roster, but i don't know how to unmarshal items from it. It seems that clientIQ type has only basic fields.
I am using a slightly modified version of your example code (go-iconv doesn't work on my version of Mac OS X but github.com/djimenez/iconv-go does work => my UTF8 conversion functions are slightly different). I can send messages just fine and I can produce some kind of output every time I receive one but the chat record itself is empty. I verified this with
go func() {
for {
chat, err := talk.Recv()
if err != nil {
log.Fatal(err)
fmt.Printf("Trouble receiving chat\n")
}
fmt.Printf("%v\n", chat)
}
}()
And I receive { }
for each message. Connecting to google talk servers.
If this library is intended to be developed by various developers, a better documentation (both comments in the source and external text files) should be developed. Perhaps a raw txt in which a TODO list is proposed and a DESIGN decisions file, just to know why important parts of code are done in the way they are actually done.
I want to use Sourcegraph for go-xmpp code search, browsing, and usage examples. Can an admin enable Sourcegraph for this repository? Just go to https://sourcegraph.com/github.com/mattn/go-xmpp. (It should only take 30 seconds.)
Thank you!
Creating a new client calls net.Dial
- this call can block indefinitely depending on the server, so for production systems it is safer to use DialTimeout
(and make the timeout value configurable) or even better, take a net.Dialer
as configuration and use the Dial
function on that.
It would be nice to add support for upload files using this xep:
https://xmpp.org/extensions/xep-0363.html
Basically consists in upload the file to the xmpp server and share de url link.
Some xmpp clients supports this xep (Conversations, gajim, dino, movim...)
Thanks in advance.
how about using glog(https://github.com/golang/glog) to output more information ?
For example, if login ok, glog.Info("Login OK!").
I think glog is a good think to make program easier to use.
Can you add supports of :
"When using the SASL SCRAM mechanism, the SCRAM-SHA-256-PLUS variant SHOULD be preferred over the SCRAM-SHA-256 variant, and SHA-256 variants [RFC7677] SHOULD be preferred over SHA-1 variants [RFC5802]".
SCRAM-SHA-1(-PLUS):
-- https://tools.ietf.org/html/rfc5802
-- https://tools.ietf.org/html/rfc6120
SCRAM-SHA-256(-PLUS):
-- https://tools.ietf.org/html/rfc7677 since 2015-11-02
-- https://tools.ietf.org/html/rfc8600 since 2019-06-21: https://mailarchive.ietf.org/arch/msg/ietf-announce/suJMmeMhuAOmGn_PJYgX5Vm8lNA
SCRAM-SHA-512(-PLUS):
-- https://tools.ietf.org/html/draft-melnikov-scram-sha-512
SCRAM-SHA3-512(-PLUS):
-- https://tools.ietf.org/html/draft-melnikov-scram-sha3-512
https://xmpp.org/extensions/inbox/hash-recommendations.html
-PLUS variants:
LDAP:
HTTP:
2FA:
IANA:
Linked to:
Would it be possible just to create a channel between the server and the client, and the other client as well? Then code would be much cleaner and security would be enhanced, since everything would rely just in the security of the channel.
I do not know if it is able to modify security properties of channels in order to establish some authentication methods and cipherings in the very communications.
Look at this netchan example: https://github.com/qrush/go/blob/master/experiments/netchan/test/main.go
Hi! I've recently realized that in 42wim/matterbridge#209 I promised to file a bug upstream (here) but never did. I'm not too sure of the details of what's going on, but it seems that sending fancy Unicode caused this library to generate invalid XMPP stanzas, which then weren't properly error-handled. See the original ticket for details.
/cc @42wim
Following message cannot be parsed:
<message id="3" type="error" to="[email protected]/ABC">
<gcm xmlns="google:mobile:data">
{"random": "text"}
</gcm>
<error code="400" type="modify">
<bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
</text>
</error>
</message>
The Other:[]
array returns empty:
&{XMLName:{Space:jabber:client Local:message} From: ID: To:[email protected]/ABC Type:error Subject: Body: Thread: Other:[ ]}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.