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