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