From dd1cb9c23392d4d43198d60879fecf61fe4503b7 Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 14:08:04 +0200 Subject: Implement detection of resource binding offer This allows to trigger resource binding if the stream supports it. --- xmpp/jid.go | 19 +++++++++++++++++++ xmpp/stream_pair.go | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/xmpp/jid.go b/xmpp/jid.go index 90c1509..d7107d4 100644 --- a/xmpp/jid.go +++ b/xmpp/jid.go @@ -1,5 +1,9 @@ package xmpp +import ( + "encoding/xml" +) + // domainpart extracts the domain name from a JID / XMPP address. See // https://datatracker.ietf.org/doc/html/rfc7622#section-3.2 for details. func domainpart(jid string) string { @@ -33,3 +37,18 @@ func username(jid string) string { return "" } + +func hasBind(e []xml.Token) bool { + bind := xml.Name{`urn:ietf:params:xml:ns:xmpp-bind`, `bind`} + + for _, v := range e { + switch s := v.(type) { + case xml.StartElement: + if s.Name == bind { + return true + } + } + } + + return false +} diff --git a/xmpp/stream_pair.go b/xmpp/stream_pair.go index 693972e..9be880f 100644 --- a/xmpp/stream_pair.go +++ b/xmpp/stream_pair.go @@ -98,5 +98,10 @@ func streamFeaturesHandler(s *session, e []xml.Token) { return } + if hasBind(e) { + log.Println("Stream supports ressource binding") + return + } + log.Println("Stream has no implemented features!") } -- cgit v1.2.3-70-g09d2 From 62a17dd6584009cad58fceee6b1ada74edf1d38f Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 14:32:58 +0200 Subject: Implement resource binding request This is the first step of resource binding which is a mandatory part of establishing an XMPP connection. --- xmpp/jid.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ xmpp/stream_pair.go | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/xmpp/jid.go b/xmpp/jid.go index d7107d4..138744c 100644 --- a/xmpp/jid.go +++ b/xmpp/jid.go @@ -2,6 +2,9 @@ package xmpp import ( "encoding/xml" + "log" + "fmt" + "math/rand" ) // domainpart extracts the domain name from a JID / XMPP address. See @@ -52,3 +55,46 @@ func hasBind(e []xml.Token) bool { return false } + +func (s *session) sendBind() { + iqStart := xml.StartElement{ + xml.Name{"jabber:client", "iq"}, + []xml.Attr{ + xml.Attr{xml.Name{"", "id"}, fmt.Sprintf("%016x", rand.Uint64())}, + xml.Attr{xml.Name{"", "type"}, "set"}, + }, + } + iqEnd := iqStart.End() + + bindStart := xml.StartElement{ + xml.Name{"urn:ietf:params:xml:ns:xmpp-bind", "bind"}, + []xml.Attr{}, + } + bindEnd := bindStart.End() + + resourceStart := xml.StartElement{ + xml.Name{"", "resource"}, + []xml.Attr{}, + } + resourceEnd := resourceStart.End() + + name := xml.CharData("limox-" + fmt.Sprintf("%08x", rand.Uint32())) + + tokens := [...]xml.Token{ + iqStart, + bindStart, + resourceStart, + name, + resourceEnd, + bindEnd, + iqEnd, + } + + for _, v := range tokens { + err := s.ed.encodeToken(v) + if err != nil { + log.Println("Could not encode ressource binding!") + return + } + } +} diff --git a/xmpp/stream_pair.go b/xmpp/stream_pair.go index 9be880f..4690f57 100644 --- a/xmpp/stream_pair.go +++ b/xmpp/stream_pair.go @@ -99,7 +99,7 @@ func streamFeaturesHandler(s *session, e []xml.Token) { } if hasBind(e) { - log.Println("Stream supports ressource binding") + s.sendBind() return } -- cgit v1.2.3-70-g09d2 From 512a217cca62563a1ed0e577289e21ed2203b37b Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 19:58:48 +0200 Subject: Add log-only handler for received IQ stanzas This handler is just a placeholder for a more extensive IQ handling but already writes to the log so that it is obvious what is happening. --- xmpp/router.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xmpp/router.go b/xmpp/router.go index 9d69033..1d9c3e5 100644 --- a/xmpp/router.go +++ b/xmpp/router.go @@ -25,9 +25,17 @@ func getRoutingTable() routingTable { {xml.Name{`http://etherx.jabber.org/streams`, `features`}, streamFeaturesHandler}, {xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `success`}, saslSuccessHandler}, {xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `failure`}, saslFailureHandler}, + {xml.Name{`jabber:client`, `iq`}, voidIq}, } } +// voidIq just logs that an IQ element was received. In the current state of +// the software there is no further processing. +// TODO process IQs for error handling and further information processing. +func voidIq(s *session, e []xml.Token) { + log.Println("Received IQ element") +} + // route determines the correct handler function for the given XML element by a // given routingTable. In addition it executes the determined handler function. // If no handler function is found an error message is send via the log module. -- cgit v1.2.3-70-g09d2 From 68b0a5c99e3aef3f3982ff02c3a50763fa7bf33a Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 20:02:35 +0200 Subject: Update ROADMAP --- ROADMAP.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index 817df4b..a0934b9 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7,11 +7,15 @@ - [x] basic XML token logging to console - [x] infrastructure to route and handle multi-token XML blocks - [x] SASL authentication -- [ ] ressource binding +- [x] ressource binding - [ ] sending initial presence - [ ] roster retrieval - [ ] single user chat text messages - [ ] SRV record parsing to get TCP port +- [ ] refactored structure +- [ ] full error handling +- [ ] retries +- [ ] timeouts ## Basic core compliance -- cgit v1.2.3-70-g09d2 From d30e2cd84ac54f4ea86f430249f09e272fe9a800 Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 20:02:53 +0200 Subject: Apply go fmt --- xmpp/jid.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmpp/jid.go b/xmpp/jid.go index 138744c..0446d19 100644 --- a/xmpp/jid.go +++ b/xmpp/jid.go @@ -2,8 +2,8 @@ package xmpp import ( "encoding/xml" - "log" "fmt" + "log" "math/rand" ) -- cgit v1.2.3-70-g09d2