X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fsmtp%2Fserv_smtp.c;h=2680d908cfdc2e681c0f14af8c9b17392bd144fc;hb=8c47559cb5ae97ec0fa35660ee16fd61a9451c72;hp=e60fcaceacb76dd4907f33f7895bc654ee068679;hpb=43331d45d4673079bacca038cdab1522178bd21a;p=citadel.git diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index e60fcacea..2680d908c 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -22,6 +22,21 @@ * 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" @@ -316,6 +331,7 @@ void smtp_get_user(char *argbuf) { 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) { @@ -659,15 +675,27 @@ void smtp_data(void) { 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"); @@ -908,7 +936,7 @@ void smtp_command_loop(void) { * */ 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]; @@ -946,52 +974,55 @@ void smtp_try(const char *key, const char *addr, int *status, 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); @@ -1132,7 +1163,7 @@ void smtp_try(const char *key, const char *addr, int *status, } /* previous command succeeded, now try the MAIL FROM: command */ - snprintf(buf, sizeof buf, "MAIL FROM:<%s>\r\n", mailfrom); + 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) { @@ -1516,6 +1547,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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; @@ -1523,6 +1555,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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) { @@ -1552,6 +1585,9 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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; @@ -1612,7 +1648,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) { --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); @@ -1688,6 +1724,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) { */ 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 @@ -1707,10 +1744,9 @@ void smtp_do_queue(void) { 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; }