From bde6e0c5095c1fd73058dc8dab408fd5f27aee7c Mon Sep 17 00:00:00 2001 From: xengineering Date: Sun, 2 Jul 2023 12:04:10 +0200 Subject: Switch to EncodeElement() for resource binding --- xmpp/jid.go | 48 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) (limited to 'xmpp/jid.go') diff --git a/xmpp/jid.go b/xmpp/jid.go index fd0d7ae..332073b 100644 --- a/xmpp/jid.go +++ b/xmpp/jid.go @@ -56,47 +56,33 @@ func hasBind(e []xml.Token) bool { return false } +type bindRequest struct { + Bind struct { + Xmlns string `xml:"xmlns,attr"` + Resource struct { + Content string `xml:",chardata"` + } `xml:"resource"` + } `xml:"bind"` +} + func (s *session) sendBind() { + s.resourceReq = fmt.Sprintf("%016x", rand.Uint64()) - iqStart := xml.StartElement{ + start := xml.StartElement{ xml.Name{"jabber:client", "iq"}, []xml.Attr{ xml.Attr{xml.Name{"", "id"}, s.resourceReq}, 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, - } + inner := bindRequest{} + inner.Bind.Xmlns = "urn:ietf:params:xml:ns:xmpp-bind" + inner.Bind.Resource.Content = "limox-" + fmt.Sprintf("%08x", rand.Uint32()) - for _, v := range tokens { - err := s.ed.encodeToken(v) - if err != nil { - log.Println("Could not encode ressource binding!") - return - } + err := s.ed.tx.EncodeElement(inner, start) + if err != nil { + log.Println("Could not encode ressource binding!") } } -- cgit v1.2.3-70-g09d2 From 2fade1039c1842f08b30da5c95b5542b57e38ec6 Mon Sep 17 00:00:00 2001 From: xengineering Date: Mon, 3 Jul 2023 22:17:15 +0200 Subject: Move xml.Encoder to session struct The encoderDecoder sub-struct of the session struct should be removed in little steps. This is the first one. --- xmpp/jid.go | 2 +- xmpp/presence.go | 2 +- xmpp/sasl.go | 2 +- xmpp/session.go | 6 ++++++ xmpp/streams.go | 4 ++-- xmpp/xml.go | 12 +++--------- 6 files changed, 14 insertions(+), 14 deletions(-) (limited to 'xmpp/jid.go') diff --git a/xmpp/jid.go b/xmpp/jid.go index 332073b..83772fd 100644 --- a/xmpp/jid.go +++ b/xmpp/jid.go @@ -81,7 +81,7 @@ func (s *session) sendBind() { inner.Bind.Xmlns = "urn:ietf:params:xml:ns:xmpp-bind" inner.Bind.Resource.Content = "limox-" + fmt.Sprintf("%08x", rand.Uint32()) - err := s.ed.tx.EncodeElement(inner, start) + err := s.tx.EncodeElement(inner, start) if err != nil { log.Println("Could not encode ressource binding!") } diff --git a/xmpp/presence.go b/xmpp/presence.go index 4adae6e..e2b1841 100644 --- a/xmpp/presence.go +++ b/xmpp/presence.go @@ -13,7 +13,7 @@ func (s *session) sendPresence() { []xml.Attr{}, } - err := s.ed.tx.EncodeElement(presence{}, start) + err := s.tx.EncodeElement(presence{}, start) if err != nil { log.Println("Could not encode presence!") return diff --git a/xmpp/sasl.go b/xmpp/sasl.go index 24edc9a..0c13f36 100644 --- a/xmpp/sasl.go +++ b/xmpp/sasl.go @@ -23,7 +23,7 @@ func (s *session) sasl() { inner.Payload = make([]byte, base64.StdEncoding.EncodedLen(len(data))) base64.StdEncoding.Encode(inner.Payload, data) - err := s.ed.tx.EncodeElement(inner, start) + err := s.tx.EncodeElement(inner, start) if err != nil { log.Println("Could not encode SASL PLAIN element!") } diff --git a/xmpp/session.go b/xmpp/session.go index a43e4f4..b4a8fab 100644 --- a/xmpp/session.go +++ b/xmpp/session.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/xml" + "io" "log" ) @@ -18,6 +19,7 @@ type session struct { out chan<- any transport *tls.Conn ed encoderDecoder + tx *xml.Encoder rx chan xml.Token resourceReq string } @@ -49,6 +51,10 @@ func (s *session) run() { go s.ed.run() defer func() { s.ed.terminator <- true }() + lw := logger{"[TX] "} + w := io.MultiWriter(s.transport, lw) + s.tx = xml.NewEncoder(w) + s.out <- SessionConnect{} runStreamPair(s) diff --git a/xmpp/streams.go b/xmpp/streams.go index 87df86a..5ba4c1d 100644 --- a/xmpp/streams.go +++ b/xmpp/streams.go @@ -47,7 +47,7 @@ func openStream(s *session) xml.EndElement { } end := start.End() - err := s.ed.encodeToken(start) + err := s.encodeToken(start) if err != nil { log.Println("Could not encode stream start!") } @@ -86,7 +86,7 @@ func syncStreams(s *session) { } func closeStream(s *session, end xml.EndElement) { - err := s.ed.encodeToken(end) + err := s.encodeToken(end) if err != nil { log.Println("Could not encode stream end!") } diff --git a/xmpp/xml.go b/xmpp/xml.go index b0ea77b..f547210 100644 --- a/xmpp/xml.go +++ b/xmpp/xml.go @@ -9,7 +9,6 @@ import ( type encoderDecoder struct { session *session - tx *xml.Encoder rx *xml.Decoder terminator chan bool } @@ -19,11 +18,6 @@ func newEncoderDecoder(s *session) encoderDecoder { ed.session = s - lw := logger{"[TX] "} - w := io.MultiWriter(s.transport, lw) - ed.tx = xml.NewEncoder(w) - ed.tx.Indent("", "") - lr := logger{"[RX] "} r := io.TeeReader(s.transport, lr) ed.rx = xml.NewDecoder(r) @@ -31,7 +25,7 @@ func newEncoderDecoder(s *session) encoderDecoder { return ed } -func (ed *encoderDecoder) encodeToken(t xml.Token) error { +func (s *session) encodeToken(t xml.Token) error { var err error defer func() { if err != nil { @@ -39,11 +33,11 @@ func (ed *encoderDecoder) encodeToken(t xml.Token) error { } }() - err = ed.tx.EncodeToken(t) + err = s.tx.EncodeToken(t) if err != nil { return err } - err = ed.tx.Flush() + err = s.tx.Flush() if err != nil { return err } -- cgit v1.2.3-70-g09d2 From a23ba089a4e715e68b8c8d4179290692215784a2 Mon Sep 17 00:00:00 2001 From: xengineering Date: Tue, 4 Jul 2023 22:04:05 +0200 Subject: Re-implement resource binding and presence This was removed for refactoring. --- xmpp/jid.go | 27 ++++++++++++--------------- xmpp/routing.go | 8 ++++++++ xmpp/sasl.go | 6 ++++++ xmpp/streams.go | 8 ++++++++ 4 files changed, 34 insertions(+), 15 deletions(-) (limited to 'xmpp/jid.go') diff --git a/xmpp/jid.go b/xmpp/jid.go index 83772fd..c732027 100644 --- a/xmpp/jid.go +++ b/xmpp/jid.go @@ -41,21 +41,6 @@ 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 -} - type bindRequest struct { Bind struct { Xmlns string `xml:"xmlns,attr"` @@ -86,3 +71,15 @@ func (s *session) sendBind() { log.Println("Could not encode ressource binding!") } } + +type iqResponse struct { + Jid string `xml:"urn:ietf:params:xml:ns:xmpp-bind bind>jid"` +} + +func handleIqResponse(s *session, i iqResponse) { + if i.Jid != "" { + s.jid = i.Jid + s.sendPresence() + return + } +} diff --git a/xmpp/routing.go b/xmpp/routing.go index a9dd8b6..5cd2040 100644 --- a/xmpp/routing.go +++ b/xmpp/routing.go @@ -9,6 +9,10 @@ func route(s *xml.StartElement, d *xml.Decoder, c chan<- any) { switch (*s).Name { case xml.Name{`http://etherx.jabber.org/streams`, `features`}: parse(streamFeatures{}, s, d, c) + case xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `success`}: + parse(saslSuccess{}, s, d, c) + case xml.Name{`jabber:client`, `iq`}: + parse(iqResponse{}, s, d, c) default: d.Skip() } @@ -27,6 +31,10 @@ func handle(s *session, element any) { switch t := element.(type) { case streamFeatures: handleStreamFeatures(s, t) + case saslSuccess: + handleSaslSuccess(s) + case iqResponse: + handleIqResponse(s, t) default: log.Printf("Unknown parsed element: %v", t) } diff --git a/xmpp/sasl.go b/xmpp/sasl.go index a20ae56..5fac934 100644 --- a/xmpp/sasl.go +++ b/xmpp/sasl.go @@ -10,6 +10,12 @@ type saslRequest struct { Payload []byte `xml:",chardata"` } +type saslSuccess struct {} + +func handleSaslSuccess(s *session) { + openStream(s.tx, s.jid) +} + func (s *session) sasl() { start := xml.StartElement{ xml.Name{"urn:ietf:params:xml:ns:xmpp-sasl", "auth"}, diff --git a/xmpp/streams.go b/xmpp/streams.go index b9cd4cd..18a5e6a 100644 --- a/xmpp/streams.go +++ b/xmpp/streams.go @@ -7,9 +7,12 @@ import ( type streamFeatures struct { SaslMechanisms []string `xml:"urn:ietf:params:xml:ns:xmpp-sasl mechanisms>mechanism"` + Bind *bool `xml:"urn:ietf:params:xml:ns:xmpp-bind bind,omitempty"` } func handleStreamFeatures(s *session, f streamFeatures) { + log.Print(f) + if len(f.SaslMechanisms) > 0 { for _, v := range f.SaslMechanisms { if v == "PLAIN" { @@ -20,6 +23,11 @@ func handleStreamFeatures(s *session, f streamFeatures) { log.Println("No compatible SASL mechanism found!") return } + + if f.Bind != nil { + s.sendBind() + return + } } func openStream(e *xml.Encoder, jid string) { -- cgit v1.2.3-70-g09d2 From d9fe0a4360770b1e4b6b4fb3686c3275ad1b6e6e Mon Sep 17 00:00:00 2001 From: xengineering Date: Tue, 4 Jul 2023 22:09:36 +0200 Subject: Apply go fmt --- xmpp/jid.go | 2 +- xmpp/sasl.go | 2 +- xmpp/session.go | 2 +- xmpp/streams.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'xmpp/jid.go') diff --git a/xmpp/jid.go b/xmpp/jid.go index c732027..9580ad5 100644 --- a/xmpp/jid.go +++ b/xmpp/jid.go @@ -43,7 +43,7 @@ func username(jid string) string { type bindRequest struct { Bind struct { - Xmlns string `xml:"xmlns,attr"` + Xmlns string `xml:"xmlns,attr"` Resource struct { Content string `xml:",chardata"` } `xml:"resource"` diff --git a/xmpp/sasl.go b/xmpp/sasl.go index ae3be4a..69b536d 100644 --- a/xmpp/sasl.go +++ b/xmpp/sasl.go @@ -29,7 +29,7 @@ func (s *session) sasl() { } } -type saslSuccess struct {} +type saslSuccess struct{} func handleSaslSuccess(s *session) { openStream(s.tx, s.jid) diff --git a/xmpp/session.go b/xmpp/session.go index 7a07280..4dfd76f 100644 --- a/xmpp/session.go +++ b/xmpp/session.go @@ -58,7 +58,7 @@ func (s *session) run() { openStream(s.tx, s.jid) defer closeStream(s.tx) - s.out <- SessionConnect{} // TODO this should be sent after initial presence + s.out <- SessionConnect{} // TODO this should be sent after initial presence defer func() { s.out <- SessionDisconnect{} }() for { diff --git a/xmpp/streams.go b/xmpp/streams.go index ec16a02..9f6ffe8 100644 --- a/xmpp/streams.go +++ b/xmpp/streams.go @@ -7,7 +7,7 @@ import ( type streamFeatures struct { SaslMechanisms []string `xml:"urn:ietf:params:xml:ns:xmpp-sasl mechanisms>mechanism"` - Bind *bool `xml:"urn:ietf:params:xml:ns:xmpp-bind bind,omitempty"` + Bind *bool `xml:"urn:ietf:params:xml:ns:xmpp-bind bind,omitempty"` } func handleStreamFeatures(s *session, f streamFeatures) { -- cgit v1.2.3-70-g09d2