- else {
- /* Fall back to default: any authenticator */
- debug_print (2, ("Using any available method.\n"));
- authenticator = imap_authenticators;
-
- while (authenticator->authenticate) {
- if ((r =
- authenticator->authenticate (idata, NULL)) != IMAP_AUTH_UNAVAIL)
- return r;
- authenticator++;
+
+ mutt_message (_("Authenticating (%s)..."), mech);
+
+ snprintf (buf, sizeof (buf), "AUTHENTICATE %s", mech);
+ imap_cmd_start (idata, buf);
+ irc = IMAP_CMD_CONTINUE;
+
+ /* looping protocol */
+ while (rc == SASL_CONTINUE || olen > 0) {
+ do
+ irc = imap_cmd_step (idata);
+ while (irc == IMAP_CMD_CONTINUE);
+
+ if (method && irc == IMAP_CMD_NO) {
+ sasl_dispose (&saslconn);
+ return IMAP_AUTH_UNAVAIL;
+ }
+
+ if (irc == IMAP_CMD_BAD || irc == IMAP_CMD_NO)
+ goto bail;
+
+ if (irc == IMAP_CMD_RESPOND) {
+ if (sasl_decode64(idata->cmd.buf.data + 2, idata->cmd.buf.len - 2, buf,
+ LONG_STRING - 1, &len) != SASL_OK)
+ {
+ goto bail;
+ }
+ }
+
+ /* client-start is only available with the SASL-IR extension, but
+ * SASL 2.1 seems to want to use it regardless, at least for DIGEST
+ * fast reauth. Override if the server sent an initial continuation */
+ if (!client_start || buf[0]) {
+ do {
+ rc = sasl_client_step (saslconn, buf, len, &interaction, &pc, &olen);
+ if (rc == SASL_INTERACT)
+ mutt_sasl_interact (interaction);
+ }
+ while (rc == SASL_INTERACT);