/** * Makes a standard plain text message while taking into * account the MIME message types and boundary's needed * if and when a file is attached. **/ static int makeMessage(dstrbuf *in, dstrbuf *out, const char *border, CharSetType charset) { dstrbuf *enc=NULL; if (Mopts.attach) { dsbPrintf(out, "--%s\r\n", border); if (charset == IS_UTF8 || charset == IS_PARTIAL_UTF8) { dsbPrintf(out, "Content-Type: text/plain; charset=utf-8\r\n"); if (IS_PARTIAL_UTF8) { dsbPrintf(out, "Content-Transfer-Encoding: quoted-printable\r\n"); enc = mimeQpEncodeString((u_char *)in->str, true); } else { dsbPrintf(out, "Content-Transfer-Encoding: base64\r\n"); enc = mimeB64EncodeString((u_char *)in->str, in->len, true); } dsbPrintf(out, "Content-Disposition: inline\r\n\r\n"); } else if (Mopts.html) { dsbPrintf(out, "Content-Type: text/html\r\n\r\n"); enc = DSB_NEW; dsbCat(enc, in->str); } else { dsbPrintf(out, "Content-Type: text/plain\r\n\r\n"); enc = DSB_NEW; dsbCat(enc, in->str); } } else { if (charset == IS_UTF8) { enc = mimeB64EncodeString((u_char *)in->str, in->len, true); } else if (charset == IS_PARTIAL_UTF8) { enc = mimeQpEncodeString((u_char *)in->str, true); } else { enc = DSB_NEW; dsbCat(enc, in->str); } } dsbPrintf(out, "%s\r\n", enc->str); if (Mopts.attach) { if (attachFiles(border, out) == ERROR) { return ERROR; } dsbPrintf(out, "\r\n\r\n--%s--\r\n", border); } dsbDestroy(enc); return 0; }
dstrbuf * encodeUtf8String(const u_char *str, bool use_qp) { const u_int max_blk_len = 45; u_int i=max_blk_len; dstrbuf *enc, *dsb = DSB_NEW; size_t len = strlen((char *)str); if (use_qp) { // TODO: We need to break this up so that we're not // creating extra long strings. enc = mimeQpEncodeString(str, false); dsbPrintf(dsb, "=?utf-8?q?%s?=", enc->str); i = len; // Just reset for now. } else { enc = mimeB64EncodeString(str, (len > max_blk_len ? max_blk_len : len), false); dsbPrintf(dsb, "=?utf-8?b?%s?=", enc->str); } dsbDestroy(enc); /* If we have anymore data to encode, we have to do it by adding a newline plus a space because each section can only be 75 chars long. */ while (i < len) { size_t newlen = strlen((char *)str + i); /* only allow max_blk_len sections */ if (newlen > max_blk_len) { newlen = max_blk_len; } enc = mimeB64EncodeString(str + i, newlen, false); dsbPrintf(dsb, "\r\n =?utf-8?b?%s?=", enc->str); dsbDestroy(enc); i += newlen; } return dsb; }
static int smtpAuthPlain(dsocket *sd, const char *user, const char *pass) { int retval = 0; dstrbuf *data=NULL; dstrbuf *up = DSB_NEW; dstrbuf *rbuf = DSB_NEW; if (writeResponse(sd, "AUTH PLAIN\r\n") < 0) { smtpSetErr("Socket write error: smtp_auth_plain"); retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("--> AUTH PLAIN\n"); fflush(stdout); #endif retval = readResponse(sd, rbuf); if (retval != 334) { if (retval != ERROR) { smtpSetErr(rbuf->str); } retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("<-- %s\n", rbuf->str); fflush(stdout); #endif dsbPrintf(up, "%c%s%c%s", '\0', user, '\0', pass); data = mimeB64EncodeString((u_char *)up->str, up->len, false); if (writeResponse(sd, "%s\r\n", data->str) < 0) { smtpSetErr("Socket write error: smtp_auth_plain"); retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("--> %s\n", data->str); fflush(stdout); #endif dsbClear(rbuf); retval = readResponse(sd, rbuf); if (retval != 235) { if (retval != ERROR) { smtpSetErr(rbuf->str); } retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("<-- %s\n", rbuf->str); fflush(stdout); #endif end: dsbDestroy(up); dsbDestroy(data); dsbDestroy(rbuf); return retval; }
/** * Makes a standard plain text message while taking into * account the MIME message types and boundary's needed * if and when a file is attached. **/ static int makeMessage(dstrbuf *in, dstrbuf *out, const char *border, CharSetType charset) { char *ptr=NULL; dstrbuf *enc=NULL; if (Mopts.attach) { dsbPrintf(out, "--%s\r\n", border); if (charset == IS_UTF8 || charset == IS_PARTIAL_UTF8) { if (Mopts.html) { dsbPrintf(out, "Content-Type: text/html; charset=utf-8\r\n"); } else { dsbPrintf(out, "Content-Type: text/plain; charset=utf-8\r\n"); } if (IS_PARTIAL_UTF8) { dsbPrintf(out, "Content-Transfer-Encoding: quoted-printable\r\n"); enc = mimeQpEncodeString((u_char *)in->str, true); } else { dsbPrintf(out, "Content-Transfer-Encoding: base64\r\n"); enc = mimeB64EncodeString((u_char *)in->str, in->len, true); } dsbPrintf(out, "Content-Disposition: inline\r\n\r\n"); } else if (Mopts.html) { dsbPrintf(out, "Content-Type: text/html\r\n\r\n"); enc = DSB_NEW; dsbCat(enc, in->str); } else { dsbPrintf(out, "Content-Type: text/plain\r\n\r\n"); enc = DSB_NEW; dsbCat(enc, in->str); } } else { if (charset == IS_UTF8) { enc = mimeB64EncodeString((u_char *)in->str, in->len, true); } else if (charset == IS_PARTIAL_UTF8) { enc = mimeQpEncodeString((u_char *)in->str, true); } else { enc = DSB_NEW; dsbCat(enc, in->str); } } /* Fix single dot on it's on line so we don't terminate the message prematurely. */ dstrbuf *formatted = DSB_NEW; char previous='\0'; for (ptr = enc->str; ptr && *ptr != '\0'; previous=*ptr, ptr++) { dsbCatChar(formatted, *ptr); /* If we have a dot starting on a newline. */ if ((previous == '\n' || previous == '\r') && *ptr == '.') { dsbCatChar(formatted, '.'); } } dsbDestroy(enc); dsbPrintf(out, "%s\r\n", formatted->str); if (Mopts.attach) { if (attachFiles(border, out) == ERROR) { return ERROR; } dsbPrintf(out, "\r\n\r\n--%s--\r\n", border); } dsbDestroy(formatted); return 0; }
/** * SMTP AUTH login. */ static int smtpAuthLogin(dsocket *sd, const char *user, const char *pass) { int retval = 0; dstrbuf *data; dstrbuf *rbuf = DSB_NEW; data = mimeB64EncodeString((u_char *)user, strlen(user), false); if (writeResponse(sd, "AUTH LOGIN %s\r\n", data->str) < 0) { smtpSetErr("Socket write error: smtp_auth_login"); retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("--> AUTH LOGIN\n"); fflush(stdout); #endif retval = readResponse(sd, rbuf); if (retval != 334) { if (retval != ERROR) { smtpSetErr(rbuf->str); } retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("<-- %s\n", rbuf->str); fflush(stdout); #endif /* Encode the password */ dsbDestroy(data); data = mimeB64EncodeString((u_char *)pass, strlen(pass), false); if (writeResponse(sd, "%s\r\n", data->str) < 0) { smtpSetErr("Socket write error: smtp_auth_login"); retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("--> %s\n", data->str); fflush(stdout); #endif dsbDestroy(data); /* Read back "OK" from server */ retval = readResponse(sd, rbuf); if (retval != 235) { if (retval != ERROR) { smtpSetErr(rbuf->str); } retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("<-- %s\n", rbuf->str); fflush(stdout); #endif end: dsbDestroy(rbuf); return retval; }