package xmpp import ( "encoding/base64" "encoding/xml" "log" ) func (s *session) sasl() { tokens := make([]xml.Token, 0, 3) start := xml.StartElement{ xml.Name{"urn:ietf:params:xml:ns:xmpp-sasl", "auth"}, []xml.Attr{ xml.Attr{xml.Name{"", "mechanism"}, "PLAIN"}, }, } tokens = append(tokens, start) data := []byte("\x00" + username(s.jid) + "\x00" + s.pwd) dst := make([]byte, base64.StdEncoding.EncodedLen(len(data))) base64.StdEncoding.Encode(dst, data) payload := xml.CharData(dst) tokens = append(tokens, payload) end := start.End() tokens = append(tokens, end) for _, t := range tokens { err := s.ed.encodeToken(t) if err != nil { log.Println("Could not encode SASL PLAIN element!") return } } } // 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!") }