From 98740fdc1c777778054dc3e444b9f4542fe04abe Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 12:44:58 +0200 Subject: Move SASL mechanism detection to xmpp/sasl.go --- xmpp/sasl.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'xmpp/sasl.go') diff --git a/xmpp/sasl.go b/xmpp/sasl.go index 8687782..e06bcd5 100644 --- a/xmpp/sasl.go +++ b/xmpp/sasl.go @@ -34,3 +34,33 @@ func (s *session) sasl() { } } } + +// hasSaslPlain scans the given stream features XML element for the SASL PLAIN +// mechanism which is supported by xengineering.eu/limox/xmpp. It returns true +// if the stream has support for this mechanism and false otherwise. +func hasSaslPlain(e []xml.Token) bool { + mechanism := xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `mechanism`} + + for i, t := range e { + switch s := t.(type) { + case xml.StartElement: + if s.Name == mechanism { + if i+1 < len(e) { + subtype := func() string { + switch c := e[i+1].(type) { + case xml.CharData: + return string(c) + default: + return "" + } + }() + if subtype == `PLAIN` { + return true + } + } + } + } + } + + return false +} -- cgit v1.2.3-70-g09d2 From 372575cd38a939d1c8f412c8cea653c86bc725df Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 13:02:39 +0200 Subject: Fix debug message --- xmpp/sasl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xmpp/sasl.go') diff --git a/xmpp/sasl.go b/xmpp/sasl.go index e06bcd5..e460f5e 100644 --- a/xmpp/sasl.go +++ b/xmpp/sasl.go @@ -29,7 +29,7 @@ func (s *session) sasl() { for _, t := range tokens { err := s.ed.encodeToken(t) if err != nil { - log.Println("Could not encode stream end!") + log.Println("Could not encode SASL PLAIN element!") return } } -- cgit v1.2.3-70-g09d2 From f3aa8bec6e7d91b84a73688191751f9723c008a8 Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 13:21:34 +0200 Subject: Add SASL success handler --- xmpp/router.go | 1 + xmpp/sasl.go | 3 +++ 2 files changed, 4 insertions(+) (limited to 'xmpp/sasl.go') diff --git a/xmpp/router.go b/xmpp/router.go index bd619b4..84256bb 100644 --- a/xmpp/router.go +++ b/xmpp/router.go @@ -23,6 +23,7 @@ type routingTable []struct { func getRoutingTable() routingTable { return routingTable{ {xml.Name{`http://etherx.jabber.org/streams`, `features`}, streamFeaturesHandler}, + {xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `success`}, saslSuccessHandler}, } } diff --git a/xmpp/sasl.go b/xmpp/sasl.go index e460f5e..62c312f 100644 --- a/xmpp/sasl.go +++ b/xmpp/sasl.go @@ -64,3 +64,6 @@ func hasSaslPlain(e []xml.Token) bool { return false } + +func saslSuccessHandler(s *session, e []xml.Token) { +} -- cgit v1.2.3-70-g09d2 From 04f24e0dade8caf029cb78d3281b3587a8362cbe Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 13:22:15 +0200 Subject: Rework and apply stream nesting on SASL success If SASL authentication is successful a new stream has to be opened by the client. This is implemented with this commit. --- xmpp/sasl.go | 1 + xmpp/session.go | 1 - xmpp/stream_pair.go | 15 ++++++++------- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'xmpp/sasl.go') diff --git a/xmpp/sasl.go b/xmpp/sasl.go index 62c312f..23e8f3f 100644 --- a/xmpp/sasl.go +++ b/xmpp/sasl.go @@ -66,4 +66,5 @@ func hasSaslPlain(e []xml.Token) bool { } func saslSuccessHandler(s *session, e []xml.Token) { + runStreamPair(s) } diff --git a/xmpp/session.go b/xmpp/session.go index f14cd34..bfa2582 100644 --- a/xmpp/session.go +++ b/xmpp/session.go @@ -19,7 +19,6 @@ type session struct { transport *tls.Conn ed encoderDecoder rx chan xml.Token - streamEnd xml.EndElement } func StartSession(out chan<- any, jid string, pwd string) (in chan<- any) { diff --git a/xmpp/stream_pair.go b/xmpp/stream_pair.go index 5674d7b..f1de345 100644 --- a/xmpp/stream_pair.go +++ b/xmpp/stream_pair.go @@ -6,8 +6,8 @@ import ( ) func runStreamPair(s *session) { - openStream(s) - defer closeStream(s) + end := openStream(s) + defer closeStream(s, end) buf := newElementBuffer() @@ -34,7 +34,7 @@ func runStreamPair(s *session) { } } -func openStream(s *session) { +func openStream(s *session) xml.EndElement { start := xml.StartElement{ xml.Name{"jabber:client", "stream:stream"}, []xml.Attr{ @@ -45,8 +45,7 @@ func openStream(s *session) { xml.Attr{xml.Name{"", "xmlns:stream"}, "http://etherx.jabber.org/streams"}, }, } - - s.streamEnd = start.End() + end := start.End() err := s.ed.encodeToken(start) if err != nil { @@ -54,6 +53,8 @@ func openStream(s *session) { } syncStreams(s) + + return end } // syncStreams drops XML tokens from the receiving stream until an @@ -84,8 +85,8 @@ func syncStreams(s *session) { } } -func closeStream(s *session) { - err := s.ed.encodeToken(s.streamEnd) +func closeStream(s *session, end xml.EndElement) { + err := s.ed.encodeToken(end) if err != nil { log.Println("Could not encode stream end!") } -- cgit v1.2.3-70-g09d2 From d7a537267e8bf5631e29ed97218e213da88f3490 Mon Sep 17 00:00:00 2001 From: xengineering Date: Fri, 30 Jun 2023 13:33:14 +0200 Subject: Implement basic handler for failed SASL auth Writing to the log is still better than doing nothing ... --- xmpp/router.go | 1 + xmpp/sasl.go | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'xmpp/sasl.go') diff --git a/xmpp/router.go b/xmpp/router.go index 84256bb..9d69033 100644 --- a/xmpp/router.go +++ b/xmpp/router.go @@ -24,6 +24,7 @@ func getRoutingTable() routingTable { return 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}, } } diff --git a/xmpp/sasl.go b/xmpp/sasl.go index 23e8f3f..512fd58 100644 --- a/xmpp/sasl.go +++ b/xmpp/sasl.go @@ -68,3 +68,7 @@ func hasSaslPlain(e []xml.Token) bool { func saslSuccessHandler(s *session, e []xml.Token) { runStreamPair(s) } + +func saslFailureHandler(s *session, e []xml.Token) { + log.Println("SASL autentication failed!") +} -- cgit v1.2.3-70-g09d2