2 * driver.c -- generic driver for mail fetch method protocols
4 * Copyright 1996 by Eric S. Raymond
6 * For license terms, see the file COPYING in this directory.
13 #if defined(STDC_HEADERS)
17 #if defined(HAVE_UNISTD_H)
20 #if defined(HAVE_STDARG_H)
28 #ifdef HAVE_GETHOSTBYNAME
31 #endif /* HAVE_GETHOSTBYNAME */
36 #include <netinet/in.h> /* must be included before "socket.h".*/
38 #endif /* KERBEROS_V4 */
40 #include "fetchmail.h"
43 #define SMTP_PORT 25 /* standard SMTP service port */
45 static const struct method *protocol;
46 static jmp_buf restart;
50 #define GENSYM (sprintf(tag, "a%04d", ++tagnum), tag)
54 static int strcrlf(dst, src, count)
55 /* replace LFs with CR-LF; return length of string with replacements */
56 char *dst; /* new string with CR-LFs */
57 char *src; /* original string with LFs */
58 int count; /* length of src */
75 static void alarm_handler (int signal)
76 /* handle server-timeout signal */
81 static void reply_hack(buf, host)
82 /* hack message headers so replies will work properly */
83 char *buf; /* header to be hacked */
84 const char *host; /* server hostname */
87 int state = 0, tokencount = 0;
88 char mycopy[POPBUFSIZE+1];
90 if (strncmp("From: ", buf, 6)
91 && strncmp("To: ", buf, 4)
92 && strncmp("Reply-", buf, 6)
93 && strncmp("Cc: ", buf, 4)
94 && strncmp("Bcc: ", buf, 5)) {
99 for (from = mycopy; *from; from++)
103 case 0: /* before header colon */
108 case 1: /* we've seen the colon, we're looking for addresses */
111 else if (*from == '(')
113 else if (*from == '<' || isalnum(*from))
115 else if (isspace(*from))
117 else if (*from == ',')
121 case 2: /* found a token boundary -- reset without copying */
122 if (*from != ' ' && *from != '\t')
130 case 3: /* we're in a quoted human name, copy and ignore */
135 case 4: /* we're in a parenthesized human name, copy and ignore */
140 case 5: /* the real work gets done here */
142 * We're in something that might be an address part,
143 * either a bare unquoted/unparenthesized text or text
144 * enclosed in <> as per RFC822.
146 /* if the address part contains an @, don't mess with it */
150 /* If the address token is not properly terminated, ignore it. */
151 else if (*from == ' ' || *from == '\t')
156 * The only lookahead case. If we're looking at space or tab,
157 * we might be looking at a local name immediately followed
160 for (cp = from; isspace(*cp); cp++)
172 * On proper termination with no @, insert hostname.
173 * Case '>' catches <>-enclosed mail IDs. Case ',' catches
174 * comma-separated bare IDs.
176 else if (strchr(">,", *from))
184 /* a single local name alone on the line */
185 else if (*from == '\n' && tokencount == 0)
193 /* everything else, including alphanumerics, just passes through */
196 case 6: /* we're in a remote mail ID, no need to append hostname */
197 if (*from == '>' || *from == ',' || isspace(*from))
202 /* all characters from the old buffer get copied to the new one */
208 static char *nxtaddr(hdr)
209 /* parse addresses in succession out of a specified RFC822 header */
210 char *hdr; /* header line to be parsed, NUL to continue in previous hdr */
212 static char *hp, *tp, address[POPBUFSIZE+1];
216 * Note 1: RFC822 escaping with \ is *not* handled. Note 2: it is
217 * important that this routine not stop on \r, since we use \r as
218 * a marker for RFC822 continuations below.
231 case 0: /* before header colon */
241 case 1: /* we've seen the colon, now grab the address */
242 if (*hp == '\n') /* end of address list */
248 else if (*hp == ',') /* end of address */
253 else if (*hp == '"') /* quoted string */
258 else if (*hp == '(') /* address comment -- ignore */
260 else if (*hp == '<') /* begin <address> */
265 else if (isspace(*hp)) /* ignore space */
267 else /* just take it */
274 case 2: /* we're in a quoted string, copy verbatim */
286 case 3: /* we're in a parenthesized comment, ignore */
293 case 4: /* possible <>-enclosed address */
294 if (*hp == '>') /* end of address */
300 else if (*hp == '<') /* nested <> */
302 else if (*hp == '"') /* quoted address */
307 else /* just copy address */
311 case 5: /* we're in a quoted address, copy verbatim */
312 if (*hp == '\n') /* mismatched quotes */
314 if (*hp != '"') /* just copy it if it isn't a quote */
316 else if (*hp == '"') /* end of quoted string */
332 #ifdef HAVE_GETHOSTBYNAME
335 static int is_host_alias(name, ctl)
336 /* determine whether name is a DNS alias of the hostname */
344 * The first two checks are optimizations that will catch a good
345 * many cases. First, check against the hostname the user specified.
346 * Odds are good this will either be the mailserver's FQDN or a
347 * suffix of it with the mailserver's domain's default host name
348 * omitted. Next, check against the mailserver's FQDN, in case
349 * it's not the same as the declared hostname.
351 * Either of these on a mail address is definitive. Only if the
352 * name doesn't match either is it time to call the bind library.
353 * If this happens odds are good we're looking at an MX name.
355 if (strcmp(name, ctl->servername) == 0)
357 else if (strcmp(name, ctl->canonical_name) == 0)
361 * We treat DNS lookup failure as a negative on the theory that
362 * the mailserver's DNS server is `nearby' and should be able
363 * to respond quickly and reliably. Ergo if we get failure,
364 * the name isn't a mailserver alias.
366 else if ((he = gethostbyname(name)) && strcmp(ctl->canonical_name, he->h_name) == 0)
370 * Search for a name match on MX records pointing to the server
371 * site. These may live far away, so allow a couple of retries.
373 for (i = 0; i < MX_RETRIES; i++)
375 struct mxentry *mxrecords, *mxp;
377 mxrecords = getmxrecords(name);
379 if (mxrecords == (struct mxentry *)NULL)
380 if (h_errno == TRY_AGAIN)
388 for (mxp = mxrecords; mxp->name; mxp++)
389 if (strcmp(name, mxp->name) == 0)
396 void find_server_names(hdr, ctl, xmit_names)
397 /* parse names out of a RFC822 header into an ID list */
398 const char *hdr; /* RFC822 header in question */
399 struct query *ctl; /* list of permissible aliases */
400 struct idlist **xmit_names; /* list of recipient names parsed out */
402 if (hdr == (char *)NULL)
408 if ((cp = nxtaddr(hdr)) != (char *)NULL)
410 char *atsign = strchr(cp, '@');
417 if (!is_host_alias(atsign+1, ctl))
421 lname = idpair_find(&ctl->localnames, cp);
422 if (lname != (char *)NULL)
424 if (outlevel == O_VERBOSE)
426 "fetchmail: mapped %s to local %s\n",
428 save_uid(xmit_names, -1, lname);
431 ((cp = nxtaddr((char *)NULL)) != (char *)NULL);
434 #endif /* HAVE_GETHOSTBYNAME */
436 static int gen_readmsg (socket, mboxfd, len, delimited, ctl)
437 /* read message content and ship to SMTP or MDA */
438 int socket; /* to which the server is connected */
439 int mboxfd; /* descriptor to which retrieved message will be written */
440 long len; /* length of message */
441 int delimited; /* does the protocol use a message delimiter? */
442 struct query *ctl; /* query control record */
444 char buf [MSGBUFSIZE+1];
445 char *bufp, *headers, *unixfrom, *fromhdr, *tohdr, *cchdr, *bcchdr;
447 int inheaders,lines,sizeticker;
449 /* read the message content from the server */
451 headers = unixfrom = fromhdr = tohdr = cchdr = bcchdr = NULL;
454 while (delimited || len > 0)
456 if ((n = SockGets(socket,buf,sizeof(buf))) < 0)
459 /* write the message size dots */
463 while (sizeticker >= SIZETICKER)
465 if (outlevel > O_SILENT)
467 sizeticker -= SIZETICKER;
472 if (buf[0] == '\0' || buf[0] == '\r' || buf[0] == '\n')
474 if (delimited && *bufp == '.') {
477 break; /* end of message */
484 reply_hack(bufp, ctl->servername);
488 oldlen = strlen(bufp);
489 headers = malloc(oldlen + 1);
492 (void) strcpy(headers, bufp);
500 * We deal with RFC822 continuation lines here.
501 * Replace previous '\n' with '\r' so nxtaddr
502 * and reply_hack will be able to see past it.
503 * (We know this safe because SocketGets stripped
504 * out all carriage returns in the read loop above
505 * and we haven't reintroduced any since then.)
506 * We'll undo this before writing the header.
508 if (isspace(bufp[0]))
509 headers[oldlen-1] = '\r';
511 newlen = oldlen + strlen(bufp);
512 headers = realloc(headers, newlen + 1);
515 strcpy(headers + oldlen, bufp);
516 bufp = headers + oldlen;
520 if (!strncmp(bufp,"From ",5))
522 else if (!strncasecmp("From:", bufp, 5))
524 else if (!strncasecmp("To:", bufp, 3))
526 else if (!strncasecmp("Cc:", bufp, 3))
528 else if (!strncasecmp("Bcc:", bufp, 4))
533 else if (headers) /* OK, we're at end of headers now */
536 struct idlist *idp, *xmit_names;
538 /* cons up a list of local recipients */
539 xmit_names = (struct idlist *)NULL;
540 #ifdef HAVE_GETHOSTBYNAME
541 /* is this a multidrop box? */
542 if (ctl->localnames != (struct idlist *)NULL
543 && ctl->localnames->next != (struct idlist *)NULL)
545 /* compute the local address list */
546 find_server_names(tohdr, ctl, &xmit_names);
547 find_server_names(cchdr, ctl, &xmit_names);
548 find_server_names(bcchdr, ctl, &xmit_names);
550 /* if nothing supplied localnames, default appropriately */
552 save_uid(&xmit_names, -1, dfltuser);
554 else /* it's a single-drop box, use first localname */
555 #endif /* HAVE_GETHOSTBYNAME */
558 save_uid(&xmit_names, -1, ctl->localnames->id);
560 save_uid(&xmit_names, -1, dfltuser);
563 /* time to address the message */
564 if (ctl->mda[0]) /* we have a declared MDA */
570 * We go through this in order to be able to handle very
571 * long lists of users.
573 for (idp = xmit_names; idp; idp = idp->next)
575 sp = sargv = (char **)alloca(ctl->mda_argcount+nlocals+2);
576 for (i = 0; i <= ctl->mda_argcount; i++)
577 *sp++ = ctl->mda_argv[i];
578 for (idp = xmit_names; idp; idp = idp->next)
584 * Arrange to run with user's permissions if we're root.
585 * This will initialize the ownership of any files the
586 * MDA creates properly. (The seteuid call is available
587 * under all BSDs and Linux)
590 #endif /* HAVE_SETEUID */
592 mboxfd = openmailpipe(sargv);
595 /* this will fail quietly if we didn't start as root */
597 #endif /* HAVE_SETEUID */
604 if (SMTP_from(mboxfd, nxtaddr(fromhdr)) != SM_OK)
607 for (idp = xmit_names; idp; idp = idp->next)
608 if (SMTP_rcpt(mboxfd, idp->id) != SM_OK)
612 if (outlevel == O_VERBOSE)
613 fputs("SMTP> ", stderr);
615 free_uid_list(&xmit_names);
617 /* change continuation markers back to regular newlines */
618 for (cp = headers; cp < headers + oldlen; cp++)
622 /* replace all LFs with CR-LF before sending to the SMTP server */
625 char *newheaders = malloc(1 + oldlen * 2);
627 if (newheaders == NULL)
629 oldlen = strcrlf(newheaders, headers, oldlen);
631 headers = newheaders;
633 if (write(mboxfd,headers,oldlen) < 0)
637 perror("gen_readmsg: writing RFC822 headers");
640 else if (outlevel == O_VERBOSE)
646 /* SMTP byte-stuffing */
647 if (*bufp == '.' && ctl->mda[0] == 0)
648 write(mboxfd, ".", 1);
650 /* write this line to the file after replacing all LFs with CR-LF */
653 char *newbufp = malloc(1 + strlen(bufp) * 2);
657 strcrlf(newbufp, bufp, strlen(bufp));
660 n = write(mboxfd,bufp,strlen(bufp));
665 perror("gen_readmsg: writing message text");
668 else if (outlevel == O_VERBOSE)
677 /* close the delivery pipe, we'll reopen before next message */
678 if (closemailpipe(mboxfd))
683 /* write message terminator */
684 if (SMTP_eom(mboxfd) != SM_OK)
693 kerberos_auth (socket, canonical)
694 /* authenticate to the server host using Kerberos V4 */
695 int socket; /* socket to server host */
696 char *canonical; /* server name */
702 Key_schedule schedule;
705 ticket = ((KTEXT) (malloc (sizeof (KTEXT_ST))));
706 rem = (krb_sendauth (0L, socket, ticket, "pop",
708 ((char *) (krb_realmofhost (canonical))),
713 ((struct sockaddr_in *) 0),
714 ((struct sockaddr_in *) 0),
719 fprintf (stderr, "fetchmail: kerberos error %s\n", (krb_get_err_text (rem)));
724 #endif /* KERBEROS_V4 */
726 int do_protocol(ctl, proto)
727 /* retrieve messages from server using given protocol method table */
728 struct query *ctl; /* parsed options with merged-in defaults */
729 const struct method *proto; /* protocol method table */
735 if (ctl->authenticate == A_KERBEROS)
737 fputs("fetchmail: Kerberos support not linked.\n", stderr);
740 #endif /* KERBEROS_V4 */
742 /* lacking methods, there are some options that may fail */
745 /* check for unsupported options */
748 "Option --flush is not supported with %s\n",
752 else if (ctl->fetchall) {
754 "Option --all is not supported with %s\n",
759 if (!proto->getsizes && ctl->limit)
762 "Option --limit is not supported with %s\n",
769 tag[0] = '\0'; /* nuke any tag hanging out from previous query */
772 if (setjmp(restart) == 1)
774 "fetchmail: timeout after %d seconds waiting for %s.\n",
775 ctl->timeout, ctl->servername);
778 char buf [POPBUFSIZE+1];
779 int *msgsizes, socket, len, num, count, new, deletions = 0;
781 /* set up the server-nonresponse timeout */
782 sigsave = signal(SIGALRM, alarm_handler);
785 /* open a socket to the mail server */
786 if ((socket = Socket(ctl->servername,
787 ctl->port ? ctl->port : protocol->port))<0)
789 perror("fetchmail, connecting to host");
795 if (ctl->authenticate == A_KERBEROS)
797 ok = (kerberos_auth (socket, ctl->canonical_name));
801 #endif /* KERBEROS_V4 */
803 /* accept greeting message from mail server */
804 ok = (protocol->parse_response)(socket, buf);
808 /* try to get authorized to fetch mail */
809 shroud = ctl->password;
810 ok = (protocol->getauth)(socket, ctl, buf);
811 shroud = (char *)NULL;
817 /* compute number of messages and number of new messages waiting */
818 if ((protocol->getrange)(socket, ctl, &count, &new) != 0)
821 /* show user how many messages we downloaded */
822 if (outlevel > O_SILENT)
824 fprintf(stderr, "No mail from %s@%s\n",
829 fprintf(stderr, "%d message%s", count, count > 1 ? "s" : "");
830 if (new != -1 && (count - new) > 0)
831 fprintf(stderr, " (%d seen)", count-new);
838 /* we may need to get sizes in order to check message limits */
839 msgsizes = (int *)NULL;
840 if (!ctl->fetchall && proto->getsizes && ctl->limit)
842 msgsizes = (int *)alloca(sizeof(int) * count);
844 if ((ok = (proto->getsizes)(socket, count, msgsizes)) != 0)
850 if (new == -1 || ctl->fetchall)
852 ok = ((new > 0) ? PS_SUCCESS : PS_NOMAIL);
857 if (ctl->mda[0] == '\0')
858 if ((mboxfd = Socket(ctl->smtphost, SMTP_PORT)) < 0
859 || SMTP_ok(mboxfd, NULL) != SM_OK
860 || SMTP_helo(mboxfd, ctl->servername) != SM_OK)
868 /* read, forward, and delete messages */
869 for (num = 1; num <= count; num++)
871 int toolarge = msgsizes && msgsizes[num-1]>ctl->limit;
872 int fetch_it = ctl->fetchall ||
873 (!(protocol->is_old && (protocol->is_old)(socket,ctl,num)) && !toolarge);
875 /* we may want to reject this message if it's old */
878 if (outlevel > O_SILENT)
880 fprintf(stderr, "skipping message %d", num);
882 fprintf(stderr, " (oversized, %d bytes)", msgsizes[num-1]);
887 /* request a message */
888 (protocol->fetch)(socket, num, &len);
890 if (outlevel > O_SILENT)
892 fprintf(stderr, "reading message %d", num);
894 fprintf(stderr, " (%d bytes)", len);
895 if (outlevel == O_VERBOSE)
902 * If we're forwarding via SMTP, mboxfd is initialized
903 * at this point (it was set at start of retrieval).
904 * If we're using an MDA it's not set -- gen_readmsg()
905 * may have to parse message headers to know what
906 * delivery addresses should be passed to the MDA
909 /* read the message and ship it to the output sink */
910 ok = gen_readmsg(socket, mboxfd,
915 /* tell the server we got it OK and resynchronize */
917 (protocol->trail)(socket, ctl, num);
923 * At this point in flow of control, either we've bombed
924 * on a protocol error or had delivery refused by the SMTP
925 * server (unlikely -- I've never seen it) or we've seen
926 * `accepted for delivery' and the message is shipped.
927 * It's safe to mark the message seen and delete it on the
931 /* maybe we delete this message now? */
933 && (fetch_it ? !ctl->keep : ctl->flush))
936 if (outlevel > O_SILENT)
937 fprintf(stderr, " flushed\n");
938 ok = (protocol->delete)(socket, ctl, num);
942 else if (outlevel > O_SILENT)
944 /* nuke it from the unseen-messages list */
945 delete_uid(&ctl->newsaved, num);
946 fprintf(stderr, " not flushed\n");
950 /* remove all messages flagged for deletion */
951 if (protocol->expunge_cmd && deletions > 0)
953 ok = gen_transact(socket, protocol->expunge_cmd);
958 ok = gen_transact(socket, protocol->exit_cmd);
965 ok = gen_transact(socket, protocol->exit_cmd);
973 if (ok != 0 && ok != PS_SOCKET)
975 gen_transact(socket, protocol->exit_cmd);
981 signal(SIGALRM, sigsave);
994 #if defined(HAVE_STDARG_H)
995 void gen_send(int socket, char *fmt, ... )
996 /* assemble command in printf(3) style and send to the server */
999 void gen_send(socket, fmt, va_alist)
1000 /* assemble command in printf(3) style and send to the server */
1001 int socket; /* socket to which server is connected */
1002 const char *fmt; /* printf-style format */
1006 char buf [POPBUFSIZE+1];
1009 if (protocol->tagged)
1010 (void) sprintf(buf, "%s ", GENSYM);
1014 #if defined(HAVE_STDARG_H)
1019 vsprintf(buf + strlen(buf), fmt, ap);
1022 SockPuts(socket, buf);
1024 if (outlevel == O_VERBOSE)
1028 if (shroud && (cp = strstr(buf, shroud)))
1029 memset(cp, '*', strlen(shroud));
1030 fprintf(stderr,"> %s\n", buf);
1034 #if defined(HAVE_STDARG_H)
1035 int gen_transact(int socket, char *fmt, ... )
1036 /* assemble command in printf(3) style, send to server, accept a response */
1039 int gen_transact(socket, fmt, va_alist)
1040 /* assemble command in printf(3) style, send to server, accept a response */
1041 int socket; /* socket to which server is connected */
1042 const char *fmt; /* printf-style format */
1047 char buf [POPBUFSIZE+1];
1050 if (protocol->tagged)
1051 (void) sprintf(buf, "%s ", GENSYM);
1055 #if defined(HAVE_STDARG_H)
1060 vsprintf(buf + strlen(buf), fmt, ap);
1063 SockPuts(socket, buf);
1064 if (outlevel == O_VERBOSE)
1068 if (shroud && (cp = strstr(buf, shroud)))
1069 memset(cp, '*', strlen(shroud));
1070 fprintf(stderr,"> %s\n", buf);
1073 /* we presume this does its own response echoing */
1074 ok = (protocol->parse_response)(socket, buf);
1079 /* driver.c ends here */