Implements dummy auth + stream error
This commit is contained in:
parent
ec68a04554
commit
b31c29a03d
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
45
component.go
45
component.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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":
|
||||||
|
|
|
@ -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"`
|
||||||
|
|
Loading…
Reference in a new issue