Apply patch from sendmail.org to handle a new header overflow bug.
This commit is contained in:
parent
fedc587dac
commit
382b4984f3
210
gnu/dist/sendmail/sendmail/headers.c
vendored
210
gnu/dist/sendmail/sendmail/headers.c
vendored
@ -648,7 +648,8 @@ eatheader(e, full)
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
if (bitset(H_FROM, h->h_flags))
|
||||
expand(crackaddr(buf), buf, sizeof buf, e);
|
||||
expand(crackaddr(buf, e),
|
||||
buf, sizeof buf, e);
|
||||
h->h_value = newstr(buf);
|
||||
h->h_flags &= ~H_DEFAULT;
|
||||
}
|
||||
@ -971,7 +972,11 @@ priencode(p)
|
||||
** it and replaces it with "$g". The parse is totally ad hoc
|
||||
** and isn't even guaranteed to leave something syntactically
|
||||
** identical to what it started with. However, it does leave
|
||||
** something semantically identical.
|
||||
** something semantically identical if possible, else at least
|
||||
** syntactically correct.
|
||||
**
|
||||
** For example, it changes "Real Name <real@example.com> (Comment)"
|
||||
** to "Real Name <$g> (Comment)".
|
||||
**
|
||||
** This algorithm has been cleaned up to handle a wider range
|
||||
** of cases -- notably quoted and backslash escaped strings.
|
||||
@ -980,6 +985,7 @@ priencode(p)
|
||||
**
|
||||
** Parameters:
|
||||
** addr -- the address to be cracked.
|
||||
** e -- the current envelope.
|
||||
**
|
||||
** Returns:
|
||||
** a pointer to the new version.
|
||||
@ -992,28 +998,50 @@ priencode(p)
|
||||
** be copied if it is to be reused.
|
||||
*/
|
||||
|
||||
#define SM_HAVE_ROOM ((bp < buflim) && (buflim <= bufend))
|
||||
|
||||
/*
|
||||
** Append a character to bp if we have room.
|
||||
** If not, punt and return $g.
|
||||
*/
|
||||
|
||||
#define SM_APPEND_CHAR(c) \
|
||||
do \
|
||||
{ \
|
||||
if (SM_HAVE_ROOM) \
|
||||
*bp++ = (c); \
|
||||
else \
|
||||
goto returng; \
|
||||
} while (0)
|
||||
|
||||
#if MAXNAME < 10
|
||||
ERROR MAXNAME must be at least 10
|
||||
#endif /* MAXNAME < 10 */
|
||||
|
||||
char *
|
||||
crackaddr(addr)
|
||||
crackaddr(addr, e)
|
||||
register char *addr;
|
||||
ENVELOPE *e;
|
||||
{
|
||||
register char *p;
|
||||
register char c;
|
||||
int cmtlev;
|
||||
int realcmtlev;
|
||||
int anglelev, realanglelev;
|
||||
int copylev;
|
||||
int bracklev;
|
||||
bool qmode;
|
||||
bool realqmode;
|
||||
bool skipping;
|
||||
bool putgmac = FALSE;
|
||||
bool quoteit = FALSE;
|
||||
bool gotangle = FALSE;
|
||||
bool gotcolon = FALSE;
|
||||
int cmtlev; /* comment level in input string */
|
||||
int realcmtlev; /* comment level in output string */
|
||||
int anglelev; /* angle level in input string */
|
||||
int copylev; /* 0 == in address, >0 copying */
|
||||
int bracklev; /* bracket level for IPv6 addr check */
|
||||
bool addangle; /* put closing angle in output */
|
||||
bool qmode; /* quoting in original string? */
|
||||
bool realqmode; /* quoting in output string? */
|
||||
bool putgmac = FALSE; /* already wrote $g */
|
||||
bool quoteit = FALSE; /* need to quote next character */
|
||||
bool gotangle = FALSE; /* found first '<' */
|
||||
bool gotcolon = FALSE; /* found a ':' */
|
||||
register char *bp;
|
||||
char *buflim;
|
||||
char *bufhead;
|
||||
char *addrhead;
|
||||
char *bufend;
|
||||
static char buf[MAXNAME + 1];
|
||||
|
||||
if (tTd(33, 1))
|
||||
@ -1028,25 +1056,22 @@ crackaddr(addr)
|
||||
** adjusted later if we find them.
|
||||
*/
|
||||
|
||||
buflim = bufend = &buf[sizeof(buf) - 1];
|
||||
bp = bufhead = buf;
|
||||
buflim = &buf[sizeof buf - 7];
|
||||
p = addrhead = addr;
|
||||
copylev = anglelev = realanglelev = cmtlev = realcmtlev = 0;
|
||||
copylev = anglelev = cmtlev = realcmtlev = 0;
|
||||
bracklev = 0;
|
||||
qmode = realqmode = FALSE;
|
||||
qmode = realqmode = addangle = FALSE;
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
/*
|
||||
** If the buffer is overful, go into a special "skipping"
|
||||
** mode that tries to keep legal syntax but doesn't actually
|
||||
** output things.
|
||||
** Try to keep legal syntax using spare buffer space
|
||||
** (maintained by buflim).
|
||||
*/
|
||||
|
||||
skipping = bp >= buflim;
|
||||
|
||||
if (copylev > 0 && !skipping)
|
||||
*bp++ = c;
|
||||
if (copylev > 0)
|
||||
SM_APPEND_CHAR(c);
|
||||
|
||||
/* check for backslash escapes */
|
||||
if (c == '\\')
|
||||
@ -1061,8 +1086,8 @@ crackaddr(addr)
|
||||
p--;
|
||||
goto putg;
|
||||
}
|
||||
if (copylev > 0 && !skipping)
|
||||
*bp++ = c;
|
||||
if (copylev > 0)
|
||||
SM_APPEND_CHAR(c);
|
||||
goto putg;
|
||||
}
|
||||
|
||||
@ -1070,8 +1095,14 @@ crackaddr(addr)
|
||||
if (c == '"' && cmtlev <= 0)
|
||||
{
|
||||
qmode = !qmode;
|
||||
if (copylev > 0 && !skipping)
|
||||
if (copylev > 0 && SM_HAVE_ROOM)
|
||||
{
|
||||
if (realqmode)
|
||||
buflim--;
|
||||
else
|
||||
buflim++;
|
||||
realqmode = !realqmode;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (qmode)
|
||||
@ -1083,15 +1114,15 @@ crackaddr(addr)
|
||||
cmtlev++;
|
||||
|
||||
/* allow space for closing paren */
|
||||
if (!skipping)
|
||||
if (SM_HAVE_ROOM)
|
||||
{
|
||||
buflim--;
|
||||
realcmtlev++;
|
||||
if (copylev++ <= 0)
|
||||
{
|
||||
if (bp != bufhead)
|
||||
*bp++ = ' ';
|
||||
*bp++ = c;
|
||||
SM_APPEND_CHAR(' ');
|
||||
SM_APPEND_CHAR(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1101,7 +1132,7 @@ crackaddr(addr)
|
||||
{
|
||||
cmtlev--;
|
||||
copylev--;
|
||||
if (!skipping)
|
||||
if (SM_HAVE_ROOM)
|
||||
{
|
||||
realcmtlev--;
|
||||
buflim++;
|
||||
@ -1112,7 +1143,7 @@ crackaddr(addr)
|
||||
else if (c == ')')
|
||||
{
|
||||
/* syntax error: unmatched ) */
|
||||
if (copylev > 0 && !skipping)
|
||||
if (copylev > 0 && SM_HAVE_ROOM)
|
||||
bp--;
|
||||
}
|
||||
|
||||
@ -1130,7 +1161,7 @@ crackaddr(addr)
|
||||
|
||||
/*
|
||||
** Check for DECnet phase IV ``::'' (host::user)
|
||||
** or ** DECnet phase V ``:.'' syntaxes. The latter
|
||||
** or DECnet phase V ``:.'' syntaxes. The latter
|
||||
** covers ``user@DEC:.tay.myhost'' and
|
||||
** ``DEC:.tay.myhost::user'' syntaxes (bletch).
|
||||
*/
|
||||
@ -1139,10 +1170,10 @@ crackaddr(addr)
|
||||
{
|
||||
if (cmtlev <= 0 && !qmode)
|
||||
quoteit = TRUE;
|
||||
if (copylev > 0 && !skipping)
|
||||
if (copylev > 0)
|
||||
{
|
||||
*bp++ = c;
|
||||
*bp++ = *p;
|
||||
SM_APPEND_CHAR(c);
|
||||
SM_APPEND_CHAR(*p);
|
||||
}
|
||||
p++;
|
||||
goto putg;
|
||||
@ -1153,41 +1184,43 @@ crackaddr(addr)
|
||||
bp = bufhead;
|
||||
if (quoteit)
|
||||
{
|
||||
*bp++ = '"';
|
||||
SM_APPEND_CHAR('"');
|
||||
|
||||
/* back up over the ':' and any spaces */
|
||||
--p;
|
||||
while (isascii(*--p) && isspace(*p))
|
||||
while (p > addr &&
|
||||
isascii(*--p) && isspace(*p))
|
||||
continue;
|
||||
p++;
|
||||
}
|
||||
for (q = addrhead; q < p; )
|
||||
{
|
||||
c = *q++;
|
||||
if (bp < buflim)
|
||||
{
|
||||
if (quoteit && c == '"')
|
||||
*bp++ = '\\';
|
||||
*bp++ = c;
|
||||
{
|
||||
SM_APPEND_CHAR('\\');
|
||||
SM_APPEND_CHAR(c);
|
||||
}
|
||||
else
|
||||
SM_APPEND_CHAR(c);
|
||||
}
|
||||
if (quoteit)
|
||||
{
|
||||
if (bp == &bufhead[1])
|
||||
bp--;
|
||||
else
|
||||
*bp++ = '"';
|
||||
SM_APPEND_CHAR('"');
|
||||
while ((c = *p++) != ':')
|
||||
{
|
||||
if (bp < buflim)
|
||||
*bp++ = c;
|
||||
}
|
||||
*bp++ = c;
|
||||
SM_APPEND_CHAR(c);
|
||||
SM_APPEND_CHAR(c);
|
||||
}
|
||||
|
||||
/* any trailing white space is part of group: */
|
||||
while (isascii(*p) && isspace(*p) && bp < buflim)
|
||||
*bp++ = *p++;
|
||||
while (isascii(*p) && isspace(*p))
|
||||
{
|
||||
SM_APPEND_CHAR(*p);
|
||||
p++;
|
||||
}
|
||||
copylev = 0;
|
||||
putgmac = quoteit = FALSE;
|
||||
bufhead = bp;
|
||||
@ -1196,10 +1229,7 @@ crackaddr(addr)
|
||||
}
|
||||
|
||||
if (c == ';' && copylev <= 0 && !ColonOkInAddr)
|
||||
{
|
||||
if (bp < buflim)
|
||||
*bp++ = c;
|
||||
}
|
||||
SM_APPEND_CHAR(c);
|
||||
|
||||
/* check for characters that may have to be quoted */
|
||||
if (strchr(MustQuoteChars, c) != NULL)
|
||||
@ -1227,42 +1257,45 @@ crackaddr(addr)
|
||||
|
||||
/* oops -- have to change our mind */
|
||||
anglelev = 1;
|
||||
if (!skipping)
|
||||
realanglelev = 1;
|
||||
if (SM_HAVE_ROOM)
|
||||
{
|
||||
if (!addangle)
|
||||
buflim--;
|
||||
addangle = TRUE;
|
||||
}
|
||||
|
||||
bp = bufhead;
|
||||
if (quoteit)
|
||||
{
|
||||
*bp++ = '"';
|
||||
SM_APPEND_CHAR('"');
|
||||
|
||||
/* back up over the '<' and any spaces */
|
||||
--p;
|
||||
while (isascii(*--p) && isspace(*p))
|
||||
while (p > addr &&
|
||||
isascii(*--p) && isspace(*p))
|
||||
continue;
|
||||
p++;
|
||||
}
|
||||
for (q = addrhead; q < p; )
|
||||
{
|
||||
c = *q++;
|
||||
if (bp < buflim)
|
||||
{
|
||||
if (quoteit && c == '"')
|
||||
*bp++ = '\\';
|
||||
*bp++ = c;
|
||||
{
|
||||
SM_APPEND_CHAR('\\');
|
||||
SM_APPEND_CHAR(c);
|
||||
}
|
||||
else
|
||||
SM_APPEND_CHAR(c);
|
||||
}
|
||||
if (quoteit)
|
||||
{
|
||||
if (bp == &buf[1])
|
||||
bp--;
|
||||
else
|
||||
*bp++ = '"';
|
||||
SM_APPEND_CHAR('"');
|
||||
while ((c = *p++) != '<')
|
||||
{
|
||||
if (bp < buflim)
|
||||
*bp++ = c;
|
||||
}
|
||||
*bp++ = c;
|
||||
SM_APPEND_CHAR(c);
|
||||
SM_APPEND_CHAR(c);
|
||||
}
|
||||
copylev = 0;
|
||||
putgmac = quoteit = FALSE;
|
||||
@ -1274,13 +1307,14 @@ crackaddr(addr)
|
||||
if (anglelev > 0)
|
||||
{
|
||||
anglelev--;
|
||||
if (!skipping)
|
||||
if (SM_HAVE_ROOM)
|
||||
{
|
||||
realanglelev--;
|
||||
if (addangle)
|
||||
buflim++;
|
||||
addangle = FALSE;
|
||||
}
|
||||
}
|
||||
else if (!skipping)
|
||||
else if (SM_HAVE_ROOM)
|
||||
{
|
||||
/* syntax error: unmatched > */
|
||||
if (copylev > 0)
|
||||
@ -1289,7 +1323,7 @@ crackaddr(addr)
|
||||
continue;
|
||||
}
|
||||
if (copylev++ <= 0)
|
||||
*bp++ = c;
|
||||
SM_APPEND_CHAR(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1297,30 +1331,42 @@ crackaddr(addr)
|
||||
putg:
|
||||
if (copylev <= 0 && !putgmac)
|
||||
{
|
||||
if (bp > bufhead && bp[-1] == ')')
|
||||
*bp++ = ' ';
|
||||
*bp++ = MACROEXPAND;
|
||||
*bp++ = 'g';
|
||||
if (bp > buf && bp[-1] == ')')
|
||||
SM_APPEND_CHAR(' ');
|
||||
SM_APPEND_CHAR(MACROEXPAND);
|
||||
SM_APPEND_CHAR('g');
|
||||
putgmac = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* repair any syntactic damage */
|
||||
if (realqmode)
|
||||
if (realqmode && bp < bufend)
|
||||
*bp++ = '"';
|
||||
while (realcmtlev-- > 0)
|
||||
while (realcmtlev-- > 0 && bp < bufend)
|
||||
*bp++ = ')';
|
||||
while (realanglelev-- > 0)
|
||||
if (addangle && bp < bufend)
|
||||
*bp++ = '>';
|
||||
*bp++ = '\0';
|
||||
*bp = '\0';
|
||||
if (bp < bufend)
|
||||
goto success;
|
||||
|
||||
returng:
|
||||
/* String too long, punt */
|
||||
buf[0] = '<';
|
||||
buf[1] = MACROEXPAND;
|
||||
buf[2]= 'g';
|
||||
buf[3] = '>';
|
||||
buf[4]= '\0';
|
||||
sm_syslog(LOG_ALERT, e->e_id,
|
||||
"Dropped invalid comments from header address");
|
||||
|
||||
success:
|
||||
if (tTd(33, 1))
|
||||
{
|
||||
dprintf("crackaddr=>`");
|
||||
xputs(buf);
|
||||
dprintf("'\n");
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
/*
|
||||
|
2
gnu/dist/sendmail/sendmail/main.c
vendored
2
gnu/dist/sendmail/sendmail/main.c
vendored
@ -3300,7 +3300,7 @@ testmodeline(line, e)
|
||||
printf("Usage: /parse address\n");
|
||||
return;
|
||||
}
|
||||
q = crackaddr(p);
|
||||
q = crackaddr(p, e);
|
||||
printf("Cracked address = ");
|
||||
xputs(q);
|
||||
printf("\nParsing %s %s address\n",
|
||||
|
2
gnu/dist/sendmail/sendmail/parseaddr.c
vendored
2
gnu/dist/sendmail/sendmail/parseaddr.c
vendored
@ -2286,7 +2286,7 @@ remotename(name, m, flags, pstat, e)
|
||||
if (bitset(RF_CANONICAL, flags) || bitnset(M_NOCOMMENT, m->m_flags))
|
||||
fancy = "\201g";
|
||||
else
|
||||
fancy = crackaddr(name);
|
||||
fancy = crackaddr(name, e);
|
||||
|
||||
/*
|
||||
** Turn the name into canonical form.
|
||||
|
2
gnu/dist/sendmail/sendmail/sendmail.h
vendored
2
gnu/dist/sendmail/sendmail/sendmail.h
vendored
@ -270,7 +270,7 @@ extern ADDRESS NullAddress; /* a null (template) address [main.c] */
|
||||
|
||||
/* functions */
|
||||
extern void cataddr __P((char **, char **, char *, int, int));
|
||||
extern char *crackaddr __P((char *));
|
||||
extern char *crackaddr __P((char *, ENVELOPE *));
|
||||
extern bool emptyaddr __P((ADDRESS *));
|
||||
extern ADDRESS *getctladdr __P((ADDRESS *));
|
||||
extern int include __P((char *, bool, ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
|
Loading…
x
Reference in New Issue
Block a user