// SASL negotiation. RFC 6120, section 6 func (d *dialer) negotiateSASL(c interfaces.Conn) error { user := d.getJIDLocalpart() password := d.password if err := c.Authenticate(user, password); err != nil { return xe.ErrAuthenticationFailed } // RFC 6120, section 6.3.2. Restart the stream err := c.SendInitialStreamHeader() if err != nil { return err } return c.BindResource() }
// RFC 6120, section 5.4 func (d *dialer) negotiateSTARTTLS(c interfaces.Conn, conn net.Conn) error { // RFC 6120, section 5.3 mandatoryToNegotiate := c.Features().StartTLS.Required.Local == "required" if c.Config().SkipTLS && !mandatoryToNegotiate { return nil } // Section 5.2 states: // "Support for STARTTLS is REQUIRED in XMPP client and server implementations" if c.Features().StartTLS.XMLName.Local == "" { return errors.New("xmpp: server doesn't support TLS") } if err := d.startTLS(c, conn); err != nil { return err } return c.SendInitialStreamHeader() }
// RFC 6120, section 4.3.2 func (d *dialer) negotiateStreamFeatures(c interfaces.Conn, conn net.Conn) error { if err := c.SendInitialStreamHeader(); err != nil { return err } // STARTTLS MUST be the first feature to be negotiated if err := d.negotiateSTARTTLS(c, conn); err != nil { return err } if registered, err := d.negotiateInBandRegistration(c); err != nil || registered { return err } // SASL negotiation. RFC 6120, section 6 if err := d.negotiateSASL(c); err != nil { return err } //TODO: negotiate other features return nil }