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