]> Pileus Git - ~andy/fetchmail/blob - sink.c
More verbosity fixes.
[~andy/fetchmail] / sink.c
1 /*
2  * sink.c -- forwarding/delivery support for fetchmail
3  *
4  * The interface of this module (open_sink(), stuff_line(), close_sink(),
5  * release_sink()) seals off the delivery logic from the protocol machine,
6  * so the latter won't have to care whether it's shipping to an SMTP
7  * listener daemon or an MDA pipe.
8  *
9  * Copyright 1998 by Eric S. Raymond
10  * For license terms, see the file COPYING in this directory.
11  */
12
13 #include  "config.h"
14 #include  <stdio.h>
15 #include  <errno.h>
16 #include  <string.h>
17 #include  <signal.h>
18 #ifdef HAVE_MEMORY_H
19 #include  <memory.h>
20 #endif /* HAVE_MEMORY_H */
21 #if defined(STDC_HEADERS)
22 #include  <stdlib.h>
23 #endif
24 #if defined(HAVE_UNISTD_H)
25 #include <unistd.h>
26 #endif
27 #if defined(HAVE_ALLOCA_H)
28 #include <alloca.h>
29 #else
30 #ifdef _AIX
31  #pragma alloca
32 #endif
33 #endif
34
35 #include  "fetchmail.h"
36 #include  "socket.h"
37 #include  "smtp.h"
38
39 /* BSD portability hack...I know, this is an ugly place to put it */
40 #if !defined(SIGCHLD) && defined(SIGCLD)
41 #define SIGCHLD SIGCLD
42 #endif
43
44 #if INET6
45 #define SMTP_PORT       "smtp"  /* standard SMTP service port */
46 #else /* INET6 */
47 #define SMTP_PORT       25      /* standard SMTP service port */
48 #endif /* INET6 */
49
50 static int smtp_open(struct query *ctl)
51 /* try to open a socket to the appropriate SMTP server for this query */ 
52 {
53     /* maybe it's time to close the socket in order to force delivery */
54     if (NUM_NONZERO(ctl->batchlimit) && (ctl->smtp_socket != -1) && batchcount++ == ctl->batchlimit)
55     {
56         close(ctl->smtp_socket);
57         ctl->smtp_socket = -1;
58         batchcount = 0;
59     }
60
61     /* if no socket to any SMTP host is already set up, try to open one */
62     if (ctl->smtp_socket == -1) 
63     {
64         /* 
65          * RFC 1123 requires that the domain name in HELO address is a
66          * "valid principal domain name" for the client host. If we're
67          * running in invisible mode, violate this with malice
68          * aforethought in order to make the Received headers and
69          * logging look right.
70          *
71          * In fact this code relies on the RFC1123 requirement that the
72          * SMTP listener must accept messages even if verification of the
73          * HELO name fails (RFC1123 section 5.2.5, paragraph 2).
74          *
75          * How we compute the true mailhost name to pass to the
76          * listener doesn't affect behavior on RFC1123- violating
77          * listeners that check for name match; we're going to lose
78          * on those anyway because we can never give them a name
79          * that matches the local machine fetchmail is running on.
80          * What it will affect is the listener's logging.
81          */
82         struct idlist   *idp;
83         char *id_me = run.invisible ? ctl->server.truename : fetchmailhost;
84         int oldphase = phase;
85
86         errno = 0;
87
88         /*
89          * Run down the SMTP hunt list looking for a server that's up.
90          * Use both explicit hunt entries (value TRUE) and implicit 
91          * (default) ones (value FALSE).
92          */
93         oldphase = phase;
94         phase = LISTENER_WAIT;
95
96         set_timeout(ctl->server.timeout);
97         for (idp = ctl->smtphunt; idp; idp = idp->next)
98         {
99             char        *cp, *parsed_host = alloca(strlen(idp->id) + 1);
100 #ifdef INET6 
101             char        *portnum = SMTP_PORT;
102 #else
103             int         portnum = SMTP_PORT;
104 #endif /* INET6 */
105
106             ctl->smtphost = idp->id;  /* remember last host tried. */
107
108             strcpy(parsed_host, idp->id);
109             if ((cp = strrchr(parsed_host, '/')))
110             {
111                 *cp++ = 0;
112 #ifdef INET6 
113                 portnum = cp;
114 #else
115                 portnum = atoi(cp);
116 #endif /* INET6 */
117             }
118
119             if ((ctl->smtp_socket = SockOpen(parsed_host,portnum,NULL)) == -1)
120                 continue;
121
122             /* first, probe for ESMTP */
123             if (SMTP_ok(ctl->smtp_socket) == SM_OK &&
124                     SMTP_ehlo(ctl->smtp_socket, id_me,
125                           &ctl->server.esmtp_options) == SM_OK)
126                break;  /* success */
127
128             /*
129              * RFC 1869 warns that some listeners hang up on a failed EHLO,
130              * so it's safest not to assume the socket will still be good.
131              */
132             SockClose(ctl->smtp_socket);
133             ctl->smtp_socket = -1;
134
135             /* if opening for ESMTP failed, try SMTP */
136             if ((ctl->smtp_socket = SockOpen(parsed_host,portnum,NULL)) == -1)
137                 continue;
138
139             if (SMTP_ok(ctl->smtp_socket) == SM_OK && 
140                     SMTP_helo(ctl->smtp_socket, id_me) == SM_OK)
141                 break;  /* success */
142
143             SockClose(ctl->smtp_socket);
144             ctl->smtp_socket = -1;
145         }
146         set_timeout(0);
147         phase = oldphase;
148     }
149
150     /*
151      * RFC 1123 requires that the domain name part of the
152      * RCPT TO address be "canonicalized", that is a FQDN
153      * or MX but not a CNAME.  Some listeners (like exim)
154      * enforce this.  Now that we have the actual hostname,
155      * compute what we should canonicalize with.
156      */
157     ctl->destaddr = ctl->smtpaddress ? ctl->smtpaddress : ( ctl->smtphost ? ctl->smtphost : "localhost");
158
159     if (outlevel >= O_DEBUG && ctl->smtp_socket != -1)
160         error(0, 0, "forwarding to %s", ctl->smtphost);
161
162     return(ctl->smtp_socket);
163 }
164
165 /* these are shared by open_sink and stuffline */
166 static FILE *sinkfp;
167 static RETSIGTYPE (*sigchld)();
168
169 int stuffline(struct query *ctl, char *buf)
170 /* ship a line to the given control block's output sink (SMTP server or MDA) */
171 {
172     int n, oldphase;
173     char *last;
174
175     /* The line may contain NUL characters. Find the last char to use
176      * -- the real line termination is the sequence "\n\0".
177      */
178     last = buf;
179     while ((last += strlen(last)) && (last[-1] != '\n'))
180         last++;
181
182     /* fix message lines that have only \n termination (for qmail) */
183     if (ctl->forcecr)
184     {
185         if (last - 1 == buf || last[-2] != '\r')
186         {
187             last[-1] = '\r';
188             *last++  = '\n';
189             *last    = '\0';
190         }
191     }
192
193     oldphase = phase;
194     phase = FORWARDING_WAIT;
195
196     /*
197      * SMTP byte-stuffing.  We only do this if the protocol does *not*
198      * use .<CR><LF> as EOM.  If it does, the server will already have
199      * decorated any . lines it sends back up.
200      */
201     if (*buf == '.')
202         if (ctl->server.base_protocol->delimited)       /* server has already byte-stuffed */
203         {
204             if (ctl->mda)
205                 ++buf;
206             else
207                 /* writing to SMTP, leave the byte-stuffing in place */;
208         }
209         else /* if (!protocol->delimited)       -- not byte-stuffed already */
210         {
211             if (!ctl->mda)
212                 SockWrite(ctl->smtp_socket, buf, 1);    /* byte-stuff it */
213             else
214                 /* leave it alone */;
215         }
216
217     /* we may need to strip carriage returns */
218     if (ctl->stripcr)
219     {
220         char    *sp, *tp;
221
222         for (sp = tp = buf; sp < last; sp++)
223             if (*sp != '\r')
224                 *tp++ =  *sp;
225         *tp = '\0';
226         last = tp;
227     }
228
229     n = 0;
230     if (ctl->mda)
231         n = fwrite(buf, 1, last - buf, sinkfp);
232     else if (ctl->smtp_socket != -1)
233         n = SockWrite(ctl->smtp_socket, buf, last - buf);
234
235     phase = oldphase;
236
237     return(n);
238 }
239
240 static void sanitize(char *s)
241 /* replace unsafe shellchars by an _ */
242 {
243     static char *ok_chars = " 1234567890!@%-_=+:,./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
244     char *cp;
245
246     for (cp = s; *(cp += strspn(cp, ok_chars)); /* NO INCREMENT */)
247         *cp = '_';
248 }
249
250 int open_sink(struct query *ctl, 
251               char *return_path,
252               struct idlist *xmit_names,
253               long reallen,
254               int *good_addresses, int *bad_addresses)
255 /* set up sinkfp to be an input sink we can ship a message to */
256 {
257     struct      idlist *idp;
258
259     *bad_addresses = *good_addresses = 0;
260
261     if (ctl->mda)               /* we have a declared MDA */
262     {
263         int     length = 0, fromlen = 0, nameslen = 0;
264         char    *names = NULL, *before, *after, *from = NULL;
265
266         ctl->destaddr = "localhost";
267
268         for (idp = xmit_names; idp; idp = idp->next)
269             if (idp->val.status.mark == XMIT_ACCEPT)
270                 (*good_addresses)++;
271
272         length = strlen(ctl->mda);
273         before = xstrdup(ctl->mda);
274
275         /* get user addresses for %T (or %s for backward compatibility) */
276         if (strstr(before, "%s") || strstr(before, "%T"))
277         {
278             /*
279              * We go through this in order to be able to handle very
280              * long lists of users and (re)implement %s.
281              */
282             nameslen = 0;
283             for (idp = xmit_names; idp; idp = idp->next)
284                 if (idp->val.status.mark == XMIT_ACCEPT)
285                     nameslen += (strlen(idp->id) + 1);  /* string + ' ' */
286             if (*good_addresses = 0)
287                 nameslen = strlen(run.postmaster);
288
289             names = (char *)xmalloc(nameslen + 1);      /* account for '\0' */
290             if (*good_addresses == 0)
291                 strcpy(names, run.postmaster);
292             else
293             {
294                 names[0] = '\0';
295                 for (idp = xmit_names; idp; idp = idp->next)
296                     if (idp->val.status.mark == XMIT_ACCEPT)
297                     {
298                         strcat(names, idp->id);
299                         strcat(names, " ");
300                     }
301                 names[--nameslen] = '\0';       /* chop trailing space */
302             }
303
304             /* sanitize names in order to contain only harmless shell chars */
305             sanitize(names);
306         }
307
308         /* get From address for %F */
309         if (strstr(before, "%F"))
310         {
311             from = xstrdup(return_path);
312
313             /* sanitize from in order to contain *only* harmless shell chars */
314             sanitize(from);
315
316             fromlen = strlen(from);
317         }
318
319         /* do we have to build an mda string? */
320         if (names || from) 
321         {               
322             char        *sp, *dp;
323
324             /* find length of resulting mda string */
325             sp = before;
326             while (sp = strstr(sp, "%s")) {
327                 length += nameslen - 2; /* subtract %s */
328                 sp += 2;
329             }
330             sp = before;
331             while (sp = strstr(sp, "%T")) {
332                 length += nameslen - 2; /* subtract %T */
333                 sp += 2;
334             }
335             sp = before;
336             while (sp = strstr(sp, "%F")) {
337                 length += fromlen - 2;  /* subtract %F */
338                 sp += 2;
339             }
340                 
341             after = xmalloc(length + 1);
342
343             /* copy mda source string to after, while expanding %[sTF] */
344             for (dp = after, sp = before; *dp = *sp; dp++, sp++) {
345                 if (sp[0] != '%')       continue;
346
347                 /* need to expand? BTW, no here overflow, because in
348                 ** the worst case (end of string) sp[1] == '\0' */
349                 if (sp[1] == 's' || sp[1] == 'T') {
350                     strcpy(dp, names);
351                     dp += nameslen;
352                     sp++;       /* position sp over [sT] */
353                     dp--;       /* adjust dp */
354                 } else if (sp[1] == 'F') {
355                     strcpy(dp, from);
356                     dp += fromlen;
357                     sp++;       /* position sp over F */
358                     dp--;       /* adjust dp */
359                 }
360             }
361
362             if (names) {
363                 free(names);
364                 names = NULL;
365             }
366             if (from) {
367                 free(from);
368                 from = NULL;
369             }
370
371             free(before);
372
373             before = after;
374         }
375
376
377         if (outlevel >= O_DEBUG)
378             error(0, 0, "about to deliver with: %s", before);
379
380 #ifdef HAVE_SETEUID
381         /*
382          * Arrange to run with user's permissions if we're root.
383          * This will initialize the ownership of any files the
384          * MDA creates properly.  (The seteuid call is available
385          * under all BSDs and Linux)
386          */
387         seteuid(ctl->uid);
388 #endif /* HAVE_SETEUID */
389
390         sinkfp = popen(before, "w");
391         free(before);
392         before = NULL;
393
394 #ifdef HAVE_SETEUID
395         /* this will fail quietly if we didn't start as root */
396         seteuid(0);
397 #endif /* HAVE_SETEUID */
398
399         if (!sinkfp)
400         {
401             error(0, 0, "MDA open failed");
402             return(PS_IOERR);
403         }
404
405         sigchld = signal(SIGCHLD, SIG_DFL);
406     }
407     else
408     {
409         char    *ap, options[MSGBUFSIZE], addr[128];
410
411         /* build a connection to the SMTP listener */
412         if ((smtp_open(ctl) == -1))
413         {
414             error(0, errno, "SMTP connect to %s failed",
415                   ctl->smtphost ? ctl->smtphost : "localhost");
416             return(PS_SMTP);
417         }
418
419         /*
420          * Compute ESMTP options.
421          */
422         options[0] = '\0';
423         if (ctl->server.esmtp_options & ESMTP_8BITMIME) {
424              if (ctl->pass8bits || (ctl->mimemsg & MSG_IS_8BIT))
425                 strcpy(options, " BODY=8BITMIME");
426              else if (ctl->mimemsg & MSG_IS_7BIT)
427                 strcpy(options, " BODY=7BIT");
428         }
429
430         if ((ctl->server.esmtp_options & ESMTP_SIZE) && reallen > 0)
431             sprintf(options + strlen(options), " SIZE=%ld", reallen);
432
433         /*
434          * Try to get the SMTP listener to take the Return-Path
435          * address as MAIL FROM .  If it won't, fall back on the
436          * calling-user ID.  This won't affect replies, which use the
437          * header From address anyway.
438          *
439          * RFC 1123 requires that the domain name part of the
440          * MAIL FROM address be "canonicalized", that is a
441          * FQDN or MX but not a CNAME.  We'll assume the From
442          * header is already in this form here (it certainly
443          * is if rewrite is on).  RFC 1123 is silent on whether
444          * a nonexistent hostname part is considered canonical.
445          *
446          * This is a potential problem if the MTAs further upstream
447          * didn't pass canonicalized From/Return-Path lines, *and* the
448          * local SMTP listener insists on them.
449          *
450          * None of these error conditions generates bouncemail.  Comments
451          * below explain for each case why this is so.
452          */
453         ap = (return_path[0]) ? return_path : user;
454         if (SMTP_from(ctl->smtp_socket, ap, options) != SM_OK)
455         {
456             int smtperr = atoi(smtp_response);
457
458             if (str_find(&ctl->antispam, smtperr))
459             {
460                 /*
461                  * SMTP listener explicitly refuses to deliver mail
462                  * coming from this address, probably due to an
463                  * anti-spam domain exclusion.  Respect this.  Don't
464                  * try to ship the message, and don't prevent it from
465                  * being deleted.  Typical values:
466                  *
467                  * 501 = exim's old antispam response
468                  * 550 = exim's new antispam response (temporary)
469                  * 553 = sendmail 8.8.7's generic REJECT 
470                  * 571 = sendmail's "unsolicited email refused"
471                  *
472                  * We don't send bouncemail on antispam failures because
473                  * we don't want the scumbags to know the address is even
474                  * valid.
475                  */
476                 SMTP_rset(ctl->smtp_socket);    /* required by RFC1870 */
477                 return(PS_REFUSED);
478             }
479
480             /*
481              * Suppress error message only if the response specifically 
482              * meant `excluded for policy reasons'.  We *should* see
483              * an error when the return code is less specific.
484              */
485             if (smtperr >= 400)
486                 error(0, -1, "SMTP error: %s", smtp_response);
487
488             switch (smtperr)
489             {
490             case 452: /* insufficient system storage */
491                 /*
492                  * Temporary out-of-queue-space condition on the
493                  * ESMTP server.  Don't try to ship the message, 
494                  * and suppress deletion so it can be retried on
495                  * a future retrieval cycle. 
496                  *
497                  * Bouncemail *might* be appropriate here as a delay
498                  * notification.  But it's not really necessary because
499                  * this is not an actual failure, we're very likely to be
500                  * able to recover on the next cycle.
501                  */
502                 SMTP_rset(ctl->smtp_socket);    /* required by RFC1870 */
503                 return(PS_TRANSIENT);
504
505             case 552: /* message exceeds fixed maximum message size */
506             case 553: /* invalid sending domain */
507                 /*
508                  * Permanent no-go condition on the
509                  * ESMTP server.  Don't try to ship the message, 
510                  * and allow it to be deleted.
511                  *
512                  * Bouncemail would be appropriate for 552, but in these 
513                  * latter days 553 usually means a spammer is trying to
514                  * cover his tracks.  We'd rather deny the scumbags any
515                  * feedback that the address is valid.
516                  */
517                 SMTP_rset(ctl->smtp_socket);    /* required by RFC1870 */
518                 return(PS_REFUSED);
519
520             default:    /* retry with postmaster's address */
521                 if (SMTP_from(ctl->smtp_socket,run.postmaster,options)!=SM_OK)
522                 {
523                     error(0, -1, "SMTP error: %s", smtp_response);
524                     return(PS_SMTP);    /* should never happen */
525                 }
526             }
527         }
528
529         /*
530          * Now list the recipient addressees
531          */
532         for (idp = xmit_names; idp; idp = idp->next)
533             if (idp->val.status.mark == XMIT_ACCEPT)
534             {
535                 if (strchr(idp->id, '@'))
536                     strcpy(addr, idp->id);
537                 else
538 #ifdef HAVE_SNPRINTF
539                     snprintf(addr, sizeof(addr)-1, "%s@%s", idp->id, ctl->destaddr);
540 #else
541                     sprintf(addr, "%s@%s", idp->id, ctl->destaddr);
542 #endif /* HAVE_SNPRINTF */
543
544                 if (SMTP_rcpt(ctl->smtp_socket, addr) == SM_OK)
545                     (*good_addresses)++;
546                 else
547                 {
548                     (*bad_addresses)++;
549                     idp->val.status.mark = XMIT_ANTISPAM;
550                     error(0, 0, 
551                           "SMTP listener doesn't like recipient address `%s'",
552                           addr);
553                 }
554             }
555         if (!(*good_addresses))
556         {
557 #ifdef HAVE_SNPRINTF
558             snprintf(addr, sizeof(addr)-1, "%s@%s", run.postmaster, ctl->destaddr);
559 #else
560             sprintf(addr, "%s@%s", run.postmaster, ctl->destaddr);
561 #endif /* HAVE_SNPRINTF */
562
563             if (SMTP_rcpt(ctl->smtp_socket, addr) != SM_OK)
564             {
565                 error(0, 0, "can't even send to %s!", run.postmaster);
566                 return(PS_SMTP);
567             }
568         }
569
570         /* tell it we're ready to send data */
571         SMTP_data(ctl->smtp_socket);
572     }
573
574     return(PS_SUCCESS);
575 }
576
577 void release_sink(struct query *ctl)
578 /* release the per-message output sink, whether it's a pipe or SMTP socket */
579 {
580     if (ctl->mda)
581     {
582         if (sinkfp)
583         {
584             pclose(sinkfp);
585             sinkfp = (FILE *)NULL;
586         }
587         signal(SIGCHLD, sigchld);
588     }
589 }
590
591 int close_sink(struct query *ctl, flag forward)
592 /* perform end-of-message actions on the current output sink */
593 {
594     if (ctl->mda)
595     {
596         int rc;
597
598         /* close the delivery pipe, we'll reopen before next message */
599         if (sinkfp)
600         {
601             rc = pclose(sinkfp);
602             sinkfp = (FILE *)NULL;
603         }
604         else
605             rc = 0;
606         signal(SIGCHLD, sigchld);
607         if (rc)
608         {
609             error(0, -1, "MDA exited abnormally or returned nonzero status");
610             return(FALSE);
611         }
612     }
613     else if (forward)
614     {
615                                 /* write message terminator */
616         if (SMTP_eom(ctl->smtp_socket) != SM_OK)
617         {
618             error(0, -1, "SMTP listener refused delivery");
619             return(FALSE);
620         }
621     }
622
623     return(TRUE);
624 }
625
626 /* sink.c ends here */