1 /* 2 * Copyright (c) 1998-2004, 2006, 2007 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14 #pragma ident "%Z%%M% %I% %E% SMI" 15 16 #include <sendmail.h> 17 #include <sm/sendmail.h> 18 19 SM_RCSID("@(#)$Id: headers.c,v 8.309 2007/01/08 23:53:25 ca Exp $") 20 21 static HDR *allocheader __P((char *, char *, int, SM_RPOOL_T *, bool)); 22 static size_t fix_mime_header __P((HDR *, ENVELOPE *)); 23 static int priencode __P((char *)); 24 static bool put_vanilla_header __P((HDR *, char *, MCI *)); 25 26 /* 27 ** SETUPHEADERS -- initialize headers in symbol table 28 ** 29 ** Parameters: 30 ** none 31 ** 32 ** Returns: 33 ** none 34 */ 35 36 void 37 setupheaders() 38 { 39 struct hdrinfo *hi; 40 STAB *s; 41 42 for (hi = HdrInfo; hi->hi_field != NULL; hi++) 43 { 44 s = stab(hi->hi_field, ST_HEADER, ST_ENTER); 45 s->s_header.hi_flags = hi->hi_flags; 46 s->s_header.hi_ruleset = NULL; 47 } 48 } 49 50 /* 51 ** DOCHOMPHEADER -- process and save a header line. 52 ** 53 ** Called by chompheader. 54 ** 55 ** Parameters: 56 ** line -- header as a text line. 57 ** pflag -- flags for chompheader() (from sendmail.h) 58 ** hdrp -- a pointer to the place to save the header. 59 ** e -- the envelope including this header. 60 ** 61 ** Returns: 62 ** flags for this header. 63 ** 64 ** Side Effects: 65 ** The header is saved on the header list. 66 ** Contents of 'line' are destroyed. 67 */ 68 69 static struct hdrinfo NormalHeader = { NULL, 0, NULL }; 70 static unsigned long dochompheader __P((char *, int, HDR **, ENVELOPE *)); 71 72 static unsigned long 73 dochompheader(line, pflag, hdrp, e) 74 char *line; 75 int pflag; 76 HDR **hdrp; 77 ENVELOPE *e; 78 { 79 unsigned char mid = '\0'; 80 register char *p; 81 register HDR *h; 82 HDR **hp; 83 char *fname; 84 char *fvalue; 85 bool cond = false; 86 bool dropfrom; 87 bool headeronly; 88 STAB *s; 89 struct hdrinfo *hi; 90 bool nullheader = false; 91 BITMAP256 mopts; 92 93 headeronly = hdrp != NULL; 94 if (!headeronly) 95 hdrp = &e->e_header; 96 97 /* strip off options */ 98 clrbitmap(mopts); 99 p = line; 100 if (!bitset(pflag, CHHDR_USER) && *p == '?') 101 { 102 int c; 103 register char *q; 104 105 q = strchr(++p, '?'); 106 if (q == NULL) 107 goto hse; 108 109 *q = '\0'; 110 c = *p & 0377; 111 112 /* possibly macro conditional */ 113 if (c == MACROEXPAND) 114 { 115 /* catch ?$? */ 116 if (*++p == '\0') 117 { 118 *q = '?'; 119 goto hse; 120 } 121 122 mid = (unsigned char) *p++; 123 124 /* catch ?$abc? */ 125 if (*p != '\0') 126 { 127 *q = '?'; 128 goto hse; 129 } 130 } 131 else if (*p == '$') 132 { 133 /* catch ?$? */ 134 if (*++p == '\0') 135 { 136 *q = '?'; 137 goto hse; 138 } 139 140 mid = (unsigned char) macid(p); 141 if (bitset(0200, mid)) 142 { 143 p += strlen(macname(mid)) + 2; 144 SM_ASSERT(p <= q); 145 } 146 else 147 p++; 148 149 /* catch ?$abc? */ 150 if (*p != '\0') 151 { 152 *q = '?'; 153 goto hse; 154 } 155 } 156 else 157 { 158 while (*p != '\0') 159 { 160 if (!isascii(*p)) 161 { 162 *q = '?'; 163 goto hse; 164 } 165 166 setbitn(bitidx(*p), mopts); 167 cond = true; 168 p++; 169 } 170 } 171 p = q + 1; 172 } 173 174 /* find canonical name */ 175 fname = p; 176 while (isascii(*p) && isgraph(*p) && *p != ':') 177 p++; 178 fvalue = p; 179 while (isascii(*p) && isspace(*p)) 180 p++; 181 if (*p++ != ':' || fname == fvalue) 182 { 183 hse: 184 syserr("553 5.3.0 header syntax error, line \"%s\"", line); 185 return 0; 186 } 187 *fvalue = '\0'; 188 fvalue = p; 189 190 /* if the field is null, go ahead and use the default */ 191 while (isascii(*p) && isspace(*p)) 192 p++; 193 if (*p == '\0') 194 nullheader = true; 195 196 /* security scan: long field names are end-of-header */ 197 if (strlen(fname) > 100) 198 return H_EOH; 199 200 /* check to see if it represents a ruleset call */ 201 if (bitset(pflag, CHHDR_DEF)) 202 { 203 char hbuf[50]; 204 205 (void) expand(fvalue, hbuf, sizeof(hbuf), e); 206 for (p = hbuf; isascii(*p) && isspace(*p); ) 207 p++; 208 if ((*p++ & 0377) == CALLSUBR) 209 { 210 auto char *endp; 211 bool strc; 212 213 strc = *p == '+'; /* strip comments? */ 214 if (strc) 215 ++p; 216 if (strtorwset(p, &endp, ST_ENTER) > 0) 217 { 218 *endp = '\0'; 219 s = stab(fname, ST_HEADER, ST_ENTER); 220 if (LogLevel > 9 && 221 s->s_header.hi_ruleset != NULL) 222 sm_syslog(LOG_WARNING, NOQID, 223 "Warning: redefined ruleset for header=%s, old=%s, new=%s", 224 fname, 225 s->s_header.hi_ruleset, p); 226 s->s_header.hi_ruleset = newstr(p); 227 if (!strc) 228 s->s_header.hi_flags |= H_STRIPCOMM; 229 } 230 return 0; 231 } 232 } 233 234 /* see if it is a known type */ 235 s = stab(fname, ST_HEADER, ST_FIND); 236 if (s != NULL) 237 hi = &s->s_header; 238 else 239 hi = &NormalHeader; 240 241 if (tTd(31, 9)) 242 { 243 if (s == NULL) 244 sm_dprintf("no header flags match\n"); 245 else 246 sm_dprintf("header match, flags=%lx, ruleset=%s\n", 247 hi->hi_flags, 248 hi->hi_ruleset == NULL ? "<NULL>" 249 : hi->hi_ruleset); 250 } 251 252 /* see if this is a resent message */ 253 if (!bitset(pflag, CHHDR_DEF) && !headeronly && 254 bitset(H_RESENT, hi->hi_flags)) 255 e->e_flags |= EF_RESENT; 256 257 /* if this is an Errors-To: header keep track of it now */ 258 if (UseErrorsTo && !bitset(pflag, CHHDR_DEF) && !headeronly && 259 bitset(H_ERRORSTO, hi->hi_flags)) 260 (void) sendtolist(fvalue, NULLADDR, &e->e_errorqueue, 0, e); 261 262 /* if this means "end of header" quit now */ 263 if (!headeronly && bitset(H_EOH, hi->hi_flags)) 264 return hi->hi_flags; 265 266 /* 267 ** Horrible hack to work around problem with Lotus Notes SMTP 268 ** mail gateway, which generates From: headers with newlines in 269 ** them and the <address> on the second line. Although this is 270 ** legal RFC 822, many MUAs don't handle this properly and thus 271 ** never find the actual address. 272 */ 273 274 if (bitset(H_FROM, hi->hi_flags) && SingleLineFromHeader) 275 { 276 while ((p = strchr(fvalue, '\n')) != NULL) 277 *p = ' '; 278 } 279 280 /* 281 ** If there is a check ruleset, verify it against the header. 282 */ 283 284 if (bitset(pflag, CHHDR_CHECK)) 285 { 286 int rscheckflags; 287 char *rs; 288 289 rscheckflags = RSF_COUNT; 290 if (!bitset(hi->hi_flags, H_FROM|H_RCPT)) 291 rscheckflags |= RSF_UNSTRUCTURED; 292 293 /* no ruleset? look for default */ 294 rs = hi->hi_ruleset; 295 if (rs == NULL) 296 { 297 s = stab("*", ST_HEADER, ST_FIND); 298 if (s != NULL) 299 { 300 rs = (&s->s_header)->hi_ruleset; 301 if (bitset((&s->s_header)->hi_flags, 302 H_STRIPCOMM)) 303 rscheckflags |= RSF_RMCOMM; 304 } 305 } 306 else if (bitset(hi->hi_flags, H_STRIPCOMM)) 307 rscheckflags |= RSF_RMCOMM; 308 if (rs != NULL) 309 { 310 int l, k; 311 char qval[MAXNAME]; 312 313 l = 0; 314 qval[l++] = '"'; 315 316 /* - 3 to avoid problems with " at the end */ 317 /* should be sizeof(qval), not MAXNAME */ 318 for (k = 0; fvalue[k] != '\0' && l < MAXNAME - 3; k++) 319 { 320 switch (fvalue[k]) 321 { 322 /* XXX other control chars? */ 323 case '\011': /* ht */ 324 case '\012': /* nl */ 325 case '\013': /* vt */ 326 case '\014': /* np */ 327 case '\015': /* cr */ 328 qval[l++] = ' '; 329 break; 330 case '"': 331 qval[l++] = '\\'; 332 /* FALLTHROUGH */ 333 default: 334 qval[l++] = fvalue[k]; 335 break; 336 } 337 } 338 qval[l++] = '"'; 339 qval[l] = '\0'; 340 k += strlen(fvalue + k); 341 if (k >= MAXNAME) 342 { 343 if (LogLevel > 9) 344 sm_syslog(LOG_WARNING, e->e_id, 345 "Warning: truncated header '%s' before check with '%s' len=%d max=%d", 346 fname, rs, k, MAXNAME - 1); 347 } 348 macdefine(&e->e_macro, A_TEMP, 349 macid("{currHeader}"), qval); 350 macdefine(&e->e_macro, A_TEMP, 351 macid("{hdr_name}"), fname); 352 353 (void) sm_snprintf(qval, sizeof(qval), "%d", k); 354 macdefine(&e->e_macro, A_TEMP, macid("{hdrlen}"), qval); 355 if (bitset(H_FROM, hi->hi_flags)) 356 macdefine(&e->e_macro, A_PERM, 357 macid("{addr_type}"), "h s"); 358 else if (bitset(H_RCPT, hi->hi_flags)) 359 macdefine(&e->e_macro, A_PERM, 360 macid("{addr_type}"), "h r"); 361 else 362 macdefine(&e->e_macro, A_PERM, 363 macid("{addr_type}"), "h"); 364 (void) rscheck(rs, fvalue, NULL, e, rscheckflags, 3, 365 NULL, e->e_id, NULL); 366 } 367 } 368 369 /* 370 ** Drop explicit From: if same as what we would generate. 371 ** This is to make MH (which doesn't always give a full name) 372 ** insert the full name information in all circumstances. 373 */ 374 375 dropfrom = false; 376 p = "resent-from"; 377 if (!bitset(EF_RESENT, e->e_flags)) 378 p += 7; 379 if (!bitset(pflag, CHHDR_DEF) && !headeronly && 380 !bitset(EF_QUEUERUN, e->e_flags) && sm_strcasecmp(fname, p) == 0) 381 { 382 if (tTd(31, 2)) 383 { 384 sm_dprintf("comparing header from (%s) against default (%s or %s)\n", 385 fvalue, e->e_from.q_paddr, e->e_from.q_user); 386 } 387 if (e->e_from.q_paddr != NULL && 388 e->e_from.q_mailer != NULL && 389 bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags) && 390 (strcmp(fvalue, e->e_from.q_paddr) == 0 || 391 strcmp(fvalue, e->e_from.q_user) == 0)) 392 dropfrom = true; 393 } 394 395 /* delete default value for this header */ 396 for (hp = hdrp; (h = *hp) != NULL; hp = &h->h_link) 397 { 398 if (sm_strcasecmp(fname, h->h_field) == 0 && 399 !bitset(H_USER, h->h_flags) && 400 !bitset(H_FORCE, h->h_flags)) 401 { 402 if (nullheader) 403 { 404 /* user-supplied value was null */ 405 return 0; 406 } 407 if (dropfrom) 408 { 409 /* make this look like the user entered it */ 410 h->h_flags |= H_USER; 411 return hi->hi_flags; 412 } 413 h->h_value = NULL; 414 if (!cond) 415 { 416 /* copy conditions from default case */ 417 memmove((char *) mopts, (char *) h->h_mflags, 418 sizeof(mopts)); 419 } 420 h->h_macro = mid; 421 } 422 } 423 424 /* create a new node */ 425 h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof(*h)); 426 h->h_field = sm_rpool_strdup_x(e->e_rpool, fname); 427 h->h_value = sm_rpool_strdup_x(e->e_rpool, fvalue); 428 h->h_link = NULL; 429 memmove((char *) h->h_mflags, (char *) mopts, sizeof(mopts)); 430 h->h_macro = mid; 431 *hp = h; 432 h->h_flags = hi->hi_flags; 433 if (bitset(pflag, CHHDR_USER) || bitset(pflag, CHHDR_QUEUE)) 434 h->h_flags |= H_USER; 435 436 /* strip EOH flag if parsing MIME headers */ 437 if (headeronly) 438 h->h_flags &= ~H_EOH; 439 if (bitset(pflag, CHHDR_DEF)) 440 h->h_flags |= H_DEFAULT; 441 if (cond || mid != '\0') 442 h->h_flags |= H_CHECK; 443 444 /* hack to see if this is a new format message */ 445 if (!bitset(pflag, CHHDR_DEF) && !headeronly && 446 bitset(H_RCPT|H_FROM, h->h_flags) && 447 (strchr(fvalue, ',') != NULL || strchr(fvalue, '(') != NULL || 448 strchr(fvalue, '<') != NULL || strchr(fvalue, ';') != NULL)) 449 { 450 e->e_flags &= ~EF_OLDSTYLE; 451 } 452 453 return h->h_flags; 454 } 455 456 /* 457 ** CHOMPHEADER -- process and save a header line. 458 ** 459 ** Called by collect, readcf, and readqf to deal with header lines. 460 ** This is just a wrapper for dochompheader(). 461 ** 462 ** Parameters: 463 ** line -- header as a text line. 464 ** pflag -- flags for chompheader() (from sendmail.h) 465 ** hdrp -- a pointer to the place to save the header. 466 ** e -- the envelope including this header. 467 ** 468 ** Returns: 469 ** flags for this header. 470 ** 471 ** Side Effects: 472 ** The header is saved on the header list. 473 ** Contents of 'line' are destroyed. 474 */ 475 476 477 unsigned long 478 chompheader(line, pflag, hdrp, e) 479 char *line; 480 int pflag; 481 HDR **hdrp; 482 register ENVELOPE *e; 483 { 484 unsigned long rval; 485 486 if (tTd(31, 6)) 487 { 488 sm_dprintf("chompheader: "); 489 xputs(sm_debug_file(), line); 490 sm_dprintf("\n"); 491 } 492 493 /* quote this if user (not config file) input */ 494 if (bitset(pflag, CHHDR_USER)) 495 { 496 char xbuf[MAXLINE]; 497 char *xbp = NULL; 498 int xbufs; 499 500 xbufs = sizeof(xbuf); 501 xbp = quote_internal_chars(line, xbuf, &xbufs); 502 if (tTd(31, 7)) 503 { 504 sm_dprintf("chompheader: quoted: "); 505 xputs(sm_debug_file(), xbp); 506 sm_dprintf("\n"); 507 } 508 rval = dochompheader(xbp, pflag, hdrp, e); 509 if (xbp != xbuf) 510 sm_free(xbp); 511 } 512 else 513 rval = dochompheader(line, pflag, hdrp, e); 514 515 return rval; 516 } 517 518 /* 519 ** ALLOCHEADER -- allocate a header entry 520 ** 521 ** Parameters: 522 ** field -- the name of the header field (will not be copied). 523 ** value -- the value of the field (will be copied). 524 ** flags -- flags to add to h_flags. 525 ** rp -- resource pool for allocations 526 ** space -- add leading space? 527 ** 528 ** Returns: 529 ** Pointer to a newly allocated and populated HDR. 530 ** 531 ** Notes: 532 ** o field and value must be in internal format, i.e., 533 ** metacharacters must be "quoted", see quote_internal_chars(). 534 ** o maybe add more flags to decide: 535 ** - what to copy (field/value) 536 ** - whether to convert value to an internal format 537 */ 538 539 static HDR * 540 allocheader(field, value, flags, rp, space) 541 char *field; 542 char *value; 543 int flags; 544 SM_RPOOL_T *rp; 545 bool space; 546 { 547 HDR *h; 548 STAB *s; 549 550 /* find info struct */ 551 s = stab(field, ST_HEADER, ST_FIND); 552 553 /* allocate space for new header */ 554 h = (HDR *) sm_rpool_malloc_x(rp, sizeof(*h)); 555 h->h_field = field; 556 if (space) 557 { 558 size_t l; 559 char *n; 560 561 l = strlen(value); 562 SM_ASSERT(l + 2 > l); 563 n = sm_rpool_malloc_x(rp, l + 2); 564 n[0] = ' '; 565 n[1] = '\0'; 566 sm_strlcpy(n + 1, value, l + 1); 567 h->h_value = n; 568 } 569 else 570 h->h_value = sm_rpool_strdup_x(rp, value); 571 h->h_flags = flags; 572 if (s != NULL) 573 h->h_flags |= s->s_header.hi_flags; 574 clrbitmap(h->h_mflags); 575 h->h_macro = '\0'; 576 577 return h; 578 } 579 580 /* 581 ** ADDHEADER -- add a header entry to the end of the queue. 582 ** 583 ** This bypasses the special checking of chompheader. 584 ** 585 ** Parameters: 586 ** field -- the name of the header field (will not be copied). 587 ** value -- the value of the field (will be copied). 588 ** flags -- flags to add to h_flags. 589 ** e -- envelope. 590 ** space -- add leading space? 591 ** 592 ** Returns: 593 ** none. 594 ** 595 ** Side Effects: 596 ** adds the field on the list of headers for this envelope. 597 ** 598 ** Notes: field and value must be in internal format, i.e., 599 ** metacharacters must be "quoted", see quote_internal_chars(). 600 */ 601 602 void 603 addheader(field, value, flags, e, space) 604 char *field; 605 char *value; 606 int flags; 607 ENVELOPE *e; 608 bool space; 609 { 610 register HDR *h; 611 HDR **hp; 612 HDR **hdrlist = &e->e_header; 613 614 /* find current place in list -- keep back pointer? */ 615 for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link) 616 { 617 if (sm_strcasecmp(field, h->h_field) == 0) 618 break; 619 } 620 621 /* allocate space for new header */ 622 h = allocheader(field, value, flags, e->e_rpool, space); 623 h->h_link = *hp; 624 *hp = h; 625 } 626 627 /* 628 ** INSHEADER -- insert a header entry at the specified index 629 ** This bypasses the special checking of chompheader. 630 ** 631 ** Parameters: 632 ** idx -- index into the header list at which to insert 633 ** field -- the name of the header field (will be copied). 634 ** value -- the value of the field (will be copied). 635 ** flags -- flags to add to h_flags. 636 ** e -- envelope. 637 ** space -- add leading space? 638 ** 639 ** Returns: 640 ** none. 641 ** 642 ** Side Effects: 643 ** inserts the field on the list of headers for this envelope. 644 ** 645 ** Notes: 646 ** - field and value must be in internal format, i.e., 647 ** metacharacters must be "quoted", see quote_internal_chars(). 648 ** - the header list contains headers that might not be 649 ** sent "out" (see putheader(): "skip"), hence there is no 650 ** reliable way to insert a header at an exact position 651 ** (except at the front or end). 652 */ 653 654 void 655 insheader(idx, field, value, flags, e, space) 656 int idx; 657 char *field; 658 char *value; 659 int flags; 660 ENVELOPE *e; 661 bool space; 662 { 663 HDR *h, *srch, *last = NULL; 664 665 /* allocate space for new header */ 666 h = allocheader(field, value, flags, e->e_rpool, space); 667 668 /* find insertion position */ 669 for (srch = e->e_header; srch != NULL && idx > 0; 670 srch = srch->h_link, idx--) 671 last = srch; 672 673 if (e->e_header == NULL) 674 { 675 e->e_header = h; 676 h->h_link = NULL; 677 } 678 else if (srch == NULL) 679 { 680 SM_ASSERT(last != NULL); 681 last->h_link = h; 682 h->h_link = NULL; 683 } 684 else 685 { 686 h->h_link = srch->h_link; 687 srch->h_link = h; 688 } 689 } 690 691 /* 692 ** HVALUE -- return value of a header. 693 ** 694 ** Only "real" fields (i.e., ones that have not been supplied 695 ** as a default) are used. 696 ** 697 ** Parameters: 698 ** field -- the field name. 699 ** header -- the header list. 700 ** 701 ** Returns: 702 ** pointer to the value part (internal format). 703 ** NULL if not found. 704 ** 705 ** Side Effects: 706 ** none. 707 */ 708 709 char * 710 hvalue(field, header) 711 char *field; 712 HDR *header; 713 { 714 register HDR *h; 715 716 for (h = header; h != NULL; h = h->h_link) 717 { 718 if (!bitset(H_DEFAULT, h->h_flags) && 719 sm_strcasecmp(h->h_field, field) == 0) 720 return h->h_value; 721 } 722 return NULL; 723 } 724 725 /* 726 ** ISHEADER -- predicate telling if argument is a header. 727 ** 728 ** A line is a header if it has a single word followed by 729 ** optional white space followed by a colon. 730 ** 731 ** Header fields beginning with two dashes, although technically 732 ** permitted by RFC822, are automatically rejected in order 733 ** to make MIME work out. Without this we could have a technically 734 ** legal header such as ``--"foo:bar"'' that would also be a legal 735 ** MIME separator. 736 ** 737 ** Parameters: 738 ** h -- string to check for possible headerness. 739 ** 740 ** Returns: 741 ** true if h is a header. 742 ** false otherwise. 743 ** 744 ** Side Effects: 745 ** none. 746 */ 747 748 bool 749 isheader(h) 750 char *h; 751 { 752 char *s; 753 754 s = h; 755 if (s[0] == '-' && s[1] == '-') 756 return false; 757 758 while (*s > ' ' && *s != ':' && *s != '\0') 759 s++; 760 761 if (h == s) 762 return false; 763 764 /* following technically violates RFC822 */ 765 while (isascii(*s) && isspace(*s)) 766 s++; 767 768 return (*s == ':'); 769 } 770 771 /* 772 ** EATHEADER -- run through the stored header and extract info. 773 ** 774 ** Parameters: 775 ** e -- the envelope to process. 776 ** full -- if set, do full processing (e.g., compute 777 ** message priority). This should not be set 778 ** when reading a queue file because some info 779 ** needed to compute the priority is wrong. 780 ** log -- call logsender()? 781 ** 782 ** Returns: 783 ** none. 784 ** 785 ** Side Effects: 786 ** Sets a bunch of global variables from information 787 ** in the collected header. 788 */ 789 790 void 791 eatheader(e, full, log) 792 register ENVELOPE *e; 793 bool full; 794 bool log; 795 { 796 register HDR *h; 797 register char *p; 798 int hopcnt = 0; 799 char buf[MAXLINE]; 800 801 /* 802 ** Set up macros for possible expansion in headers. 803 */ 804 805 macdefine(&e->e_macro, A_PERM, 'f', e->e_sender); 806 macdefine(&e->e_macro, A_PERM, 'g', e->e_sender); 807 if (e->e_origrcpt != NULL && *e->e_origrcpt != '\0') 808 macdefine(&e->e_macro, A_PERM, 'u', e->e_origrcpt); 809 else 810 macdefine(&e->e_macro, A_PERM, 'u', NULL); 811 812 /* full name of from person */ 813 p = hvalue("full-name", e->e_header); 814 if (p != NULL) 815 { 816 if (!rfc822_string(p)) 817 { 818 /* 819 ** Quote a full name with special characters 820 ** as a comment so crackaddr() doesn't destroy 821 ** the name portion of the address. 822 */ 823 824 p = addquotes(p, e->e_rpool); 825 } 826 macdefine(&e->e_macro, A_PERM, 'x', p); 827 } 828 829 if (tTd(32, 1)) 830 sm_dprintf("----- collected header -----\n"); 831 e->e_msgid = NULL; 832 for (h = e->e_header; h != NULL; h = h->h_link) 833 { 834 if (tTd(32, 1)) 835 sm_dprintf("%s:", h->h_field); 836 if (h->h_value == NULL) 837 { 838 if (tTd(32, 1)) 839 sm_dprintf("<NULL>\n"); 840 continue; 841 } 842 843 /* do early binding */ 844 if (bitset(H_DEFAULT, h->h_flags) && 845 !bitset(H_BINDLATE, h->h_flags)) 846 { 847 if (tTd(32, 1)) 848 { 849 sm_dprintf("("); 850 xputs(sm_debug_file(), h->h_value); 851 sm_dprintf(") "); 852 } 853 expand(h->h_value, buf, sizeof(buf), e); 854 if (buf[0] != '\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 1087 void 1088 logsender(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 1220 static int 1221 priencode(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 1286 ERROR MAXNAME must be at least 10 1287 #endif /* MAXNAME < 10 */ 1288 1289 char * 1290 crackaddr(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 1658 bool 1659 putheader(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 } 1871 else 1872 { 1873 if (!put_vanilla_header(h, p, mci)) 1874 goto writeerr; 1875 } 1876 } 1877 1878 /* 1879 ** If we are converting this to a MIME message, add the 1880 ** MIME headers (but not in MIME mode!). 1881 */ 1882 1883 #if MIME8TO7 1884 if (bitset(MM_MIME8BIT, MimeMode) && 1885 bitset(EF_HAS8BIT, e->e_flags) && 1886 !bitset(EF_DONT_MIME, e->e_flags) && 1887 !bitnset(M_8BITS, mci->mci_mailer->m_flags) && 1888 !bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME, mci->mci_flags) && 1889 hvalue("MIME-Version", e->e_header) == NULL) 1890 { 1891 if (!putline("MIME-Version: 1.0", mci)) 1892 goto writeerr; 1893 if (hvalue("Content-Type", e->e_header) == NULL) 1894 { 1895 (void) sm_snprintf(obuf, sizeof(obuf), 1896 "Content-Type: text/plain; charset=%s", 1897 defcharset(e)); 1898 if (!putline(obuf, mci)) 1899 goto writeerr; 1900 } 1901 if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL 1902 && !putline("Content-Transfer-Encoding: 8bit", mci)) 1903 goto writeerr; 1904 } 1905 #endif /* MIME8TO7 */ 1906 return true; 1907 1908 writeerr: 1909 return false; 1910 } 1911 1912 /* 1913 ** PUT_VANILLA_HEADER -- output a fairly ordinary header 1914 ** 1915 ** Parameters: 1916 ** h -- the structure describing this header 1917 ** v -- the value of this header 1918 ** mci -- the connection info for output 1919 ** 1920 ** Returns: 1921 ** true iff header was written successfully 1922 */ 1923 1924 static bool 1925 put_vanilla_header(h, v, mci) 1926 HDR *h; 1927 char *v; 1928 MCI *mci; 1929 { 1930 register char *nlp; 1931 register char *obp; 1932 int putflags; 1933 char obuf[MAXLINE + 256]; /* additional length for h_field */ 1934 1935 putflags = PXLF_HEADER | PXLF_STRIPMQUOTE; 1936 if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags)) 1937 putflags |= PXLF_STRIP8BIT; 1938 (void) sm_snprintf(obuf, sizeof(obuf), "%.200s:", h->h_field); 1939 obp = obuf + strlen(obuf); 1940 while ((nlp = strchr(v, '\n')) != NULL) 1941 { 1942 int l; 1943 1944 l = nlp - v; 1945 1946 /* 1947 ** XXX This is broken for SPACELEFT()==0 1948 ** However, SPACELEFT() is always > 0 unless MAXLINE==1. 1949 */ 1950 1951 if (SPACELEFT(obuf, obp) - 1 < (size_t) l) 1952 l = SPACELEFT(obuf, obp) - 1; 1953 1954 (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v); 1955 if (!putxline(obuf, strlen(obuf), mci, putflags)) 1956 goto writeerr; 1957 v += l + 1; 1958 obp = obuf; 1959 if (*v != ' ' && *v != '\t') 1960 *obp++ = ' '; 1961 } 1962 1963 /* XXX This is broken for SPACELEFT()==0 */ 1964 (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", 1965 (int) (SPACELEFT(obuf, obp) - 1), v); 1966 return putxline(obuf, strlen(obuf), mci, putflags); 1967 1968 writeerr: 1969 return false; 1970 } 1971 1972 /* 1973 ** COMMAIZE -- output a header field, making a comma-translated list. 1974 ** 1975 ** Parameters: 1976 ** h -- the header field to output. 1977 ** p -- the value to put in it. 1978 ** oldstyle -- true if this is an old style header. 1979 ** mci -- the connection information. 1980 ** e -- the envelope containing the message. 1981 ** 1982 ** Returns: 1983 ** true iff header field was written successfully 1984 ** 1985 ** Side Effects: 1986 ** outputs "p" to "mci". 1987 */ 1988 1989 bool 1990 commaize(h, p, oldstyle, mci, e) 1991 register HDR *h; 1992 register char *p; 1993 bool oldstyle; 1994 register MCI *mci; 1995 register ENVELOPE *e; 1996 { 1997 register char *obp; 1998 int opos, omax, spaces; 1999 bool firstone = true; 2000 int putflags = PXLF_HEADER | PXLF_STRIPMQUOTE; 2001 char **res; 2002 char obuf[MAXLINE + 3]; 2003 2004 /* 2005 ** Output the address list translated by the 2006 ** mailer and with commas. 2007 */ 2008 2009 if (tTd(14, 2)) 2010 sm_dprintf("commaize(%s:%s)\n", h->h_field, p); 2011 2012 if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags)) 2013 putflags |= PXLF_STRIP8BIT; 2014 2015 obp = obuf; 2016 (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.200s:", h->h_field); 2017 /* opos = strlen(obp); instead of the next 3 lines? */ 2018 opos = strlen(h->h_field) + 1; 2019 if (opos > 201) 2020 opos = 201; 2021 obp += opos; 2022 2023 spaces = 0; 2024 while (*p != '\0' && isascii(*p) && isspace(*p)) 2025 { 2026 ++spaces; 2027 ++p; 2028 } 2029 if (spaces > 0) 2030 { 2031 SM_ASSERT(sizeof(obuf) > opos * 2); 2032 2033 /* 2034 ** Restrict number of spaces to half the length of buffer 2035 ** so the header field body can be put in here too. 2036 ** Note: this is a hack... 2037 */ 2038 2039 if (spaces > sizeof(obuf) / 2) 2040 spaces = sizeof(obuf) / 2; 2041 (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%*s", spaces, 2042 ""); 2043 opos += spaces; 2044 obp += spaces; 2045 SM_ASSERT(obp < &obuf[MAXLINE]); 2046 } 2047 2048 omax = mci->mci_mailer->m_linelimit - 2; 2049 if (omax < 0 || omax > 78) 2050 omax = 78; 2051 2052 /* 2053 ** Run through the list of values. 2054 */ 2055 2056 while (*p != '\0') 2057 { 2058 register char *name; 2059 register int c; 2060 char savechar; 2061 int flags; 2062 auto int status; 2063 2064 /* 2065 ** Find the end of the name. New style names 2066 ** end with a comma, old style names end with 2067 ** a space character. However, spaces do not 2068 ** necessarily delimit an old-style name -- at 2069 ** signs mean keep going. 2070 */ 2071 2072 /* find end of name */ 2073 while ((isascii(*p) && isspace(*p)) || *p == ',') 2074 p++; 2075 name = p; 2076 res = NULL; 2077 for (;;) 2078 { 2079 auto char *oldp; 2080 char pvpbuf[PSBUFSIZE]; 2081 2082 res = prescan(p, oldstyle ? ' ' : ',', pvpbuf, 2083 sizeof(pvpbuf), &oldp, ExtTokenTab, false); 2084 p = oldp; 2085 #if _FFR_IGNORE_BOGUS_ADDR 2086 /* ignore addresses that can't be parsed */ 2087 if (res == NULL) 2088 { 2089 name = p; 2090 continue; 2091 } 2092 #endif /* _FFR_IGNORE_BOGUS_ADDR */ 2093 2094 /* look to see if we have an at sign */ 2095 while (*p != '\0' && isascii(*p) && isspace(*p)) 2096 p++; 2097 2098 if (*p != '@') 2099 { 2100 p = oldp; 2101 break; 2102 } 2103 ++p; 2104 while (*p != '\0' && isascii(*p) && isspace(*p)) 2105 p++; 2106 } 2107 /* at the end of one complete name */ 2108 2109 /* strip off trailing white space */ 2110 while (p >= name && 2111 ((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0')) 2112 p--; 2113 if (++p == name) 2114 continue; 2115 2116 /* 2117 ** if prescan() failed go a bit backwards; this is a hack, 2118 ** there should be some better error recovery. 2119 */ 2120 2121 if (res == NULL && p > name && 2122 !((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0')) 2123 --p; 2124 savechar = *p; 2125 *p = '\0'; 2126 2127 /* translate the name to be relative */ 2128 flags = RF_HEADERADDR|RF_ADDDOMAIN; 2129 if (bitset(H_FROM, h->h_flags)) 2130 flags |= RF_SENDERADDR; 2131 #if USERDB 2132 else if (e->e_from.q_mailer != NULL && 2133 bitnset(M_UDBRECIPIENT, e->e_from.q_mailer->m_flags)) 2134 { 2135 char *q; 2136 2137 q = udbsender(name, e->e_rpool); 2138 if (q != NULL) 2139 name = q; 2140 } 2141 #endif /* USERDB */ 2142 status = EX_OK; 2143 name = remotename(name, mci->mci_mailer, flags, &status, e); 2144 if (*name == '\0') 2145 { 2146 *p = savechar; 2147 continue; 2148 } 2149 name = denlstring(name, false, true); 2150 2151 /* output the name with nice formatting */ 2152 opos += strlen(name); 2153 if (!firstone) 2154 opos += 2; 2155 if (opos > omax && !firstone) 2156 { 2157 (void) sm_strlcpy(obp, ",\n", SPACELEFT(obuf, obp)); 2158 if (!putxline(obuf, strlen(obuf), mci, putflags)) 2159 goto writeerr; 2160 obp = obuf; 2161 (void) sm_strlcpy(obp, " ", sizeof(obuf)); 2162 opos = strlen(obp); 2163 obp += opos; 2164 opos += strlen(name); 2165 } 2166 else if (!firstone) 2167 { 2168 (void) sm_strlcpy(obp, ", ", SPACELEFT(obuf, obp)); 2169 obp += 2; 2170 } 2171 2172 while ((c = *name++) != '\0' && obp < &obuf[MAXLINE]) 2173 *obp++ = c; 2174 firstone = false; 2175 *p = savechar; 2176 } 2177 if (obp < &obuf[sizeof(obuf)]) 2178 *obp = '\0'; 2179 else 2180 obuf[sizeof(obuf) - 1] = '\0'; 2181 return putxline(obuf, strlen(obuf), mci, putflags); 2182 2183 writeerr: 2184 return false; 2185 } 2186 2187 /* 2188 ** COPYHEADER -- copy header list 2189 ** 2190 ** This routine is the equivalent of newstr for header lists 2191 ** 2192 ** Parameters: 2193 ** header -- list of header structures to copy. 2194 ** rpool -- resource pool, or NULL 2195 ** 2196 ** Returns: 2197 ** a copy of 'header'. 2198 ** 2199 ** Side Effects: 2200 ** none. 2201 */ 2202 2203 HDR * 2204 copyheader(header, rpool) 2205 register HDR *header; 2206 SM_RPOOL_T *rpool; 2207 { 2208 register HDR *newhdr; 2209 HDR *ret; 2210 register HDR **tail = &ret; 2211 2212 while (header != NULL) 2213 { 2214 newhdr = (HDR *) sm_rpool_malloc_x(rpool, sizeof(*newhdr)); 2215 STRUCTCOPY(*header, *newhdr); 2216 *tail = newhdr; 2217 tail = &newhdr->h_link; 2218 header = header->h_link; 2219 } 2220 *tail = NULL; 2221 2222 return ret; 2223 } 2224 2225 /* 2226 ** FIX_MIME_HEADER -- possibly truncate/rebalance parameters in a MIME header 2227 ** 2228 ** Run through all of the parameters of a MIME header and 2229 ** possibly truncate and rebalance the parameter according 2230 ** to MaxMimeFieldLength. 2231 ** 2232 ** Parameters: 2233 ** h -- the header to truncate/rebalance 2234 ** e -- the current envelope 2235 ** 2236 ** Returns: 2237 ** length of last offending field, 0 if all ok. 2238 ** 2239 ** Side Effects: 2240 ** string modified in place 2241 */ 2242 2243 static size_t 2244 fix_mime_header(h, e) 2245 HDR *h; 2246 ENVELOPE *e; 2247 { 2248 char *begin = h->h_value; 2249 char *end; 2250 size_t len = 0; 2251 size_t retlen = 0; 2252 2253 if (begin == NULL || *begin == '\0') 2254 return 0; 2255 2256 /* Split on each ';' */ 2257 /* find_character() never returns NULL */ 2258 while ((end = find_character(begin, ';')) != NULL) 2259 { 2260 char save = *end; 2261 char *bp; 2262 2263 *end = '\0'; 2264 2265 len = strlen(begin); 2266 2267 /* Shorten individual parameter */ 2268 if (shorten_rfc822_string(begin, MaxMimeFieldLength)) 2269 { 2270 if (len < MaxMimeFieldLength) 2271 { 2272 /* we only rebalanced a bogus field */ 2273 sm_syslog(LOG_ALERT, e->e_id, 2274 "Fixed MIME %s header field (possible attack)", 2275 h->h_field); 2276 if (tTd(34, 11)) 2277 sm_dprintf(" fixed MIME %s header field (possible attack)\n", 2278 h->h_field); 2279 } 2280 else 2281 { 2282 /* we actually shortened the header */ 2283 retlen = len; 2284 } 2285 } 2286 2287 /* Collapse the possibly shortened string with rest */ 2288 bp = begin + strlen(begin); 2289 if (bp != end) 2290 { 2291 char *ep = end; 2292 2293 *end = save; 2294 end = bp; 2295 2296 /* copy character by character due to overlap */ 2297 while (*ep != '\0') 2298 *bp++ = *ep++; 2299 *bp = '\0'; 2300 } 2301 else 2302 *end = save; 2303 if (*end == '\0') 2304 break; 2305 2306 /* Move past ';' */ 2307 begin = end + 1; 2308 } 2309 return retlen; 2310 } 2311