headers.c revision 244833
1/*
2 * Copyright (c) 1998-2004, 2006, 2007 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
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.
7 *
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.
11 *
12 */
13
14#include <sendmail.h>
15#include <sm/sendmail.h>
16
17SM_RCSID("@(#)$Id: headers.c,v 8.318 2012/06/14 23:54:02 ca Exp $")
18
19static HDR	*allocheader __P((char *, char *, int, SM_RPOOL_T *, bool));
20static size_t	fix_mime_header __P((HDR *, ENVELOPE *));
21static int	priencode __P((char *));
22static bool	put_vanilla_header __P((HDR *, char *, MCI *));
23
24/*
25**  SETUPHEADERS -- initialize headers in symbol table
26**
27**	Parameters:
28**		none
29**
30**	Returns:
31**		none
32*/
33
34void
35setupheaders()
36{
37	struct hdrinfo *hi;
38	STAB *s;
39
40	for (hi = HdrInfo; hi->hi_field != NULL; hi++)
41	{
42		s = stab(hi->hi_field, ST_HEADER, ST_ENTER);
43		s->s_header.hi_flags = hi->hi_flags;
44		s->s_header.hi_ruleset = NULL;
45	}
46}
47
48/*
49**  DOCHOMPHEADER -- process and save a header line.
50**
51**	Called by chompheader.
52**
53**	Parameters:
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.
58**
59**	Returns:
60**		flags for this header.
61**
62**	Side Effects:
63**		The header is saved on the header list.
64**		Contents of 'line' are destroyed.
65*/
66
67static struct hdrinfo	NormalHeader =	{ NULL, 0, NULL };
68static unsigned long	dochompheader __P((char *, int, HDR **, ENVELOPE *));
69
70static unsigned long
71dochompheader(line, pflag, hdrp, e)
72	char *line;
73	int pflag;
74	HDR **hdrp;
75	ENVELOPE *e;
76{
77	unsigned char mid = '\0';
78	register char *p;
79	register HDR *h;
80	HDR **hp;
81	char *fname;
82	char *fvalue;
83	bool cond = false;
84	bool dropfrom;
85	bool headeronly;
86	STAB *s;
87	struct hdrinfo *hi;
88	bool nullheader = false;
89	BITMAP256 mopts;
90
91	headeronly = hdrp != NULL;
92	if (!headeronly)
93		hdrp = &e->e_header;
94
95	/* strip off options */
96	clrbitmap(mopts);
97	p = line;
98	if (!bitset(pflag, CHHDR_USER) && *p == '?')
99	{
100		int c;
101		register char *q;
102
103		q = strchr(++p, '?');
104		if (q == NULL)
105			goto hse;
106
107		*q = '\0';
108		c = *p & 0377;
109
110		/* possibly macro conditional */
111		if (c == MACROEXPAND)
112		{
113			/* catch ?$? */
114			if (*++p == '\0')
115			{
116				*q = '?';
117				goto hse;
118			}
119
120			mid = (unsigned char) *p++;
121
122			/* catch ?$abc? */
123			if (*p != '\0')
124			{
125				*q = '?';
126				goto hse;
127			}
128		}
129		else if (*p == '$')
130		{
131			/* catch ?$? */
132			if (*++p == '\0')
133			{
134				*q = '?';
135				goto hse;
136			}
137
138			mid = (unsigned char) macid(p);
139			if (bitset(0200, mid))
140			{
141				p += strlen(macname(mid)) + 2;
142				SM_ASSERT(p <= q);
143			}
144			else
145				p++;
146
147			/* catch ?$abc? */
148			if (*p != '\0')
149			{
150				*q = '?';
151				goto hse;
152			}
153		}
154		else
155		{
156			while (*p != '\0')
157			{
158				if (!isascii(*p))
159				{
160					*q = '?';
161					goto hse;
162				}
163
164				setbitn(bitidx(*p), mopts);
165				cond = true;
166				p++;
167			}
168		}
169		p = q + 1;
170	}
171
172	/* find canonical name */
173	fname = p;
174	while (isascii(*p) && isgraph(*p) && *p != ':')
175		p++;
176	fvalue = p;
177	while (isascii(*p) && isspace(*p))
178		p++;
179	if (*p++ != ':' || fname == fvalue)
180	{
181hse:
182		syserr("553 5.3.0 header syntax error, line \"%s\"", line);
183		return 0;
184	}
185	*fvalue = '\0';
186	fvalue = p;
187
188	/* if the field is null, go ahead and use the default */
189	while (isascii(*p) && isspace(*p))
190		p++;
191	if (*p == '\0')
192		nullheader = true;
193
194	/* security scan: long field names are end-of-header */
195	if (strlen(fname) > 100)
196		return H_EOH;
197
198	/* check to see if it represents a ruleset call */
199	if (bitset(pflag, CHHDR_DEF))
200	{
201		char hbuf[50];
202
203		(void) expand(fvalue, hbuf, sizeof(hbuf), e);
204		for (p = hbuf; isascii(*p) && isspace(*p); )
205			p++;
206		if ((*p++ & 0377) == CALLSUBR)
207		{
208			auto char *endp;
209			bool strc;
210
211			strc = *p == '+';	/* strip comments? */
212			if (strc)
213				++p;
214			if (strtorwset(p, &endp, ST_ENTER) > 0)
215			{
216				*endp = '\0';
217				s = stab(fname, ST_HEADER, ST_ENTER);
218				if (LogLevel > 9 &&
219				    s->s_header.hi_ruleset != NULL)
220					sm_syslog(LOG_WARNING, NOQID,
221						  "Warning: redefined ruleset for header=%s, old=%s, new=%s",
222						  fname,
223						  s->s_header.hi_ruleset, p);
224				s->s_header.hi_ruleset = newstr(p);
225				if (!strc)
226					s->s_header.hi_flags |= H_STRIPCOMM;
227			}
228			return 0;
229		}
230	}
231
232	/* see if it is a known type */
233	s = stab(fname, ST_HEADER, ST_FIND);
234	if (s != NULL)
235		hi = &s->s_header;
236	else
237		hi = &NormalHeader;
238
239	if (tTd(31, 9))
240	{
241		if (s == NULL)
242			sm_dprintf("no header flags match\n");
243		else
244			sm_dprintf("header match, flags=%lx, ruleset=%s\n",
245				   hi->hi_flags,
246				   hi->hi_ruleset == NULL ? "<NULL>"
247							  : hi->hi_ruleset);
248	}
249
250	/* see if this is a resent message */
251	if (!bitset(pflag, CHHDR_DEF) && !headeronly &&
252	    bitset(H_RESENT, hi->hi_flags))
253		e->e_flags |= EF_RESENT;
254
255	/* if this is an Errors-To: header keep track of it now */
256	if (UseErrorsTo && !bitset(pflag, CHHDR_DEF) && !headeronly &&
257	    bitset(H_ERRORSTO, hi->hi_flags))
258		(void) sendtolist(fvalue, NULLADDR, &e->e_errorqueue, 0, e);
259
260	/* if this means "end of header" quit now */
261	if (!headeronly && bitset(H_EOH, hi->hi_flags))
262		return hi->hi_flags;
263
264	/*
265	**  Horrible hack to work around problem with Lotus Notes SMTP
266	**  mail gateway, which generates From: headers with newlines in
267	**  them and the <address> on the second line.  Although this is
268	**  legal RFC 822, many MUAs don't handle this properly and thus
269	**  never find the actual address.
270	*/
271
272	if (bitset(H_FROM, hi->hi_flags) && SingleLineFromHeader)
273	{
274		while ((p = strchr(fvalue, '\n')) != NULL)
275			*p = ' ';
276	}
277
278	/*
279	**  If there is a check ruleset, verify it against the header.
280	*/
281
282	if (bitset(pflag, CHHDR_CHECK))
283	{
284		int rscheckflags;
285		char *rs;
286
287		rscheckflags = RSF_COUNT;
288		if (!bitset(hi->hi_flags, H_FROM|H_RCPT))
289			rscheckflags |= RSF_UNSTRUCTURED;
290
291		/* no ruleset? look for default */
292		rs = hi->hi_ruleset;
293		if (rs == NULL)
294		{
295			s = stab("*", ST_HEADER, ST_FIND);
296			if (s != NULL)
297			{
298				rs = (&s->s_header)->hi_ruleset;
299				if (bitset((&s->s_header)->hi_flags,
300					   H_STRIPCOMM))
301					rscheckflags |= RSF_RMCOMM;
302			}
303		}
304		else if (bitset(hi->hi_flags, H_STRIPCOMM))
305			rscheckflags |= RSF_RMCOMM;
306		if (rs != NULL)
307		{
308			int l, k;
309			char qval[MAXNAME];
310
311			l = 0;
312			qval[l++] = '"';
313
314			/* - 3 to avoid problems with " at the end */
315			/* should be sizeof(qval), not MAXNAME */
316			for (k = 0; fvalue[k] != '\0' && l < MAXNAME - 3; k++)
317			{
318				switch (fvalue[k])
319				{
320				  /* XXX other control chars? */
321				  case '\011': /* ht */
322				  case '\012': /* nl */
323				  case '\013': /* vt */
324				  case '\014': /* np */
325				  case '\015': /* cr */
326					qval[l++] = ' ';
327					break;
328				  case '"':
329					qval[l++] = '\\';
330					/* FALLTHROUGH */
331				  default:
332					qval[l++] = fvalue[k];
333					break;
334				}
335			}
336			qval[l++] = '"';
337			qval[l] = '\0';
338			k += strlen(fvalue + k);
339			if (k >= MAXNAME)
340			{
341				if (LogLevel > 9)
342					sm_syslog(LOG_WARNING, e->e_id,
343						  "Warning: truncated header '%s' before check with '%s' len=%d max=%d",
344						  fname, rs, k, MAXNAME - 1);
345			}
346			macdefine(&e->e_macro, A_TEMP,
347				macid("{currHeader}"), qval);
348			macdefine(&e->e_macro, A_TEMP,
349				macid("{hdr_name}"), fname);
350
351			(void) sm_snprintf(qval, sizeof(qval), "%d", k);
352			macdefine(&e->e_macro, A_TEMP, macid("{hdrlen}"), qval);
353			if (bitset(H_FROM, hi->hi_flags))
354				macdefine(&e->e_macro, A_PERM,
355					macid("{addr_type}"), "h s");
356			else if (bitset(H_RCPT, hi->hi_flags))
357				macdefine(&e->e_macro, A_PERM,
358					macid("{addr_type}"), "h r");
359			else
360				macdefine(&e->e_macro, A_PERM,
361					macid("{addr_type}"), "h");
362			(void) rscheck(rs, fvalue, NULL, e, rscheckflags, 3,
363				       NULL, e->e_id, NULL);
364		}
365	}
366
367	/*
368	**  Drop explicit From: if same as what we would generate.
369	**  This is to make MH (which doesn't always give a full name)
370	**  insert the full name information in all circumstances.
371	*/
372
373	dropfrom = false;
374	p = "resent-from";
375	if (!bitset(EF_RESENT, e->e_flags))
376		p += 7;
377	if (!bitset(pflag, CHHDR_DEF) && !headeronly &&
378	    !bitset(EF_QUEUERUN, e->e_flags) && sm_strcasecmp(fname, p) == 0)
379	{
380		if (tTd(31, 2))
381		{
382			sm_dprintf("comparing header from (%s) against default (%s or %s)\n",
383				fvalue, e->e_from.q_paddr, e->e_from.q_user);
384		}
385		if (e->e_from.q_paddr != NULL &&
386		    e->e_from.q_mailer != NULL &&
387		    bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags) &&
388		    (strcmp(fvalue, e->e_from.q_paddr) == 0 ||
389		     strcmp(fvalue, e->e_from.q_user) == 0))
390			dropfrom = true;
391	}
392
393	/* delete default value for this header */
394	for (hp = hdrp; (h = *hp) != NULL; hp = &h->h_link)
395	{
396		if (sm_strcasecmp(fname, h->h_field) == 0 &&
397		    !bitset(H_USER, h->h_flags) &&
398		    !bitset(H_FORCE, h->h_flags))
399		{
400			if (nullheader)
401			{
402				/* user-supplied value was null */
403				return 0;
404			}
405			if (dropfrom)
406			{
407				/* make this look like the user entered it */
408				h->h_flags |= H_USER;
409				return hi->hi_flags;
410			}
411			h->h_value = NULL;
412			if (!cond)
413			{
414				/* copy conditions from default case */
415				memmove((char *) mopts, (char *) h->h_mflags,
416					sizeof(mopts));
417			}
418			h->h_macro = mid;
419		}
420	}
421
422	/* create a new node */
423	h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof(*h));
424	h->h_field = sm_rpool_strdup_x(e->e_rpool, fname);
425	h->h_value = sm_rpool_strdup_x(e->e_rpool, fvalue);
426	h->h_link = NULL;
427	memmove((char *) h->h_mflags, (char *) mopts, sizeof(mopts));
428	h->h_macro = mid;
429	*hp = h;
430	h->h_flags = hi->hi_flags;
431	if (bitset(pflag, CHHDR_USER) || bitset(pflag, CHHDR_QUEUE))
432		h->h_flags |= H_USER;
433
434	/* strip EOH flag if parsing MIME headers */
435	if (headeronly)
436		h->h_flags &= ~H_EOH;
437	if (bitset(pflag, CHHDR_DEF))
438		h->h_flags |= H_DEFAULT;
439	if (cond || mid != '\0')
440		h->h_flags |= H_CHECK;
441
442	/* hack to see if this is a new format message */
443	if (!bitset(pflag, CHHDR_DEF) && !headeronly &&
444	    bitset(H_RCPT|H_FROM, h->h_flags) &&
445	    (strchr(fvalue, ',') != NULL || strchr(fvalue, '(') != NULL ||
446	     strchr(fvalue, '<') != NULL || strchr(fvalue, ';') != NULL))
447	{
448		e->e_flags &= ~EF_OLDSTYLE;
449	}
450
451	return h->h_flags;
452}
453
454/*
455**  CHOMPHEADER -- process and save a header line.
456**
457**	Called by collect, readcf, and readqf to deal with header lines.
458**	This is just a wrapper for dochompheader().
459**
460**	Parameters:
461**		line -- header as a text line.
462**		pflag -- flags for chompheader() (from sendmail.h)
463**		hdrp -- a pointer to the place to save the header.
464**		e -- the envelope including this header.
465**
466**	Returns:
467**		flags for this header.
468**
469**	Side Effects:
470**		The header is saved on the header list.
471**		Contents of 'line' are destroyed.
472*/
473
474
475unsigned long
476chompheader(line, pflag, hdrp, e)
477	char *line;
478	int pflag;
479	HDR **hdrp;
480	register ENVELOPE *e;
481{
482	unsigned long rval;
483
484	if (tTd(31, 6))
485	{
486		sm_dprintf("chompheader: ");
487		xputs(sm_debug_file(), line);
488		sm_dprintf("\n");
489	}
490
491	/* quote this if user (not config file) input */
492	if (bitset(pflag, CHHDR_USER))
493	{
494		char xbuf[MAXLINE];
495		char *xbp = NULL;
496		int xbufs;
497
498		xbufs = sizeof(xbuf);
499		xbp = quote_internal_chars(line, xbuf, &xbufs);
500		if (tTd(31, 7))
501		{
502			sm_dprintf("chompheader: quoted: ");
503			xputs(sm_debug_file(), xbp);
504			sm_dprintf("\n");
505		}
506		rval = dochompheader(xbp, pflag, hdrp, e);
507		if (xbp != xbuf)
508			sm_free(xbp);
509	}
510	else
511		rval = dochompheader(line, pflag, hdrp, e);
512
513	return rval;
514}
515
516/*
517**  ALLOCHEADER -- allocate a header entry
518**
519**	Parameters:
520**		field -- the name of the header field (will not be copied).
521**		value -- the value of the field (will be copied).
522**		flags -- flags to add to h_flags.
523**		rp -- resource pool for allocations
524**		space -- add leading space?
525**
526**	Returns:
527**		Pointer to a newly allocated and populated HDR.
528**
529**	Notes:
530**		o field and value must be in internal format, i.e.,
531**		metacharacters must be "quoted", see quote_internal_chars().
532**		o maybe add more flags to decide:
533**		  - what to copy (field/value)
534**		  - whether to convert value to an internal format
535*/
536
537static HDR *
538allocheader(field, value, flags, rp, space)
539	char *field;
540	char *value;
541	int flags;
542	SM_RPOOL_T *rp;
543	bool space;
544{
545	HDR *h;
546	STAB *s;
547
548	/* find info struct */
549	s = stab(field, ST_HEADER, ST_FIND);
550
551	/* allocate space for new header */
552	h = (HDR *) sm_rpool_malloc_x(rp, sizeof(*h));
553	h->h_field = field;
554	if (space)
555	{
556		size_t l;
557		char *n;
558
559		l = strlen(value);
560		SM_ASSERT(l + 2 > l);
561		n = sm_rpool_malloc_x(rp, l + 2);
562		n[0] = ' ';
563		n[1] = '\0';
564		sm_strlcpy(n + 1, value, l + 1);
565		h->h_value = n;
566	}
567	else
568		h->h_value = sm_rpool_strdup_x(rp, value);
569	h->h_flags = flags;
570	if (s != NULL)
571		h->h_flags |= s->s_header.hi_flags;
572	clrbitmap(h->h_mflags);
573	h->h_macro = '\0';
574
575	return h;
576}
577
578/*
579**  ADDHEADER -- add a header entry to the end of the queue.
580**
581**	This bypasses the special checking of chompheader.
582**
583**	Parameters:
584**		field -- the name of the header field (will not be copied).
585**		value -- the value of the field (will be copied).
586**		flags -- flags to add to h_flags.
587**		e -- envelope.
588**		space -- add leading space?
589**
590**	Returns:
591**		none.
592**
593**	Side Effects:
594**		adds the field on the list of headers for this envelope.
595**
596**	Notes: field and value must be in internal format, i.e.,
597**		metacharacters must be "quoted", see quote_internal_chars().
598*/
599
600void
601addheader(field, value, flags, e, space)
602	char *field;
603	char *value;
604	int flags;
605	ENVELOPE *e;
606	bool space;
607{
608	register HDR *h;
609	HDR **hp;
610	HDR **hdrlist = &e->e_header;
611
612	/* find current place in list -- keep back pointer? */
613	for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link)
614	{
615		if (sm_strcasecmp(field, h->h_field) == 0)
616			break;
617	}
618
619	/* allocate space for new header */
620	h = allocheader(field, value, flags, e->e_rpool, space);
621	h->h_link = *hp;
622	*hp = h;
623}
624
625/*
626**  INSHEADER -- insert a header entry at the specified index
627**	This bypasses the special checking of chompheader.
628**
629**	Parameters:
630**		idx -- index into the header list at which to insert
631**		field -- the name of the header field (will be copied).
632**		value -- the value of the field (will be copied).
633**		flags -- flags to add to h_flags.
634**		e -- envelope.
635**		space -- add leading space?
636**
637**	Returns:
638**		none.
639**
640**	Side Effects:
641**		inserts the field on the list of headers for this envelope.
642**
643**	Notes:
644**		- field and value must be in internal format, i.e.,
645**		metacharacters must be "quoted", see quote_internal_chars().
646**		- the header list contains headers that might not be
647**		sent "out" (see putheader(): "skip"), hence there is no
648**		reliable way to insert a header at an exact position
649**		(except at the front or end).
650*/
651
652void
653insheader(idx, field, value, flags, e, space)
654	int idx;
655	char *field;
656	char *value;
657	int flags;
658	ENVELOPE *e;
659	bool space;
660{
661	HDR *h, *srch, *last = NULL;
662
663	/* allocate space for new header */
664	h = allocheader(field, value, flags, e->e_rpool, space);
665
666	/* find insertion position */
667	for (srch = e->e_header; srch != NULL && idx > 0;
668	     srch = srch->h_link, idx--)
669		last = srch;
670
671	if (e->e_header == NULL)
672	{
673		e->e_header = h;
674		h->h_link = NULL;
675	}
676	else if (srch == NULL)
677	{
678		SM_ASSERT(last != NULL);
679		last->h_link = h;
680		h->h_link = NULL;
681	}
682	else
683	{
684		h->h_link = srch->h_link;
685		srch->h_link = h;
686	}
687}
688
689/*
690**  HVALUE -- return value of a header.
691**
692**	Only "real" fields (i.e., ones that have not been supplied
693**	as a default) are used.
694**
695**	Parameters:
696**		field -- the field name.
697**		header -- the header list.
698**
699**	Returns:
700**		pointer to the value part (internal format).
701**		NULL if not found.
702**
703**	Side Effects:
704**		none.
705*/
706
707char *
708hvalue(field, header)
709	char *field;
710	HDR *header;
711{
712	register HDR *h;
713
714	for (h = header; h != NULL; h = h->h_link)
715	{
716		if (!bitset(H_DEFAULT, h->h_flags) &&
717		    sm_strcasecmp(h->h_field, field) == 0)
718		{
719			char *s;
720
721			s = h->h_value;
722			if (s == NULL)
723				return NULL;
724			while (isascii(*s) && isspace(*s))
725				s++;
726			return s;
727		}
728	}
729	return NULL;
730}
731
732/*
733**  ISHEADER -- predicate telling if argument is a header.
734**
735**	A line is a header if it has a single word followed by
736**	optional white space followed by a colon.
737**
738**	Header fields beginning with two dashes, although technically
739**	permitted by RFC822, are automatically rejected in order
740**	to make MIME work out.  Without this we could have a technically
741**	legal header such as ``--"foo:bar"'' that would also be a legal
742**	MIME separator.
743**
744**	Parameters:
745**		h -- string to check for possible headerness.
746**
747**	Returns:
748**		true if h is a header.
749**		false otherwise.
750**
751**	Side Effects:
752**		none.
753*/
754
755bool
756isheader(h)
757	char *h;
758{
759	char *s;
760
761	s = h;
762	if (s[0] == '-' && s[1] == '-')
763		return false;
764
765	while (*s > ' ' && *s != ':' && *s != '\0')
766		s++;
767
768	if (h == s)
769		return false;
770
771	/* following technically violates RFC822 */
772	while (isascii(*s) && isspace(*s))
773		s++;
774
775	return (*s == ':');
776}
777
778/*
779**  EATHEADER -- run through the stored header and extract info.
780**
781**	Parameters:
782**		e -- the envelope to process.
783**		full -- if set, do full processing (e.g., compute
784**			message priority).  This should not be set
785**			when reading a queue file because some info
786**			needed to compute the priority is wrong.
787**		log -- call logsender()?
788**
789**	Returns:
790**		none.
791**
792**	Side Effects:
793**		Sets a bunch of global variables from information
794**			in the collected header.
795*/
796
797void
798eatheader(e, full, log)
799	register ENVELOPE *e;
800	bool full;
801	bool log;
802{
803	register HDR *h;
804	register char *p;
805	int hopcnt = 0;
806	char buf[MAXLINE];
807
808	/*
809	**  Set up macros for possible expansion in headers.
810	*/
811
812	macdefine(&e->e_macro, A_PERM, 'f', e->e_sender);
813	macdefine(&e->e_macro, A_PERM, 'g', e->e_sender);
814	if (e->e_origrcpt != NULL && *e->e_origrcpt != '\0')
815		macdefine(&e->e_macro, A_PERM, 'u', e->e_origrcpt);
816	else
817		macdefine(&e->e_macro, A_PERM, 'u', NULL);
818
819	/* full name of from person */
820	p = hvalue("full-name", e->e_header);
821	if (p != NULL)
822	{
823		if (!rfc822_string(p))
824		{
825			/*
826			**  Quote a full name with special characters
827			**  as a comment so crackaddr() doesn't destroy
828			**  the name portion of the address.
829			*/
830
831			p = addquotes(p, e->e_rpool);
832		}
833		macdefine(&e->e_macro, A_PERM, 'x', p);
834	}
835
836	if (tTd(32, 1))
837		sm_dprintf("----- collected header -----\n");
838	e->e_msgid = NULL;
839	for (h = e->e_header; h != NULL; h = h->h_link)
840	{
841		if (tTd(32, 1))
842			sm_dprintf("%s:", h->h_field);
843		if (h->h_value == NULL)
844		{
845			if (tTd(32, 1))
846				sm_dprintf("<NULL>\n");
847			continue;
848		}
849
850		/* do early binding */
851		if (bitset(H_DEFAULT, h->h_flags) &&
852		    !bitset(H_BINDLATE, h->h_flags))
853		{
854			if (tTd(32, 1))
855			{
856				sm_dprintf("(");
857				xputs(sm_debug_file(), h->h_value);
858				sm_dprintf(") ");
859			}
860			expand(h->h_value, buf, sizeof(buf), e);
861			if (buf[0] != '\0' &&
862			    (buf[0] != ' ' || buf[1] != '\0'))
863			{
864				if (bitset(H_FROM, h->h_flags))
865					expand(crackaddr(buf, e),
866					       buf, sizeof(buf), e);
867				h->h_value = sm_rpool_strdup_x(e->e_rpool, buf);
868				h->h_flags &= ~H_DEFAULT;
869			}
870		}
871		if (tTd(32, 1))
872		{
873			xputs(sm_debug_file(), h->h_value);
874			sm_dprintf("\n");
875		}
876
877		/* count the number of times it has been processed */
878		if (bitset(H_TRACE, h->h_flags))
879			hopcnt++;
880
881		/* send to this person if we so desire */
882		if (GrabTo && bitset(H_RCPT, h->h_flags) &&
883		    !bitset(H_DEFAULT, h->h_flags) &&
884		    (!bitset(EF_RESENT, e->e_flags) ||
885		     bitset(H_RESENT, h->h_flags)))
886		{
887#if 0
888			int saveflags = e->e_flags;
889#endif /* 0 */
890
891			(void) sendtolist(denlstring(h->h_value, true, false),
892					  NULLADDR, &e->e_sendqueue, 0, e);
893
894#if 0
895			/*
896			**  Change functionality so a fatal error on an
897			**  address doesn't affect the entire envelope.
898			*/
899
900			/* delete fatal errors generated by this address */
901			if (!bitset(EF_FATALERRS, saveflags))
902				e->e_flags &= ~EF_FATALERRS;
903#endif /* 0 */
904		}
905
906		/* save the message-id for logging */
907		p = "resent-message-id";
908		if (!bitset(EF_RESENT, e->e_flags))
909			p += 7;
910		if (sm_strcasecmp(h->h_field, p) == 0)
911		{
912			e->e_msgid = h->h_value;
913			while (isascii(*e->e_msgid) && isspace(*e->e_msgid))
914				e->e_msgid++;
915			macdefine(&e->e_macro, A_PERM, macid("{msg_id}"),
916				  e->e_msgid);
917		}
918	}
919	if (tTd(32, 1))
920		sm_dprintf("----------------------------\n");
921
922	/* if we are just verifying (that is, sendmail -t -bv), drop out now */
923	if (OpMode == MD_VERIFY)
924		return;
925
926	/* store hop count */
927	if (hopcnt > e->e_hopcount)
928	{
929		e->e_hopcount = hopcnt;
930		(void) sm_snprintf(buf, sizeof(buf), "%d", e->e_hopcount);
931		macdefine(&e->e_macro, A_TEMP, 'c', buf);
932	}
933
934	/* message priority */
935	p = hvalue("precedence", e->e_header);
936	if (p != NULL)
937		e->e_class = priencode(p);
938	if (e->e_class < 0)
939		e->e_timeoutclass = TOC_NONURGENT;
940	else if (e->e_class > 0)
941		e->e_timeoutclass = TOC_URGENT;
942	if (full)
943	{
944		e->e_msgpriority = e->e_msgsize
945				 - e->e_class * WkClassFact
946				 + e->e_nrcpts * WkRecipFact;
947	}
948
949	/* check for DSN to properly set e_timeoutclass */
950	p = hvalue("content-type", e->e_header);
951	if (p != NULL)
952	{
953		bool oldsupr;
954		char **pvp;
955		char pvpbuf[MAXLINE];
956		extern unsigned char MimeTokenTab[256];
957
958		/* tokenize header */
959		oldsupr = SuprErrs;
960		SuprErrs = true;
961		pvp = prescan(p, '\0', pvpbuf, sizeof(pvpbuf), NULL,
962			      MimeTokenTab, false);
963		SuprErrs = oldsupr;
964
965		/* Check if multipart/report */
966		if (pvp != NULL && pvp[0] != NULL &&
967		    pvp[1] != NULL && pvp[2] != NULL &&
968		    sm_strcasecmp(*pvp++, "multipart") == 0 &&
969		    strcmp(*pvp++, "/") == 0 &&
970		    sm_strcasecmp(*pvp++, "report") == 0)
971		{
972			/* Look for report-type=delivery-status */
973			while (*pvp != NULL)
974			{
975				/* skip to semicolon separator */
976				while (*pvp != NULL && strcmp(*pvp, ";") != 0)
977					pvp++;
978
979				/* skip semicolon */
980				if (*pvp++ == NULL || *pvp == NULL)
981					break;
982
983				/* look for report-type */
984				if (sm_strcasecmp(*pvp++, "report-type") != 0)
985					continue;
986
987				/* skip equal */
988				if (*pvp == NULL || strcmp(*pvp, "=") != 0)
989					continue;
990
991				/* check value */
992				if (*++pvp != NULL &&
993				    sm_strcasecmp(*pvp,
994						  "delivery-status") == 0)
995					e->e_timeoutclass = TOC_DSN;
996
997				/* found report-type, no need to continue */
998				break;
999			}
1000		}
1001	}
1002
1003	/* message timeout priority */
1004	p = hvalue("priority", e->e_header);
1005	if (p != NULL)
1006	{
1007		/* (this should be in the configuration file) */
1008		if (sm_strcasecmp(p, "urgent") == 0)
1009			e->e_timeoutclass = TOC_URGENT;
1010		else if (sm_strcasecmp(p, "normal") == 0)
1011			e->e_timeoutclass = TOC_NORMAL;
1012		else if (sm_strcasecmp(p, "non-urgent") == 0)
1013			e->e_timeoutclass = TOC_NONURGENT;
1014		else if (bitset(EF_RESPONSE, e->e_flags))
1015			e->e_timeoutclass = TOC_DSN;
1016	}
1017	else if (bitset(EF_RESPONSE, e->e_flags))
1018		e->e_timeoutclass = TOC_DSN;
1019
1020	/* date message originated */
1021	p = hvalue("posted-date", e->e_header);
1022	if (p == NULL)
1023		p = hvalue("date", e->e_header);
1024	if (p != NULL)
1025		macdefine(&e->e_macro, A_PERM, 'a', p);
1026
1027	/* check to see if this is a MIME message */
1028	if ((e->e_bodytype != NULL &&
1029	     sm_strcasecmp(e->e_bodytype, "8BITMIME") == 0) ||
1030	    hvalue("MIME-Version", e->e_header) != NULL)
1031	{
1032		e->e_flags |= EF_IS_MIME;
1033		if (HasEightBits)
1034			e->e_bodytype = "8BITMIME";
1035	}
1036	else if ((p = hvalue("Content-Type", e->e_header)) != NULL)
1037	{
1038		/* this may be an RFC 1049 message */
1039		p = strpbrk(p, ";/");
1040		if (p == NULL || *p == ';')
1041		{
1042			/* yep, it is */
1043			e->e_flags |= EF_DONT_MIME;
1044		}
1045	}
1046
1047	/*
1048	**  From person in antiquated ARPANET mode
1049	**	required by UK Grey Book e-mail gateways (sigh)
1050	*/
1051
1052	if (OpMode == MD_ARPAFTP)
1053	{
1054		register struct hdrinfo *hi;
1055
1056		for (hi = HdrInfo; hi->hi_field != NULL; hi++)
1057		{
1058			if (bitset(H_FROM, hi->hi_flags) &&
1059			    (!bitset(H_RESENT, hi->hi_flags) ||
1060			     bitset(EF_RESENT, e->e_flags)) &&
1061			    (p = hvalue(hi->hi_field, e->e_header)) != NULL)
1062				break;
1063		}
1064		if (hi->hi_field != NULL)
1065		{
1066			if (tTd(32, 2))
1067				sm_dprintf("eatheader: setsender(*%s == %s)\n",
1068					hi->hi_field, p);
1069			setsender(p, e, NULL, '\0', true);
1070		}
1071	}
1072
1073	/*
1074	**  Log collection information.
1075	*/
1076
1077	if (tTd(92, 2))
1078		sm_dprintf("eatheader: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d, log=%d\n",
1079			e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel,
1080			log);
1081	if (log && bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4)
1082	{
1083		logsender(e, e->e_msgid);
1084		e->e_flags &= ~EF_LOGSENDER;
1085	}
1086}
1087
1088/*
1089**  LOGSENDER -- log sender information
1090**
1091**	Parameters:
1092**		e -- the envelope to log
1093**		msgid -- the message id
1094**
1095**	Returns:
1096**		none
1097*/
1098
1099void
1100logsender(e, msgid)
1101	register ENVELOPE *e;
1102	char *msgid;
1103{
1104	char *name;
1105	register char *sbp;
1106	register char *p;
1107	char hbuf[MAXNAME + 1];
1108	char sbuf[MAXLINE + 1];
1109	char mbuf[MAXNAME + 1];
1110
1111	/* don't allow newlines in the message-id */
1112	/* XXX do we still need this? sm_syslog() replaces control chars */
1113	if (msgid != NULL)
1114	{
1115		size_t l;
1116
1117		l = strlen(msgid);
1118		if (l > sizeof(mbuf) - 1)
1119			l = sizeof(mbuf) - 1;
1120		memmove(mbuf, msgid, l);
1121		mbuf[l] = '\0';
1122		p = mbuf;
1123		while ((p = strchr(p, '\n')) != NULL)
1124			*p++ = ' ';
1125	}
1126
1127	if (bitset(EF_RESPONSE, e->e_flags))
1128		name = "[RESPONSE]";
1129	else if ((name = macvalue('_', e)) != NULL)
1130		/* EMPTY */
1131		;
1132	else if (RealHostName == NULL)
1133		name = "localhost";
1134	else if (RealHostName[0] == '[')
1135		name = RealHostName;
1136	else
1137	{
1138		name = hbuf;
1139		(void) sm_snprintf(hbuf, sizeof(hbuf), "%.80s", RealHostName);
1140		if (RealHostAddr.sa.sa_family != 0)
1141		{
1142			p = &hbuf[strlen(hbuf)];
1143			(void) sm_snprintf(p, SPACELEFT(hbuf, p),
1144					   " (%.100s)",
1145					   anynet_ntoa(&RealHostAddr));
1146		}
1147	}
1148
1149	/* some versions of syslog only take 5 printf args */
1150#if (SYSLOG_BUFSIZE) >= 256
1151	sbp = sbuf;
1152	(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
1153		"from=%.200s, size=%ld, class=%d, nrcpts=%d",
1154		e->e_from.q_paddr == NULL ? "<NONE>" : e->e_from.q_paddr,
1155		PRT_NONNEGL(e->e_msgsize), e->e_class, e->e_nrcpts);
1156	sbp += strlen(sbp);
1157	if (msgid != NULL)
1158	{
1159		(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
1160				", msgid=%.100s", mbuf);
1161		sbp += strlen(sbp);
1162	}
1163	if (e->e_bodytype != NULL)
1164	{
1165		(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
1166				", bodytype=%.20s", e->e_bodytype);
1167		sbp += strlen(sbp);
1168	}
1169	p = macvalue('r', e);
1170	if (p != NULL)
1171	{
1172		(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
1173				", proto=%.20s", p);
1174		sbp += strlen(sbp);
1175	}
1176	p = macvalue(macid("{daemon_name}"), e);
1177	if (p != NULL)
1178	{
1179		(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
1180				", daemon=%.20s", p);
1181		sbp += strlen(sbp);
1182	}
1183	sm_syslog(LOG_INFO, e->e_id, "%.850s, relay=%s", sbuf, name);
1184
1185#else /* (SYSLOG_BUFSIZE) >= 256 */
1186
1187	sm_syslog(LOG_INFO, e->e_id,
1188		  "from=%s",
1189		  e->e_from.q_paddr == NULL ? "<NONE>"
1190					    : shortenstring(e->e_from.q_paddr,
1191							    83));
1192	sm_syslog(LOG_INFO, e->e_id,
1193		  "size=%ld, class=%ld, nrcpts=%d",
1194		  PRT_NONNEGL(e->e_msgsize), e->e_class, e->e_nrcpts);
1195	if (msgid != NULL)
1196		sm_syslog(LOG_INFO, e->e_id,
1197			  "msgid=%s",
1198			  shortenstring(mbuf, 83));
1199	sbp = sbuf;
1200	*sbp = '\0';
1201	if (e->e_bodytype != NULL)
1202	{
1203		(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
1204				"bodytype=%.20s, ", e->e_bodytype);
1205		sbp += strlen(sbp);
1206	}
1207	p = macvalue('r', e);
1208	if (p != NULL)
1209	{
1210		(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
1211				"proto=%.20s, ", p);
1212		sbp += strlen(sbp);
1213	}
1214	sm_syslog(LOG_INFO, e->e_id,
1215		  "%.400srelay=%s", sbuf, name);
1216#endif /* (SYSLOG_BUFSIZE) >= 256 */
1217}
1218
1219/*
1220**  PRIENCODE -- encode external priority names into internal values.
1221**
1222**	Parameters:
1223**		p -- priority in ascii.
1224**
1225**	Returns:
1226**		priority as a numeric level.
1227**
1228**	Side Effects:
1229**		none.
1230*/
1231
1232static int
1233priencode(p)
1234	char *p;
1235{
1236	register int i;
1237
1238	for (i = 0; i < NumPriorities; i++)
1239	{
1240		if (sm_strcasecmp(p, Priorities[i].pri_name) == 0)
1241			return Priorities[i].pri_val;
1242	}
1243
1244	/* unknown priority */
1245	return 0;
1246}
1247
1248/*
1249**  CRACKADDR -- parse an address and turn it into a macro
1250**
1251**	This doesn't actually parse the address -- it just extracts
1252**	it and replaces it with "$g".  The parse is totally ad hoc
1253**	and isn't even guaranteed to leave something syntactically
1254**	identical to what it started with.  However, it does leave
1255**	something semantically identical if possible, else at least
1256**	syntactically correct.
1257**
1258**	For example, it changes "Real Name <real@example.com> (Comment)"
1259**	to "Real Name <$g> (Comment)".
1260**
1261**	This algorithm has been cleaned up to handle a wider range
1262**	of cases -- notably quoted and backslash escaped strings.
1263**	This modification makes it substantially better at preserving
1264**	the original syntax.
1265**
1266**	Parameters:
1267**		addr -- the address to be cracked.
1268**		e -- the current envelope.
1269**
1270**	Returns:
1271**		a pointer to the new version.
1272**
1273**	Side Effects:
1274**		none.
1275**
1276**	Warning:
1277**		The return value is saved in local storage and should
1278**		be copied if it is to be reused.
1279*/
1280
1281#define SM_HAVE_ROOM		((bp < buflim) && (buflim <= bufend))
1282
1283/*
1284**  Append a character to bp if we have room.
1285**  If not, punt and return $g.
1286*/
1287
1288#define SM_APPEND_CHAR(c)					\
1289	do							\
1290	{							\
1291		if (SM_HAVE_ROOM)				\
1292			*bp++ = (c);				\
1293		else						\
1294			goto returng;				\
1295	} while (0)
1296
1297#if MAXNAME < 10
1298ERROR MAXNAME must be at least 10
1299#endif /* MAXNAME < 10 */
1300
1301char *
1302crackaddr(addr, e)
1303	register char *addr;
1304	ENVELOPE *e;
1305{
1306	register char *p;
1307	register char c;
1308	int cmtlev;			/* comment level in input string */
1309	int realcmtlev;			/* comment level in output string */
1310	int anglelev;			/* angle level in input string */
1311	int copylev;			/* 0 == in address, >0 copying */
1312	int bracklev;			/* bracket level for IPv6 addr check */
1313	bool addangle;			/* put closing angle in output */
1314	bool qmode;			/* quoting in original string? */
1315	bool realqmode;			/* quoting in output string? */
1316	bool putgmac = false;		/* already wrote $g */
1317	bool quoteit = false;		/* need to quote next character */
1318	bool gotangle = false;		/* found first '<' */
1319	bool gotcolon = false;		/* found a ':' */
1320	register char *bp;
1321	char *buflim;
1322	char *bufhead;
1323	char *addrhead;
1324	char *bufend;
1325	static char buf[MAXNAME + 1];
1326
1327	if (tTd(33, 1))
1328		sm_dprintf("crackaddr(%s)\n", addr);
1329
1330	buflim = bufend = &buf[sizeof(buf) - 1];
1331	bp = bufhead = buf;
1332
1333	/* skip over leading spaces but preserve them */
1334	while (*addr != '\0' && isascii(*addr) && isspace(*addr))
1335	{
1336		SM_APPEND_CHAR(*addr);
1337		addr++;
1338	}
1339	bufhead = bp;
1340
1341	/*
1342	**  Start by assuming we have no angle brackets.  This will be
1343	**  adjusted later if we find them.
1344	*/
1345
1346	p = addrhead = addr;
1347	copylev = anglelev = cmtlev = realcmtlev = 0;
1348	bracklev = 0;
1349	qmode = realqmode = addangle = false;
1350
1351	while ((c = *p++) != '\0')
1352	{
1353		/*
1354		**  Try to keep legal syntax using spare buffer space
1355		**  (maintained by buflim).
1356		*/
1357
1358		if (copylev > 0)
1359			SM_APPEND_CHAR(c);
1360
1361		/* check for backslash escapes */
1362		if (c == '\\')
1363		{
1364			/* arrange to quote the address */
1365			if (cmtlev <= 0 && !qmode)
1366				quoteit = true;
1367
1368			if ((c = *p++) == '\0')
1369			{
1370				/* too far */
1371				p--;
1372				goto putg;
1373			}
1374			if (copylev > 0)
1375				SM_APPEND_CHAR(c);
1376			goto putg;
1377		}
1378
1379		/* check for quoted strings */
1380		if (c == '"' && cmtlev <= 0)
1381		{
1382			qmode = !qmode;
1383			if (copylev > 0 && SM_HAVE_ROOM)
1384			{
1385				if (realqmode)
1386					buflim--;
1387				else
1388					buflim++;
1389				realqmode = !realqmode;
1390			}
1391			continue;
1392		}
1393		if (qmode)
1394			goto putg;
1395
1396		/* check for comments */
1397		if (c == '(')
1398		{
1399			cmtlev++;
1400
1401			/* allow space for closing paren */
1402			if (SM_HAVE_ROOM)
1403			{
1404				buflim--;
1405				realcmtlev++;
1406				if (copylev++ <= 0)
1407				{
1408					if (bp != bufhead)
1409						SM_APPEND_CHAR(' ');
1410					SM_APPEND_CHAR(c);
1411				}
1412			}
1413		}
1414		if (cmtlev > 0)
1415		{
1416			if (c == ')')
1417			{
1418				cmtlev--;
1419				copylev--;
1420				if (SM_HAVE_ROOM)
1421				{
1422					realcmtlev--;
1423					buflim++;
1424				}
1425			}
1426			continue;
1427		}
1428		else if (c == ')')
1429		{
1430			/* syntax error: unmatched ) */
1431			if (copylev > 0 && SM_HAVE_ROOM && bp > bufhead)
1432				bp--;
1433		}
1434
1435		/* count nesting on [ ... ] (for IPv6 domain literals) */
1436		if (c == '[')
1437			bracklev++;
1438		else if (c == ']')
1439			bracklev--;
1440
1441		/* check for group: list; syntax */
1442		if (c == ':' && anglelev <= 0 && bracklev <= 0 &&
1443		    !gotcolon && !ColonOkInAddr)
1444		{
1445			register char *q;
1446
1447			/*
1448			**  Check for DECnet phase IV ``::'' (host::user)
1449			**  or DECnet phase V ``:.'' syntaxes.  The latter
1450			**  covers ``user@DEC:.tay.myhost'' and
1451			**  ``DEC:.tay.myhost::user'' syntaxes (bletch).
1452			*/
1453
1454			if (*p == ':' || *p == '.')
1455			{
1456				if (cmtlev <= 0 && !qmode)
1457					quoteit = true;
1458				if (copylev > 0)
1459				{
1460					SM_APPEND_CHAR(c);
1461					SM_APPEND_CHAR(*p);
1462				}
1463				p++;
1464				goto putg;
1465			}
1466
1467			gotcolon = true;
1468
1469			bp = bufhead;
1470			if (quoteit)
1471			{
1472				SM_APPEND_CHAR('"');
1473
1474				/* back up over the ':' and any spaces */
1475				--p;
1476				while (p > addr &&
1477				       isascii(*--p) && isspace(*p))
1478					continue;
1479				p++;
1480			}
1481			for (q = addrhead; q < p; )
1482			{
1483				c = *q++;
1484				if (quoteit && c == '"')
1485					SM_APPEND_CHAR('\\');
1486				SM_APPEND_CHAR(c);
1487			}
1488			if (quoteit)
1489			{
1490				if (bp == &bufhead[1])
1491					bp--;
1492				else
1493					SM_APPEND_CHAR('"');
1494				while ((c = *p++) != ':')
1495					SM_APPEND_CHAR(c);
1496				SM_APPEND_CHAR(c);
1497			}
1498
1499			/* any trailing white space is part of group: */
1500			while (isascii(*p) && isspace(*p))
1501			{
1502				SM_APPEND_CHAR(*p);
1503				p++;
1504			}
1505			copylev = 0;
1506			putgmac = quoteit = false;
1507			bufhead = bp;
1508			addrhead = p;
1509			continue;
1510		}
1511
1512		if (c == ';' && copylev <= 0 && !ColonOkInAddr)
1513			SM_APPEND_CHAR(c);
1514
1515		/* check for characters that may have to be quoted */
1516		if (strchr(MustQuoteChars, c) != NULL)
1517		{
1518			/*
1519			**  If these occur as the phrase part of a <>
1520			**  construct, but are not inside of () or already
1521			**  quoted, they will have to be quoted.  Note that
1522			**  now (but don't actually do the quoting).
1523			*/
1524
1525			if (cmtlev <= 0 && !qmode)
1526				quoteit = true;
1527		}
1528
1529		/* check for angle brackets */
1530		if (c == '<')
1531		{
1532			register char *q;
1533
1534			/* assume first of two angles is bogus */
1535			if (gotangle)
1536				quoteit = true;
1537			gotangle = true;
1538
1539			/* oops -- have to change our mind */
1540			anglelev = 1;
1541			if (SM_HAVE_ROOM)
1542			{
1543				if (!addangle)
1544					buflim--;
1545				addangle = true;
1546			}
1547
1548			bp = bufhead;
1549			if (quoteit)
1550			{
1551				SM_APPEND_CHAR('"');
1552
1553				/* back up over the '<' and any spaces */
1554				--p;
1555				while (p > addr &&
1556				       isascii(*--p) && isspace(*p))
1557					continue;
1558				p++;
1559			}
1560			for (q = addrhead; q < p; )
1561			{
1562				c = *q++;
1563				if (quoteit && c == '"')
1564				{
1565					SM_APPEND_CHAR('\\');
1566					SM_APPEND_CHAR(c);
1567				}
1568				else
1569					SM_APPEND_CHAR(c);
1570			}
1571			if (quoteit)
1572			{
1573				if (bp == &buf[1])
1574					bp--;
1575				else
1576					SM_APPEND_CHAR('"');
1577				while ((c = *p++) != '<')
1578					SM_APPEND_CHAR(c);
1579				SM_APPEND_CHAR(c);
1580			}
1581			copylev = 0;
1582			putgmac = quoteit = false;
1583			continue;
1584		}
1585
1586		if (c == '>')
1587		{
1588			if (anglelev > 0)
1589			{
1590				anglelev--;
1591				if (SM_HAVE_ROOM)
1592				{
1593					if (addangle)
1594						buflim++;
1595					addangle = false;
1596				}
1597			}
1598			else if (SM_HAVE_ROOM)
1599			{
1600				/* syntax error: unmatched > */
1601				if (copylev > 0 && bp > bufhead)
1602					bp--;
1603				quoteit = true;
1604				continue;
1605			}
1606			if (copylev++ <= 0)
1607				SM_APPEND_CHAR(c);
1608			continue;
1609		}
1610
1611		/* must be a real address character */
1612	putg:
1613		if (copylev <= 0 && !putgmac)
1614		{
1615			if (bp > buf && bp[-1] == ')')
1616				SM_APPEND_CHAR(' ');
1617			SM_APPEND_CHAR(MACROEXPAND);
1618			SM_APPEND_CHAR('g');
1619			putgmac = true;
1620		}
1621	}
1622
1623	/* repair any syntactic damage */
1624	if (realqmode && bp < bufend)
1625		*bp++ = '"';
1626	while (realcmtlev-- > 0 && bp < bufend)
1627		*bp++ = ')';
1628	if (addangle && bp < bufend)
1629		*bp++ = '>';
1630	*bp = '\0';
1631	if (bp < bufend)
1632		goto success;
1633
1634 returng:
1635	/* String too long, punt */
1636	buf[0] = '<';
1637	buf[1] = MACROEXPAND;
1638	buf[2]= 'g';
1639	buf[3] = '>';
1640	buf[4]= '\0';
1641	sm_syslog(LOG_ALERT, e->e_id,
1642		  "Dropped invalid comments from header address");
1643
1644 success:
1645	if (tTd(33, 1))
1646	{
1647		sm_dprintf("crackaddr=>`");
1648		xputs(sm_debug_file(), buf);
1649		sm_dprintf("'\n");
1650	}
1651	return buf;
1652}
1653
1654/*
1655**  PUTHEADER -- put the header part of a message from the in-core copy
1656**
1657**	Parameters:
1658**		mci -- the connection information.
1659**		hdr -- the header to put.
1660**		e -- envelope to use.
1661**		flags -- MIME conversion flags.
1662**
1663**	Returns:
1664**		true iff header part was written successfully
1665**
1666**	Side Effects:
1667**		none.
1668*/
1669
1670bool
1671putheader(mci, hdr, e, flags)
1672	register MCI *mci;
1673	HDR *hdr;
1674	register ENVELOPE *e;
1675	int flags;
1676{
1677	register HDR *h;
1678	char buf[SM_MAX(MAXLINE,BUFSIZ)];
1679	char obuf[MAXLINE];
1680
1681	if (tTd(34, 1))
1682		sm_dprintf("--- putheader, mailer = %s ---\n",
1683			mci->mci_mailer->m_name);
1684
1685	/*
1686	**  If we're in MIME mode, we're not really in the header of the
1687	**  message, just the header of one of the parts of the body of
1688	**  the message.  Therefore MCIF_INHEADER should not be turned on.
1689	*/
1690
1691	if (!bitset(MCIF_INMIME, mci->mci_flags))
1692		mci->mci_flags |= MCIF_INHEADER;
1693
1694	for (h = hdr; h != NULL; h = h->h_link)
1695	{
1696		register char *p = h->h_value;
1697		char *q;
1698
1699		if (tTd(34, 11))
1700		{
1701			sm_dprintf("  %s:", h->h_field);
1702			xputs(sm_debug_file(), p);
1703		}
1704
1705		/* Skip empty headers */
1706		if (h->h_value == NULL)
1707			continue;
1708
1709		/* heuristic shortening of MIME fields to avoid MUA overflows */
1710		if (MaxMimeFieldLength > 0 &&
1711		    wordinclass(h->h_field,
1712				macid("{checkMIMEFieldHeaders}")))
1713		{
1714			size_t len;
1715
1716			len = fix_mime_header(h, e);
1717			if (len > 0)
1718			{
1719				sm_syslog(LOG_ALERT, e->e_id,
1720					  "Truncated MIME %s header due to field size (length = %ld) (possible attack)",
1721					  h->h_field, (unsigned long) len);
1722				if (tTd(34, 11))
1723					sm_dprintf("  truncated MIME %s header due to field size  (length = %ld) (possible attack)\n",
1724						   h->h_field,
1725						   (unsigned long) len);
1726			}
1727		}
1728
1729		if (MaxMimeHeaderLength > 0 &&
1730		    wordinclass(h->h_field,
1731				macid("{checkMIMETextHeaders}")))
1732		{
1733			size_t len;
1734
1735			len = strlen(h->h_value);
1736			if (len > (size_t) MaxMimeHeaderLength)
1737			{
1738				h->h_value[MaxMimeHeaderLength - 1] = '\0';
1739				sm_syslog(LOG_ALERT, e->e_id,
1740					  "Truncated long MIME %s header (length = %ld) (possible attack)",
1741					  h->h_field, (unsigned long) len);
1742				if (tTd(34, 11))
1743					sm_dprintf("  truncated long MIME %s header (length = %ld) (possible attack)\n",
1744						   h->h_field,
1745						   (unsigned long) len);
1746			}
1747		}
1748
1749		if (MaxMimeHeaderLength > 0 &&
1750		    wordinclass(h->h_field,
1751				macid("{checkMIMEHeaders}")))
1752		{
1753			size_t len;
1754
1755			len = strlen(h->h_value);
1756			if (shorten_rfc822_string(h->h_value,
1757						  MaxMimeHeaderLength))
1758			{
1759				if (len < MaxMimeHeaderLength)
1760				{
1761					/* we only rebalanced a bogus header */
1762					sm_syslog(LOG_ALERT, e->e_id,
1763						  "Fixed MIME %s header (possible attack)",
1764						  h->h_field);
1765					if (tTd(34, 11))
1766						sm_dprintf("  fixed MIME %s header (possible attack)\n",
1767							   h->h_field);
1768				}
1769				else
1770				{
1771					/* we actually shortened header */
1772					sm_syslog(LOG_ALERT, e->e_id,
1773						  "Truncated long MIME %s header (length = %ld) (possible attack)",
1774						  h->h_field,
1775						  (unsigned long) len);
1776					if (tTd(34, 11))
1777						sm_dprintf("  truncated long MIME %s header (length = %ld) (possible attack)\n",
1778							   h->h_field,
1779							   (unsigned long) len);
1780				}
1781			}
1782		}
1783
1784		/*
1785		**  Suppress Content-Transfer-Encoding: if we are MIMEing
1786		**  and we are potentially converting from 8 bit to 7 bit
1787		**  MIME.  If converting, add a new CTE header in
1788		**  mime8to7().
1789		*/
1790
1791		if (bitset(H_CTE, h->h_flags) &&
1792		    bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME,
1793			   mci->mci_flags) &&
1794		    !bitset(M87F_NO8TO7, flags))
1795		{
1796			if (tTd(34, 11))
1797				sm_dprintf(" (skipped (content-transfer-encoding))\n");
1798			continue;
1799		}
1800
1801		if (bitset(MCIF_INMIME, mci->mci_flags))
1802		{
1803			if (tTd(34, 11))
1804				sm_dprintf("\n");
1805			if (!put_vanilla_header(h, p, mci))
1806				goto writeerr;
1807			continue;
1808		}
1809
1810		if (bitset(H_CHECK|H_ACHECK, h->h_flags) &&
1811		    !bitintersect(h->h_mflags, mci->mci_mailer->m_flags) &&
1812		    (h->h_macro == '\0' ||
1813		     (q = macvalue(bitidx(h->h_macro), e)) == NULL ||
1814		     *q == '\0'))
1815		{
1816			if (tTd(34, 11))
1817				sm_dprintf(" (skipped)\n");
1818			continue;
1819		}
1820
1821		/* handle Resent-... headers specially */
1822		if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags))
1823		{
1824			if (tTd(34, 11))
1825				sm_dprintf(" (skipped (resent))\n");
1826			continue;
1827		}
1828
1829		/* suppress return receipts if requested */
1830		if (bitset(H_RECEIPTTO, h->h_flags) &&
1831		    (RrtImpliesDsn || bitset(EF_NORECEIPT, e->e_flags)))
1832		{
1833			if (tTd(34, 11))
1834				sm_dprintf(" (skipped (receipt))\n");
1835			continue;
1836		}
1837
1838		/* macro expand value if generated internally */
1839		if (bitset(H_DEFAULT, h->h_flags) ||
1840		    bitset(H_BINDLATE, h->h_flags))
1841		{
1842			expand(p, buf, sizeof(buf), e);
1843			p = buf;
1844			if (*p == '\0')
1845			{
1846				if (tTd(34, 11))
1847					sm_dprintf(" (skipped -- null value)\n");
1848				continue;
1849			}
1850		}
1851
1852		if (bitset(H_BCC, h->h_flags))
1853		{
1854			/* Bcc: field -- either truncate or delete */
1855			if (bitset(EF_DELETE_BCC, e->e_flags))
1856			{
1857				if (tTd(34, 11))
1858					sm_dprintf(" (skipped -- bcc)\n");
1859			}
1860			else
1861			{
1862				/* no other recipient headers: truncate value */
1863				(void) sm_strlcpyn(obuf, sizeof(obuf), 2,
1864						   h->h_field, ":");
1865				if (!putline(obuf, mci))
1866					goto writeerr;
1867			}
1868			continue;
1869		}
1870
1871		if (tTd(34, 11))
1872			sm_dprintf("\n");
1873
1874		if (bitset(H_FROM|H_RCPT, h->h_flags))
1875		{
1876			/* address field */
1877			bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags);
1878
1879			if (bitset(H_FROM, h->h_flags))
1880				oldstyle = false;
1881			commaize(h, p, oldstyle, mci, e,
1882				 PXLF_HEADER | PXLF_STRIPMQUOTE);
1883		}
1884		else
1885		{
1886			if (!put_vanilla_header(h, p, mci))
1887				goto writeerr;
1888		}
1889	}
1890
1891	/*
1892	**  If we are converting this to a MIME message, add the
1893	**  MIME headers (but not in MIME mode!).
1894	*/
1895
1896#if MIME8TO7
1897	if (bitset(MM_MIME8BIT, MimeMode) &&
1898	    bitset(EF_HAS8BIT, e->e_flags) &&
1899	    !bitset(EF_DONT_MIME, e->e_flags) &&
1900	    !bitnset(M_8BITS, mci->mci_mailer->m_flags) &&
1901	    !bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME, mci->mci_flags) &&
1902	    hvalue("MIME-Version", e->e_header) == NULL)
1903	{
1904		if (!putline("MIME-Version: 1.0", mci))
1905			goto writeerr;
1906		if (hvalue("Content-Type", e->e_header) == NULL)
1907		{
1908			(void) sm_snprintf(obuf, sizeof(obuf),
1909					"Content-Type: text/plain; charset=%s",
1910					defcharset(e));
1911			if (!putline(obuf, mci))
1912				goto writeerr;
1913		}
1914		if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL
1915		    && !putline("Content-Transfer-Encoding: 8bit", mci))
1916			goto writeerr;
1917	}
1918#endif /* MIME8TO7 */
1919	return true;
1920
1921  writeerr:
1922	return false;
1923}
1924
1925/*
1926**  PUT_VANILLA_HEADER -- output a fairly ordinary header
1927**
1928**	Parameters:
1929**		h -- the structure describing this header
1930**		v -- the value of this header
1931**		mci -- the connection info for output
1932**
1933**	Returns:
1934**		true iff header was written successfully
1935*/
1936
1937static bool
1938put_vanilla_header(h, v, mci)
1939	HDR *h;
1940	char *v;
1941	MCI *mci;
1942{
1943	register char *nlp;
1944	register char *obp;
1945	int putflags;
1946	char obuf[MAXLINE + 256];	/* additional length for h_field */
1947
1948	putflags = PXLF_HEADER | PXLF_STRIPMQUOTE;
1949	if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags))
1950		putflags |= PXLF_STRIP8BIT;
1951	(void) sm_snprintf(obuf, sizeof(obuf), "%.200s:", h->h_field);
1952	obp = obuf + strlen(obuf);
1953	while ((nlp = strchr(v, '\n')) != NULL)
1954	{
1955		int l;
1956
1957		l = nlp - v;
1958
1959		/*
1960		**  XXX This is broken for SPACELEFT()==0
1961		**  However, SPACELEFT() is always > 0 unless MAXLINE==1.
1962		*/
1963
1964		if (SPACELEFT(obuf, obp) - 1 < (size_t) l)
1965			l = SPACELEFT(obuf, obp) - 1;
1966
1967		(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v);
1968		if (!putxline(obuf, strlen(obuf), mci, putflags))
1969			goto writeerr;
1970		v += l + 1;
1971		obp = obuf;
1972		if (*v != ' ' && *v != '\t')
1973			*obp++ = ' ';
1974	}
1975
1976	/* XXX This is broken for SPACELEFT()==0 */
1977	(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
1978			   (int) (SPACELEFT(obuf, obp) - 1), v);
1979	return putxline(obuf, strlen(obuf), mci, putflags);
1980
1981  writeerr:
1982	return false;
1983}
1984
1985/*
1986**  COMMAIZE -- output a header field, making a comma-translated list.
1987**
1988**	Parameters:
1989**		h -- the header field to output.
1990**		p -- the value to put in it.
1991**		oldstyle -- true if this is an old style header.
1992**		mci -- the connection information.
1993**		e -- the envelope containing the message.
1994**		putflags -- flags for putxline()
1995**
1996**	Returns:
1997**		true iff header field was written successfully
1998**
1999**	Side Effects:
2000**		outputs "p" to "mci".
2001*/
2002
2003bool
2004commaize(h, p, oldstyle, mci, e, putflags)
2005	register HDR *h;
2006	register char *p;
2007	bool oldstyle;
2008	register MCI *mci;
2009	register ENVELOPE *e;
2010	int putflags;
2011{
2012	register char *obp;
2013	int opos, omax, spaces;
2014	bool firstone = true;
2015	char **res;
2016	char obuf[MAXLINE + 3];
2017
2018	/*
2019	**  Output the address list translated by the
2020	**  mailer and with commas.
2021	*/
2022
2023	if (tTd(14, 2))
2024		sm_dprintf("commaize(%s:%s)\n", h->h_field, p);
2025
2026	if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags))
2027		putflags |= PXLF_STRIP8BIT;
2028
2029	obp = obuf;
2030	(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.200s:", h->h_field);
2031	/* opos = strlen(obp); instead of the next 3 lines? */
2032	opos = strlen(h->h_field) + 1;
2033	if (opos > 201)
2034		opos = 201;
2035	obp += opos;
2036
2037	spaces = 0;
2038	while (*p != '\0' && isascii(*p) && isspace(*p))
2039	{
2040		++spaces;
2041		++p;
2042	}
2043	if (spaces > 0)
2044	{
2045		SM_ASSERT(sizeof(obuf) > opos  * 2);
2046
2047		/*
2048		**  Restrict number of spaces to half the length of buffer
2049		**  so the header field body can be put in here too.
2050		**  Note: this is a hack...
2051		*/
2052
2053		if (spaces > sizeof(obuf) / 2)
2054			spaces = sizeof(obuf) / 2;
2055		(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%*s", spaces,
2056				"");
2057		opos += spaces;
2058		obp += spaces;
2059		SM_ASSERT(obp < &obuf[MAXLINE]);
2060	}
2061
2062	omax = mci->mci_mailer->m_linelimit - 2;
2063	if (omax < 0 || omax > 78)
2064		omax = 78;
2065
2066	/*
2067	**  Run through the list of values.
2068	*/
2069
2070	while (*p != '\0')
2071	{
2072		register char *name;
2073		register int c;
2074		char savechar;
2075		int flags;
2076		auto int status;
2077
2078		/*
2079		**  Find the end of the name.  New style names
2080		**  end with a comma, old style names end with
2081		**  a space character.  However, spaces do not
2082		**  necessarily delimit an old-style name -- at
2083		**  signs mean keep going.
2084		*/
2085
2086		/* find end of name */
2087		while ((isascii(*p) && isspace(*p)) || *p == ',')
2088			p++;
2089		name = p;
2090		res = NULL;
2091		for (;;)
2092		{
2093			auto char *oldp;
2094			char pvpbuf[PSBUFSIZE];
2095
2096			res = prescan(p, oldstyle ? ' ' : ',', pvpbuf,
2097				      sizeof(pvpbuf), &oldp, ExtTokenTab, false);
2098			p = oldp;
2099#if _FFR_IGNORE_BOGUS_ADDR
2100			/* ignore addresses that can't be parsed */
2101			if (res == NULL)
2102			{
2103				name = p;
2104				continue;
2105			}
2106#endif /* _FFR_IGNORE_BOGUS_ADDR */
2107
2108			/* look to see if we have an at sign */
2109			while (*p != '\0' && isascii(*p) && isspace(*p))
2110				p++;
2111
2112			if (*p != '@')
2113			{
2114				p = oldp;
2115				break;
2116			}
2117			++p;
2118			while (*p != '\0' && isascii(*p) && isspace(*p))
2119				p++;
2120		}
2121		/* at the end of one complete name */
2122
2123		/* strip off trailing white space */
2124		while (p >= name &&
2125		       ((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0'))
2126			p--;
2127		if (++p == name)
2128			continue;
2129
2130		/*
2131		**  if prescan() failed go a bit backwards; this is a hack,
2132		**  there should be some better error recovery.
2133		*/
2134
2135		if (res == NULL && p > name &&
2136		    !((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0'))
2137			--p;
2138		savechar = *p;
2139		*p = '\0';
2140
2141		/* translate the name to be relative */
2142		flags = RF_HEADERADDR|RF_ADDDOMAIN;
2143		if (bitset(H_FROM, h->h_flags))
2144			flags |= RF_SENDERADDR;
2145#if USERDB
2146		else if (e->e_from.q_mailer != NULL &&
2147			 bitnset(M_UDBRECIPIENT, e->e_from.q_mailer->m_flags))
2148		{
2149			char *q;
2150
2151			q = udbsender(name, e->e_rpool);
2152			if (q != NULL)
2153				name = q;
2154		}
2155#endif /* USERDB */
2156		status = EX_OK;
2157		name = remotename(name, mci->mci_mailer, flags, &status, e);
2158		if (*name == '\0')
2159		{
2160			*p = savechar;
2161			continue;
2162		}
2163		name = denlstring(name, false, true);
2164
2165		/* output the name with nice formatting */
2166		opos += strlen(name);
2167		if (!firstone)
2168			opos += 2;
2169		if (opos > omax && !firstone)
2170		{
2171			(void) sm_strlcpy(obp, ",\n", SPACELEFT(obuf, obp));
2172			if (!putxline(obuf, strlen(obuf), mci, putflags))
2173				goto writeerr;
2174			obp = obuf;
2175			(void) sm_strlcpy(obp, "        ", sizeof(obuf));
2176			opos = strlen(obp);
2177			obp += opos;
2178			opos += strlen(name);
2179		}
2180		else if (!firstone)
2181		{
2182			(void) sm_strlcpy(obp, ", ", SPACELEFT(obuf, obp));
2183			obp += 2;
2184		}
2185
2186		while ((c = *name++) != '\0' && obp < &obuf[MAXLINE])
2187			*obp++ = c;
2188		firstone = false;
2189		*p = savechar;
2190	}
2191	if (obp < &obuf[sizeof(obuf)])
2192		*obp = '\0';
2193	else
2194		obuf[sizeof(obuf) - 1] = '\0';
2195	return putxline(obuf, strlen(obuf), mci, putflags);
2196
2197  writeerr:
2198	return false;
2199}
2200
2201/*
2202**  COPYHEADER -- copy header list
2203**
2204**	This routine is the equivalent of newstr for header lists
2205**
2206**	Parameters:
2207**		header -- list of header structures to copy.
2208**		rpool -- resource pool, or NULL
2209**
2210**	Returns:
2211**		a copy of 'header'.
2212**
2213**	Side Effects:
2214**		none.
2215*/
2216
2217HDR *
2218copyheader(header, rpool)
2219	register HDR *header;
2220	SM_RPOOL_T *rpool;
2221{
2222	register HDR *newhdr;
2223	HDR *ret;
2224	register HDR **tail = &ret;
2225
2226	while (header != NULL)
2227	{
2228		newhdr = (HDR *) sm_rpool_malloc_x(rpool, sizeof(*newhdr));
2229		STRUCTCOPY(*header, *newhdr);
2230		*tail = newhdr;
2231		tail = &newhdr->h_link;
2232		header = header->h_link;
2233	}
2234	*tail = NULL;
2235
2236	return ret;
2237}
2238
2239/*
2240**  FIX_MIME_HEADER -- possibly truncate/rebalance parameters in a MIME header
2241**
2242**	Run through all of the parameters of a MIME header and
2243**	possibly truncate and rebalance the parameter according
2244**	to MaxMimeFieldLength.
2245**
2246**	Parameters:
2247**		h -- the header to truncate/rebalance
2248**		e -- the current envelope
2249**
2250**	Returns:
2251**		length of last offending field, 0 if all ok.
2252**
2253**	Side Effects:
2254**		string modified in place
2255*/
2256
2257static size_t
2258fix_mime_header(h, e)
2259	HDR *h;
2260	ENVELOPE *e;
2261{
2262	char *begin = h->h_value;
2263	char *end;
2264	size_t len = 0;
2265	size_t retlen = 0;
2266
2267	if (begin == NULL || *begin == '\0')
2268		return 0;
2269
2270	/* Split on each ';' */
2271	/* find_character() never returns NULL */
2272	while ((end = find_character(begin, ';')) != NULL)
2273	{
2274		char save = *end;
2275		char *bp;
2276
2277		*end = '\0';
2278
2279		len = strlen(begin);
2280
2281		/* Shorten individual parameter */
2282		if (shorten_rfc822_string(begin, MaxMimeFieldLength))
2283		{
2284			if (len < MaxMimeFieldLength)
2285			{
2286				/* we only rebalanced a bogus field */
2287				sm_syslog(LOG_ALERT, e->e_id,
2288					  "Fixed MIME %s header field (possible attack)",
2289					  h->h_field);
2290				if (tTd(34, 11))
2291					sm_dprintf("  fixed MIME %s header field (possible attack)\n",
2292						   h->h_field);
2293			}
2294			else
2295			{
2296				/* we actually shortened the header */
2297				retlen = len;
2298			}
2299		}
2300
2301		/* Collapse the possibly shortened string with rest */
2302		bp = begin + strlen(begin);
2303		if (bp != end)
2304		{
2305			char *ep = end;
2306
2307			*end = save;
2308			end = bp;
2309
2310			/* copy character by character due to overlap */
2311			while (*ep != '\0')
2312				*bp++ = *ep++;
2313			*bp = '\0';
2314		}
2315		else
2316			*end = save;
2317		if (*end == '\0')
2318			break;
2319
2320		/* Move past ';' */
2321		begin = end + 1;
2322	}
2323	return retlen;
2324}
2325