From 7cf14c4f353933e73d51cb0bf17e8ed2f4229a86 Mon Sep 17 00:00:00 2001 From: Matt Goodall Date: Wed, 27 Jun 2012 13:03:42 +0100 Subject: [PATCH] Add component API and example. --- component.go | 27 ++++++++++++++ src/xmpp/component.go | 86 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 component.go create mode 100644 src/xmpp/component.go diff --git a/component.go b/component.go new file mode 100644 index 0000000..97a150f --- /dev/null +++ b/component.go @@ -0,0 +1,27 @@ +package main + +import ( + "flag" + "log" + "xmpp" +) + +func main() { + + jid := flag.String("jid", "", "JID") + secret := flag.String("secret", "", "Component secret") + flag.Parse() + + jid2, err := xmpp.ParseJID(*jid) + if err != nil { + log.Fatal(err) + } + + c, err := xmpp.NewComponent("localhost:5347", jid2, *secret) + if err != nil { + log.Fatal(err) + } + + log.Println(c) + select {} +} diff --git a/src/xmpp/component.go b/src/xmpp/component.go new file mode 100644 index 0000000..fb5d57f --- /dev/null +++ b/src/xmpp/component.go @@ -0,0 +1,86 @@ +package xmpp + +import ( + "crypto/sha1" + "encoding/xml" + "errors" + "fmt" + "log" +) + +type component struct { + jid JID + stream *Stream +} + +func NewComponent(addr string, jid JID, secret string) (*component, error) { + + stream, err := NewStream(addr) + if err != nil { + return nil, err + } + + if err := stream.Send(""); err != nil { + return nil, err + } + + streamId, err := startComponent(stream, jid) + if err != nil { + return nil, err + } + + if err := handshake(stream, streamId, secret); err != nil { + return nil, err + } + + return &component{jid, stream}, nil +} + +func startComponent(stream *Stream, jid JID) (string, error) { + + s := fmt.Sprintf( + "", + jid) + if err := stream.Send(s); err != nil { + return "", err + } + + streamId := "" + if e, err := stream.Next(&xml.Name{nsStream, "stream"}); err != nil { + return "", err + } else { + // Find the stream id. + for _, attr := range e.Attr { + if attr.Name.Local == "id" { + streamId = attr.Value + break + } + } + if streamId == "" { + return "", errors.New("Missing stream id") + } + } + + return streamId, nil +} + +func handshake(stream *Stream, streamId, secret string) error { + + hash := sha1.New() + hash.Write([]byte(streamId)) + hash.Write([]byte(secret)) + + // Send handshake. + s := fmt.Sprintf("%x", hash.Sum(nil)) + log.Println(s) + if err := stream.Send(s); err != nil { + return err + } + + // Get handshake response. + if _, err := stream.Next(&xml.Name{"jabber:component:accept", "handshake"}); err != nil { + return err + } + + return nil +}