package xmpp import ( "encoding/base64" "encoding/xml" "log" ) type saslRequest struct { Payload []byte `xml:",chardata"` } func (s *session) sasl() { 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(s.jid) + "\x00" + s.pwd) inner := saslRequest{} inner.Payload = make([]byte, base64.StdEncoding.EncodedLen(len(data))) base64.StdEncoding.Encode(inner.Payload, data) err := s.ed.tx.EncodeElement(inner, start) if err != nil { log.Println("Could not encode SASL PLAIN element!") } } // hasSaslPlain scans the given stream features XML element for the SASL PLAIN // mechanism which is supported by xengineering.eu/limox/xmpp. It returns true // if the stream has support for this mechanism and false otherwise. func hasSaslPlain(e []xml.Token) bool { mechanism := xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `mechanism`} for i, t := range e { switch s := t.(type) { case xml.StartElement: if s.Name == mechanism { if i+1 < len(e) { subtype := func() string { switch c := e[i+1].(type) { case xml.CharData: return string(c) default: return "" } }() if subtype == `PLAIN` { return true } } } } } return false } func saslSuccessHandler(s *session, e []xml.Token) { runStreamPair(s) } func saslFailureHandler(s *session, e []xml.Token) { log.Println("SASL autentication failed!") }