diff options
Diffstat (limited to 'contrib/sendmail/src/headers.c')
-rw-r--r-- | contrib/sendmail/src/headers.c | 289 |
1 files changed, 79 insertions, 210 deletions
diff --git a/contrib/sendmail/src/headers.c b/contrib/sendmail/src/headers.c index bb78d22..383a053 100644 --- a/contrib/sendmail/src/headers.c +++ b/contrib/sendmail/src/headers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2004, 2006, 2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004, 2006 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -9,14 +9,14 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * + * $FreeBSD$ */ #include <sendmail.h> -#include <sm/sendmail.h> -SM_RCSID("@(#)$Id: headers.c,v 8.310 2007/02/07 22:44:35 ca Exp $") +SM_RCSID("@(#)$Id: headers.c,v 8.291 2006/03/24 01:01:56 ca Exp $") -static HDR *allocheader __P((char *, char *, int, SM_RPOOL_T *, bool)); +static HDR *allocheader __P((char *, char *, int, SM_RPOOL_T *)); static size_t fix_mime_header __P((HDR *, ENVELOPE *)); static int priencode __P((char *)); static bool put_vanilla_header __P((HDR *, char *, MCI *)); @@ -44,11 +44,10 @@ setupheaders() s->s_header.hi_ruleset = NULL; } } - /* -** DOCHOMPHEADER -- process and save a header line. +** CHOMPHEADER -- process and save a header line. ** -** Called by chompheader. +** Called by collect, readcf, and readqf to deal with header lines. ** ** Parameters: ** line -- header as a text line. @@ -65,14 +64,13 @@ setupheaders() */ static struct hdrinfo NormalHeader = { NULL, 0, NULL }; -static unsigned long dochompheader __P((char *, int, HDR **, ENVELOPE *)); -static unsigned long -dochompheader(line, pflag, hdrp, e) +unsigned long +chompheader(line, pflag, hdrp, e) char *line; int pflag; HDR **hdrp; - ENVELOPE *e; + register ENVELOPE *e; { unsigned char mid = '\0'; register char *p; @@ -88,6 +86,13 @@ dochompheader(line, pflag, hdrp, e) bool nullheader = false; BITMAP256 mopts; + if (tTd(31, 6)) + { + sm_dprintf("chompheader: "); + xputs(sm_debug_file(), line); + sm_dprintf("\n"); + } + headeronly = hdrp != NULL; if (!headeronly) hdrp = &e->e_header; @@ -183,6 +188,10 @@ hse: return 0; } *fvalue = '\0'; + + /* strip field value on front */ + if (*p == ' ') + p++; fvalue = p; /* if the field is null, go ahead and use the default */ @@ -200,7 +209,7 @@ hse: { char hbuf[50]; - (void) expand(fvalue, hbuf, sizeof(hbuf), e); + (void) expand(fvalue, hbuf, sizeof hbuf, e); for (p = hbuf; isascii(*p) && isspace(*p); ) p++; if ((*p++ & 0377) == CALLSUBR) @@ -348,8 +357,9 @@ hse: macdefine(&e->e_macro, A_TEMP, macid("{hdr_name}"), fname); - (void) sm_snprintf(qval, sizeof(qval), "%d", k); + (void) sm_snprintf(qval, sizeof qval, "%d", k); macdefine(&e->e_macro, A_TEMP, macid("{hdrlen}"), qval); +#if _FFR_HDR_TYPE if (bitset(H_FROM, hi->hi_flags)) macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "h s"); @@ -357,10 +367,11 @@ hse: macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "h r"); else +#endif /* _FFR_HDR_TYPE */ macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "h"); (void) rscheck(rs, fvalue, NULL, e, rscheckflags, 3, - NULL, e->e_id, NULL); + NULL, e->e_id); } } @@ -413,18 +424,18 @@ hse: { /* copy conditions from default case */ memmove((char *) mopts, (char *) h->h_mflags, - sizeof(mopts)); + sizeof mopts); } h->h_macro = mid; } } /* create a new node */ - h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof(*h)); + h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof *h); h->h_field = sm_rpool_strdup_x(e->e_rpool, fname); h->h_value = sm_rpool_strdup_x(e->e_rpool, fvalue); h->h_link = NULL; - memmove((char *) h->h_mflags, (char *) mopts, sizeof(mopts)); + memmove((char *) h->h_mflags, (char *) mopts, sizeof mopts); h->h_macro = mid; *hp = h; h->h_flags = hi->hi_flags; @@ -450,97 +461,25 @@ hse: return h->h_flags; } - -/* -** CHOMPHEADER -- process and save a header line. -** -** Called by collect, readcf, and readqf to deal with header lines. -** This is just a wrapper for dochompheader(). -** -** Parameters: -** line -- header as a text line. -** pflag -- flags for chompheader() (from sendmail.h) -** hdrp -- a pointer to the place to save the header. -** e -- the envelope including this header. -** -** Returns: -** flags for this header. -** -** Side Effects: -** The header is saved on the header list. -** Contents of 'line' are destroyed. -*/ - - -unsigned long -chompheader(line, pflag, hdrp, e) - char *line; - int pflag; - HDR **hdrp; - register ENVELOPE *e; -{ - unsigned long rval; - - if (tTd(31, 6)) - { - sm_dprintf("chompheader: "); - xputs(sm_debug_file(), line); - sm_dprintf("\n"); - } - - /* quote this if user (not config file) input */ - if (bitset(pflag, CHHDR_USER)) - { - char xbuf[MAXLINE]; - char *xbp = NULL; - int xbufs; - - xbufs = sizeof(xbuf); - xbp = quote_internal_chars(line, xbuf, &xbufs); - if (tTd(31, 7)) - { - sm_dprintf("chompheader: quoted: "); - xputs(sm_debug_file(), xbp); - sm_dprintf("\n"); - } - rval = dochompheader(xbp, pflag, hdrp, e); - if (xbp != xbuf) - sm_free(xbp); - } - else - rval = dochompheader(line, pflag, hdrp, e); - - return rval; -} - /* ** ALLOCHEADER -- allocate a header entry ** ** Parameters: -** field -- the name of the header field (will not be copied). -** value -- the value of the field (will be copied). +** field -- the name of the header field. +** value -- the value of the field. ** flags -- flags to add to h_flags. ** rp -- resource pool for allocations -** space -- add leading space? ** ** Returns: ** Pointer to a newly allocated and populated HDR. -** -** Notes: -** o field and value must be in internal format, i.e., -** metacharacters must be "quoted", see quote_internal_chars(). -** o maybe add more flags to decide: -** - what to copy (field/value) -** - whether to convert value to an internal format */ static HDR * -allocheader(field, value, flags, rp, space) +allocheader(field, value, flags, rp) char *field; char *value; int flags; SM_RPOOL_T *rp; - bool space; { HDR *h; STAB *s; @@ -549,23 +488,9 @@ allocheader(field, value, flags, rp, space) s = stab(field, ST_HEADER, ST_FIND); /* allocate space for new header */ - h = (HDR *) sm_rpool_malloc_x(rp, sizeof(*h)); + h = (HDR *) sm_rpool_malloc_x(rp, sizeof *h); h->h_field = field; - if (space) - { - size_t l; - char *n; - - l = strlen(value); - SM_ASSERT(l + 2 > l); - n = sm_rpool_malloc_x(rp, l + 2); - n[0] = ' '; - n[1] = '\0'; - sm_strlcpy(n + 1, value, l + 1); - h->h_value = n; - } - else - h->h_value = sm_rpool_strdup_x(rp, value); + h->h_value = sm_rpool_strdup_x(rp, value); h->h_flags = flags; if (s != NULL) h->h_flags |= s->s_header.hi_flags; @@ -574,36 +499,30 @@ allocheader(field, value, flags, rp, space) return h; } - /* ** ADDHEADER -- add a header entry to the end of the queue. ** ** This bypasses the special checking of chompheader. ** ** Parameters: -** field -- the name of the header field (will not be copied). -** value -- the value of the field (will be copied). +** field -- the name of the header field. +** value -- the value of the field. ** flags -- flags to add to h_flags. ** e -- envelope. -** space -- add leading space? ** ** Returns: ** none. ** ** Side Effects: ** adds the field on the list of headers for this envelope. -** -** Notes: field and value must be in internal format, i.e., -** metacharacters must be "quoted", see quote_internal_chars(). */ void -addheader(field, value, flags, e, space) +addheader(field, value, flags, e) char *field; char *value; int flags; ENVELOPE *e; - bool space; { register HDR *h; HDR **hp; @@ -617,51 +536,41 @@ addheader(field, value, flags, e, space) } /* allocate space for new header */ - h = allocheader(field, value, flags, e->e_rpool, space); + h = allocheader(field, value, flags, e->e_rpool); h->h_link = *hp; *hp = h; } - /* ** INSHEADER -- insert a header entry at the specified index +** ** This bypasses the special checking of chompheader. ** ** Parameters: ** idx -- index into the header list at which to insert -** field -- the name of the header field (will be copied). -** value -- the value of the field (will be copied). +** field -- the name of the header field. +** value -- the value of the field. ** flags -- flags to add to h_flags. ** e -- envelope. -** space -- add leading space? ** ** Returns: ** none. ** ** Side Effects: ** inserts the field on the list of headers for this envelope. -** -** Notes: -** - field and value must be in internal format, i.e., -** metacharacters must be "quoted", see quote_internal_chars(). -** - the header list contains headers that might not be -** sent "out" (see putheader(): "skip"), hence there is no -** reliable way to insert a header at an exact position -** (except at the front or end). */ void -insheader(idx, field, value, flags, e, space) +insheader(idx, field, value, flags, e) int idx; char *field; char *value; int flags; ENVELOPE *e; - bool space; { HDR *h, *srch, *last = NULL; /* allocate space for new header */ - h = allocheader(field, value, flags, e->e_rpool, space); + h = allocheader(field, value, flags, e->e_rpool); /* find insertion position */ for (srch = e->e_header; srch != NULL && idx > 0; @@ -685,7 +594,6 @@ insheader(idx, field, value, flags, e, space) srch->h_link = h; } } - /* ** HVALUE -- return value of a header. ** @@ -697,7 +605,7 @@ insheader(idx, field, value, flags, e, space) ** header -- the header list. ** ** Returns: -** pointer to the value part (internal format). +** pointer to the value part. ** NULL if not found. ** ** Side Effects: @@ -719,7 +627,6 @@ hvalue(field, header) } return NULL; } - /* ** ISHEADER -- predicate telling if argument is a header. ** @@ -747,9 +654,8 @@ bool isheader(h) char *h; { - char *s; + register char *s = h; - s = h; if (s[0] == '-' && s[1] == '-') return false; @@ -765,7 +671,6 @@ isheader(h) return (*s == ':'); } - /* ** EATHEADER -- run through the stored header and extract info. ** @@ -830,7 +735,7 @@ eatheader(e, full, log) for (h = e->e_header; h != NULL; h = h->h_link) { if (tTd(32, 1)) - sm_dprintf("%s:", h->h_field); + sm_dprintf("%s: ", h->h_field); if (h->h_value == NULL) { if (tTd(32, 1)) @@ -848,13 +753,12 @@ eatheader(e, full, log) xputs(sm_debug_file(), h->h_value); sm_dprintf(") "); } - expand(h->h_value, buf, sizeof(buf), e); - if (buf[0] != '\0' && - (buf[0] != ' ' || buf[1] != '\0')) + expand(h->h_value, buf, sizeof buf, e); + if (buf[0] != '\0') { if (bitset(H_FROM, h->h_flags)) expand(crackaddr(buf, e), - buf, sizeof(buf), e); + buf, sizeof buf, e); h->h_value = sm_rpool_strdup_x(e->e_rpool, buf); h->h_flags &= ~H_DEFAULT; } @@ -918,7 +822,7 @@ eatheader(e, full, log) if (hopcnt > e->e_hopcount) { e->e_hopcount = hopcnt; - (void) sm_snprintf(buf, sizeof(buf), "%d", e->e_hopcount); + (void) sm_snprintf(buf, sizeof buf, "%d", e->e_hopcount); macdefine(&e->e_macro, A_TEMP, 'c', buf); } @@ -949,7 +853,7 @@ eatheader(e, full, log) /* tokenize header */ oldsupr = SuprErrs; SuprErrs = true; - pvp = prescan(p, '\0', pvpbuf, sizeof(pvpbuf), NULL, + pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL, MimeTokenTab, false); SuprErrs = oldsupr; @@ -1071,7 +975,6 @@ eatheader(e, full, log) e->e_flags &= ~EF_LOGSENDER; } } - /* ** LOGSENDER -- log sender information ** @@ -1102,8 +1005,8 @@ logsender(e, msgid) size_t l; l = strlen(msgid); - if (l > sizeof(mbuf) - 1) - l = sizeof(mbuf) - 1; + if (l > sizeof mbuf - 1) + l = sizeof mbuf - 1; memmove(mbuf, msgid, l); mbuf[l] = '\0'; p = mbuf; @@ -1123,7 +1026,7 @@ logsender(e, msgid) else { name = hbuf; - (void) sm_snprintf(hbuf, sizeof(hbuf), "%.80s", RealHostName); + (void) sm_snprintf(hbuf, sizeof hbuf, "%.80s", RealHostName); if (RealHostAddr.sa.sa_family != 0) { p = &hbuf[strlen(hbuf)]; @@ -1202,7 +1105,6 @@ logsender(e, msgid) "%.400srelay=%s", sbuf, name); #endif /* (SYSLOG_BUFSIZE) >= 256 */ } - /* ** PRIENCODE -- encode external priority names into internal values. ** @@ -1231,7 +1133,6 @@ priencode(p) /* unknown priority */ return 0; } - /* ** CRACKADDR -- parse an address and turn it into a macro ** @@ -1314,22 +1215,17 @@ crackaddr(addr, e) if (tTd(33, 1)) sm_dprintf("crackaddr(%s)\n", addr); - buflim = bufend = &buf[sizeof(buf) - 1]; - bp = bufhead = buf; - - /* skip over leading spaces but preserve them */ + /* strip leading spaces */ while (*addr != '\0' && isascii(*addr) && isspace(*addr)) - { - SM_APPEND_CHAR(*addr); addr++; - } - bufhead = bp; /* ** Start by assuming we have no angle brackets. This will be ** adjusted later if we find them. */ + buflim = bufend = &buf[sizeof(buf) - 1]; + bp = bufhead = buf; p = addrhead = addr; copylev = anglelev = cmtlev = realcmtlev = 0; bracklev = 0; @@ -1637,7 +1533,6 @@ crackaddr(addr, e) } return buf; } - /* ** PUTHEADER -- put the header part of a message from the in-core copy ** @@ -1685,7 +1580,7 @@ putheader(mci, hdr, e, flags) if (tTd(34, 11)) { - sm_dprintf(" %s:", h->h_field); + sm_dprintf(" %s: ", h->h_field); xputs(sm_debug_file(), p); } @@ -1826,7 +1721,7 @@ putheader(mci, hdr, e, flags) if (bitset(H_DEFAULT, h->h_flags) || bitset(H_BINDLATE, h->h_flags)) { - expand(p, buf, sizeof(buf), e); + expand(p, buf, sizeof buf, e); p = buf; if (*p == '\0') { @@ -1847,7 +1742,7 @@ putheader(mci, hdr, e, flags) else { /* no other recipient headers: truncate value */ - (void) sm_strlcpyn(obuf, sizeof(obuf), 2, + (void) sm_strlcpyn(obuf, sizeof obuf, 2, h->h_field, ":"); if (!putline(obuf, mci)) goto writeerr; @@ -1891,7 +1786,7 @@ putheader(mci, hdr, e, flags) goto writeerr; if (hvalue("Content-Type", e->e_header) == NULL) { - (void) sm_snprintf(obuf, sizeof(obuf), + (void) sm_snprintf(obuf, sizeof obuf, "Content-Type: text/plain; charset=%s", defcharset(e)); if (!putline(obuf, mci)) @@ -1907,7 +1802,6 @@ putheader(mci, hdr, e, flags) writeerr: return false; } - /* ** PUT_VANILLA_HEADER -- output a fairly ordinary header ** @@ -1931,10 +1825,10 @@ put_vanilla_header(h, v, mci) int putflags; char obuf[MAXLINE + 256]; /* additional length for h_field */ - putflags = PXLF_HEADER | PXLF_STRIPMQUOTE; + putflags = PXLF_HEADER; if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags)) putflags |= PXLF_STRIP8BIT; - (void) sm_snprintf(obuf, sizeof(obuf), "%.200s:", h->h_field); + (void) sm_snprintf(obuf, sizeof obuf, "%.200s: ", h->h_field); obp = obuf + strlen(obuf); while ((nlp = strchr(v, '\n')) != NULL) { @@ -1967,7 +1861,6 @@ put_vanilla_header(h, v, mci) writeerr: return false; } - /* ** COMMAIZE -- output a header field, making a comma-translated list. ** @@ -1982,7 +1875,7 @@ put_vanilla_header(h, v, mci) ** true iff header field was written successfully ** ** Side Effects: -** outputs "p" to "mci". +** outputs "p" to file "fp". */ bool @@ -1994,9 +1887,10 @@ commaize(h, p, oldstyle, mci, e) register ENVELOPE *e; { register char *obp; - int opos, omax, spaces; + int opos; + int omax; bool firstone = true; - int putflags = PXLF_HEADER | PXLF_STRIPMQUOTE; + int putflags = PXLF_HEADER; char **res; char obuf[MAXLINE + 3]; @@ -2006,44 +1900,20 @@ commaize(h, p, oldstyle, mci, e) */ if (tTd(14, 2)) - sm_dprintf("commaize(%s:%s)\n", h->h_field, p); + sm_dprintf("commaize(%s: %s)\n", h->h_field, p); if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags)) putflags |= PXLF_STRIP8BIT; obp = obuf; - (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.200s:", h->h_field); - /* opos = strlen(obp); instead of the next 3 lines? */ - opos = strlen(h->h_field) + 1; - if (opos > 201) - opos = 201; - obp += opos; - - spaces = 0; - while (*p != '\0' && isascii(*p) && isspace(*p)) - { - ++spaces; - ++p; - } - if (spaces > 0) - { - SM_ASSERT(sizeof(obuf) > opos * 2); - - /* - ** Restrict number of spaces to half the length of buffer - ** so the header field body can be put in here too. - ** Note: this is a hack... - */ - - if (spaces > sizeof(obuf) / 2) - spaces = sizeof(obuf) / 2; - (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%*s", spaces, - ""); - opos += spaces; - obp += spaces; - SM_ASSERT(obp < &obuf[MAXLINE]); - } + (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.200s: ", + h->h_field); + /* opos = strlen(obp); */ + opos = strlen(h->h_field) + 2; + if (opos > 202) + opos = 202; + obp += opos; omax = mci->mci_mailer->m_linelimit - 2; if (omax < 0 || omax > 78) omax = 78; @@ -2079,7 +1949,7 @@ commaize(h, p, oldstyle, mci, e) char pvpbuf[PSBUFSIZE]; res = prescan(p, oldstyle ? ' ' : ',', pvpbuf, - sizeof(pvpbuf), &oldp, ExtTokenTab, false); + sizeof pvpbuf, &oldp, NULL, false); p = oldp; #if _FFR_IGNORE_BOGUS_ADDR /* ignore addresses that can't be parsed */ @@ -2157,7 +2027,7 @@ commaize(h, p, oldstyle, mci, e) if (!putxline(obuf, strlen(obuf), mci, putflags)) goto writeerr; obp = obuf; - (void) sm_strlcpy(obp, " ", sizeof(obuf)); + (void) sm_strlcpy(obp, " ", sizeof obuf); opos = strlen(obp); obp += opos; opos += strlen(name); @@ -2173,10 +2043,10 @@ commaize(h, p, oldstyle, mci, e) firstone = false; *p = savechar; } - if (obp < &obuf[sizeof(obuf)]) + if (obp < &obuf[sizeof obuf]) *obp = '\0'; else - obuf[sizeof(obuf) - 1] = '\0'; + obuf[sizeof obuf - 1] = '\0'; return putxline(obuf, strlen(obuf), mci, putflags); writeerr: @@ -2210,7 +2080,7 @@ copyheader(header, rpool) while (header != NULL) { - newhdr = (HDR *) sm_rpool_malloc_x(rpool, sizeof(*newhdr)); + newhdr = (HDR *) sm_rpool_malloc_x(rpool, sizeof *newhdr); STRUCTCOPY(*header, *newhdr); *tail = newhdr; tail = &newhdr->h_link; @@ -2220,7 +2090,6 @@ copyheader(header, rpool) return ret; } - /* ** FIX_MIME_HEADER -- possibly truncate/rebalance parameters in a MIME header ** |