]> Pileus Git - ~andy/fetchmail/blob - driver.c
Grab hostname from greeting line.
[~andy/fetchmail] / driver.c
1 /*
2  * driver.c -- generic driver for mail fetch method protocols
3  *
4  * Copyright 1996 by Eric S. Raymond
5  * All rights reserved.
6  * For license terms, see the file COPYING in this directory.
7  */
8
9 #include  <config.h>
10 #include  <stdio.h>
11 #include  <setjmp.h>
12 #include  <errno.h>
13 #include  <ctype.h>
14 #include  <string.h>
15 #if defined(STDC_HEADERS)
16 #include  <stdlib.h>
17 #endif
18 #if defined(HAVE_UNISTD_H)
19 #include <unistd.h>
20 #endif
21 #if defined(HAVE_STDARG_H)
22 #include  <stdarg.h>
23 #else
24 #include  <varargs.h>
25 #endif
26 #if defined(HAVE_ALLOCA_H)
27 #include <alloca.h>
28 #endif
29 #include  <sys/time.h>
30 #include  <signal.h>
31
32 #ifdef HAVE_GETHOSTBYNAME
33 #include <netdb.h>
34 #include "mx.h"
35 #endif /* HAVE_GETHOSTBYNAME */
36
37 #ifdef KERBEROS_V4
38 #include <krb.h>
39 #include <des.h>
40 #include <netinet/in.h>
41 #include <netdb.h>
42 #endif /* KERBEROS_V4 */
43 #include  "socket.h"
44 #include  "fetchmail.h"
45 #include  "socket.h"
46 #include  "smtp.h"
47
48 /* BSD portability hack...I know, this is an ugly place to put it */
49 #if !defined(SIGCHLD) && defined(SIGCLD)
50 #define SIGCHLD SIGCLD
51 #endif
52
53 #define SMTP_PORT       25      /* standard SMTP service port */
54
55 int batchlimit;         /* how often to tear down the delivery connection */
56 int fetchlimit;         /* how often to tear down the server connection */
57 int batchcount;         /* count of messages sent in current batch */
58 int peek_capable;       /* can we peek for better error recovery? */
59
60 static const struct method *protocol;
61 static jmp_buf  restart;
62
63 char tag[TAGLEN];
64 static int tagnum;
65 #define GENSYM  (sprintf(tag, "a%04d", ++tagnum), tag)
66
67 static char *shroud;    /* string to shroud in debug output, if  non-NULL */
68 static int mytimeout;   /* value of nonreponse timeout */
69
70 static int strcrlf(dst, src, count)
71 /* replace LFs with CR-LF; return length of string with replacements */
72 char *dst;      /* new string with CR-LFs */
73 char *src;      /* original string with LFs */
74 int count;      /* length of src */
75 {
76   int len = count;
77
78   while (count--)
79   {
80       if (*src == '\n')
81       {
82           *dst++ = '\r';
83           len++;
84       }
85       *dst++ = *src++;
86   }
87   *dst = '\0';
88   return len;
89 }
90
91 static void vtalarm(int timeleft)
92 /* reset the nonresponse-timeout */
93 {
94     struct itimerval ntimeout;
95
96     ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0;
97     ntimeout.it_value.tv_sec  = timeleft;
98     ntimeout.it_value.tv_usec = 0;
99     setitimer(ITIMER_VIRTUAL, &ntimeout, (struct itimerval *)NULL);
100 }
101
102 static void vtalarm_handler (int signal)
103 /* handle server-timeout SIGVTALARM signal */
104 {
105     longjmp(restart, 1);
106 }
107
108 #ifdef HAVE_RES_SEARCH
109 #define MX_RETRIES      3
110
111 static int is_host_alias(const char *name, struct query *ctl)
112 /* determine whether name is a DNS alias of the hostname */
113 {
114     struct hostent      *he;
115     struct mxentry      *mxp, *mxrecords;
116
117     /*
118      * The first two checks are optimizations that will catch a good
119      * many cases.  (1) check against the hostname the user
120      * specified.  Odds are good this will either be the mailserver's
121      * FQDN or a suffix of it with the mailserver's domain's default
122      * host name omitted.  Then check the rest of the `also known as'
123      * cache accumulated by previous DNS checks.  This cache is primed
124      * by the aka list option.
125      *
126      * (2) check against the mailserver's FQDN, in case
127      * it's not the same as the declared hostname.
128      *
129      * Either of these on a mail address is definitive.  Only if the
130      * name doesn't match either is it time to call the bind library.
131      * If this happens odds are good we're looking at an MX name.
132      */
133     if (str_in_list(&ctl->lead_server->servernames, name))
134         return(TRUE);
135     else if (strcmp(name, ctl->canonical_name) == 0)
136         return(TRUE);
137
138     /*
139      * We know DNS service was up at the beginning of this poll cycle.
140      * If it's down, our nameserver has crashed.  We don't want to try
141      * delivering the current message or anything else from this
142      * mailbox until it's back up.
143      */
144     else if ((he = gethostbyname(name)) != (struct hostent *)NULL)
145     {
146         if (strcmp(ctl->canonical_name, he->h_name) == 0)
147             goto match;
148         else
149             return(FALSE);
150     }
151     else
152         switch (h_errno)
153         {
154         case HOST_NOT_FOUND:    /* specified host is unknown */
155         case NO_ADDRESS:        /* valid, but does not have an IP address */
156             break;
157
158         case NO_RECOVERY:       /* non-recoverable name server error */
159         case TRY_AGAIN:         /* temporary error on authoritative server */
160         default:
161             if (outlevel != O_SILENT)
162                 putchar('\n');  /* terminate the progress message */
163             error(0, 0,
164                 "nameserver failure while looking for `%s' during poll of %s.",
165                 name, ctl->servernames->id);
166             ctl->errcount++;
167             longjmp(restart, 2);        /* try again next poll cycle */
168             break;
169         }
170
171     /*
172      * We're only here if DNS was OK but the gethostbyname() failed
173      * with a HOST_NOT_FOUND or NO_ADDRESS error.
174      * Search for a name match on MX records pointing to the server.
175      */
176     h_errno = 0;
177     if ((mxrecords = getmxrecords(name)) == (struct mxentry *)NULL)
178     {
179         switch (h_errno)
180         {
181         case HOST_NOT_FOUND:    /* specified host is unknown */
182         case NO_ADDRESS:        /* valid, but does not have an IP address */
183             return(FALSE);
184             break;
185
186         case NO_RECOVERY:       /* non-recoverable name server error */
187         case TRY_AGAIN:         /* temporary error on authoritative server */
188         default:
189             error(0, 0,
190                 "nameserver failure while looking for `%s' during poll of %s.",
191                 name, ctl->servernames->id);
192             ctl->errcount++;
193             longjmp(restart, 2);        /* try again next poll cycle */
194             break;
195         }
196     }
197     else
198     {
199         for (mxp = mxrecords; mxp->name; mxp++)
200             if (strcmp(ctl->canonical_name, mxp->name) == 0)
201                 goto match;
202         return(FALSE);
203     match:;
204     }
205
206     /* add this name to relevant server's `also known as' list */
207     save_str(&ctl->lead_server->servernames, -1, name);
208     return(TRUE);
209 }
210
211 static void map_name(name, ctl, xmit_names)
212 /* add given name to xmit_names if it matches declared localnames */
213 const char *name;               /* name to map */
214 struct query *ctl;              /* list of permissible aliases */
215 struct idlist **xmit_names;     /* list of recipient names parsed out */
216 {
217     const char  *lname;
218
219     lname = idpair_find(&ctl->localnames, name);
220     if (!lname && ctl->wildcard)
221         lname = name;
222
223     if (lname != (char *)NULL)
224     {
225         if (outlevel == O_VERBOSE)
226             error(0, 0, "mapped %s to local %s", name, lname);
227         save_str(xmit_names, -1, lname);
228     }
229 }
230
231 void find_server_names(hdr, ctl, xmit_names)
232 /* parse names out of a RFC822 header into an ID list */
233 const char *hdr;                /* RFC822 header in question */
234 struct query *ctl;              /* list of permissible aliases */
235 struct idlist **xmit_names;     /* list of recipient names parsed out */
236 {
237     if (hdr == (char *)NULL)
238         return;
239     else
240     {
241         char    *cp, *lname;
242
243         if ((cp = nxtaddr(hdr)) != (char *)NULL)
244             do {
245                 char    *atsign;
246
247                 if ((atsign = strchr(cp, '@')))
248                 {
249                     struct idlist       *idp;
250
251                     /*
252                      * Does a trailing segment of the hostname match something
253                      * on the localdomains list?  If so, save the whole name
254                      * and keep going.
255                      */
256                     for (idp = ctl->localdomains; idp; idp = idp->next)
257                     {
258                         char    *rhs;
259
260                         rhs = atsign + 1 + (strlen(atsign) - strlen(idp->id));
261                         if ((rhs[-1] == '.' || rhs[-1] == '@')
262                                         && strcmp(rhs, idp->id) == 0)
263                         {
264                             if (outlevel == O_VERBOSE)
265                                 error(0, 0, "passed through %s matching %s", 
266                                       cp, idp->id);
267                             save_str(xmit_names, -1, cp);
268                             continue;
269                         }
270                     }
271
272                     /*
273                      * Check to see if the right-hand part is an alias
274                      * or MX equivalent of the mailserver.  If it's
275                      * not, skip this name.  If it is, we'll keep
276                      * going and try to find a mapping to a client name.
277                      */
278                     if (!is_host_alias(atsign+1, ctl))
279                         continue;
280                     atsign[0] = '\0';
281                 }
282
283                 map_name(cp, ctl, xmit_names);
284             } while
285                 ((cp = nxtaddr((char *)NULL)) != (char *)NULL);
286     }
287 }
288 #endif /* HAVE_RES_SEARCH */
289
290 static FILE *smtp_open(struct query *ctl)
291 /* try to open a socket to the appropriate SMTP server for this query */ 
292 {
293     struct query *lead;
294
295     lead = ctl->lead_smtp; /* go to the SMTP leader for this query */
296
297     /* maybe it's time to close the socket in order to force delivery */
298     if (batchlimit && lead->smtp_sockfp && batchcount++ == batchlimit)
299     {
300         fclose(lead->smtp_sockfp);
301         lead->smtp_sockfp = (FILE *)NULL;
302         batchcount = 0;
303     }
304
305     /* if no socket to this host is already set up, try to open one */
306     if (lead->smtp_sockfp == (FILE *)NULL)
307     {
308         if ((lead->smtp_sockfp = SockOpen(lead->smtphost, SMTP_PORT)) == (FILE *)NULL)
309             return((FILE *)NULL);
310         else if (SMTP_ok(lead->smtp_sockfp) != SM_OK
311                  || SMTP_helo(lead->smtp_sockfp, ctl->servernames->id) != SM_OK)
312         {
313             fclose(lead->smtp_sockfp);
314             lead->smtp_sockfp = (FILE *)NULL;
315         }
316     }
317
318     return(lead->smtp_sockfp);
319 }
320
321 static int gen_readmsg (sockfp, len, delimited, ctl)
322 /* read message content and ship to SMTP or MDA */
323 FILE *sockfp;           /* to which the server is connected */
324 long len;               /* length of message */
325 int delimited;          /* does the protocol use a message delimiter? */
326 struct query *ctl;      /* query control record */
327 {
328     char buf [MSGBUFSIZE+1]; 
329     char *bufp, *headers, *fromhdr,*tohdr,*cchdr,*bcchdr,*received_for,*envto;
330     char *fromptr, *toptr;
331     int n, oldlen;
332     int inheaders,lines,sizeticker;
333     FILE *sinkfp;
334     RETSIGTYPE (*sigchld)();
335 #ifdef HAVE_GETHOSTBYNAME
336     char rbuf[HOSTLEN + USERNAMELEN + 4]; 
337 #endif /* HAVE_GETHOSTBYNAME */
338
339     /* read the message content from the server */
340     inheaders = 1;
341     headers = fromhdr = tohdr = cchdr = bcchdr = received_for = envto = NULL;
342     lines = 0;
343     sizeticker = 0;
344     oldlen = 0;
345     while (delimited || len > 0)
346     {
347         if (!SockGets(buf,sizeof(buf),sockfp))
348             return(PS_SOCKET);
349         n = strlen(buf);
350         vtalarm(ctl->timeout);
351
352         /* squeeze out all carriage returns */
353         for (fromptr = toptr = buf; *fromptr; fromptr++)
354             if (*fromptr != '\r' && *fromptr != '\n')
355                 *toptr++ = *fromptr;
356         *toptr = '\0';
357
358         /* write the message size dots */
359         if (n > 0)
360         {
361             sizeticker += n;
362             while (sizeticker >= SIZETICKER)
363             {
364                 if (outlevel > O_SILENT)
365                     error_build(".");
366                 sizeticker -= SIZETICKER;
367             }
368         }
369         len -= n;
370         bufp = buf;
371         if (buf[0] == '\0' || buf[0] == '\r' || buf[0] == '\n')
372             inheaders = 0;
373         if (delimited && *bufp == '.') {
374             bufp++;
375             if (*bufp == 0)
376                 break;  /* end of message */
377         }
378         strcat(bufp, "\n");
379      
380         if (inheaders)
381         {
382             if (!ctl->norewrite)
383                 reply_hack(bufp, ctl->servernames->id);
384
385             if (!lines)
386             {
387                 oldlen = strlen(bufp);
388                 headers = xmalloc(oldlen + 1);
389                 (void) strcpy(headers, bufp);
390                 bufp = headers;
391             }
392             else
393             {
394                 int     newlen;
395
396                 /*
397                  * We deal with RFC822 continuation lines here.
398                  * Replace previous '\n' with '\r' so nxtaddr 
399                  * and reply_hack will be able to see past it.
400                  * (We know this is safe because SocketGets stripped
401                  * out all carriage returns in the read loop above
402                  * and we haven't reintroduced any since then.)
403                  * We'll undo this before writing the header.
404                  */
405                 if (isspace(bufp[0]))
406                     headers[oldlen-1] = '\r';
407
408                 newlen = oldlen + strlen(bufp);
409                 headers = realloc(headers, newlen + 1);
410                 if (headers == NULL)
411                     return(PS_IOERR);
412                 strcpy(headers + oldlen, bufp);
413                 bufp = headers + oldlen;
414                 oldlen = newlen;
415             }
416
417             if (!strncasecmp("From:", bufp, 5))
418                 fromhdr = bufp;
419             else if (!fromhdr && !strncasecmp("Resent-From:", bufp, 12))
420                 fromhdr = bufp;
421             else if (!fromhdr && !strncasecmp("Apparently-From:", bufp, 16))
422                 fromhdr = bufp;
423             else if (!strncasecmp("To:", bufp, 3))
424                 tohdr = bufp;
425             else if (!strncasecmp("Apparently-To:", bufp, 14))
426                 envto = bufp;
427             else if (!strncasecmp(ctl->envelope, bufp, 14))
428                 envto = bufp;
429             else if (!strncasecmp("Cc:", bufp, 3))
430                 cchdr = bufp;
431             else if (!strncasecmp("Bcc:", bufp, 4))
432                 bcchdr = bufp;
433 #ifdef HAVE_RES_SEARCH
434             else if (MULTIDROP(ctl) && !strncasecmp("Received:", bufp, 9))
435             {
436                 char *ok;
437
438                 /*
439                  * Try to extract the real envelope addressee.  We look here
440                  * specifically for the mailserver's Received line.
441                  * Note: this will only work for sendmail, or an MTA that
442                  * shares sendmail's convention for embedding the envelope
443                  * address in the Received line.  Sendmail itself only
444                  * does this when the mail has a single recipient.
445                  */
446                 if ((ok = strstr(bufp, "by ")) == (char *)NULL)
447                     ok = (char *)NULL;
448                 else
449                 {
450                     char        *sp, *tp;
451
452                     /* extract space-delimited token after "by " */
453                     tp = rbuf;
454                     for (sp = ok + 3; !isspace(*sp); sp++)
455                         *tp++ = *sp;
456                     *tp = '\0';
457
458                     /*
459                      * If it's a DNS name of the mail server, look for the
460                      * recipient name after a following "for".  Otherwise
461                      * punt.
462                      */
463                     if (is_host_alias(rbuf, ctl))
464                         ok = strstr(sp, "for ");
465                     else
466                         ok = (char *)NULL;
467                 }
468
469                 if (ok != 0)
470                 {
471                     char        *sp, *tp;
472
473                     tp = rbuf;
474                     sp = ok + 4;
475                     if (*sp == '<')
476                         sp++;
477                     while (*sp && *sp != '>' && *sp != '@' && *sp != ';')
478                         if (!isspace(*sp))
479                             *tp++ = *sp++;
480                         else
481                         {
482                             /* uh oh -- whitespace here can't be right! */
483                             ok = (char *)NULL;
484                             break;
485                         }
486                     *tp = '\0';
487                 }
488
489                 if (ok != 0)
490                 {
491                     received_for = alloca(strlen(rbuf)+1);
492                     strcpy(received_for, rbuf);
493                     if (outlevel == O_VERBOSE)
494                         error(0, 0, 
495                                 "found Received address `%s'",
496                                 received_for);
497                 }
498             }
499 #endif /* HAVE_RES_SEARCH */
500
501             goto skipwrite;
502         }
503         else if (headers)       /* OK, we're at end of headers now */
504         {
505             char                *cp;
506             struct idlist       *idp, *xmit_names;
507             int                 good_addresses, bad_addresses;
508 #ifdef HAVE_RES_SEARCH
509             int                 no_local_matches = FALSE;
510 #endif /* HAVE_RES_SEARCH */
511
512             /* cons up a list of local recipients */
513             xmit_names = (struct idlist *)NULL;
514             bad_addresses = good_addresses = 0;
515 #ifdef HAVE_RES_SEARCH
516             /* is this a multidrop box? */
517             if (MULTIDROP(ctl))
518             {
519                 if (envto)          /* We have the actual envelope addressee */
520                     find_server_names(envto, ctl, &xmit_names);
521                 else if (received_for)
522                     /*
523                      * We have the Received for addressee.  
524                      * It has to be a mailserver address, or we
525                      * wouldn't have got here.
526                      */
527                     map_name(received_for, ctl, &xmit_names);
528                 else
529                 {
530                     /*
531                      * We haven't extracted the envelope address.
532                      * So check all the header addresses.
533                      */
534                     find_server_names(tohdr,  ctl, &xmit_names);
535                     find_server_names(cchdr,  ctl, &xmit_names);
536                     find_server_names(bcchdr, ctl, &xmit_names);
537                 }
538                 if (!xmit_names)
539                 {
540                     no_local_matches = TRUE;
541                     save_str(&xmit_names, -1, user);
542                     if (outlevel == O_VERBOSE)
543                         error(0, 0, 
544                                 "no local matches, forwarding to %s",
545                                 user);
546                 }
547             }
548             else        /* it's a single-drop box, use first localname */
549 #endif /* HAVE_RES_SEARCH */
550                 save_str(&xmit_names, -1, ctl->localnames->id);
551
552             /* time to address the message */
553             if (ctl->mda[0])    /* we have a declared MDA */
554             {
555                 int     length = 0;
556                 char    *names, *cmd;
557
558                 /*
559                  * We go through this in order to be able to handle very
560                  * long lists of users and (re)implement %s.
561                  */
562                 for (idp = xmit_names; idp; idp = idp->next)
563                     length += (strlen(idp->id) + 1);
564                 names = (char *)alloca(length);
565                 names[0] = '\0';
566                 for (idp = xmit_names; idp; idp = idp->next)
567                 {
568                     strcat(names, idp->id);
569                     strcat(names, " ");
570                 }
571                 cmd = (char *)alloca(strlen(ctl->mda) + length);
572                 sprintf(cmd, ctl->mda, names);
573                 if (outlevel == O_VERBOSE)
574                     error(0, 0, "about to deliver with: %s", cmd);
575
576 #ifdef HAVE_SETEUID
577                 /*
578                  * Arrange to run with user's permissions if we're root.
579                  * This will initialize the ownership of any files the
580                  * MDA creates properly.  (The seteuid call is available
581                  * under all BSDs and Linux)
582                  */
583                 seteuid(ctl->uid);
584 #endif /* HAVE_SETEUID */
585
586                 sinkfp = popen(cmd, "w");
587
588 #ifdef HAVE_SETEUID
589                 /* this will fail quietly if we didn't start as root */
590                 seteuid(0);
591 #endif /* HAVE_SETEUID */
592
593                 if (!sinkfp)
594                 {
595                     error(0, 0, "MDA open failed");
596                     return(PS_IOERR);
597                 }
598
599                 sigchld = signal(SIGCHLD, SIG_DFL);
600             }
601             else
602             {
603                 char    *ap;
604
605                 /* build a connection to the SMTP listener */
606                 if (ctl->mda[0] == '\0' && ((sinkfp = smtp_open(ctl)) == NULL))
607                 {
608                     free_str_list(&xmit_names);
609                     error(0, 0, "SMTP connect failed");
610                     return(PS_SMTP);
611                 }
612
613                 /*
614                  * Try to get the SMTP listener to take the header
615                  * From address as MAIL FROM (this makes the logging
616                  * nicer).  If it won't, fall back on the calling-user
617                  * ID.  This won't affect replies, which use the header
618                  * From address anyway.
619                  */
620                 if (!fromhdr || !(ap = nxtaddr(fromhdr)))
621                 {
622                     if (SMTP_from(sinkfp, user) != SM_OK)
623                         return(PS_SMTP);        /* should never happen */
624                 }
625                 else if (SMTP_from(sinkfp, ap) != SM_OK)
626                     if (smtp_response == 571)
627                     {
628                         /*
629                          * SMTP listener explicitly refuses to deliver
630                          * mail coming from this address, probably due
631                          * to an anti-spam domain exclusion.  Respect
632                          * this.
633                          */
634                         sinkfp = (FILE *)NULL;
635                         goto skiptext;
636                     }
637                     else if (SMTP_from(sinkfp, user) != SM_OK)
638                         return(PS_SMTP);        /* should never happen */
639
640                 /* now list the recipient addressees */
641                 for (idp = xmit_names; idp; idp = idp->next)
642                     if (SMTP_rcpt(sinkfp, idp->id) == SM_OK)
643                         good_addresses++;
644                     else
645                     {
646                         bad_addresses++;
647                         idp->val.num = 0;
648                         error(0, 0, 
649                                 "SMTP listener doesn't like recipient address `%s'", idp->id);
650                     }
651                 if (!good_addresses && SMTP_rcpt(sinkfp, user) != SM_OK)
652                 {
653                     error(0, 0, 
654                             "can't even send to calling user!");
655                     return(PS_SMTP);
656                 }
657
658                 /* tell it we're ready to send data */
659                 SMTP_data(sinkfp);
660
661             skiptext:;
662             }
663
664             /* change continuation markers back to regular newlines */
665             for (cp = headers; cp < headers + oldlen; cp++)
666                 if (*cp == '\r')
667                     *cp = '\n';
668
669             /* replace all LFs with CR-LF before sending to the SMTP server */
670             if (!ctl->mda[0])
671             {
672                 char *newheaders = xmalloc(1 + oldlen * 2);
673
674                 oldlen = strcrlf(newheaders, headers, oldlen);
675                 free(headers);
676                 headers = newheaders;
677             }
678
679             /* write all the headers */
680             n = 0;
681             if (ctl->mda[0])
682                 n = fwrite(headers, 1, oldlen, sinkfp);
683             else if (sinkfp)
684                 n = SockWrite(headers, 1, oldlen, sinkfp);
685
686             if (n < 0)
687             {
688                 free(headers);
689                 headers = NULL;
690                 error(0, errno, "writing RFC822 headers");
691                 if (ctl->mda[0])
692                 {
693                     pclose(sinkfp);
694                     signal(SIGCHLD, sigchld);
695                 }
696                 return(PS_IOERR);
697             }
698             else if (outlevel == O_VERBOSE)
699                 fputs("#", stderr);
700             free(headers);
701             headers = NULL;
702
703             /* write error notifications */
704 #ifdef HAVE_RES_SEARCH
705             if (no_local_matches || bad_addresses)
706 #else
707             if (bad_addresses)
708 #endif /* HAVE_RES_SEARCH */
709             {
710                 int     errlen = 0;
711                 char    errhd[USERNAMELEN + POPBUFSIZE], *errmsg;
712
713                 errmsg = errhd;
714                 (void) strcpy(errhd, "X-Fetchmail-Warning: ");
715 #ifdef HAVE_RES_SEARCH
716                 if (no_local_matches)
717                 {
718                     strcat(errhd, "no recipient addresses matched declared local names");
719                     if (bad_addresses)
720                         strcat(errhd, "; ");
721                 }
722 #endif /* HAVE_RES_SEARCH */
723
724                 if (bad_addresses)
725                 {
726                     strcat(errhd, "SMTP listener rejected local recipient addresses: ");
727                     errlen = strlen(errhd);
728                     for (idp = xmit_names; idp; idp = idp->next)
729                         if (!idp->val.num)
730                             errlen += strlen(idp->id) + 2;
731
732                     errmsg = alloca(errlen+3);
733                     (void) strcpy(errmsg, errhd);
734                     for (idp = xmit_names; idp; idp = idp->next)
735                         if (!idp->val.num)
736                         {
737                             strcat(errmsg, idp->id);
738                             if (idp->next)
739                                 strcat(errmsg, ", ");
740                         }
741                 }
742
743                 strcat(errmsg, "\n");
744
745                 if (sinkfp)
746                     fputs(errmsg, sinkfp);
747             }
748
749             free_str_list(&xmit_names);
750         }
751
752         /* SMTP byte-stuffing */
753         if (*bufp == '.')
754             if (ctl->mda[0])
755                 fputs(".", sinkfp);
756             else if (sinkfp)
757                 SockWrite(bufp, 1, 1, sinkfp);
758
759         /* replace all LFs with CR-LF  in the line */
760         if (!ctl->mda[0])
761         {
762             char *newbufp = xmalloc(1 + strlen(bufp) * 2);
763
764             strcrlf(newbufp, bufp, strlen(bufp));
765             bufp = newbufp;
766         }
767
768         /* ship out the text line */
769         n = 0;
770         if (ctl->mda[0])
771             n = fwrite(bufp, 1, strlen(bufp), sinkfp);
772         else if (sinkfp)
773             n = SockWrite(bufp, 1, strlen(bufp), sinkfp);
774
775         if (!ctl->mda[0])
776             free(bufp);
777         if (n < 0)
778         {
779             error(0, errno, "writing message text");
780             if (ctl->mda[0])
781             {
782                 pclose(sinkfp);
783                 signal(SIGCHLD, sigchld);
784             }
785             return(PS_IOERR);
786         }
787         else if (outlevel == O_VERBOSE)
788             fputc('*', stderr);
789
790     skipwrite:;
791         lines++;
792     }
793
794     if (outlevel == O_VERBOSE)
795         fputc('\n', stderr);
796
797     if (ctl->mda[0])
798     {
799         int rc;
800
801         /* close the delivery pipe, we'll reopen before next message */
802         rc = pclose(sinkfp);
803         signal(SIGCHLD, sigchld);
804         if (rc)
805         {
806             error(0, 0, "MDA exited abnormally or returned nonzero status");
807             return(PS_IOERR);
808         }
809     }
810     else if (sinkfp)
811     {
812         /* write message terminator */
813         if (SMTP_eom(sinkfp) != SM_OK)
814         {
815             error(0, 0, "SMTP listener refused delivery");
816             return(PS_SMTP);
817         }
818     }
819
820     return(0);
821 }
822
823 #ifdef KERBEROS_V4
824 int
825 kerberos_auth (socket, canonical) 
826 /* authenticate to the server host using Kerberos V4 */
827 int socket;             /* socket to server host */
828 const char *canonical;  /* server name */
829 {
830     char * host_primary;
831     KTEXT ticket;
832     MSG_DAT msg_data;
833     CREDENTIALS cred;
834     Key_schedule schedule;
835     int rem;
836   
837     ticket = ((KTEXT) (malloc (sizeof (KTEXT_ST))));
838     rem = (krb_sendauth (0L, socket, ticket, "pop",
839                          canonical,
840                          ((char *) (krb_realmofhost (canonical))),
841                          ((unsigned long) 0),
842                          (&msg_data),
843                          (&cred),
844                          (schedule),
845                          ((struct sockaddr_in *) 0),
846                          ((struct sockaddr_in *) 0),
847                          "KPOPV0.1"));
848     free (ticket);
849     if (rem != KSUCCESS)
850     {
851         error(0, 0, "kerberos error %s", (krb_get_err_text (rem)));
852         return (PS_ERROR);
853     }
854     return (0);
855 }
856 #endif /* KERBEROS_V4 */
857
858 int do_protocol(ctl, proto)
859 /* retrieve messages from server using given protocol method table */
860 struct query *ctl;              /* parsed options with merged-in defaults */
861 const struct method *proto;     /* protocol method table */
862 {
863     int ok, js, pst;
864     char *msg, *sp, *cp, realname[HOSTLEN];
865     void (*sigsave)();
866
867 #ifndef KERBEROS_V4
868     if (ctl->authenticate == A_KERBEROS)
869     {
870         error(0, 0, "Kerberos support not linked.");
871         return(PS_ERROR);
872     }
873 #endif /* KERBEROS_V4 */
874
875     /* lacking methods, there are some options that may fail */
876     if (!proto->is_old)
877     {
878         /* check for unsupported options */
879         if (ctl->flush) {
880             error(0, 0,
881                     "Option --flush is not supported with %s",
882                     proto->name);
883             return(PS_SYNTAX);
884         }
885         else if (ctl->fetchall) {
886             error(0, 0,
887                     "Option --all is not supported with %s",
888                     proto->name);
889             return(PS_SYNTAX);
890         }
891     }
892     if (!proto->getsizes && ctl->limit)
893     {
894         error(0, 0,
895                 "Option --limit is not supported with %s",
896                 proto->name);
897         return(PS_SYNTAX);
898     }
899
900     protocol = proto;
901     tagnum = 0;
902     tag[0] = '\0';      /* nuke any tag hanging out from previous query */
903     ok = 0;
904     error_init(poll_interval == 0 && !logfile);
905
906     /* set up the server-nonresponse timeout */
907     sigsave = signal(SIGVTALRM, vtalarm_handler);
908     vtalarm(mytimeout = ctl->timeout);
909
910     if ((js = setjmp(restart)) == 1)
911     {
912         error(0, 0,
913                 "timeout after %d seconds waiting for %s.",
914                 ctl->timeout, ctl->servernames->id);
915         ok = PS_ERROR;
916     }
917     else if (js == 2)
918     {
919         /* error message printed at point of longjmp */
920         ok = PS_ERROR;
921     }
922     else
923     {
924         char buf [POPBUFSIZE+1];
925         int *msgsizes, len, num, count, new, deletions = 0;
926         FILE *sockfp; 
927         /* execute pre-initialization command, if any */
928         if (ctl->preconnect[0] && (ok = system(ctl->preconnect)))
929         {
930             sprintf(buf, "pre-connection command failed with status %d", ok);
931             error(0, 0, buf);
932             ok = PS_SYNTAX;
933             goto closeUp;
934         }
935
936         /* open a socket to the mail server */
937         if ((sockfp = SockOpen(ctl->servernames->id,
938                              ctl->port ? ctl->port : protocol->port)) == NULL)
939         {
940             if (errno != EHOSTUNREACH)
941                 error(0, errno, "connecting to host");
942             ok = PS_SOCKET;
943             goto closeUp;
944         }
945
946 #ifdef KERBEROS_V4
947         if (ctl->authenticate == A_KERBEROS)
948         {
949             ok = kerberos_auth(fileno(sockfp), ctl->canonical_name);
950             if (ok != 0)
951                 goto cleanUp;
952             vtalarm(ctl->timeout);
953         }
954 #endif /* KERBEROS_V4 */
955
956         /* accept greeting message from mail server */
957         ok = (protocol->parse_response)(sockfp, buf);
958         if (ok != 0)
959             goto cleanUp;
960         vtalarm(ctl->timeout);
961
962         /*
963          * Try to parse the host's actual name out of the greeting message.
964          * We do this so that the progress messages will make sense even
965          * if the connection is indirected through ssh --- *don't* use
966          * this for error logging as the names in that should correlate
967          * directly back to rc file entries.
968          *
969          * This assumes that the first space-delimited token found
970          * that contains at least two dots (with the characters on
971          * each side of the dot alphanumeric to exclude version
972          * numbers) is the hostname.  If no such token is found, fall
973          * back on the .fetchmailrc id.
974          */
975         pst = 0;
976         for (cp = buf; *cp; cp++)
977         {
978             switch (pst)
979             {
980             case 0:             /* looking for blank-delimited token */
981                 if (*cp != ' ')
982                 {
983                     sp = cp;
984                     pst = 1;
985                 }
986                 break;
987
988             case 1:             /* looking for first dot */
989                 if (*cp == ' ')
990                     pst = 0;
991                 else if (*cp == '.' && isalpha(cp[1]) && isalpha(cp[-1]))
992                     pst = 2;
993                 break;
994
995             case 2:             /* looking for second dot */
996                 if (*cp == ' ')
997                     pst = 0;
998                 else if (*cp == '.' && isalpha(cp[1]) && isalpha(cp[-1]))
999                     pst = 3;
1000                 break;
1001
1002             case 3:             /* looking for trailing space */
1003                 if (*cp == ' ')
1004                 {
1005                     pst = 4;
1006                     goto done;
1007                 }
1008                 break;
1009             }
1010         }
1011     done:
1012         if (pst == 4)
1013         {
1014             char        *tp = realname;
1015
1016             while (sp < cp)
1017                 *tp++ = *sp++;
1018             *tp = '\0';
1019         }
1020         else
1021             strcpy(realname, ctl->servernames->id);
1022
1023         /* try to get authorized to fetch mail */
1024         shroud = ctl->password;
1025         ok = (protocol->getauth)(sockfp, ctl, buf);
1026         shroud = (char *)NULL;
1027         if (ok == PS_ERROR)
1028             ok = PS_AUTHFAIL;
1029         if (ok != 0)
1030             goto cleanUp;
1031         vtalarm(ctl->timeout);
1032
1033         /* compute number of messages and number of new messages waiting */
1034         ok = (protocol->getrange)(sockfp, ctl, &count, &new);
1035         if (ok != 0)
1036             goto cleanUp;
1037         vtalarm(ctl->timeout);
1038
1039         /* show user how many messages we downloaded */
1040         if (outlevel > O_SILENT)
1041             if (count == 0)
1042                 error(0, 0, "No mail from %s@%s", 
1043                         ctl->remotename,
1044                         realname);
1045             else
1046             {
1047                 if (new != -1 && (count - new) > 0)
1048                     error(0, 0, "%d message%s (%d seen) from %s@%s.",
1049                                 count, count > 1 ? "s" : "", count-new,
1050                                 ctl->remotename,
1051                                 realname);
1052                 else
1053                     error(0, 0, "%d message%s from %s@%s.", count, count > 1 ? "s" : "",
1054                                 ctl->remotename,
1055                                 realname);
1056             }
1057
1058         /* we may need to get sizes in order to check message limits */
1059         msgsizes = (int *)NULL;
1060         if (!ctl->fetchall && proto->getsizes && ctl->limit)
1061         {
1062             msgsizes = (int *)alloca(sizeof(int) * count);
1063
1064             ok = (proto->getsizes)(sockfp, count, msgsizes);
1065             if (ok != 0)
1066                 goto cleanUp;
1067             vtalarm(ctl->timeout);
1068         }
1069
1070
1071         if (check_only)
1072         {
1073             if (new == -1 || ctl->fetchall)
1074                 new = count;
1075             ok = ((new > 0) ? PS_SUCCESS : PS_NOMAIL);
1076             goto cleanUp;
1077         }
1078         else if (count > 0)
1079         {    
1080             /*
1081              * What forces this code is that in POP3 and IMAP2BIS you can't
1082              * fetch a message without having it marked `seen'.  In IMAP4,
1083              * on the other hand, you can (peek_capable is set to convey
1084              * this).
1085              *
1086              * The result of being unable to peek is that if there's
1087              * any kind of transient error (DNS lookup failure, or
1088              * sendmail refusing delivery due to process-table limits)
1089              * the message will be marked "seen" on the server without
1090              * having been delivered.  This is not a big problem if
1091              * fetchmail is running in foreground, because the user
1092              * will see a "skipped" message when it next runs and get
1093              * clued in.
1094              *
1095              * But in daemon mode this leads to the message being silently
1096              * ignored forever.  This is not acceptable.
1097              *
1098              * We compensate for this by checking the error count from the 
1099              * previous pass and forcing all messages to be considered new
1100              * if it's nonzero.
1101              */
1102             int force_retrieval = !peek_capable && (ctl->errcount > 0);
1103
1104             ctl->errcount = 0;
1105
1106             /* read, forward, and delete messages */
1107             for (num = 1; num <= count; num++)
1108             {
1109                 int     toolarge = msgsizes && (msgsizes[num-1] > ctl->limit);
1110                 int     fetch_it = ctl->fetchall ||
1111                     (!toolarge && (force_retrieval || !(protocol->is_old && (protocol->is_old)(sockfp,ctl,num))));
1112
1113                 /* we may want to reject this message if it's old */
1114                 if (!fetch_it)
1115                 {
1116                     if (outlevel > O_SILENT)
1117                     {
1118                         error_build("skipping message %d", num);
1119                         if (toolarge)
1120                             error_build(" (oversized, %d bytes)", msgsizes[num-1]);
1121                     }
1122                 }
1123                 else
1124                 {
1125                     /* request a message */
1126                     ok = (protocol->fetch)(sockfp, ctl, num, &len);
1127                     if (ok != 0)
1128                         goto cleanUp;
1129                     vtalarm(ctl->timeout);
1130
1131                     if (outlevel > O_SILENT)
1132                     {
1133                         error_build("reading message %d", num);
1134                         if (len > 0)
1135                             error_build(" (%d bytes)", len);
1136                         if (outlevel == O_VERBOSE)
1137                             error_complete(0, 0, "");
1138                         else
1139                             error_build(" ");
1140                     }
1141
1142                     /* read the message and ship it to the output sink */
1143                     ok = gen_readmsg(sockfp,
1144                                      len, 
1145                                      protocol->delimited,
1146                                      ctl);
1147                     if (ok != 0)
1148                         goto cleanUp;
1149                     vtalarm(ctl->timeout);
1150
1151                     /* tell the server we got it OK and resynchronize */
1152                     if (protocol->trail)
1153                     {
1154                         ok = (protocol->trail)(sockfp, ctl, num);
1155                         if (ok != 0)
1156                             goto cleanUp;
1157                         vtalarm(ctl->timeout);
1158                     }
1159                 }
1160
1161                 /*
1162                  * At this point in flow of control, either we've bombed
1163                  * on a protocol error or had delivery refused by the SMTP
1164                  * server (unlikely -- I've never seen it) or we've seen
1165                  * `accepted for delivery' and the message is shipped.
1166                  * It's safe to mark the message seen and delete it on the
1167                  * server now.
1168                  */
1169
1170                 /* maybe we delete this message now? */
1171                 if (protocol->delete
1172                     && (fetch_it ? !ctl->keep : ctl->flush))
1173                 {
1174                     deletions++;
1175                     if (outlevel > O_SILENT) 
1176                         error_complete(0, 0, " flushed");
1177                     ok = (protocol->delete)(sockfp, ctl, num);
1178                     if (ok != 0)
1179                         goto cleanUp;
1180                     vtalarm(ctl->timeout);
1181                     delete_str(&ctl->newsaved, num);
1182                 }
1183                 else if (outlevel > O_SILENT) 
1184                     error_complete(0, 0, " not flushed");
1185
1186                 /* perhaps this as many as we're ready to handle */
1187                 if (ctl->fetchlimit && ctl->fetchlimit <= num)
1188                     break;
1189             }
1190
1191             /* remove all messages flagged for deletion */
1192             if (protocol->expunge_cmd && deletions > 0)
1193             {
1194                 ok = gen_transact(sockfp, protocol->expunge_cmd);
1195                 if (ok != 0)
1196                     goto cleanUp;
1197                 vtalarm(ctl->timeout);
1198             }
1199
1200             ok = gen_transact(sockfp, protocol->exit_cmd);
1201             if (ok == 0)
1202                 ok = PS_SUCCESS;
1203             vtalarm(0);
1204             fclose(sockfp);
1205             goto closeUp;
1206         }
1207         else {
1208             ok = gen_transact(sockfp, protocol->exit_cmd);
1209             if (ok == 0)
1210                 ok = PS_NOMAIL;
1211             vtalarm(0);
1212             fclose(sockfp);
1213             goto closeUp;
1214         }
1215
1216     cleanUp:
1217         vtalarm(ctl->timeout);
1218         if (ok != 0 && ok != PS_SOCKET)
1219             gen_transact(sockfp, protocol->exit_cmd);
1220         vtalarm(0);
1221         fclose(sockfp);
1222     }
1223
1224     switch (ok)
1225     {
1226     case PS_SOCKET:
1227         msg = "socket";
1228         break;
1229     case PS_AUTHFAIL:
1230         msg = "authorization";
1231         break;
1232     case PS_SYNTAX:
1233         msg = "missing or bad RFC822 header";
1234         break;
1235     case PS_IOERR:
1236         msg = "MDA";
1237         break;
1238     case PS_ERROR:
1239         msg = "client/server synchronization";
1240         break;
1241     case PS_PROTOCOL:
1242         msg = "client/server protocol";
1243         break;
1244     case PS_SMTP:
1245         msg = "SMTP transaction";
1246         break;
1247     case PS_UNDEFINED:
1248         error(0, 0, "undefined");
1249         break;
1250     }
1251     if (ok==PS_SOCKET || ok==PS_AUTHFAIL || ok==PS_SYNTAX || ok==PS_IOERR
1252                 || ok==PS_ERROR || ok==PS_PROTOCOL || ok==PS_SMTP)
1253         error(0, 0, "%s error while fetching from %s", msg, ctl->servernames->id);
1254
1255 closeUp:
1256     signal(SIGVTALRM, sigsave);
1257     return(ok);
1258 }
1259
1260 #if defined(HAVE_STDARG_H)
1261 void gen_send(FILE *sockfp, char *fmt, ... )
1262 /* assemble command in printf(3) style and send to the server */
1263 #else
1264 void gen_send(sockfp, fmt, va_alist)
1265 /* assemble command in printf(3) style and send to the server */
1266 FILE *sockfp;           /* socket to which server is connected */
1267 const char *fmt;        /* printf-style format */
1268 va_dcl
1269 #endif
1270 {
1271     char buf [POPBUFSIZE+1];
1272     va_list ap;
1273
1274     if (protocol->tagged)
1275         (void) sprintf(buf, "%s ", GENSYM);
1276     else
1277         buf[0] = '\0';
1278
1279 #if defined(HAVE_STDARG_H)
1280     va_start(ap, fmt) ;
1281 #else
1282     va_start(ap);
1283 #endif
1284     vsprintf(buf + strlen(buf), fmt, ap);
1285     va_end(ap);
1286
1287     strcat(buf, "\r\n");
1288     SockWrite(buf, 1, strlen(buf), sockfp);
1289
1290     if (outlevel == O_VERBOSE)
1291     {
1292         char *cp;
1293
1294         if (shroud && (cp = strstr(buf, shroud)))
1295             memset(cp, '*', strlen(shroud));
1296         buf[strlen(buf)-1] = '\0';
1297         error(0, 0, "%s> %s", protocol->name, buf);
1298     }
1299 }
1300
1301 #if defined(HAVE_STDARG_H)
1302 int gen_transact(FILE *sockfp, char *fmt, ... )
1303 /* assemble command in printf(3) style, send to server, accept a response */
1304 #else
1305 int gen_transact(sockfp, fmt, va_alist)
1306 /* assemble command in printf(3) style, send to server, accept a response */
1307 FILE *sockfp;           /* socket to which server is connected */
1308 const char *fmt;        /* printf-style format */
1309 va_dcl
1310 #endif
1311 {
1312     int ok;
1313     char buf [POPBUFSIZE+1];
1314     va_list ap;
1315
1316     if (protocol->tagged)
1317         (void) sprintf(buf, "%s ", GENSYM);
1318     else
1319         buf[0] = '\0';
1320
1321 #if defined(HAVE_STDARG_H)
1322     va_start(ap, fmt) ;
1323 #else
1324     va_start(ap);
1325 #endif
1326     vsprintf(buf + strlen(buf), fmt, ap);
1327     va_end(ap);
1328
1329     strcat(buf, "\r\n");
1330     SockWrite(buf, 1, strlen(buf), sockfp);
1331
1332     if (outlevel == O_VERBOSE)
1333     {
1334         char *cp;
1335
1336         if (shroud && (cp = strstr(buf, shroud)))
1337             memset(cp, '*', strlen(shroud));
1338         buf[strlen(buf)-1] = '\0';
1339         error(0, 0, "%s> %s", protocol->name, buf);
1340     }
1341
1342     /* we presume this does its own response echoing */
1343     ok = (protocol->parse_response)(sockfp, buf);
1344     vtalarm(mytimeout);
1345
1346     return(ok);
1347 }
1348
1349 /* driver.c ends here */