/* * Authenticate to the server with the Challenge-Response Authentication * Mechanism (CRAM). The authentication type associated with CRAM is * "CRAM-MD5". */ int auth_cram_md5(session *ssn, const char *user, const char *pass) { int t; size_t n; unsigned int i; unsigned char *chal, *resp, *out, *buf; unsigned char md[EVP_MAX_MD_SIZE], mdhex[EVP_MAX_MD_SIZE * 2 + 1]; unsigned int mdlen; HMAC_CTX hmac; if ((t = imap_authenticate(ssn, "CRAM-MD5")) == -1) return -1; if (response_authenticate(ssn, t, &chal) == STATUS_RESPONSE_CONTINUE) { n = strlen((char *)(chal)) * 3 / 4 + 1; resp = (unsigned char *)xmalloc(n * sizeof(char)); memset(resp, 0, n); EVP_DecodeBlock(resp, chal, strlen((char *)(chal))); HMAC_Init(&hmac, (const unsigned char *)pass, strlen(pass), EVP_md5()); HMAC_Update(&hmac, resp, strlen((char *)(resp))); HMAC_Final(&hmac, md, &mdlen); xfree(chal); xfree(resp); for (i = 0; i < mdlen; i++) snprintf((char *)(mdhex) + i * 2, mdlen * 2 - i * 2 + 1, "%02x", md[i]); mdhex[mdlen * 2] = '\0'; n = strlen(user) + 1 + strlen((char *)(mdhex)) + 1; buf = (unsigned char *)xmalloc(n * sizeof(unsigned char)); memset(buf, 0, n); snprintf((char *)(buf), n, "%s %s", user, mdhex); n = (strlen((char *)(buf)) + 3) * 4 / 3 + 1; out = (unsigned char *)xmalloc(n * sizeof(unsigned char)); memset(out, 0, n); EVP_EncodeBlock(out, buf, strlen((char *)(buf))); imap_continuation(ssn, (char *)(out), strlen((char *)(out))); xfree(buf); xfree(out); } else return -1; return response_authenticate(ssn, t, NULL); }
/* * Append supplied message to the specified mailbox. */ int request_append(const char *server, const char *port, const char *user, const char *mbox, const char *mesg, size_t mesglen, const char *flags, const char *date) { int t, r; session *s; const char *m; if (!(s = session_find(server, port, user))) return -1; m = apply_namespace(mbox, s->ns.prefix, s->ns.delim); do { if ((t = imap_append(s, m, flags, date, mesglen)) == -1) goto fail; if ((r = response_continuation(s)) == -1) goto fail; switch (r) { case STATUS_RESPONSE_CONTINUE: if (imap_continuation(s, mesg, mesglen) == -1) goto fail; if ((r = response_generic(s, t)) == -1) goto fail; break; case STATUS_RESPONSE_TRYCREATE: if (create_mailbox(s, mbox) == -1) goto fail; break; case -1: goto fail; break; } } while (r == STATUS_RESPONSE_TRYCREATE); return r; fail: close_connection(s); session_destroy(s); return -1; }