|
|
|
@ -28,12 +28,8 @@ type Component struct {
|
|
|
|
|
decoder *xml.Decoder
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Handshake struct {
|
|
|
|
|
XMLName xml.Name `xml:"jabber:component:accept handshake"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handshake generates an authentication token based on StreamID and shared secret.
|
|
|
|
|
func (c *Component) Handshake(streamId string) string {
|
|
|
|
|
// handshake generates an authentication token based on StreamID and shared secret.
|
|
|
|
|
func (c *Component) handshake(streamId string) string {
|
|
|
|
|
// 1. Concatenate the Stream ID received from the server with the shared secret.
|
|
|
|
|
concatStr := streamId + c.Secret
|
|
|
|
|
|
|
|
|
@ -50,55 +46,51 @@ func (c *Component) Handshake(streamId string) string {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO Helper to prepare connection string
|
|
|
|
|
func Open(connStr string) error {
|
|
|
|
|
c := Component{Host: connStr, Secret: "mypass"}
|
|
|
|
|
|
|
|
|
|
func (c *Component) Connect(connStr string) error {
|
|
|
|
|
var conn net.Conn
|
|
|
|
|
var err error
|
|
|
|
|
if conn, err = net.DialTimeout("tcp", "localhost:8888", time.Duration(5)*time.Second); err != nil {
|
|
|
|
|
if conn, err = net.DialTimeout("tcp", connStr, time.Duration(5)*time.Second); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
c.conn = conn
|
|
|
|
|
|
|
|
|
|
// TODO send stream open and check for reply
|
|
|
|
|
// Send stream open tag
|
|
|
|
|
componentHost := connStr // TODO Fix me: Extract componentID + secret
|
|
|
|
|
if _, err := fmt.Fprintf(conn, componentStreamOpen, componentHost, NSComponent, NSStream); err != nil {
|
|
|
|
|
fmt.Println("cannot send stream open.")
|
|
|
|
|
return err
|
|
|
|
|
// 1. Send stream open tag
|
|
|
|
|
if _, err := fmt.Fprintf(conn, componentStreamOpen, c.Host, NSComponent, NSStream); err != nil {
|
|
|
|
|
return errors.New("cannot send stream open " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
c.decoder = xml.NewDecoder(conn)
|
|
|
|
|
|
|
|
|
|
// Initialize xml decoder and extract streamID from reply
|
|
|
|
|
// 2. Initialize xml decoder and extract streamID from reply
|
|
|
|
|
streamId, err := initDecoder(c.decoder)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("cannot init decoder")
|
|
|
|
|
return err
|
|
|
|
|
return errors.New("cannot init decoder " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Println("StreamID = ", streamId)
|
|
|
|
|
|
|
|
|
|
// Authentication
|
|
|
|
|
if _, err := fmt.Fprintf(conn, "<handshake>%s</handshake>", c.Handshake(streamId)); err != nil {
|
|
|
|
|
fmt.Println("cannot send stream open.")
|
|
|
|
|
return err
|
|
|
|
|
// 3. Authentication
|
|
|
|
|
if _, err := fmt.Fprintf(conn, "<handshake>%s</handshake>", c.handshake(streamId)); err != nil {
|
|
|
|
|
return errors.New("cannot send handshake " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Next message should be either success or failure.
|
|
|
|
|
// 4. Check server response for authentication
|
|
|
|
|
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)
|
|
|
|
|
return errors.New("handshake failed " + v.Error.Local)
|
|
|
|
|
case *Handshake:
|
|
|
|
|
fmt.Println("Component connected")
|
|
|
|
|
return nil
|
|
|
|
|
default:
|
|
|
|
|
return errors.New("unexpected packet, got " + name.Local + " in " + name.Space)
|
|
|
|
|
}
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// XMPP packets struct
|
|
|
|
|
|
|
|
|
|
type Handshake struct {
|
|
|
|
|
XMLName xml.Name `xml:"jabber:component:accept handshake"`
|
|
|
|
|
}
|
|
|
|
|