* The VRFY and EXPN commands have been removed from this implementation
* because nobody uses these commands anymore, except for spammers.
*
+ * Copyright (c) 1998-2009 by the citadel.org team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdep.h"
void smtp_get_pass(char *argbuf) {
char password[SIZ];
+ memset(password, 0, sizeof(password));
CtdlDecodeBase64(password, argbuf, SIZ);
/* CtdlLogPrintf(CTDL_DEBUG, "Trying <%s>\n", password); */
if (CtdlTryPassword(password) == pass_ok) {
}
/*
- * Implements the "MAIL From:" command
+ * Implements the "MAIL FROM:" command
*/
void smtp_mail(char *argbuf) {
char user[SIZ];
datestring(nowstamp, sizeof nowstamp, time(NULL), DATESTRING_RFC822);
body = malloc(4096);
- if (body != NULL) snprintf(body, 4096,
- "Received: from %s (%s [%s])\n"
- " by %s; %s\n",
- SMTP->helo_node,
- CC->cs_host,
- CC->cs_addr,
- config.c_fqdn,
- nowstamp);
-
+ if (body != NULL) {
+ if (SMTP->is_lmtp && (CC->cs_UDSclientUID != -1)) {
+ snprintf(body, 4096,
+ "Received: from %s (Citadel from userid %ld)\n"
+ " by %s; %s\n",
+ SMTP->helo_node,
+ CC->cs_UDSclientUID,
+ config.c_fqdn,
+ nowstamp);
+ }
+ else {
+ snprintf(body, 4096,
+ "Received: from %s (%s [%s])\n"
+ " by %s; %s\n",
+ SMTP->helo_node,
+ CC->cs_host,
+ CC->cs_addr,
+ config.c_fqdn,
+ nowstamp);
+ }
+ }
body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1, 0);
if (body == NULL) {
cprintf("550 Unable to save message: internal error.\r\n");
*
*/
void smtp_try(const char *key, const char *addr, int *status,
- char *dsn, size_t n, long msgnum)
+ char *dsn, size_t n, long msgnum, char *envelope_from)
{
int sock = (-1);
char mxhosts[1024];
CC->redirect_len = 0;
CC->redirect_alloc = 0;
- /* Extract something to send later in the 'MAIL From:' command */
- strcpy(mailfrom, "");
- scan_done = 0;
- ptr = msgtext;
- do {
- if (ptr = memreadline(ptr, buf, sizeof buf), *ptr == 0) {
- scan_done = 1;
- }
- if (!strncasecmp(buf, "From:", 5)) {
- safestrncpy(mailfrom, &buf[5], sizeof mailfrom);
- striplt(mailfrom);
- for (i=0; mailfrom[i]; ++i) {
- if (!isprint(mailfrom[i])) {
- strcpy(&mailfrom[i], &mailfrom[i+1]);
- i=0;
- }
- }
-
- /* Strip out parenthesized names */
- lp = (-1);
- rp = (-1);
- for (i=0; mailfrom[i]; ++i) {
- if (mailfrom[i] == '(') lp = i;
- if (mailfrom[i] == ')') rp = i;
+ /* If no envelope_from is supplied, extract one from the message */
+ if ( (envelope_from == NULL) || (IsEmptyStr(envelope_from)) ) {
+ strcpy(mailfrom, "");
+ scan_done = 0;
+ ptr = msgtext;
+ do {
+ if (ptr = memreadline(ptr, buf, sizeof buf), *ptr == 0) {
+ scan_done = 1;
}
- if ((lp>0)&&(rp>lp)) {
- strcpy(&mailfrom[lp-1], &mailfrom[rp+1]);
- }
-
- /* Prefer brokketized names */
- lp = (-1);
- rp = (-1);
- for (i=0; mailfrom[i]; ++i) {
- if (mailfrom[i] == '<') lp = i;
- if (mailfrom[i] == '>') rp = i;
- }
- if ( (lp>=0) && (rp>lp) ) {
- mailfrom[rp] = 0;
- strcpy(mailfrom, &mailfrom[lp]);
+ if (!strncasecmp(buf, "From:", 5)) {
+ safestrncpy(mailfrom, &buf[5], sizeof mailfrom);
+ striplt(mailfrom);
+ for (i=0; mailfrom[i]; ++i) {
+ if (!isprint(mailfrom[i])) {
+ strcpy(&mailfrom[i], &mailfrom[i+1]);
+ i=0;
+ }
+ }
+
+ /* Strip out parenthesized names */
+ lp = (-1);
+ rp = (-1);
+ for (i=0; mailfrom[i]; ++i) {
+ if (mailfrom[i] == '(') lp = i;
+ if (mailfrom[i] == ')') rp = i;
+ }
+ if ((lp>0)&&(rp>lp)) {
+ strcpy(&mailfrom[lp-1], &mailfrom[rp+1]);
+ }
+
+ /* Prefer brokketized names */
+ lp = (-1);
+ rp = (-1);
+ for (i=0; mailfrom[i]; ++i) {
+ if (mailfrom[i] == '<') lp = i;
+ if (mailfrom[i] == '>') rp = i;
+ }
+ if ( (lp>=0) && (rp>lp) ) {
+ mailfrom[rp] = 0;
+ strcpy(mailfrom, &mailfrom[lp]);
+ }
+
+ scan_done = 1;
}
-
- scan_done = 1;
- }
- } while (scan_done == 0);
- if (IsEmptyStr(mailfrom)) strcpy(mailfrom, "someone@somewhere.org");
- stripallbut(mailfrom, '<', '>');
+ } while (scan_done == 0);
+ if (IsEmptyStr(mailfrom)) strcpy(mailfrom, "someone@somewhere.org");
+ stripallbut(mailfrom, '<', '>');
+ envelope_from = mailfrom;
+ }
/* Figure out what mail exchanger host we have to connect to */
num_mxhosts = getmx(mxhosts, node);
- CtdlLogPrintf(CTDL_DEBUG, "Number of MX hosts for <%s> is %d\n", node, num_mxhosts);
+ CtdlLogPrintf(CTDL_DEBUG, "Number of MX hosts for <%s> is %d [%s]\n", node, num_mxhosts, mxhosts);
if (num_mxhosts < 1) {
*status = 5;
snprintf(dsn, SIZ, "No MX hosts found for <%s>", node);
}
}
- /* previous command succeeded, now try the MAIL From: command */
- snprintf(buf, sizeof buf, "MAIL From: <%s>\r\n", mailfrom);
+ /* previous command succeeded, now try the MAIL FROM: command */
+ snprintf(buf, sizeof buf, "MAIL FROM:<%s>\r\n", envelope_from);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
sock_write(sock, buf, strlen(buf));
if (ml_sock_gets(sock, buf) < 0) {
}
/* MAIL succeeded, now try the RCPT To: command */
- snprintf(buf, sizeof buf, "RCPT To: <%s@%s>\r\n", user, node);
+ snprintf(buf, sizeof buf, "RCPT TO:<%s@%s>\r\n", user, node);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
sock_write(sock, buf, strlen(buf));
if (ml_sock_gets(sock, buf) < 0) {
char key[1024];
char addr[1024];
char dsn[1024];
+ char envelope_from[1024];
long text_msgid = (-1);
int incomplete_deliveries_remaining;
time_t attempted = 0L;
time_t retry = SMTP_RETRY_INTERVAL;
CtdlLogPrintf(CTDL_DEBUG, "SMTP client: smtp_do_procmsg(%ld)\n", msgnum);
+ strcpy(envelope_from, "");
msg = CtdlFetchMessage(msgnum, 1);
if (msg == NULL) {
if (!strcasecmp(key, "msgid")) {
text_msgid = extract_long(buf, 1);
}
+ if (!strcasecmp(key, "envelope_from")) {
+ extract_token(envelope_from, buf, 1, '|', sizeof envelope_from);
+ }
if (!strcasecmp(key, "retry")) {
/* double the retry interval after each attempt */
retry = extract_long(buf, 1) * 2L;
--i;
--lines;
CtdlLogPrintf(CTDL_DEBUG, "SMTP client: Trying <%s>\n", addr);
- smtp_try(key, addr, &status, dsn, sizeof dsn, text_msgid);
+ smtp_try(key, addr, &status, dsn, sizeof dsn, text_msgid, envelope_from);
if (status != 2) {
if (results == NULL) {
results = malloc(1024);
*/
void smtp_do_queue(void) {
static int doing_queue = 0;
+ int num_processed = 0;
/*
* This is a simple concurrency check to make sure only one queue run
CtdlLogPrintf(CTDL_ERR, "Cannot find room <%s>\n", SMTP_SPOOLOUT_ROOM);
return;
}
- CtdlForEachMessage(MSGS_ALL, 0L, NULL,
- SPOOLMIME, NULL, smtp_do_procmsg, NULL);
+ num_processed = CtdlForEachMessage(MSGS_ALL, 0L, NULL, SPOOLMIME, NULL, smtp_do_procmsg, NULL);
- CtdlLogPrintf(CTDL_INFO, "SMTP client: queue run completed\n");
+ CtdlLogPrintf(CTDL_INFO, "SMTP client: queue run completed; %d messages processed\n", num_processed);
run_queue_now = 0;
doing_queue = 0;
}