clear sockaddr_in's on stack before use

set sin_len
close one ftp port bounce attack
have rresvport() use bindresvport() rather than duplicate the code,
  rresvport() is a superset of bindresvport().

Obtained from: OpenBSD / Jason Downs / Theo de Raadt, minor tweaks by me.
This commit is contained in:
peter 1996-08-12 14:14:09 +00:00
parent 36d45bbacb
commit 665b6e261b

View File

@ -100,9 +100,11 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
return (-1);
}
fcntl(s, F_SETOWN, pid);
bzero(&sin, sizeof sin);
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_family = hp->h_addrtype;
bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length);
sin.sin_port = rport;
bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length);
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
break;
(void)close(s);
@ -159,6 +161,7 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
(void)close(s2);
goto bad;
}
again:
FD_ZERO(&reads);
FD_SET(s, &reads);
FD_SET(s2, &reads);
@ -175,6 +178,14 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
goto bad;
}
s3 = accept(s2, (struct sockaddr *)&from, &len);
/*
* XXX careful for ftp bounce attacks. If discovered, shut them
* down and check for the real auxiliary channel to connect.
*/
if (from.sin_family == AF_INET && from.sin_port == htons(20)) {
close(s3);
goto again;
}
(void)close(s2);
if (s3 < 0) {
(void)fprintf(stderr,
@ -224,40 +235,31 @@ rresvport(alport)
int *alport;
{
struct sockaddr_in sin;
int s, on, len;
int s;
bzero(&sin, sizeof sin);
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = 0;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
return (-1);
on = IP_PORTRANGE_LOW;
if (setsockopt(s, IPPROTO_IP, IP_PORTRANGE, (char*)&on, sizeof(on)) < 0)
{
(void)close(s);
return(-1);
}
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) {
/* attempt to find the port that we were assigned */
len = sizeof(sin);
if (getsockname(s, (struct sockaddr *)&sin, &len) >= 0)
*alport = ntohs(sin.sin_port);
else {
(void)close(s);
return (-1);
}
#if 0 /* compat_exact_traditional_rresvport_semantics */
sin.sin_port = htons((u_short)*alport);
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
return (s);
if (errno != EADDRINUSE) {
(void)close(s);
return (-1);
}
if (errno == EADDRNOTAVAIL) /* no available ports? */
errno = EAGAIN; /* "official" return for this case */
(void)close(s);
return (-1);
#endif
sin.sin_port = 0;
if (bindresvport(s, &sin) == -1) {
(void)close(s);
return (-1);
}
*alport = (int)ntohs(sin.sin_port);
return (s);
}
int __check_rhosts_file = 1;