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 * $FreeBSD: head/contrib/sendmail/src/headers.c 132946 2004-08-01 01:16:16Z gshapiro $ |
13 */ 14 15#include <sendmail.h> 16 |
17SM_RCSID("@(#)$Id: headers.c,v 8.286 2004/07/08 17:57:32 ca Exp $") |
18 |
19static HDR *allocheader __P((char *, char *, int, SM_RPOOL_T *)); |
20static size_t fix_mime_header __P((HDR *, ENVELOPE *)); 21static int priencode __P((char *)); 22static void put_vanilla_header __P((HDR *, char *, MCI *)); 23 24/* 25** SETUPHEADERS -- initialize headers in symbol table 26** 27** Parameters: --- 56 unchanged lines hidden (view full) --- 84 STAB *s; 85 struct hdrinfo *hi; 86 bool nullheader = false; 87 BITMAP256 mopts; 88 89 if (tTd(31, 6)) 90 { 91 sm_dprintf("chompheader: "); |
92 xputs(sm_debug_file(), line); |
93 sm_dprintf("\n"); 94 } 95 96 headeronly = hdrp != NULL; 97 if (!headeronly) 98 hdrp = &e->e_header; 99 100 /* strip off options */ --- 187 unchanged lines hidden (view full) --- 288 ** If there is a check ruleset, verify it against the header. 289 */ 290 291 if (bitset(pflag, CHHDR_CHECK)) 292 { 293 int rscheckflags; 294 char *rs; 295 |
296 rscheckflags = RSF_COUNT; 297 if (!bitset(hi->hi_flags, H_FROM|H_RCPT)) 298 rscheckflags |= RSF_UNSTRUCTURED; |
299 300 /* no ruleset? look for default */ 301 rs = hi->hi_ruleset; |
302 if (rs == NULL) 303 { 304 s = stab("*", ST_HEADER, ST_FIND); 305 if (s != NULL) 306 { 307 rs = (&s->s_header)->hi_ruleset; 308 if (bitset((&s->s_header)->hi_flags, 309 H_STRIPCOMM)) --- 45 unchanged lines hidden (view full) --- 355 macdefine(&e->e_macro, A_TEMP, 356 macid("{currHeader}"), qval); 357 macdefine(&e->e_macro, A_TEMP, 358 macid("{hdr_name}"), fname); 359 360 (void) sm_snprintf(qval, sizeof qval, "%d", k); 361 macdefine(&e->e_macro, A_TEMP, macid("{hdrlen}"), qval); 362#if _FFR_HDR_TYPE |
363 if (bitset(H_FROM, hi->hi_flags)) |
364 macdefine(&e->e_macro, A_PERM, 365 macid("{addr_type}"), "h s"); |
366 else if (bitset(H_RCPT, hi->hi_flags)) |
367 macdefine(&e->e_macro, A_PERM, 368 macid("{addr_type}"), "h r"); 369 else 370#endif /* _FFR_HDR_TYPE */ 371 macdefine(&e->e_macro, A_PERM, 372 macid("{addr_type}"), "h"); 373 (void) rscheck(rs, fvalue, NULL, e, rscheckflags, 3, 374 NULL, e->e_id); --- 82 unchanged lines hidden (view full) --- 457 strchr(fvalue, '<') != NULL || strchr(fvalue, ';') != NULL)) 458 { 459 e->e_flags &= ~EF_OLDSTYLE; 460 } 461 462 return h->h_flags; 463} 464/* |
465** ALLOCHEADER -- allocate a header entry 466** 467** Parameters: 468** field -- the name of the header field. 469** value -- the value of the field. 470** flags -- flags to add to h_flags. 471** rp -- resource pool for allocations 472** 473** Returns: 474** Pointer to a newly allocated and populated HDR. 475*/ 476 477static HDR * 478allocheader(field, value, flags, rp) 479 char *field; 480 char *value; 481 int flags; 482 SM_RPOOL_T *rp; 483{ 484 HDR *h; 485 STAB *s; 486 487 /* find info struct */ 488 s = stab(field, ST_HEADER, ST_FIND); 489 490 /* allocate space for new header */ 491 h = (HDR *) sm_rpool_malloc_x(rp, sizeof *h); 492 h->h_field = field; 493 h->h_value = sm_rpool_strdup_x(rp, value); 494 h->h_flags = flags; 495 if (s != NULL) 496 h->h_flags |= s->s_header.hi_flags; 497 clrbitmap(h->h_mflags); 498 h->h_macro = '\0'; 499 500 return h; 501} 502/* |
503** ADDHEADER -- add a header entry to the end of the queue. 504** 505** This bypasses the special checking of chompheader. 506** 507** Parameters: 508** field -- the name of the header field. 509** value -- the value of the field. 510** flags -- flags to add to h_flags. --- 9 unchanged lines hidden (view full) --- 520void 521addheader(field, value, flags, e) 522 char *field; 523 char *value; 524 int flags; 525 ENVELOPE *e; 526{ 527 register HDR *h; |
528 HDR **hp; 529 HDR **hdrlist = &e->e_header; 530 |
531 /* find current place in list -- keep back pointer? */ 532 for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link) 533 { 534 if (sm_strcasecmp(field, h->h_field) == 0) 535 break; 536 } 537 538 /* allocate space for new header */ |
539 h = allocheader(field, value, flags, e->e_rpool); |
540 h->h_link = *hp; |
541 *hp = h; 542} 543/* |
544** INSHEADER -- insert a header entry at the specified index 545** 546** This bypasses the special checking of chompheader. 547** 548** Parameters: 549** idx -- index into the header list at which to insert 550** field -- the name of the header field. 551** value -- the value of the field. 552** flags -- flags to add to h_flags. 553** e -- envelope. 554** 555** Returns: 556** none. 557** 558** Side Effects: 559** inserts the field on the list of headers for this envelope. 560*/ 561 562void 563insheader(idx, field, value, flags, e) 564 int idx; 565 char *field; 566 char *value; 567 int flags; 568 ENVELOPE *e; 569{ 570 HDR *h, *srch, *last = NULL; 571 572 /* allocate space for new header */ 573 h = allocheader(field, value, flags, e->e_rpool); 574 575 /* find insertion position */ 576 for (srch = e->e_header; srch != NULL && idx > 0; 577 srch = srch->h_link, idx--) 578 last = srch; 579 580 if (e->e_header == NULL) 581 { 582 e->e_header = h; 583 h->h_link = NULL; 584 } 585 else if (srch == NULL) 586 { 587 SM_ASSERT(last != NULL); 588 last->h_link = h; 589 h->h_link = NULL; 590 } 591 else 592 { 593 h->h_link = srch->h_link; 594 srch->h_link = h; 595 } 596} 597/* |
598** HVALUE -- return value of a header. 599** 600** Only "real" fields (i.e., ones that have not been supplied 601** as a default) are used. 602** 603** Parameters: 604** field -- the field name. 605** header -- the header list. --- 139 unchanged lines hidden (view full) --- 745 746 /* do early binding */ 747 if (bitset(H_DEFAULT, h->h_flags) && 748 !bitset(H_BINDLATE, h->h_flags)) 749 { 750 if (tTd(32, 1)) 751 { 752 sm_dprintf("("); |
753 xputs(sm_debug_file(), h->h_value); |
754 sm_dprintf(") "); 755 } 756 expand(h->h_value, buf, sizeof buf, e); 757 if (buf[0] != '\0') 758 { 759 if (bitset(H_FROM, h->h_flags)) 760 expand(crackaddr(buf, e), 761 buf, sizeof buf, e); 762 h->h_value = sm_rpool_strdup_x(e->e_rpool, buf); 763 h->h_flags &= ~H_DEFAULT; 764 } 765 } 766 if (tTd(32, 1)) 767 { |
768 xputs(sm_debug_file(), h->h_value); |
769 sm_dprintf("\n"); 770 } 771 772 /* count the number of times it has been processed */ 773 if (bitset(H_TRACE, h->h_flags)) 774 hopcnt++; 775 776 /* send to this person if we so desire */ --- 25 unchanged lines hidden (view full) --- 802 p = "resent-message-id"; 803 if (!bitset(EF_RESENT, e->e_flags)) 804 p += 7; 805 if (sm_strcasecmp(h->h_field, p) == 0) 806 { 807 e->e_msgid = h->h_value; 808 while (isascii(*e->e_msgid) && isspace(*e->e_msgid)) 809 e->e_msgid++; |
810 macdefine(&e->e_macro, A_PERM, macid("{msg_id}"), |
811 e->e_msgid); |
812 } 813 } 814 if (tTd(32, 1)) 815 sm_dprintf("----------------------------\n"); 816 817 /* if we are just verifying (that is, sendmail -t -bv), drop out now */ 818 if (OpMode == MD_VERIFY) 819 return; --- 16 unchanged lines hidden (view full) --- 836 e->e_timeoutclass = TOC_URGENT; 837 if (full) 838 { 839 e->e_msgpriority = e->e_msgsize 840 - e->e_class * WkClassFact 841 + e->e_nrcpts * WkRecipFact; 842 } 843 |
844 /* check for DSN to properly set e_timeoutclass */ 845 p = hvalue("content-type", e->e_header); 846 if (p != NULL) 847 { 848 bool oldsupr; 849 char **pvp; 850 char pvpbuf[MAXLINE]; 851 extern unsigned char MimeTokenTab[256]; 852 853 /* tokenize header */ 854 oldsupr = SuprErrs; 855 SuprErrs = true; 856 pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL, 857 MimeTokenTab, false); 858 SuprErrs = oldsupr; 859 860 /* Check if multipart/report */ 861 if (pvp != NULL && pvp[0] != NULL && 862 pvp[1] != NULL && pvp[2] != NULL && 863 sm_strcasecmp(*pvp++, "multipart") == 0 && 864 strcmp(*pvp++, "/") == 0 && 865 sm_strcasecmp(*pvp++, "report") == 0) 866 { 867 /* Look for report-type=delivery-status */ 868 while (*pvp != NULL) 869 { 870 /* skip to semicolon separator */ 871 while (*pvp != NULL && strcmp(*pvp, ";") != 0) 872 pvp++; 873 874 /* skip semicolon */ 875 if (*pvp++ == NULL || *pvp == NULL) 876 break; 877 878 /* look for report-type */ 879 if (sm_strcasecmp(*pvp++, "report-type") != 0) 880 continue; 881 882 /* skip equal */ 883 if (*pvp == NULL || strcmp(*pvp, "=") != 0) 884 continue; 885 886 /* check value */ 887 if (*++pvp != NULL && 888 sm_strcasecmp(*pvp, 889 "delivery-status") == 0) 890 e->e_timeoutclass = TOC_DSN; 891 892 /* found report-type, no need to continue */ 893 break; 894 } 895 } 896 } 897 |
898 /* message timeout priority */ 899 p = hvalue("priority", e->e_header); 900 if (p != NULL) 901 { 902 /* (this should be in the configuration file) */ 903 if (sm_strcasecmp(p, "urgent") == 0) 904 e->e_timeoutclass = TOC_URGENT; 905 else if (sm_strcasecmp(p, "normal") == 0) 906 e->e_timeoutclass = TOC_NORMAL; 907 else if (sm_strcasecmp(p, "non-urgent") == 0) 908 e->e_timeoutclass = TOC_NONURGENT; |
909 else if (bitset(EF_RESPONSE, e->e_flags)) 910 e->e_timeoutclass = TOC_DSN; |
911 } |
912 else if (bitset(EF_RESPONSE, e->e_flags)) 913 e->e_timeoutclass = TOC_DSN; |
914 915 /* date message originated */ 916 p = hvalue("posted-date", e->e_header); 917 if (p == NULL) 918 p = hvalue("date", e->e_header); 919 if (p != NULL) 920 macdefine(&e->e_macro, A_PERM, 'a', p); 921 --- 437 unchanged lines hidden (view full) --- 1359 isascii(*--p) && isspace(*p)) 1360 continue; 1361 p++; 1362 } 1363 for (q = addrhead; q < p; ) 1364 { 1365 c = *q++; 1366 if (quoteit && c == '"') |
1367 SM_APPEND_CHAR('\\'); |
1368 SM_APPEND_CHAR(c); |
1369 } 1370 if (quoteit) 1371 { 1372 if (bp == &bufhead[1]) 1373 bp--; 1374 else 1375 SM_APPEND_CHAR('"'); 1376 while ((c = *p++) != ':') --- 145 unchanged lines hidden (view full) --- 1522 buf[4]= '\0'; 1523 sm_syslog(LOG_ALERT, e->e_id, 1524 "Dropped invalid comments from header address"); 1525 1526 success: 1527 if (tTd(33, 1)) 1528 { 1529 sm_dprintf("crackaddr=>`"); |
1530 xputs(sm_debug_file(), buf); |
1531 sm_dprintf("'\n"); 1532 } 1533 return buf; 1534} 1535/* 1536** PUTHEADER -- put the header part of a message from the in-core copy 1537** 1538** Parameters: --- 36 unchanged lines hidden (view full) --- 1575 for (h = hdr; h != NULL; h = h->h_link) 1576 { 1577 register char *p = h->h_value; 1578 char *q; 1579 1580 if (tTd(34, 11)) 1581 { 1582 sm_dprintf(" %s: ", h->h_field); |
1583 xputs(sm_debug_file(), p); |
1584 } 1585 1586 /* Skip empty headers */ 1587 if (h->h_value == NULL) 1588 continue; 1589 1590 /* heuristic shortening of MIME fields to avoid MUA overflows */ 1591 if (MaxMimeFieldLength > 0 && --- 337 unchanged lines hidden (view full) --- 1929 name = p; 1930 res = NULL; 1931 for (;;) 1932 { 1933 auto char *oldp; 1934 char pvpbuf[PSBUFSIZE]; 1935 1936 res = prescan(p, oldstyle ? ' ' : ',', pvpbuf, |
1937 sizeof pvpbuf, &oldp, NULL, false); |
1938 p = oldp; 1939#if _FFR_IGNORE_BOGUS_ADDR 1940 /* ignore addresses that can't be parsed */ 1941 if (res == NULL) 1942 { 1943 name = p; 1944 continue; 1945 } --- 220 unchanged lines hidden --- |