2 * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
12 * $FreeBSD: src/contrib/sendmail/src/headers.c,v 1.4.2.12 2003/10/30 22:31:44 gshapiro Exp $
14 * $DragonFly: src/contrib/sendmail/src/Attic/headers.c,v 1.4 2003/12/22 04:04:23 drhodus Exp $
19 SM_RCSID("@(#)$Id: headers.c,v 8.266.4.7 2003/09/03 21:32:20 ca Exp $")
21 static size_t fix_mime_header __P((HDR *, ENVELOPE *));
22 static int priencode __P((char *));
23 static void put_vanilla_header __P((HDR *, char *, MCI *));
26 ** SETUPHEADERS -- initialize headers in symbol table
41 for (hi = HdrInfo; hi->hi_field != NULL; hi++)
43 s = stab(hi->hi_field, ST_HEADER, ST_ENTER);
44 s->s_header.hi_flags = hi->hi_flags;
45 s->s_header.hi_ruleset = NULL;
49 ** CHOMPHEADER -- process and save a header line.
51 ** Called by collect, readcf, and readqf to deal with header lines.
54 ** line -- header as a text line.
55 ** pflag -- flags for chompheader() (from sendmail.h)
56 ** hdrp -- a pointer to the place to save the header.
57 ** e -- the envelope including this header.
60 ** flags for this header.
63 ** The header is saved on the header list.
64 ** Contents of 'line' are destroyed.
67 static struct hdrinfo NormalHeader = { NULL, 0, NULL };
70 chompheader(line, pflag, hdrp, e)
76 unsigned char mid = '\0';
87 bool nullheader = false;
92 sm_dprintf("chompheader: ");
97 headeronly = hdrp != NULL;
101 /* strip off options */
104 if (!bitset(pflag, CHHDR_USER) && *p == '?')
109 q = strchr(++p, '?');
116 /* possibly macro conditional */
117 if (c == MACROEXPAND)
126 mid = (unsigned char) *p++;
144 mid = (unsigned char) macid(p);
145 if (bitset(0200, mid))
147 p += strlen(macname(mid)) + 2;
170 setbitn(bitidx(*p), mopts);
178 /* find canonical name */
180 while (isascii(*p) && isgraph(*p) && *p != ':')
183 while (isascii(*p) && isspace(*p))
185 if (*p++ != ':' || fname == fvalue)
188 syserr("553 5.3.0 header syntax error, line \"%s\"", line);
193 /* strip field value on front */
198 /* if the field is null, go ahead and use the default */
199 while (isascii(*p) && isspace(*p))
204 /* security scan: long field names are end-of-header */
205 if (strlen(fname) > 100)
208 /* check to see if it represents a ruleset call */
209 if (bitset(pflag, CHHDR_DEF))
213 (void) expand(fvalue, hbuf, sizeof hbuf, e);
214 for (p = hbuf; isascii(*p) && isspace(*p); )
216 if ((*p++ & 0377) == CALLSUBR)
221 strc = *p == '+'; /* strip comments? */
224 if (strtorwset(p, &endp, ST_ENTER) > 0)
227 s = stab(fname, ST_HEADER, ST_ENTER);
229 s->s_header.hi_ruleset != NULL)
230 sm_syslog(LOG_WARNING, NOQID,
231 "Warning: redefined ruleset for header=%s, old=%s, new=%s",
233 s->s_header.hi_ruleset, p);
234 s->s_header.hi_ruleset = newstr(p);
236 s->s_header.hi_flags |= H_STRIPCOMM;
242 /* see if it is a known type */
243 s = stab(fname, ST_HEADER, ST_FIND);
252 sm_dprintf("no header flags match\n");
254 sm_dprintf("header match, flags=%lx, ruleset=%s\n",
256 hi->hi_ruleset == NULL ? "<NULL>"
260 /* see if this is a resent message */
261 if (!bitset(pflag, CHHDR_DEF) && !headeronly &&
262 bitset(H_RESENT, hi->hi_flags))
263 e->e_flags |= EF_RESENT;
265 /* if this is an Errors-To: header keep track of it now */
266 if (UseErrorsTo && !bitset(pflag, CHHDR_DEF) && !headeronly &&
267 bitset(H_ERRORSTO, hi->hi_flags))
268 (void) sendtolist(fvalue, NULLADDR, &e->e_errorqueue, 0, e);
270 /* if this means "end of header" quit now */
271 if (!headeronly && bitset(H_EOH, hi->hi_flags))
275 ** Horrible hack to work around problem with Lotus Notes SMTP
276 ** mail gateway, which generates From: headers with newlines in
277 ** them and the <address> on the second line. Although this is
278 ** legal RFC 822, many MUAs don't handle this properly and thus
279 ** never find the actual address.
282 if (bitset(H_FROM, hi->hi_flags) && SingleLineFromHeader)
284 while ((p = strchr(fvalue, '\n')) != NULL)
289 ** If there is a check ruleset, verify it against the header.
292 if (bitset(pflag, CHHDR_CHECK))
297 /* no ruleset? look for default */
299 rscheckflags = RSF_COUNT;
300 if (!bitset(hi->hi_flags, H_FROM|H_RCPT))
301 rscheckflags |= RSF_UNSTRUCTURED;
304 s = stab("*", ST_HEADER, ST_FIND);
307 rs = (&s->s_header)->hi_ruleset;
308 if (bitset((&s->s_header)->hi_flags,
310 rscheckflags |= RSF_RMCOMM;
313 else if (bitset(hi->hi_flags, H_STRIPCOMM))
314 rscheckflags |= RSF_RMCOMM;
323 /* - 3 to avoid problems with " at the end */
324 /* should be sizeof(qval), not MAXNAME */
325 for (k = 0; fvalue[k] != '\0' && l < MAXNAME - 3; k++)
329 /* XXX other control chars? */
330 case '\011': /* ht */
331 case '\012': /* nl */
332 case '\013': /* vt */
333 case '\014': /* np */
334 case '\015': /* cr */
341 qval[l++] = fvalue[k];
347 k += strlen(fvalue + k);
351 sm_syslog(LOG_WARNING, e->e_id,
352 "Warning: truncated header '%s' before check with '%s' len=%d max=%d",
353 fname, rs, k, MAXNAME - 1);
355 macdefine(&e->e_macro, A_TEMP,
356 macid("{currHeader}"), qval);
357 macdefine(&e->e_macro, A_TEMP,
358 macid("{hdr_name}"), fname);
360 (void) sm_snprintf(qval, sizeof qval, "%d", k);
361 macdefine(&e->e_macro, A_TEMP, macid("{hdrlen}"), qval);
364 ** XXX: h isn't set yet
365 ** If we really want to be precise then we have
366 ** to lookup the header (see below).
367 ** It's probably not worth the effort.
370 if (bitset(H_FROM, h->h_flags))
371 macdefine(&e->e_macro, A_PERM,
372 macid("{addr_type}"), "h s");
373 else if (bitset(H_RCPT, h->h_flags))
374 macdefine(&e->e_macro, A_PERM,
375 macid("{addr_type}"), "h r");
377 #endif /* _FFR_HDR_TYPE */
378 macdefine(&e->e_macro, A_PERM,
379 macid("{addr_type}"), "h");
380 (void) rscheck(rs, fvalue, NULL, e, rscheckflags, 3,
386 ** Drop explicit From: if same as what we would generate.
387 ** This is to make MH (which doesn't always give a full name)
388 ** insert the full name information in all circumstances.
393 if (!bitset(EF_RESENT, e->e_flags))
395 if (!bitset(pflag, CHHDR_DEF) && !headeronly &&
396 !bitset(EF_QUEUERUN, e->e_flags) && sm_strcasecmp(fname, p) == 0)
400 sm_dprintf("comparing header from (%s) against default (%s or %s)\n",
401 fvalue, e->e_from.q_paddr, e->e_from.q_user);
403 if (e->e_from.q_paddr != NULL &&
404 e->e_from.q_mailer != NULL &&
405 bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags) &&
406 (strcmp(fvalue, e->e_from.q_paddr) == 0 ||
407 strcmp(fvalue, e->e_from.q_user) == 0))
411 /* delete default value for this header */
412 for (hp = hdrp; (h = *hp) != NULL; hp = &h->h_link)
414 if (sm_strcasecmp(fname, h->h_field) == 0 &&
415 !bitset(H_USER, h->h_flags) &&
416 !bitset(H_FORCE, h->h_flags))
420 /* user-supplied value was null */
425 /* make this look like the user entered it */
426 h->h_flags |= H_USER;
432 /* copy conditions from default case */
433 memmove((char *) mopts, (char *) h->h_mflags,
440 /* create a new node */
441 h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof *h);
442 h->h_field = sm_rpool_strdup_x(e->e_rpool, fname);
443 h->h_value = sm_rpool_strdup_x(e->e_rpool, fvalue);
445 memmove((char *) h->h_mflags, (char *) mopts, sizeof mopts);
448 h->h_flags = hi->hi_flags;
449 if (bitset(pflag, CHHDR_USER) || bitset(pflag, CHHDR_QUEUE))
450 h->h_flags |= H_USER;
452 /* strip EOH flag if parsing MIME headers */
454 h->h_flags &= ~H_EOH;
455 if (bitset(pflag, CHHDR_DEF))
456 h->h_flags |= H_DEFAULT;
457 if (cond || mid != '\0')
458 h->h_flags |= H_CHECK;
460 /* hack to see if this is a new format message */
461 if (!bitset(pflag, CHHDR_DEF) && !headeronly &&
462 bitset(H_RCPT|H_FROM, h->h_flags) &&
463 (strchr(fvalue, ',') != NULL || strchr(fvalue, '(') != NULL ||
464 strchr(fvalue, '<') != NULL || strchr(fvalue, ';') != NULL))
466 e->e_flags &= ~EF_OLDSTYLE;
472 ** ADDHEADER -- add a header entry to the end of the queue.
474 ** This bypasses the special checking of chompheader.
477 ** field -- the name of the header field.
478 ** value -- the value of the field.
479 ** flags -- flags to add to h_flags.
486 ** adds the field on the list of headers for this envelope.
490 addheader(field, value, flags, e)
499 HDR **hdrlist = &e->e_header;
501 /* find info struct */
502 s = stab(field, ST_HEADER, ST_FIND);
504 /* find current place in list -- keep back pointer? */
505 for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link)
507 if (sm_strcasecmp(field, h->h_field) == 0)
511 /* allocate space for new header */
512 h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof *h);
514 h->h_value = sm_rpool_strdup_x(e->e_rpool, value);
518 h->h_flags |= s->s_header.hi_flags;
519 clrbitmap(h->h_mflags);
524 ** HVALUE -- return value of a header.
526 ** Only "real" fields (i.e., ones that have not been supplied
527 ** as a default) are used.
530 ** field -- the field name.
531 ** header -- the header list.
534 ** pointer to the value part.
535 ** NULL if not found.
542 hvalue(field, header)
548 for (h = header; h != NULL; h = h->h_link)
550 if (!bitset(H_DEFAULT, h->h_flags) &&
551 sm_strcasecmp(h->h_field, field) == 0)
557 ** ISHEADER -- predicate telling if argument is a header.
559 ** A line is a header if it has a single word followed by
560 ** optional white space followed by a colon.
562 ** Header fields beginning with two dashes, although technically
563 ** permitted by RFC822, are automatically rejected in order
564 ** to make MIME work out. Without this we could have a technically
565 ** legal header such as ``--"foo:bar"'' that would also be a legal
569 ** h -- string to check for possible headerness.
572 ** true if h is a header.
583 register char *s = h;
585 if (s[0] == '-' && s[1] == '-')
588 while (*s > ' ' && *s != ':' && *s != '\0')
594 /* following technically violates RFC822 */
595 while (isascii(*s) && isspace(*s))
601 ** EATHEADER -- run through the stored header and extract info.
604 ** e -- the envelope to process.
605 ** full -- if set, do full processing (e.g., compute
606 ** message priority). This should not be set
607 ** when reading a queue file because some info
608 ** needed to compute the priority is wrong.
609 ** log -- call logsender()?
615 ** Sets a bunch of global variables from information
616 ** in the collected header.
620 eatheader(e, full, log)
621 register ENVELOPE *e;
631 ** Set up macros for possible expansion in headers.
634 macdefine(&e->e_macro, A_PERM, 'f', e->e_sender);
635 macdefine(&e->e_macro, A_PERM, 'g', e->e_sender);
636 if (e->e_origrcpt != NULL && *e->e_origrcpt != '\0')
637 macdefine(&e->e_macro, A_PERM, 'u', e->e_origrcpt);
639 macdefine(&e->e_macro, A_PERM, 'u', NULL);
641 /* full name of from person */
642 p = hvalue("full-name", e->e_header);
645 if (!rfc822_string(p))
648 ** Quote a full name with special characters
649 ** as a comment so crackaddr() doesn't destroy
650 ** the name portion of the address.
653 p = addquotes(p, e->e_rpool);
655 macdefine(&e->e_macro, A_PERM, 'x', p);
659 sm_dprintf("----- collected header -----\n");
661 for (h = e->e_header; h != NULL; h = h->h_link)
664 sm_dprintf("%s: ", h->h_field);
665 if (h->h_value == NULL)
668 sm_dprintf("<NULL>\n");
672 /* do early binding */
673 if (bitset(H_DEFAULT, h->h_flags) &&
674 !bitset(H_BINDLATE, h->h_flags))
682 expand(h->h_value, buf, sizeof buf, e);
685 if (bitset(H_FROM, h->h_flags))
686 expand(crackaddr(buf, e),
688 h->h_value = sm_rpool_strdup_x(e->e_rpool, buf);
689 h->h_flags &= ~H_DEFAULT;
698 /* count the number of times it has been processed */
699 if (bitset(H_TRACE, h->h_flags))
702 /* send to this person if we so desire */
703 if (GrabTo && bitset(H_RCPT, h->h_flags) &&
704 !bitset(H_DEFAULT, h->h_flags) &&
705 (!bitset(EF_RESENT, e->e_flags) ||
706 bitset(H_RESENT, h->h_flags)))
709 int saveflags = e->e_flags;
712 (void) sendtolist(denlstring(h->h_value, true, false),
713 NULLADDR, &e->e_sendqueue, 0, e);
717 ** Change functionality so a fatal error on an
718 ** address doesn't affect the entire envelope.
721 /* delete fatal errors generated by this address */
722 if (!bitset(EF_FATALERRS, saveflags))
723 e->e_flags &= ~EF_FATALERRS;
727 /* save the message-id for logging */
728 p = "resent-message-id";
729 if (!bitset(EF_RESENT, e->e_flags))
731 if (sm_strcasecmp(h->h_field, p) == 0)
733 e->e_msgid = h->h_value;
734 while (isascii(*e->e_msgid) && isspace(*e->e_msgid))
739 sm_dprintf("----------------------------\n");
741 /* if we are just verifying (that is, sendmail -t -bv), drop out now */
742 if (OpMode == MD_VERIFY)
745 /* store hop count */
746 if (hopcnt > e->e_hopcount)
748 e->e_hopcount = hopcnt;
749 (void) sm_snprintf(buf, sizeof buf, "%d", e->e_hopcount);
750 macdefine(&e->e_macro, A_TEMP, 'c', buf);
753 /* message priority */
754 p = hvalue("precedence", e->e_header);
756 e->e_class = priencode(p);
758 e->e_timeoutclass = TOC_NONURGENT;
759 else if (e->e_class > 0)
760 e->e_timeoutclass = TOC_URGENT;
763 e->e_msgpriority = e->e_msgsize
764 - e->e_class * WkClassFact
765 + e->e_nrcpts * WkRecipFact;
768 /* message timeout priority */
769 p = hvalue("priority", e->e_header);
772 /* (this should be in the configuration file) */
773 if (sm_strcasecmp(p, "urgent") == 0)
774 e->e_timeoutclass = TOC_URGENT;
775 else if (sm_strcasecmp(p, "normal") == 0)
776 e->e_timeoutclass = TOC_NORMAL;
777 else if (sm_strcasecmp(p, "non-urgent") == 0)
778 e->e_timeoutclass = TOC_NONURGENT;
781 #if _FFR_QUEUERETURN_DSN
782 /* If no timeoutclass picked and it's a DSN, use that timeoutclass */
783 if (e->e_timeoutclass == TOC_NORMAL && bitset(EF_RESPONSE, e->e_flags))
784 e->e_timeoutclass = TOC_DSN;
785 #endif /* _FFR_QUEUERETURN_DSN */
787 /* date message originated */
788 p = hvalue("posted-date", e->e_header);
790 p = hvalue("date", e->e_header);
792 macdefine(&e->e_macro, A_PERM, 'a', p);
794 /* check to see if this is a MIME message */
795 if ((e->e_bodytype != NULL &&
796 sm_strcasecmp(e->e_bodytype, "8BITMIME") == 0) ||
797 hvalue("MIME-Version", e->e_header) != NULL)
799 e->e_flags |= EF_IS_MIME;
801 e->e_bodytype = "8BITMIME";
803 else if ((p = hvalue("Content-Type", e->e_header)) != NULL)
805 /* this may be an RFC 1049 message */
806 p = strpbrk(p, ";/");
807 if (p == NULL || *p == ';')
810 e->e_flags |= EF_DONT_MIME;
815 ** From person in antiquated ARPANET mode
816 ** required by UK Grey Book e-mail gateways (sigh)
819 if (OpMode == MD_ARPAFTP)
821 register struct hdrinfo *hi;
823 for (hi = HdrInfo; hi->hi_field != NULL; hi++)
825 if (bitset(H_FROM, hi->hi_flags) &&
826 (!bitset(H_RESENT, hi->hi_flags) ||
827 bitset(EF_RESENT, e->e_flags)) &&
828 (p = hvalue(hi->hi_field, e->e_header)) != NULL)
831 if (hi->hi_field != NULL)
834 sm_dprintf("eatheader: setsender(*%s == %s)\n",
836 setsender(p, e, NULL, '\0', true);
841 ** Log collection information.
844 if (log && bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4)
846 logsender(e, e->e_msgid);
847 e->e_flags &= ~EF_LOGSENDER;
851 ** LOGSENDER -- log sender information
854 ** e -- the envelope to log
855 ** msgid -- the message id
863 register ENVELOPE *e;
870 char hbuf[MAXNAME + 1];
871 char sbuf[MAXLINE + 1];
872 char mbuf[MAXNAME + 1];
874 /* don't allow newlines in the message-id */
875 /* XXX do we still need this? sm_syslog() replaces control chars */
879 if (l > sizeof mbuf - 1)
881 memmove(mbuf, msgid, l);
884 while ((p = strchr(p, '\n')) != NULL)
888 if (bitset(EF_RESPONSE, e->e_flags))
890 else if ((name = macvalue('_', e)) != NULL)
893 else if (RealHostName == NULL)
895 else if (RealHostName[0] == '[')
900 (void) sm_snprintf(hbuf, sizeof hbuf, "%.80s", RealHostName);
901 if (RealHostAddr.sa.sa_family != 0)
903 p = &hbuf[strlen(hbuf)];
904 (void) sm_snprintf(p, SPACELEFT(hbuf, p),
906 anynet_ntoa(&RealHostAddr));
910 /* some versions of syslog only take 5 printf args */
911 #if (SYSLOG_BUFSIZE) >= 256
913 (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
914 "from=%.200s, size=%ld, class=%d, nrcpts=%d",
915 e->e_from.q_paddr == NULL ? "<NONE>" : e->e_from.q_paddr,
916 e->e_msgsize, e->e_class, e->e_nrcpts);
920 (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
921 ", msgid=%.100s", mbuf);
924 if (e->e_bodytype != NULL)
926 (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
927 ", bodytype=%.20s", e->e_bodytype);
930 p = macvalue('r', e);
933 (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
937 p = macvalue(macid("{daemon_name}"), e);
940 (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
941 ", daemon=%.20s", p);
944 sm_syslog(LOG_INFO, e->e_id, "%.850s, relay=%s", sbuf, name);
946 #else /* (SYSLOG_BUFSIZE) >= 256 */
948 sm_syslog(LOG_INFO, e->e_id,
950 e->e_from.q_paddr == NULL ? "<NONE>"
951 : shortenstring(e->e_from.q_paddr,
953 sm_syslog(LOG_INFO, e->e_id,
954 "size=%ld, class=%ld, nrcpts=%d",
955 e->e_msgsize, e->e_class, e->e_nrcpts);
957 sm_syslog(LOG_INFO, e->e_id,
959 shortenstring(mbuf, 83));
962 if (e->e_bodytype != NULL)
964 (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
965 "bodytype=%.20s, ", e->e_bodytype);
968 p = macvalue('r', e);
971 (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
975 sm_syslog(LOG_INFO, e->e_id,
976 "%.400srelay=%s", sbuf, name);
977 #endif /* (SYSLOG_BUFSIZE) >= 256 */
980 ** PRIENCODE -- encode external priority names into internal values.
983 ** p -- priority in ascii.
986 ** priority as a numeric level.
998 for (i = 0; i < NumPriorities; i++)
1000 if (sm_strcasecmp(p, Priorities[i].pri_name) == 0)
1001 return Priorities[i].pri_val;
1004 /* unknown priority */
1008 ** CRACKADDR -- parse an address and turn it into a macro
1010 ** This doesn't actually parse the address -- it just extracts
1011 ** it and replaces it with "$g". The parse is totally ad hoc
1012 ** and isn't even guaranteed to leave something syntactically
1013 ** identical to what it started with. However, it does leave
1014 ** something semantically identical if possible, else at least
1015 ** syntactically correct.
1017 ** For example, it changes "Real Name <real@example.com> (Comment)"
1018 ** to "Real Name <$g> (Comment)".
1020 ** This algorithm has been cleaned up to handle a wider range
1021 ** of cases -- notably quoted and backslash escaped strings.
1022 ** This modification makes it substantially better at preserving
1023 ** the original syntax.
1026 ** addr -- the address to be cracked.
1027 ** e -- the current envelope.
1030 ** a pointer to the new version.
1036 ** The return value is saved in local storage and should
1037 ** be copied if it is to be reused.
1040 #define SM_HAVE_ROOM ((bp < buflim) && (buflim <= bufend))
1043 ** Append a character to bp if we have room.
1044 ** If not, punt and return $g.
1047 #define SM_APPEND_CHAR(c) \
1057 ERROR MAXNAME must be at least 10
1058 #endif /* MAXNAME < 10 */
1062 register char *addr;
1067 int cmtlev; /* comment level in input string */
1068 int realcmtlev; /* comment level in output string */
1069 int anglelev; /* angle level in input string */
1070 int copylev; /* 0 == in address, >0 copying */
1071 int bracklev; /* bracket level for IPv6 addr check */
1072 bool addangle; /* put closing angle in output */
1073 bool qmode; /* quoting in original string? */
1074 bool realqmode; /* quoting in output string? */
1075 bool putgmac = false; /* already wrote $g */
1076 bool quoteit = false; /* need to quote next character */
1077 bool gotangle = false; /* found first '<' */
1078 bool gotcolon = false; /* found a ':' */
1084 static char buf[MAXNAME + 1];
1087 sm_dprintf("crackaddr(%s)\n", addr);
1089 /* strip leading spaces */
1090 while (*addr != '\0' && isascii(*addr) && isspace(*addr))
1094 ** Start by assuming we have no angle brackets. This will be
1095 ** adjusted later if we find them.
1098 buflim = bufend = &buf[sizeof(buf) - 1];
1100 p = addrhead = addr;
1101 copylev = anglelev = cmtlev = realcmtlev = 0;
1103 qmode = realqmode = addangle = false;
1105 while ((c = *p++) != '\0')
1108 ** Try to keep legal syntax using spare buffer space
1109 ** (maintained by buflim).
1115 /* check for backslash escapes */
1118 /* arrange to quote the address */
1119 if (cmtlev <= 0 && !qmode)
1122 if ((c = *p++) == '\0')
1133 /* check for quoted strings */
1134 if (c == '"' && cmtlev <= 0)
1137 if (copylev > 0 && SM_HAVE_ROOM)
1143 realqmode = !realqmode;
1150 /* check for comments */
1155 /* allow space for closing paren */
1163 SM_APPEND_CHAR(' ');
1184 /* syntax error: unmatched ) */
1185 if (copylev > 0 && SM_HAVE_ROOM && bp > bufhead)
1189 /* count nesting on [ ... ] (for IPv6 domain literals) */
1195 /* check for group: list; syntax */
1196 if (c == ':' && anglelev <= 0 && bracklev <= 0 &&
1197 !gotcolon && !ColonOkInAddr)
1202 ** Check for DECnet phase IV ``::'' (host::user)
1203 ** or DECnet phase V ``:.'' syntaxes. The latter
1204 ** covers ``user@DEC:.tay.myhost'' and
1205 ** ``DEC:.tay.myhost::user'' syntaxes (bletch).
1208 if (*p == ':' || *p == '.')
1210 if (cmtlev <= 0 && !qmode)
1226 SM_APPEND_CHAR('"');
1228 /* back up over the ':' and any spaces */
1231 isascii(*--p) && isspace(*p))
1235 for (q = addrhead; q < p; )
1238 if (quoteit && c == '"')
1240 SM_APPEND_CHAR('\\');
1248 if (bp == &bufhead[1])
1251 SM_APPEND_CHAR('"');
1252 while ((c = *p++) != ':')
1257 /* any trailing white space is part of group: */
1258 while (isascii(*p) && isspace(*p))
1264 putgmac = quoteit = false;
1270 if (c == ';' && copylev <= 0 && !ColonOkInAddr)
1273 /* check for characters that may have to be quoted */
1274 if (strchr(MustQuoteChars, c) != NULL)
1277 ** If these occur as the phrase part of a <>
1278 ** construct, but are not inside of () or already
1279 ** quoted, they will have to be quoted. Note that
1280 ** now (but don't actually do the quoting).
1283 if (cmtlev <= 0 && !qmode)
1287 /* check for angle brackets */
1292 /* assume first of two angles is bogus */
1297 /* oops -- have to change our mind */
1309 SM_APPEND_CHAR('"');
1311 /* back up over the '<' and any spaces */
1314 isascii(*--p) && isspace(*p))
1318 for (q = addrhead; q < p; )
1321 if (quoteit && c == '"')
1323 SM_APPEND_CHAR('\\');
1334 SM_APPEND_CHAR('"');
1335 while ((c = *p++) != '<')
1340 putgmac = quoteit = false;
1356 else if (SM_HAVE_ROOM)
1358 /* syntax error: unmatched > */
1359 if (copylev > 0 && bp > bufhead)
1369 /* must be a real address character */
1371 if (copylev <= 0 && !putgmac)
1373 if (bp > buf && bp[-1] == ')')
1374 SM_APPEND_CHAR(' ');
1375 SM_APPEND_CHAR(MACROEXPAND);
1376 SM_APPEND_CHAR('g');
1381 /* repair any syntactic damage */
1382 if (realqmode && bp < bufend)
1384 while (realcmtlev-- > 0 && bp < bufend)
1386 if (addangle && bp < bufend)
1393 /* String too long, punt */
1395 buf[1] = MACROEXPAND;
1399 sm_syslog(LOG_ALERT, e->e_id,
1400 "Dropped invalid comments from header address");
1405 sm_dprintf("crackaddr=>`");
1412 ** PUTHEADER -- put the header part of a message from the in-core copy
1415 ** mci -- the connection information.
1416 ** hdr -- the header to put.
1417 ** e -- envelope to use.
1418 ** flags -- MIME conversion flags.
1428 putheader(mci, hdr, e, flags)
1431 register ENVELOPE *e;
1435 char buf[SM_MAX(MAXLINE,BUFSIZ)];
1439 sm_dprintf("--- putheader, mailer = %s ---\n",
1440 mci->mci_mailer->m_name);
1443 ** If we're in MIME mode, we're not really in the header of the
1444 ** message, just the header of one of the parts of the body of
1445 ** the message. Therefore MCIF_INHEADER should not be turned on.
1448 if (!bitset(MCIF_INMIME, mci->mci_flags))
1449 mci->mci_flags |= MCIF_INHEADER;
1451 for (h = hdr; h != NULL; h = h->h_link)
1453 register char *p = h->h_value;
1458 sm_dprintf(" %s: ", h->h_field);
1462 /* Skip empty headers */
1463 if (h->h_value == NULL)
1466 /* heuristic shortening of MIME fields to avoid MUA overflows */
1467 if (MaxMimeFieldLength > 0 &&
1468 wordinclass(h->h_field,
1469 macid("{checkMIMEFieldHeaders}")))
1473 len = fix_mime_header(h, e);
1476 sm_syslog(LOG_ALERT, e->e_id,
1477 "Truncated MIME %s header due to field size (length = %ld) (possible attack)",
1478 h->h_field, (unsigned long) len);
1480 sm_dprintf(" truncated MIME %s header due to field size (length = %ld) (possible attack)\n",
1482 (unsigned long) len);
1486 if (MaxMimeHeaderLength > 0 &&
1487 wordinclass(h->h_field,
1488 macid("{checkMIMETextHeaders}")))
1492 len = strlen(h->h_value);
1493 if (len > (size_t) MaxMimeHeaderLength)
1495 h->h_value[MaxMimeHeaderLength - 1] = '\0';
1496 sm_syslog(LOG_ALERT, e->e_id,
1497 "Truncated long MIME %s header (length = %ld) (possible attack)",
1498 h->h_field, (unsigned long) len);
1500 sm_dprintf(" truncated long MIME %s header (length = %ld) (possible attack)\n",
1502 (unsigned long) len);
1506 if (MaxMimeHeaderLength > 0 &&
1507 wordinclass(h->h_field,
1508 macid("{checkMIMEHeaders}")))
1512 len = strlen(h->h_value);
1513 if (shorten_rfc822_string(h->h_value,
1514 MaxMimeHeaderLength))
1516 if (len < MaxMimeHeaderLength)
1518 /* we only rebalanced a bogus header */
1519 sm_syslog(LOG_ALERT, e->e_id,
1520 "Fixed MIME %s header (possible attack)",
1523 sm_dprintf(" fixed MIME %s header (possible attack)\n",
1528 /* we actually shortened header */
1529 sm_syslog(LOG_ALERT, e->e_id,
1530 "Truncated long MIME %s header (length = %ld) (possible attack)",
1532 (unsigned long) len);
1534 sm_dprintf(" truncated long MIME %s header (length = %ld) (possible attack)\n",
1536 (unsigned long) len);
1542 ** Suppress Content-Transfer-Encoding: if we are MIMEing
1543 ** and we are potentially converting from 8 bit to 7 bit
1544 ** MIME. If converting, add a new CTE header in
1548 if (bitset(H_CTE, h->h_flags) &&
1549 bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME,
1551 !bitset(M87F_NO8TO7, flags))
1554 sm_dprintf(" (skipped (content-transfer-encoding))\n");
1558 if (bitset(MCIF_INMIME, mci->mci_flags))
1562 put_vanilla_header(h, p, mci);
1566 if (bitset(H_CHECK|H_ACHECK, h->h_flags) &&
1567 !bitintersect(h->h_mflags, mci->mci_mailer->m_flags) &&
1568 (h->h_macro == '\0' ||
1569 (q = macvalue(bitidx(h->h_macro), e)) == NULL ||
1573 sm_dprintf(" (skipped)\n");
1577 /* handle Resent-... headers specially */
1578 if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags))
1581 sm_dprintf(" (skipped (resent))\n");
1585 /* suppress return receipts if requested */
1586 if (bitset(H_RECEIPTTO, h->h_flags) &&
1587 (RrtImpliesDsn || bitset(EF_NORECEIPT, e->e_flags)))
1590 sm_dprintf(" (skipped (receipt))\n");
1594 /* macro expand value if generated internally */
1595 if (bitset(H_DEFAULT, h->h_flags) ||
1596 bitset(H_BINDLATE, h->h_flags))
1598 expand(p, buf, sizeof buf, e);
1603 sm_dprintf(" (skipped -- null value)\n");
1608 if (bitset(H_BCC, h->h_flags))
1610 /* Bcc: field -- either truncate or delete */
1611 if (bitset(EF_DELETE_BCC, e->e_flags))
1614 sm_dprintf(" (skipped -- bcc)\n");
1618 /* no other recipient headers: truncate value */
1619 (void) sm_strlcpyn(obuf, sizeof obuf, 2,
1629 if (bitset(H_FROM|H_RCPT, h->h_flags))
1632 bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags);
1634 if (bitset(H_FROM, h->h_flags))
1636 commaize(h, p, oldstyle, mci, e);
1640 put_vanilla_header(h, p, mci);
1645 ** If we are converting this to a MIME message, add the
1646 ** MIME headers (but not in MIME mode!).
1650 if (bitset(MM_MIME8BIT, MimeMode) &&
1651 bitset(EF_HAS8BIT, e->e_flags) &&
1652 !bitset(EF_DONT_MIME, e->e_flags) &&
1653 !bitnset(M_8BITS, mci->mci_mailer->m_flags) &&
1654 !bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME, mci->mci_flags) &&
1655 hvalue("MIME-Version", e->e_header) == NULL)
1657 putline("MIME-Version: 1.0", mci);
1658 if (hvalue("Content-Type", e->e_header) == NULL)
1660 (void) sm_snprintf(obuf, sizeof obuf,
1661 "Content-Type: text/plain; charset=%s",
1665 if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL)
1666 putline("Content-Transfer-Encoding: 8bit", mci);
1668 #endif /* MIME8TO7 */
1671 ** PUT_VANILLA_HEADER -- output a fairly ordinary header
1674 ** h -- the structure describing this header
1675 ** v -- the value of this header
1676 ** mci -- the connection info for output
1683 put_vanilla_header(h, v, mci)
1693 putflags = PXLF_HEADER;
1694 if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags))
1695 putflags |= PXLF_STRIP8BIT;
1696 (void) sm_snprintf(obuf, sizeof obuf, "%.200s: ", h->h_field);
1697 obp = obuf + strlen(obuf);
1698 while ((nlp = strchr(v, '\n')) != NULL)
1705 ** XXX This is broken for SPACELEFT()==0
1706 ** However, SPACELEFT() is always > 0 unless MAXLINE==1.
1709 if (SPACELEFT(obuf, obp) - 1 < (size_t) l)
1710 l = SPACELEFT(obuf, obp) - 1;
1712 (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v);
1713 putxline(obuf, strlen(obuf), mci, putflags);
1716 if (*v != ' ' && *v != '\t')
1720 /* XXX This is broken for SPACELEFT()==0 */
1721 (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
1722 (int) (SPACELEFT(obuf, obp) - 1), v);
1723 putxline(obuf, strlen(obuf), mci, putflags);
1726 ** COMMAIZE -- output a header field, making a comma-translated list.
1729 ** h -- the header field to output.
1730 ** p -- the value to put in it.
1731 ** oldstyle -- true if this is an old style header.
1732 ** mci -- the connection information.
1733 ** e -- the envelope containing the message.
1739 ** outputs "p" to file "fp".
1743 commaize(h, p, oldstyle, mci, e)
1748 register ENVELOPE *e;
1753 bool firstone = true;
1754 int putflags = PXLF_HEADER;
1756 char obuf[MAXLINE + 3];
1759 ** Output the address list translated by the
1760 ** mailer and with commas.
1764 sm_dprintf("commaize(%s: %s)\n", h->h_field, p);
1766 if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags))
1767 putflags |= PXLF_STRIP8BIT;
1770 (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.200s: ",
1773 /* opos = strlen(obp); */
1774 opos = strlen(h->h_field) + 2;
1778 omax = mci->mci_mailer->m_linelimit - 2;
1779 if (omax < 0 || omax > 78)
1783 ** Run through the list of values.
1788 register char *name;
1795 ** Find the end of the name. New style names
1796 ** end with a comma, old style names end with
1797 ** a space character. However, spaces do not
1798 ** necessarily delimit an old-style name -- at
1799 ** signs mean keep going.
1802 /* find end of name */
1803 while ((isascii(*p) && isspace(*p)) || *p == ',')
1810 char pvpbuf[PSBUFSIZE];
1812 res = prescan(p, oldstyle ? ' ' : ',', pvpbuf,
1813 sizeof pvpbuf, &oldp, NULL);
1815 #if _FFR_IGNORE_BOGUS_ADDR
1816 /* ignore addresses that can't be parsed */
1822 #endif /* _FFR_IGNORE_BOGUS_ADDR */
1824 /* look to see if we have an at sign */
1825 while (*p != '\0' && isascii(*p) && isspace(*p))
1834 while (*p != '\0' && isascii(*p) && isspace(*p))
1837 /* at the end of one complete name */
1839 /* strip off trailing white space */
1841 ((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0'))
1847 ** if prescan() failed go a bit backwards; this is a hack,
1848 ** there should be some better error recovery.
1851 if (res == NULL && p > name &&
1852 !((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0'))
1857 /* translate the name to be relative */
1858 flags = RF_HEADERADDR|RF_ADDDOMAIN;
1859 if (bitset(H_FROM, h->h_flags))
1860 flags |= RF_SENDERADDR;
1862 else if (e->e_from.q_mailer != NULL &&
1863 bitnset(M_UDBRECIPIENT, e->e_from.q_mailer->m_flags))
1867 q = udbsender(name, e->e_rpool);
1873 name = remotename(name, mci->mci_mailer, flags, &status, e);
1879 name = denlstring(name, false, true);
1882 ** record data progress so DNS timeouts
1883 ** don't cause DATA timeouts
1886 DataProgress = true;
1888 /* output the name with nice formatting */
1889 opos += strlen(name);
1892 if (opos > omax && !firstone)
1894 (void) sm_strlcpy(obp, ",\n", SPACELEFT(obuf, obp));
1895 putxline(obuf, strlen(obuf), mci, putflags);
1897 (void) sm_strlcpy(obp, " ", sizeof obuf);
1900 opos += strlen(name);
1904 (void) sm_strlcpy(obp, ", ", SPACELEFT(obuf, obp));
1908 while ((c = *name++) != '\0' && obp < &obuf[MAXLINE])
1913 if (obp < &obuf[sizeof obuf])
1916 obuf[sizeof obuf - 1] = '\0';
1917 putxline(obuf, strlen(obuf), mci, putflags);
1920 ** COPYHEADER -- copy header list
1922 ** This routine is the equivalent of newstr for header lists
1925 ** header -- list of header structures to copy.
1926 ** rpool -- resource pool, or NULL
1929 ** a copy of 'header'.
1936 copyheader(header, rpool)
1937 register HDR *header;
1940 register HDR *newhdr;
1942 register HDR **tail = &ret;
1944 while (header != NULL)
1946 newhdr = (HDR *) sm_rpool_malloc_x(rpool, sizeof *newhdr);
1947 STRUCTCOPY(*header, *newhdr);
1949 tail = &newhdr->h_link;
1950 header = header->h_link;
1957 ** FIX_MIME_HEADER -- possibly truncate/rebalance parameters in a MIME header
1959 ** Run through all of the parameters of a MIME header and
1960 ** possibly truncate and rebalance the parameter according
1961 ** to MaxMimeFieldLength.
1964 ** h -- the header to truncate/rebalance
1965 ** e -- the current envelope
1968 ** length of last offending field, 0 if all ok.
1971 ** string modified in place
1975 fix_mime_header(h, e)
1979 char *begin = h->h_value;
1984 if (begin == NULL || *begin == '\0')
1987 /* Split on each ';' */
1988 /* find_character() never returns NULL */
1989 while ((end = find_character(begin, ';')) != NULL)
1996 len = strlen(begin);
1998 /* Shorten individual parameter */
1999 if (shorten_rfc822_string(begin, MaxMimeFieldLength))
2001 if (len < MaxMimeFieldLength)
2003 /* we only rebalanced a bogus field */
2004 sm_syslog(LOG_ALERT, e->e_id,
2005 "Fixed MIME %s header field (possible attack)",
2008 sm_dprintf(" fixed MIME %s header field (possible attack)\n",
2013 /* we actually shortened the header */
2018 /* Collapse the possibly shortened string with rest */
2019 bp = begin + strlen(begin);
2027 /* copy character by character due to overlap */