Implements dummy auth + stream error

This commit is contained in:
Mickael Remond 2018-01-11 23:00:59 +01:00
parent ec68a04554
commit b31c29a03d
No known key found for this signature in database
GPG Key ID: E6F6045D79965AA3
4 changed files with 53 additions and 6 deletions

View File

@ -3,5 +3,5 @@ package main
import "fluux.io/xmpp" import "fluux.io/xmpp"
func main() { func main() {
xmpp.Open("test") xmpp.Open("mqtt.localhost")
} }

View File

@ -1,7 +1,10 @@
package xmpp package xmpp
import ( import (
"encoding/xml"
"errors"
"fmt" "fmt"
"io"
"net" "net"
"time" "time"
) )
@ -14,24 +17,60 @@ const componentStreamOpen = "<?xml version='1.0'?><stream:stream to='%s' xmlns='
type Component struct { type Component struct {
// TCP level connection // TCP level connection
conn net.Conn conn net.Conn
// read / write
socketProxy io.ReadWriter
decoder *xml.Decoder
} }
// TODO Helper to prepare connection string // TODO Helper to prepare connection string
func Open(connStr string) error { func Open(connStr string) error {
c := Component{}
var conn net.Conn var conn net.Conn
var err error var err error
if conn, err = net.DialTimeout("tcp", "localhost:8888", time.Duration(5)*time.Second); err != nil { if conn, err = net.DialTimeout("tcp", "localhost:8888", time.Duration(5)*time.Second); err != nil {
return err return err
} }
c.conn = conn
// TODO send stream open and check for reply // TODO send stream open and check for reply
// Send stream open tag // Send stream open tag
componentHost := "mqtt.localhost" componentHost := connStr // TODO Fix me
if _, err := fmt.Fprintf(conn, componentStreamOpen, componentHost, NSComponent, NSStream); err != nil { if _, err := fmt.Fprintf(conn, componentStreamOpen, componentHost, NSComponent, NSStream); err != nil {
fmt.Println("Cannot send stream open.") fmt.Println("cannot send stream open.")
return err return err
} }
c.decoder = xml.NewDecoder(conn)
// Initialize xml decoder and extract streamID from reply
streamId, err := initDecoder(c.decoder)
if err != nil {
fmt.Println("cannot init decoder")
return err
}
fmt.Println("StreamID = ", streamId)
// Authentication
if _, err := fmt.Fprint(conn, "<handshake>aaee83c26aeeafcbabeabfcbcd50df997e0a2a1e</handshake>"); err != nil {
fmt.Println("cannot send stream open.")
return err
}
// Next message should be either success or failure.
name, val, err := next(c.decoder)
if err != nil {
fmt.Println(err)
return err
}
switch v := val.(type) {
case *StreamError:
fmt.Printf("error: %s", v.Error.Local)
default:
return errors.New("unexpected packet, got " + name.Local + " in " + name.Space)
}
return nil return nil
} }

View File

@ -8,11 +8,12 @@ import (
) )
// Reads and checks the opening XMPP stream element. // Reads and checks the opening XMPP stream element.
// It returns a stream structure containing: // TODO It returns a stream structure containing:
// - Host: You can check the host against the host you were expecting to connect to // - Host: You can check the host against the host you were expecting to connect to
// - Id: the Stream ID is a temporary shared secret used for some hash calculation. It is also used by ProcessOne // - Id: the Stream ID is a temporary shared secret used for some hash calculation. It is also used by ProcessOne
// reattach features (allowing to resume an existing stream at the point the connection was interrupted, without // reattach features (allowing to resume an existing stream at the point the connection was interrupted, without
// getting through the authentication process. // getting through the authentication process.
// TODO We should handle stream error from XEP-0114 ( <conflict/> or <host-unknown/> )
func initDecoder(p *xml.Decoder) (sessionID string, err error) { func initDecoder(p *xml.Decoder) (sessionID string, err error) {
for { for {
var t xml.Token var t xml.Token
@ -72,7 +73,9 @@ func next(p *xml.Decoder) (xml.Name, interface{}, error) {
// Put it in an interface and allocate one. // Put it in an interface and allocate one.
var nv interface{} var nv interface{}
switch se.Name.Space + " " + se.Name.Local { switch se.Name.Space + " " + se.Name.Local {
// TODO: general case = Parse IQ / presence / message => split SASL case case NSStream + " error":
nv = &StreamError{}
// TODO: general case = Parse IQ / presence / message => split SASL case
case nsSASL + " success": case nsSASL + " success":
nv = &saslSuccess{} nv = &saslSuccess{}
case nsSASL + " failure": case nsSASL + " failure":

View File

@ -13,6 +13,11 @@ type streamFeatures struct {
Any []xml.Name `xml:",any"` Any []xml.Name `xml:",any"`
} }
type StreamError struct {
XMLName xml.Name `xml:"http://etherx.jabber.org/streams error"`
Error xml.Name `xml:",any"`
}
type Caps struct { type Caps struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/caps c"` XMLName xml.Name `xml:"http://jabber.org/protocol/caps c"`
Hash string `xml:"hash,attr"` Hash string `xml:"hash,attr"`