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