in sasl.go [197:242]
func (s saslXOAUTH2Handler) step(ctx context.Context) (stateFunc, error) {
// read challenge or outcome frame
fr, err := s.conn.readFrame()
if err != nil {
return nil, err
}
switch v := fr.Body.(type) {
case *frames.SASLOutcome:
// check if auth succeeded
if v.Code != encoding.CodeSASLOK {
return nil, fmt.Errorf("SASL XOAUTH2 auth failed with code %#00x: %s : %s",
v.Code, v.AdditionalData, s.errorResponse)
}
// return to c.negotiateProto
s.conn.saslComplete = true
return s.conn.negotiateProto, nil
case *frames.SASLChallenge:
if s.errorResponse == nil {
s.errorResponse = v.Challenge
timeout, err := s.conn.getWriteTimeout(ctx)
if err != nil {
return nil, err
}
// The SASL protocol requires clients to send an empty response to this challenge.
err = s.conn.writeFrame(timeout, frames.Frame{
Type: frames.TypeSASL,
Body: &frames.SASLResponse{
Response: []byte{},
},
})
if err != nil {
return nil, err
}
return s.step, nil
} else {
return nil, fmt.Errorf("SASL XOAUTH2 unexpected additional error response received during "+
"exchange. Initial error response: %s, additional response: %s", s.errorResponse, v.Challenge)
}
default:
return nil, fmt.Errorf("sasl: unexpected frame type %T", fr.Body)
}
}