Merge conflicts (see also previous commit).

Reinsert our local changes to ntp_control.c:

1.4:    Do not log every potential exploit attempt since a denial-of-service
        may result
1.5:    int -> unsigned char fixes
This commit is contained in:
Ollivier Robert 2004-07-20 15:18:31 +00:00
parent 9ab5ee2e96
commit 4a0fa52fa0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132455

View File

@ -23,10 +23,6 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef PUBKEY
#include "ntp_crypto.h"
#endif /* PUBKEY */
/*
* Structure to hold request procedure information
*/
@ -51,7 +47,9 @@ struct ctl_proc {
* Request processing routines
*/
static void ctl_error P((int));
#ifdef REFCLOCK
static u_short ctlclkstatus P((struct refclockstat *));
#endif
static void ctl_flushpkt P((int));
static void ctl_putdata P((const char *, unsigned int, int));
static void ctl_putstr P((const char *, const char *,
@ -61,7 +59,7 @@ static void ctl_putuint P((const char *, u_long));
static void ctl_puthex P((const char *, u_long));
static void ctl_putint P((const char *, long));
static void ctl_putts P((const char *, l_fp *));
static void ctl_putadr P((const char *, u_int32));
static void ctl_putadr P((const char *, u_int32, struct sockaddr_storage*));
static void ctl_putid P((const char *, char *));
static void ctl_putarray P((const char *, double *, int));
static void ctl_putsys P((int));
@ -79,7 +77,7 @@ static void read_clock_status P((struct recvbuf *, int));
static void write_clock_status P((struct recvbuf *, int));
static void set_trap P((struct recvbuf *, int));
static void unset_trap P((struct recvbuf *, int));
static struct ctl_trap *ctlfindtrap P((struct sockaddr_in *,
static struct ctl_trap *ctlfindtrap P((struct sockaddr_storage *,
struct interface *));
static struct ctl_proc control_codes[] = {
@ -119,16 +117,16 @@ static struct ctl_var sys_var[] = {
{ CS_VERSION, RO, "version" }, /* 17 */
{ CS_STABIL, RO, "stability" }, /* 18 */
{ CS_VARLIST, RO, "sys_var_list" }, /* 19 */
#ifdef PUBKEY
#ifdef OPENSSL
{ CS_FLAGS, RO, "flags" }, /* 20 */
{ CS_HOST, RO, "hostname" }, /* 21 */
{ CS_PUBLIC, RO, "publickey" }, /* 22 */
{ CS_CERTIF, RO, "certificate" }, /* 23 */
{ CS_DHPARAMS, RO, "params" }, /* 24 */
{ CS_REVTIME, RO, "refresh" }, /* 25 */
{ CS_LEAPTAB, RO, "leapseconds" }, /* 26 */
{ CS_TAI, RO, "tai"}, /* 27 */
#endif /* PUBKEY */
{ CS_PUBLIC, RO, "hostkey" }, /* 22 */
{ CS_CERTIF, RO, "cert" }, /* 23 */
{ CS_REVTIME, RO, "refresh" }, /* 24 */
{ CS_LEAPTAB, RO, "leapseconds" }, /* 25 */
{ CS_TAI, RO, "tai" }, /* 26 */
{ CS_DIGEST, RO, "signature" }, /* 27 */
#endif /* OPENSSL */
{ 0, EOV, "" } /* 28 */
};
@ -157,14 +155,15 @@ static u_char def_sys_var[] = {
CS_DRIFT,
CS_JITTER,
CS_STABIL,
#ifdef PUBKEY
CS_FLAGS,
#ifdef OPENSSL
CS_HOST,
CS_CERTIF,
CS_DHPARAMS,
CS_DIGEST,
CS_FLAGS,
CS_PUBLIC,
CS_REVTIME,
CS_LEAPTAB,
#endif /* PUBKEY */
CS_CERTIF,
#endif /* OPENSSL */
0
};
@ -210,20 +209,18 @@ static struct ctl_var peer_var[] = {
{ CP_FILTERROR, RO, "filtdisp=" }, /* 34 */
{ CP_FLASH, RO, "flash" }, /* 35 */
{ CP_TTL, RO, "ttl" }, /* 36 */
{ CP_TTLMAX, RO, "ttlmax" }, /* 37 */
{ CP_RANK, RO, "rank" }, /* 37 */
{ CP_VARLIST, RO, "peer_var_list" }, /* 38 */
#ifdef PUBKEY
{ CP_FLAGS, RO, "flags" }, /* 38 */
{ CP_HOST, RO, "hostname" }, /* 39 */
{ CP_PUBLIC, RO, "publickey" }, /* 40 */
{ CP_CERTIF, RO, "certificate" }, /* 41 */
{ CP_SESKEY, RO, "pcookie" }, /* 42 */
{ CP_SASKEY, RO, "hcookie" }, /* 43 */
{ CP_INITSEQ, RO, "initsequence" }, /* 44 */
{ CP_INITKEY, RO, "initkey" }, /* 45 */
{ CP_INITTSP, RO, "timestamp" }, /* 46 */
#endif /* PUBKEY */
{ 0, EOV, "" } /* 47 */
#ifdef OPENSSL
{ CP_FLAGS, RO, "flags" }, /* 39 */
{ CP_HOST, RO, "hostname" }, /* 40 */
{ CP_INITSEQ, RO, "initsequence" }, /* 41 */
{ CP_INITKEY, RO, "initkey" }, /* 42 */
{ CP_INITTSP, RO, "timestamp" }, /* 43 */
{ CP_DIGEST, RO, "signature" }, /* 44 */
{ CP_IDENT, RO, "identity" }, /* 45 */
#endif /* OPENSSL */
{ 0, EOV, "" } /* 39/46 */
};
@ -250,7 +247,6 @@ static u_char def_peer_var[] = {
CP_FLASH,
CP_KEYID,
CP_TTL,
CP_TTLMAX,
CP_OFFSET,
CP_DELAY,
CP_DISPERSION,
@ -262,13 +258,13 @@ static u_char def_peer_var[] = {
CP_FILTDELAY,
CP_FILTOFFSET,
CP_FILTERROR,
#ifdef PUBKEY
CP_FLAGS,
#ifdef OPENSSL
CP_HOST,
CP_CERTIF,
CP_SESKEY,
CP_DIGEST,
CP_FLAGS,
CP_IDENT,
CP_INITSEQ,
#endif /* PUBKEY */
#endif /* OPENSSL */
0
};
@ -455,7 +451,7 @@ static u_char * datapt;
static u_char * dataend;
static int datalinelen;
static int datanotbinflag;
static struct sockaddr_in *rmt_addr;
static struct sockaddr_storage *rmt_addr;
static struct interface *lcl_inter;
static u_char res_authenticate;
@ -740,14 +736,16 @@ ctlpeerstatus(
/*
* ctlclkstatus - return a status word for this clock
*/
#ifdef REFCLOCK
static u_short
ctlclkstatus(
struct refclockstat *this_clock
)
{
return ((u_short)(this_clock->currentstatus) << 8) |
(u_short)(this_clock->lastevent);
return ((u_short)(((this_clock->currentstatus) << 8) |
(this_clock->lastevent)));
}
#endif
/*
@ -1079,12 +1077,13 @@ ctl_putts(
/*
* ctl_putadr - write a dotted quad IP address into the response
* ctl_putadr - write an IP address into the response
*/
static void
ctl_putadr(
const char *tag,
u_int32 addr
u_int32 addr32,
struct sockaddr_storage* addr
)
{
register char *cp;
@ -1097,7 +1096,10 @@ ctl_putadr(
*cp++ = *cq++;
*cp++ = '=';
cq = numtoa(addr);
if (addr == NULL)
cq = numtoa(addr32);
else
cq = stoa(addr);
while (*cq != '\0')
*cp++ = *cq++;
ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
@ -1144,7 +1146,6 @@ ctl_putarray(
register const char *cq;
char buffer[200];
int i;
cp = buffer;
cq = tag;
while (*cq != '\0')
@ -1171,9 +1172,11 @@ ctl_putsys(
)
{
l_fp tmp;
#ifdef HAVE_UNAME
char str[256];
#endif
#ifdef OPENSSL
struct cert_info *cp;
char cbuf[256];
#endif /* OPENSSL */
switch (varid) {
@ -1200,8 +1203,8 @@ ctl_putsys(
break;
case CS_REFID:
if (sys_stratum > 1)
ctl_putadr(sys_var[CS_REFID].text, sys_refid);
if (sys_stratum > 1 && sys_stratum < STRATUM_UNSPEC)
ctl_putadr(sys_var[CS_REFID].text, sys_refid, NULL);
else
ctl_putid(sys_var[CS_REFID].text,
(char *)&sys_refid);
@ -1259,8 +1262,7 @@ ctl_putsys(
ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
sizeof(str_system) - 1);
#else
(void)strcpy(str, utsnamebuf.sysname);
(void)strcat(str, utsnamebuf.release);
sprintf(str, "%s/%s", utsnamebuf.sysname, utsnamebuf.release);
ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
#endif /* HAVE_UNAME */
break;
@ -1338,37 +1340,50 @@ ctl_putsys(
}
break;
#ifdef PUBKEY
#ifdef OPENSSL
case CS_FLAGS:
if (crypto_flags)
ctl_puthex(sys_var[CS_FLAGS].text,
crypto_flags);
if (crypto_flags) {
ctl_puthex(sys_var[CS_FLAGS].text, crypto_flags);
}
break;
case CS_DIGEST:
if (crypto_flags) {
const EVP_MD *dp;
dp = EVP_get_digestbynid(crypto_flags >> 16);
strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
ctl_putstr(sys_var[CS_DIGEST].text, str,
strlen(str));
}
break;
case CS_HOST:
ctl_putstr(sys_var[CS_HOST].text, sys_hostname,
strlen(sys_hostname));
if (host.fstamp != 0)
ctl_putuint(sys_var[CS_PUBLIC].text,
ntohl(host.fstamp));
if (sys_hostname != NULL)
ctl_putstr(sys_var[CS_HOST].text, sys_hostname,
strlen(sys_hostname));
break;
case CS_CERTIF:
if (certif.fstamp != 0)
ctl_putuint(sys_var[CS_CERTIF].text,
ntohl(certif.fstamp));
for (cp = cinfo; cp != NULL; cp = cp->link) {
sprintf(cbuf, "%s %s 0x%x %u", cp->subject,
cp->issuer, cp->flags,
ntohl(cp->cert.fstamp));
ctl_putstr(sys_var[CS_CERTIF].text, cbuf,
strlen(cbuf));
}
break;
case CS_DHPARAMS:
if (dhparam.fstamp != 0)
ctl_putuint(sys_var[CS_DHPARAMS].text,
ntohl(dhparam.fstamp));
case CS_PUBLIC:
if (hostval.fstamp != 0)
ctl_putuint(sys_var[CS_PUBLIC].text,
ntohl(hostval.fstamp));
break;
case CS_REVTIME:
if (host.tstamp != 0)
if (hostval.tstamp != 0)
ctl_putuint(sys_var[CS_REVTIME].text,
ntohl(host.tstamp));
ntohl(hostval.tstamp));
break;
case CS_LEAPTAB:
@ -1378,7 +1393,7 @@ ctl_putsys(
if (sys_tai != 0)
ctl_putuint(sys_var[CS_TAI].text, sys_tai);
break;
#endif /* PUBKEY */
#endif /* OPENSSL */
}
}
@ -1392,6 +1407,11 @@ ctl_putpeer(
struct peer *peer
)
{
#ifdef OPENSSL
char str[256];
struct autokey *ap;
#endif /* OPENSSL */
switch (varid) {
case CP_CONFIG:
@ -1410,24 +1430,24 @@ ctl_putpeer(
break;
case CP_SRCADR:
ctl_putadr(peer_var[CP_SRCADR].text,
peer->srcadr.sin_addr.s_addr);
ctl_putadr(peer_var[CP_SRCADR].text, 0,
&peer->srcadr);
break;
case CP_SRCPORT:
ctl_putuint(peer_var[CP_SRCPORT].text,
ntohs(peer->srcadr.sin_port));
ntohs(((struct sockaddr_in*)&peer->srcadr)->sin_port));
break;
case CP_DSTADR:
ctl_putadr(peer_var[CP_DSTADR].text,
peer->dstadr->sin.sin_addr.s_addr);
ctl_putadr(peer_var[CP_DSTADR].text, 0,
&(peer->dstadr->sin));
break;
case CP_DSTPORT:
ctl_putuint(peer_var[CP_DSTPORT].text,
(u_long)(peer->dstadr ?
ntohs(peer->dstadr->sin.sin_port) : 0));
ntohs(((struct sockaddr_in*)&peer->dstadr->sin)->sin_port) : 0));
break;
case CP_LEAP:
@ -1466,16 +1486,22 @@ ctl_putpeer(
break;
case CP_REFID:
if (peer->stratum > 1) {
if (peer->flags & FLAG_REFCLOCK)
ctl_putadr(peer_var[CP_REFID].text,
peer->srcadr.sin_addr.s_addr);
if (peer->flags & FLAG_REFCLOCK) {
if (peer->stratum > 0 && peer->stratum <
STRATUM_UNSPEC)
ctl_putadr(peer_var[CP_REFID].text,
peer->refid, NULL);
else
ctl_putadr(peer_var[CP_REFID].text,
peer->refid);
ctl_putid(peer_var[CP_REFID].text,
(char *)&peer->refid);
} else {
ctl_putid(peer_var[CP_REFID].text,
(char *)&peer->refid);
if (peer->stratum > 1 && peer->stratum <
STRATUM_UNSPEC)
ctl_putadr(peer_var[CP_REFID].text,
peer->refid, NULL);
else
ctl_putid(peer_var[CP_REFID].text,
(char *)&peer->refid);
}
break;
@ -1504,21 +1530,17 @@ ctl_putpeer(
break;
case CP_TTL:
if (!(peer->cast_flags & MDF_ACAST))
break;
ctl_putint(peer_var[CP_TTL].text, peer->ttl);
break;
case CP_TTLMAX:
if (!(peer->cast_flags & (MDF_MCAST | MDF_ACAST)))
break;
ctl_putint(peer_var[CP_TTLMAX].text, peer->ttlmax);
ctl_putint(peer_var[CP_TTL].text, sys_ttl[peer->ttl]);
break;
case CP_VALID:
ctl_putuint(peer_var[CP_VALID].text, peer->unreach);
break;
case CP_RANK:
ctl_putuint(peer_var[CP_RANK].text, peer->rank);
break;
case CP_TIMER:
ctl_putuint(peer_var[CP_TIMER].text,
peer->nextdate - current_time);
@ -1612,47 +1634,44 @@ ctl_putpeer(
ctl_putdata(buf, (unsigned)(s - buf), 0);
}
break;
#ifdef PUBKEY
#ifdef OPENSSL
case CP_FLAGS:
if (peer->crypto)
ctl_puthex(peer_var[CP_FLAGS].text, peer->crypto);
break;
case CP_DIGEST:
if (peer->crypto) {
const EVP_MD *dp;
dp = EVP_get_digestbynid(peer->crypto >> 16);
strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
ctl_putstr(peer_var[CP_DIGEST].text, str,
strlen(str));
}
break;
case CP_HOST:
if (peer->keystr != NULL)
ctl_putstr(peer_var[CP_HOST].text, peer->keystr,
strlen(peer->keystr));
if (peer->pubkey.fstamp != 0)
ctl_putuint(peer_var[CP_PUBLIC].text,
peer->pubkey.fstamp);
if (peer->subject != NULL)
ctl_putstr(peer_var[CP_HOST].text, peer->subject,
strlen(peer->subject));
break;
case CP_CERTIF:
if (peer->certif.fstamp != 0)
ctl_putuint(peer_var[CP_CERTIF].text,
peer->certif.fstamp);
break;
case CP_SESKEY:
if (peer->pcookie.key != 0)
ctl_puthex(peer_var[CP_SESKEY].text,
peer->pcookie.key);
if (peer->hcookie != 0)
ctl_puthex(peer_var[CP_SASKEY].text,
peer->hcookie);
case CP_IDENT:
if (peer->issuer != NULL)
ctl_putstr(peer_var[CP_IDENT].text, peer->issuer,
strlen(peer->issuer));
break;
case CP_INITSEQ:
if (peer->recauto.key == 0)
if ((ap = (struct autokey *)peer->recval.ptr) == NULL)
break;
ctl_putint(peer_var[CP_INITSEQ].text,
peer->recauto.seq);
ctl_puthex(peer_var[CP_INITKEY].text,
peer->recauto.key);
ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
ctl_putuint(peer_var[CP_INITTSP].text,
peer->recauto.tstamp);
ntohl(peer->recval.tstamp));
break;
#endif /* PUBKEY */
#endif /* OPENSSL */
}
}
@ -1722,7 +1741,7 @@ ctl_putclock(
if (mustput || (clock_stat->haveflags & CLK_HAVEVAL2)) {
if (clock_stat->fudgeval1 > 1)
ctl_putadr(clock_var[CC_FUDGEVAL2].text,
(u_int32)clock_stat->fudgeval2);
(u_int32)clock_stat->fudgeval2, NULL);
else
ctl_putid(clock_var[CC_FUDGEVAL2].text,
(char *)&clock_stat->fudgeval2);
@ -1872,20 +1891,21 @@ ctl_getitem(
if (*cp == '=') {
cp++;
tp = buf;
while (cp < reqend && isspace((int)*cp))
while (cp < reqend && isspace((unsigned char)*cp))
cp++;
while (cp < reqend && *cp != ',') {
*tp++ = *cp++;
if (tp >= buf + sizeof(buf))
if (tp >= buf + sizeof(buf))
return (0);
}
}
if (cp < reqend)
cp++;
*tp-- = '\0';
while (tp > buf) {
*tp-- = '\0';
while (tp >= buf) {
if (!isspace((unsigned char)(*tp)))
break;
*tp-- = '\0';
}
reqpt = cp;
*data = buf;
@ -2128,7 +2148,7 @@ write_variables(
register struct ctl_var *v;
register int ext_var;
char *valuep;
long val;
long val = 0;
/*
* If he's trying to write into a peer tell him no way
@ -2432,7 +2452,7 @@ unset_trap(
*/
int
ctlsettrap(
struct sockaddr_in *raddr,
struct sockaddr_storage *raddr,
struct interface *linter,
int traptype,
int version
@ -2537,7 +2557,7 @@ ctlsettrap(
tptouse->tr_sequence = 1;
tptouse->tr_addr = *raddr;
tptouse->tr_localaddr = linter;
tptouse->tr_version = version;
tptouse->tr_version = (u_char) version;
tptouse->tr_flags = TRAP_INUSE;
if (traptype == TRAP_TYPE_CONFIG)
tptouse->tr_flags |= TRAP_CONFIGURED;
@ -2553,7 +2573,7 @@ ctlsettrap(
*/
int
ctlclrtrap(
struct sockaddr_in *raddr,
struct sockaddr_storage *raddr,
struct interface *linter,
int traptype
)
@ -2578,18 +2598,18 @@ ctlclrtrap(
*/
static struct ctl_trap *
ctlfindtrap(
struct sockaddr_in *raddr,
struct sockaddr_storage *raddr,
struct interface *linter
)
{
register struct ctl_trap *tp;
for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
if (tp->tr_flags & TRAP_INUSE && NSRCADR(raddr) ==
NSRCADR(&tp->tr_addr) && NSRCPORT(raddr) ==
NSRCPORT(&tp->tr_addr) && linter ==
tp->tr_localaddr)
return (tp);
if ((tp->tr_flags & TRAP_INUSE)
&& (NSRCPORT(raddr) == NSRCPORT(&tp->tr_addr))
&& SOCKCMP(raddr, &tp->tr_addr)
&& (linter == tp->tr_localaddr) )
return (tp);
}
return (struct ctl_trap *)NULL;
}
@ -2610,7 +2630,7 @@ report_event(
* Record error code in proper spots, but have mercy on the
* log file.
*/
if (!(err & PEER_EVENT)) {
if (!(err & (PEER_EVENT | CRPT_EVENT))) {
if (ctl_sys_num_events < CTL_SYS_MAXEVENTS)
ctl_sys_num_events++;
if (ctl_sys_last_event != (u_char)err) {
@ -2632,10 +2652,10 @@ report_event(
#ifdef REFCLOCK
if (ISREFCLOCKADR(&peer->srcadr))
src = refnumtoa(peer->srcadr.sin_addr.s_addr);
src = refnumtoa(&peer->srcadr);
else
#endif
src = ntoa(&peer->srcadr);
src = stoa(&peer->srcadr);
peer->last_event = (u_char)(err & ~PEER_EVENT);
if (peer->num_events < CTL_PEER_MAXEVENTS)
@ -2688,10 +2708,10 @@ report_event(
* variables. Don't send crypto strings.
*/
for (i = 1; i <= CS_MAXCODE; i++) {
#ifdef PUBKEY
#ifdef OPENSSL
if (i > CS_VARLIST)
continue;
#endif /* PUBKEY */
#endif /* OPENSSL */
ctl_putsys(i);
}
#ifdef REFCLOCK
@ -2717,7 +2737,7 @@ report_event(
strlen(kv->text), 0);
free_varlist(clock_stat.kv_list);
}
#endif /*REFCLOCK*/
#endif /* REFCLOCK */
} else {
rpkt.associd = htons(peer->associd);
rpkt.status = htons(ctlpeerstatus(peer));
@ -2725,12 +2745,13 @@ report_event(
/*
* Dump it all. Later, maybe less.
*/
for (i = 1; i <= CP_MAXCODE; i++)
#ifdef PUBKEY
for (i = 1; i <= CP_MAXCODE; i++) {
#ifdef OPENSSL
if (i > CP_VARLIST)
continue;
#endif /* PUBKEY */
#endif /* OPENSSL */
ctl_putpeer(i, peer);
}
#ifdef REFCLOCK
/*
* for clock exception events: add clock variables to
@ -2756,7 +2777,7 @@ report_event(
strlen(kv->text), 0);
free_varlist(clock_stat.kv_list);
}
#endif /*REFCLOCK*/
#endif /* REFCLOCK */
}
/*
@ -2810,7 +2831,7 @@ char *
add_var(
struct ctl_var **kv,
u_long size,
int def
u_short def
)
{
register u_long c;
@ -2839,7 +2860,7 @@ set_var(
struct ctl_var **kv,
const char *data,
u_long size,
int def
u_short def
)
{
register struct ctl_var *k;
@ -2850,7 +2871,8 @@ set_var(
if (!data || !size)
return;
if ((k = *kv)) {
k = *kv;
if (k != NULL) {
while (!(k->flags & EOV)) {
s = data;
t = k->text;
@ -2885,7 +2907,7 @@ void
set_sys_var(
char *data,
u_long size,
int def
u_short def
)
{
set_var(&ext_sys_var, data, size, def);