- if (buflen) {
- CHECKB64SIZE(buflen, outbuf, outbufsize);
- status = sasl_encode64(buf, buflen, outbuf, outbufsize, NULL);
- if (status != SASL_OK) {
- snprintf(response, sizeof(response), "SASL base64 encode "
- "failed: %s", sasl_errstring(status, NULL, NULL));
- if (outbuf)
- free(outbuf);
- return NOTOK;
- }
-
- status = command("AUTH %s %s", chosen_mech, outbuf);
- } else
- status = command("AUTH %s", chosen_mech);
-
- while (result == SASL_CONTINUE) {
- size_t inlen;
-
- if (status == NOTOK) {
- if (outbuf)
- free(outbuf);
- return NOTOK;
- }
-
- /*
- * If we get a "+OK" prefix to our response, then we should
- * exit out of this exchange now (because authenticated should
- * have succeeded)
- */
-
- if (strncmp(response, "+OK", 3) == 0)
- break;
-
- /*
- * Otherwise, make sure the server challenge is correctly formatted
- */
-
- if (strncmp(response, "+ ", 2) != 0) {
- command("*");
- snprintf(response, sizeof(response),
- "Malformed authentication message from server");
- if (outbuf)
- free(outbuf);
- return NOTOK;
- }
-
- /*
- * For decode, it will always be shorter, so just make sure
- * that outbuf is as at least as big as the encoded response.
- */
-
- inlen = strlen(response + 2);
-
- if (inlen > outbufsize) {
- outbuf = mh_xrealloc(outbuf, outbufsize = inlen);
- }
-
- result = sasl_decode64(response + 2, strlen(response + 2),
- outbuf, outbufsize, &outlen);
-
- if (result != SASL_OK) {
- command("*");
- snprintf(response, sizeof(response), "SASL base64 decode "
- "failed: %s", sasl_errstring(result, NULL, NULL));
- if (outbuf)
- free(outbuf);
- return NOTOK;
- }
-
- result = sasl_client_step(conn, outbuf, outlen, NULL,
- (const char **) &buf, &buflen);
-
- if (result != SASL_OK && result != SASL_CONTINUE) {
- command("*");
- snprintf(response, sizeof(response), "SASL client negotiaton "
- "failed: %s", sasl_errdetail(conn));
- if (outbuf)
- free(outbuf);
- return NOTOK;
- }
-
- CHECKB64SIZE(buflen, outbuf, outbufsize);
-
- status = sasl_encode64(buf, buflen, outbuf, outbufsize, NULL);
-
- if (status != SASL_OK) {
- command("*");
- snprintf(response, sizeof(response), "SASL base64 encode "
- "failed: %s", sasl_errstring(status, NULL, NULL));
- if (outbuf)
- free(outbuf);