summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ROADMAP.md2
-rw-r--r--xmpp/jid.go20
-rw-r--r--xmpp/routing.go39
-rw-r--r--xmpp/xmpp.go13
4 files changed, 56 insertions, 18 deletions
diff --git a/ROADMAP.md b/ROADMAP.md
index 739711a..a02ffcf 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -6,7 +6,7 @@
- [x] infrastructure to encode and decode XML tokens
- [x] basic XML token logging to console
- [x] infrastructure to route and handle multi-token XML blocks
-- [ ] SASL authentication
+- [x] SASL authentication
- [ ] ressource binding
- [ ] roster retrieval
- [ ] single user chat text messages
diff --git a/xmpp/jid.go b/xmpp/jid.go
index f3a5d49..672e934 100644
--- a/xmpp/jid.go
+++ b/xmpp/jid.go
@@ -21,3 +21,23 @@ func domainpart(jid string) string {
return string(list)
}
+
+func username(jid string) string {
+ list := []rune(jid)
+
+ for i, v := range list {
+ if v == '/' {
+ list = list[:i]
+ break
+ }
+ }
+
+ for i, v := range list {
+ if v == '@' {
+ list = list[:i]
+ break
+ }
+ }
+
+ return string(list)
+}
diff --git a/xmpp/routing.go b/xmpp/routing.go
index 55ec135..23f92bb 100644
--- a/xmpp/routing.go
+++ b/xmpp/routing.go
@@ -2,6 +2,7 @@ package xmpp
import (
"encoding/xml"
+ "encoding/base64"
"errors"
"log"
)
@@ -14,15 +15,14 @@ type tokenRouter struct {
enc *encoder
}
-func newTokenRouter(e *encoder) tokenRouter {
+func newTokenRouter() tokenRouter {
return tokenRouter{
buffer: make([]xml.Token, 0),
level: 0,
- enc: e,
}
}
-func (r *tokenRouter) route(t xml.Token) error {
+func (r *tokenRouter) route(t xml.Token, c *Conn) error {
r.buffer = append(r.buffer, t)
switch unwrapped := t.(type) {
@@ -43,8 +43,7 @@ func (r *tokenRouter) route(t xml.Token) error {
case 0:
return errors.New("Stream was closed by server")
case 1:
- // call elementRouter
- err := routeElement(r.buffer)
+ err := routeElement(r.buffer, c)
if err != nil {
return err
}
@@ -64,7 +63,7 @@ func (r *tokenRouter) route(t xml.Token) error {
return nil
}
-func routeElement(b []xml.Token) error {
+func routeElement(b []xml.Token, c *Conn) error {
tab := elementRoutingTable{
{xml.Name{"http://etherx.jabber.org/streams", "features"}, streamFeatures},
}
@@ -73,7 +72,7 @@ func routeElement(b []xml.Token) error {
case xml.StartElement:
for _, v := range(tab) {
if unwrapped.Name == v.name {
- err := v.handler(b)
+ err := v.handler(b, c)
if err != nil {
return err
}
@@ -91,11 +90,11 @@ func routeElement(b []xml.Token) error {
type elementRoutingTable []struct {
name xml.Name
- handler func(b []xml.Token) error
+ handler func(b []xml.Token, c *Conn) error
}
-func streamFeatures(b []xml.Token) error {
- err := sendSaslAuth(b)
+func streamFeatures(b []xml.Token, c *Conn) error {
+ err := sendSaslAuth(b, c)
if err != nil {
return err
}
@@ -103,7 +102,7 @@ func streamFeatures(b []xml.Token) error {
return nil
}
-func sendSaslAuth(b []xml.Token) error {
+func sendSaslAuth(b []xml.Token, c *Conn) error {
mechanisms := make([]string, 0)
for i, v := range(b) {
switch token := v.(type) {
@@ -121,6 +120,24 @@ func sendSaslAuth(b []xml.Token) error {
for _, v := range(mechanisms) {
if v == "PLAIN" {
+ start := xml.StartElement{
+ xml.Name{"urn:ietf:params:xml:ns:xmpp-sasl", "auth"},
+ []xml.Attr{
+ xml.Attr{xml.Name{"", "mechanism"}, "PLAIN"},
+ },
+ }
+
+ data := []byte("\x00" + username(c.jid) + "\x00" + c.pwd)
+ dst := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
+ base64.StdEncoding.Encode(dst, data)
+ payload := xml.CharData(dst)
+
+ end := start.End()
+
+ c.enc.encodeNow(start)
+ c.enc.encode(payload)
+ c.enc.encodeNow(end)
+
return nil
}
}
diff --git a/xmpp/xmpp.go b/xmpp/xmpp.go
index 624090b..07d4c6d 100644
--- a/xmpp/xmpp.go
+++ b/xmpp/xmpp.go
@@ -19,6 +19,7 @@ type Conn struct {
ch chan Event
jid, pwd string
tcp *tls.Conn
+ enc encoder
}
func NewConn(ch chan Event, jid string, pwd string) *Conn {
@@ -65,13 +66,13 @@ func (c *Conn) Run() {
go decoder.run()
defer decoder.stop()
- enc := newEncoder(c.tcp)
- defer enc.Close()
+ c.enc = newEncoder(c.tcp)
+ defer c.enc.Close()
- tr := newTokenRouter(&enc)
+ tr := newTokenRouter()
- end := sendStreamStart(&enc, c.jid)
- defer sendStreamEnd(&enc, end)
+ end := sendStreamStart(&c.enc, c.jid)
+ defer sendStreamEnd(&c.enc, end)
c.ch <- ConnectEvent
defer func() { c.ch <- DisconnectEvent }()
@@ -86,7 +87,7 @@ func (c *Conn) Run() {
log.Printf("Unknown Event '%d'!\n", ev)
}
case token := <-decoder.data:
- err = tr.route(token)
+ err = tr.route(token, c)
if err != nil {
log.Println(err)
return