X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/ad7871609881e73855d0b04da49b486cd93efca7..ed554bc5e4201344d7eaad78263566e79428759c:/usr/src/usr.sbin/sendmail/src/headers.c diff --git a/usr/src/usr.sbin/sendmail/src/headers.c b/usr/src/usr.sbin/sendmail/src/headers.c index 387b7fb796..8493e79cf7 100644 --- a/usr/src/usr.sbin/sendmail/src/headers.c +++ b/usr/src/usr.sbin/sendmail/src/headers.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)headers.c 8.1 (Berkeley) 6/7/93"; +static char sccsid[] = "@(#)headers.c 8.32 (Berkeley) 4/14/94"; #endif /* not lint */ # include @@ -70,6 +70,7 @@ chompheader(line, def, e) struct hdrinfo *hi; bool cond = FALSE; BITMAP mopts; + char buf[MAXNAME]; if (tTd(31, 6)) printf("chompheader: %s\n", line); @@ -96,16 +97,18 @@ chompheader(line, def, e) /* find canonical name */ fname = p; - p = strchr(p, ':'); - if (p == NULL) + while (isascii(*p) && isgraph(*p) && *p != ':') + p++; + fvalue = p; + while (isascii(*p) && isspace(*p)) + p++; + if (*p++ != ':' || fname == fvalue) { syserr("553 header syntax error, line \"%s\"", line); return (0); } - fvalue = &p[1]; - while (isascii(*--p) && isspace(*p)) - continue; - *++p = '\0'; + *fvalue = '\0'; + fvalue = p; /* strip field value on front */ if (*fvalue == ' ') @@ -118,6 +121,14 @@ chompheader(line, def, e) break; } + if (tTd(31, 9)) + { + if (hi->hi_field == NULL) + printf("no header match\n"); + else + printf("header match, hi_flags=%o\n", hi->hi_flags); + } + /* see if this is a resent message */ if (!def && bitset(H_RESENT, hi->hi_flags)) e->e_flags |= EF_RESENT; @@ -126,15 +137,66 @@ chompheader(line, def, e) if (bitset(H_EOH, hi->hi_flags)) return (hi->hi_flags); - /* drop explicit From: if same as what we would generate -- for MH */ + /* + ** Drop explicit From: if same as what we would generate. + ** This is to make MH (which doesn't always give a full name) + ** insert the full name information in all circumstances. + */ + p = "resent-from"; if (!bitset(EF_RESENT, e->e_flags)) p += 7; if (!def && !bitset(EF_QUEUERUN, e->e_flags) && strcasecmp(fname, p) == 0) { + if (tTd(31, 2)) + { + printf("comparing header from (%s) against default (%s or %s)\n", + fvalue, e->e_from.q_paddr, e->e_from.q_user); + } if (e->e_from.q_paddr != NULL && - strcmp(fvalue, e->e_from.q_paddr) == 0) + (strcmp(fvalue, e->e_from.q_paddr) == 0 || + strcmp(fvalue, e->e_from.q_user) == 0)) return (hi->hi_flags); +#ifdef MAYBENEXTRELEASE /* XXX UNTESTED XXX UNTESTED XXX UNTESTED XXX */ +#ifdef USERDB + else + { + auto ADDRESS a; + char *fancy; + bool oldSuprErrs = SuprErrs; + extern char *crackaddr(); + extern char *udbsender(); + + /* + ** Try doing USERDB rewriting even on fully commented + ** names; this saves the "comment" information (such + ** as full name) and rewrites the electronic part. + ** + ** XXX This code doesn't belong here -- parsing should + ** XXX not be done during collect() phase because + ** XXX error messages can confuse the SMTP phase. + ** XXX Setting SuprErrs is a crude hack around this + ** XXX problem. + */ + + if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP) + SuprErrs = TRUE; + fancy = crackaddr(fvalue); + if (parseaddr(fvalue, &a, RF_COPYNONE, '\0', NULL, e) != NULL && + a.q_mailer == LocalMailer && + (p = udbsender(a.q_user)) != NULL) + { + char *oldg = macvalue('g', e); + + define('g', p, e); + expand(fancy, buf, &buf[sizeof buf], e); + define('g', oldg, e); + fvalue = buf; + } + SuprErrs = oldSuprErrs; + } +#endif +#endif } /* delete default value for this header */ @@ -149,7 +211,7 @@ chompheader(line, def, e) /* create a new node */ h = (HDR *) xalloc(sizeof *h); h->h_field = newstr(fname); - h->h_value = NULL; + h->h_value = newstr(fvalue); h->h_link = NULL; bcopy((char *) mopts, (char *) h->h_mflags, sizeof mopts); *hp = h; @@ -158,9 +220,6 @@ chompheader(line, def, e) h->h_flags |= H_DEFAULT; if (cond) h->h_flags |= H_CHECK; - if (h->h_value != NULL) - free((char *) h->h_value); - h->h_value = newstr(fvalue); /* hack to see if this is a new format message */ if (!def && bitset(H_RCPT|H_FROM, h->h_flags) && @@ -317,14 +376,30 @@ eatheader(e, full) define('f', e->e_sender, e); define('g', e->e_sender, e); + if (e->e_origrcpt != NULL && *e->e_origrcpt != '\0') + define('u', e->e_origrcpt, e); + else + define('u', NULL, e); + + /* full name of from person */ + p = hvalue("full-name", e); + if (p != NULL) + define('x', p, e); if (tTd(32, 1)) printf("----- collected header -----\n"); msgid = ""; for (h = e->e_header; h != NULL; h = h->h_link) { + if (h->h_value == NULL) + { + if (tTd(32, 1)) + printf("%s: \n", h->h_field); + continue; + } + /* do early binding */ - if (bitset(H_DEFAULT, h->h_flags) && h->h_value != NULL) + if (bitset(H_DEFAULT, h->h_flags)) { expand(h->h_value, buf, &buf[sizeof buf], e); if (buf[0] != '\0') @@ -335,7 +410,11 @@ eatheader(e, full) } if (tTd(32, 1)) - printf("%s: %s\n", h->h_field, h->h_value); + { + printf("%s: ", h->h_field); + xputs(h->h_value); + printf("\n"); + } /* count the number of times it has been processed */ if (bitset(H_TRACE, h->h_flags)) @@ -346,13 +425,18 @@ eatheader(e, full) !bitset(H_DEFAULT, h->h_flags) && (!bitset(EF_RESENT, e->e_flags) || bitset(H_RESENT, h->h_flags))) { - (void) sendtolist(h->h_value, (ADDRESS *) NULL, + int saveflags = e->e_flags; + + (void) sendtolist(h->h_value, NULLADDR, &e->e_sendqueue, e); + + /* delete fatal errors generated by this address */ + if (!GrabTo && !bitset(EF_FATALERRS, saveflags)) + e->e_flags &= ~EF_FATALERRS; } /* save the message-id for logging */ - if (full && h->h_value != NULL && - strcasecmp(h->h_field, "message-id") == 0) + if (full && strcasecmp(h->h_field, "message-id") == 0) { msgid = h->h_value; while (isascii(*msgid) && isspace(*msgid)) @@ -365,7 +449,7 @@ eatheader(e, full) /* see if this is an errors-to header */ if (UseErrorsTo && bitset(H_ERRORSTO, h->h_flags)) - (void) sendtolist(h->h_value, (ADDRESS *) NULL, + (void) sendtolist(h->h_value, NULLADDR, &e->e_errorqueue, e); } if (tTd(32, 1)) @@ -388,11 +472,6 @@ eatheader(e, full) - e->e_class * WkClassFact + e->e_nrcpts * WkRecipFact; - /* full name of from person */ - p = hvalue("full-name", e); - if (p != NULL) - define('x', p, e); - /* date message originated */ p = hvalue("posted-date", e); if (p == NULL) @@ -400,54 +479,133 @@ eatheader(e, full) if (p != NULL) define('a', p, e); + /* + ** From person in antiquated ARPANET mode + ** required by UK Grey Book e-mail gateways (sigh) + */ + + if (OpMode == MD_ARPAFTP) + { + register struct hdrinfo *hi; + + for (hi = HdrInfo; hi->hi_field != NULL; hi++) + { + if (bitset(H_FROM, hi->hi_flags) && + (!bitset(H_RESENT, hi->hi_flags) || + bitset(EF_RESENT, e->e_flags)) && + (p = hvalue(hi->hi_field, e)) != NULL) + break; + } + if (hi->hi_field != NULL) + { + if (tTd(32, 2)) + printf("eatheader: setsender(*%s == %s)\n", + hi->hi_field, p); + setsender(p, e, NULL, TRUE); + } + } + /* ** Log collection information. */ # ifdef LOG if (full && LogLevel > 4) + logsender(e, msgid); +# endif /* LOG */ + e->e_flags &= ~EF_LOGSENDER; +} + /* +** LOGSENDER -- log sender information +** +** Parameters: +** e -- the envelope to log +** msgid -- the message id +** +** Returns: +** none +*/ + +logsender(e, msgid) + register ENVELOPE *e; + char *msgid; +{ +# ifdef LOG + char *name; + register char *sbp; + register char *p; + char hbuf[MAXNAME]; + char sbuf[MAXLINE]; + + if (bitset(EF_RESPONSE, e->e_flags)) + name = "[RESPONSE]"; + else if ((name = macvalue('_', e)) != NULL) + ; + else if (RealHostName == NULL) + name = "localhost"; + else if (RealHostName[0] == '[') + name = RealHostName; + else { - char *name; - register char *sbp; - char hbuf[MAXNAME]; - char sbuf[MAXLINE]; - - if (bitset(EF_RESPONSE, e->e_flags)) - name = "[RESPONSE]"; - else if ((name = macvalue('_', e)) != NULL) - ; - else if (RealHostName[0] == '[') - name = RealHostName; - else + name = hbuf; + (void) sprintf(hbuf, "%.80s", RealHostName); + if (RealHostAddr.sa.sa_family != 0) { - name = hbuf; - (void) sprintf(hbuf, "%.80s", RealHostName); - if (RealHostAddr.sa.sa_family != 0) - { - p = &hbuf[strlen(hbuf)]; - (void) sprintf(p, " (%s)", - anynet_ntoa(&RealHostAddr)); - } + p = &hbuf[strlen(hbuf)]; + (void) sprintf(p, " (%s)", + anynet_ntoa(&RealHostAddr)); } + } - /* some versions of syslog only take 5 printf args */ - sbp = sbuf; - sprintf(sbp, "from=%.200s, size=%ld, class=%d, pri=%ld, nrcpts=%d, msgid=%.100s", - e->e_from.q_paddr, e->e_msgsize, e->e_class, - e->e_msgpriority, e->e_nrcpts, msgid); + /* some versions of syslog only take 5 printf args */ +# if (SYSLOG_BUFSIZE) >= 256 + sbp = sbuf; + sprintf(sbp, "from=%.200s, size=%ld, class=%d, pri=%ld, nrcpts=%d", + e->e_from.q_paddr, e->e_msgsize, e->e_class, + e->e_msgpriority, e->e_nrcpts); + sbp += strlen(sbp); + if (msgid != NULL) + { + sprintf(sbp, ", msgid=%.100s", msgid); sbp += strlen(sbp); - if (e->e_bodytype != NULL) - { - (void) sprintf(sbp, ", bodytype=%.20s", e->e_bodytype); - sbp += strlen(sbp); - } - p = macvalue('r', e); - if (p != NULL) - (void) sprintf(sbp, ", proto=%.20s", p); - syslog(LOG_INFO, "%s: %s, relay=%s", - e->e_id, sbuf, name); } -# endif /* LOG */ + if (e->e_bodytype != NULL) + { + (void) sprintf(sbp, ", bodytype=%.20s", e->e_bodytype); + sbp += strlen(sbp); + } + p = macvalue('r', e); + if (p != NULL) + (void) sprintf(sbp, ", proto=%.20s", p); + syslog(LOG_INFO, "%s: %s, relay=%s", + e->e_id, sbuf, name); + +# else /* short syslog buffer */ + + syslog(LOG_INFO, "%s: from=%s", + e->e_id, shortenstring(e->e_from.q_paddr, 83)); + syslog(LOG_INFO, "%s: size=%ld, class=%ld, pri=%ld, nrcpts=%d", + e->e_id, e->e_msgsize, e->e_class, + e->e_msgpriority, e->e_nrcpts); + if (msgid != NULL) + syslog(LOG_INFO, "%s: msgid=%s", e->e_id, msgid); + sbp = sbuf; + sprintf(sbp, "%s:", e->e_id); + sbp += strlen(sbp); + if (e->e_bodytype != NULL) + { + sprintf(sbp, " bodytype=%s,", e->e_bodytype); + sbp += strlen(sbp); + } + p = macvalue('r', e); + if (p != NULL) + { + sprintf(sbp, " proto=%s,", p); + sbp += strlen(sbp); + } + syslog(LOG_INFO, "%s relay=%s", sbuf, name); +# endif +# endif } /* ** PRIENCODE -- encode external priority names into internal values. @@ -519,6 +677,7 @@ crackaddr(addr) bool skipping; bool putgmac = FALSE; bool quoteit = FALSE; + bool gotangle = FALSE; register char *bp; char *buflim; static char buf[MAXNAME]; @@ -573,7 +732,7 @@ crackaddr(addr) } /* check for quoted strings */ - if (c == '"') + if (c == '"' && cmtlev <= 0) { qmode = !qmode; if (copylev > 0 && !skipping) @@ -617,13 +776,12 @@ crackaddr(addr) else if (c == ')') { /* syntax error: unmatched ) */ - if (!skipping) + if (copylev > 0 && !skipping) bp--; } - /* check for characters that may have to be quoted */ - if (strchr(".'@,;:\\()", c) != NULL) + if (strchr(".'@,;:\\()[]", c) != NULL) { /* ** If these occur as the phrase part of a <> @@ -641,10 +799,15 @@ crackaddr(addr) { register char *q; + /* assume first of two angles is bogus */ + if (gotangle) + quoteit = TRUE; + gotangle = TRUE; + /* oops -- have to change our mind */ - anglelev++; + anglelev = 1; if (!skipping) - realanglelev++; + realanglelev = 1; bp = buf; if (quoteit) @@ -669,7 +832,10 @@ crackaddr(addr) } if (quoteit) { - *bp++ = '"'; + if (bp == &buf[1]) + bp--; + else + *bp++ = '"'; while ((c = *p++) != '<') { if (bp < buflim) @@ -698,6 +864,7 @@ crackaddr(addr) /* syntax error: unmatched > */ if (copylev > 0) bp--; + quoteit = TRUE; continue; } if (copylev++ <= 0) @@ -733,8 +900,7 @@ crackaddr(addr) ** PUTHEADER -- put the header part of a message from the in-core copy ** ** Parameters: -** fp -- file to put it on. -** m -- mailer to use. +** mci -- the connection information. ** e -- envelope to use. ** ** Returns: @@ -751,9 +917,8 @@ crackaddr(addr) # define MAX(a,b) (((a)>(b))?(a):(b)) #endif -putheader(fp, m, e) - register FILE *fp; - register MAILER *m; +putheader(mci, e) + register MCI *mci; register ENVELOPE *e; { char buf[MAX(MAXLINE,BUFSIZ)]; @@ -761,7 +926,8 @@ putheader(fp, m, e) char obuf[MAXLINE]; if (tTd(34, 1)) - printf("--- putheader, mailer = %s ---\n", m->m_name); + printf("--- putheader, mailer = %s ---\n", + mci->mci_mailer->m_name); for (h = e->e_header; h != NULL; h = h->h_link) { @@ -775,7 +941,7 @@ putheader(fp, m, e) } if (bitset(H_CHECK|H_ACHECK, h->h_flags) && - !bitintersect(h->h_mflags, m->m_flags)) + !bitintersect(h->h_mflags, mci->mci_mailer->m_flags)) { if (tTd(34, 11)) printf(" (skipped)\n"); @@ -789,19 +955,33 @@ putheader(fp, m, e) printf(" (skipped (resent))\n"); continue; } - if (tTd(34, 11)) - printf("\n"); + /* suppress return receipts if requested */ + if (bitset(H_RECEIPTTO, h->h_flags) && + bitset(EF_NORECEIPT, e->e_flags)) + { + if (tTd(34, 11)) + printf(" (skipped (receipt))\n"); + continue; + } + + /* macro expand value if generated internally */ p = h->h_value; if (bitset(H_DEFAULT, h->h_flags)) { - /* macro expand value if generated internally */ expand(p, buf, &buf[sizeof buf], e); p = buf; if (p == NULL || *p == '\0') + { + if (tTd(34, 11)) + printf(" (skipped -- null value)\n"); continue; + } } + if (tTd(34, 11)) + printf("\n"); + if (bitset(H_FROM|H_RCPT, h->h_flags)) { /* address field */ @@ -809,7 +989,7 @@ putheader(fp, m, e) if (bitset(H_FROM, h->h_flags)) oldstyle = FALSE; - commaize(h, p, fp, oldstyle, m, e); + commaize(h, p, oldstyle, mci, e); } else { @@ -822,12 +1002,12 @@ putheader(fp, m, e) *nlp = '\0'; (void) strcat(obuf, p); *nlp = '\n'; - putline(obuf, fp, m); + putline(obuf, mci); p = ++nlp; obuf[0] = '\0'; } (void) strcat(obuf, p); - putline(obuf, fp, m); + putline(obuf, mci); } } } @@ -837,10 +1017,8 @@ putheader(fp, m, e) ** Parameters: ** h -- the header field to output. ** p -- the value to put in it. -** fp -- file to put it to. ** oldstyle -- TRUE if this is an old style header. -** m -- a pointer to the mailer descriptor. If NULL, -** don't transform the name at all. +** mci -- the connection information. ** e -- the envelope containing the message. ** ** Returns: @@ -850,16 +1028,17 @@ putheader(fp, m, e) ** outputs "p" to file "fp". */ -commaize(h, p, fp, oldstyle, m, e) +void +commaize(h, p, oldstyle, mci, e) register HDR *h; register char *p; - FILE *fp; bool oldstyle; - register MAILER *m; + register MCI *mci; register ENVELOPE *e; { register char *obp; int opos; + int omax; bool firstone = TRUE; char obuf[MAXLINE + 3]; @@ -875,6 +1054,9 @@ commaize(h, p, fp, oldstyle, m, e) (void) sprintf(obp, "%s: ", h->h_field); opos = strlen(h->h_field) + 2; obp += opos; + omax = mci->mci_mailer->m_linelimit - 2; + if (omax < 0 || omax > 78) + omax = 78; /* ** Run through the list of values. @@ -905,7 +1087,8 @@ commaize(h, p, fp, oldstyle, m, e) auto char *oldp; char pvpbuf[PSBUFSIZE]; - (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf, &oldp); + (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf, + sizeof pvpbuf, &oldp); p = oldp; /* look to see if we have an at sign */ @@ -937,7 +1120,7 @@ commaize(h, p, fp, oldstyle, m, e) if (bitset(H_FROM, h->h_flags)) flags |= RF_SENDERADDR; stat = EX_OK; - name = remotename(name, m, flags, &stat, e); + name = remotename(name, mci->mci_mailer, flags, &stat, e); if (*name == '\0') { *p = savechar; @@ -948,19 +1131,19 @@ commaize(h, p, fp, oldstyle, m, e) opos += strlen(name); if (!firstone) opos += 2; - if (opos > 78 && !firstone) + if (opos > omax && !firstone) { (void) strcpy(obp, ",\n"); - putline(obuf, fp, m); + putline(obuf, mci); obp = obuf; - (void) sprintf(obp, " "); + (void) strcpy(obp, " "); opos = strlen(obp); obp += opos; opos += strlen(name); } else if (!firstone) { - (void) sprintf(obp, ", "); + (void) strcpy(obp, ", "); obp += 2; } @@ -970,7 +1153,7 @@ commaize(h, p, fp, oldstyle, m, e) *p = savechar; } (void) strcpy(obp, "\n"); - putline(obuf, fp, m); + putline(obuf, mci); } /* ** COPYHEADER -- copy header list