You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

452 lines
14 KiB

diff -up netkit-rsh-0.17/rcp/rcp.c.ipv6 netkit-rsh-0.17/rcp/rcp.c
--- netkit-rsh-0.17/rcp/rcp.c.ipv6 2008-10-03 12:44:22.000000000 +0200
+++ netkit-rsh-0.17/rcp/rcp.c 2008-10-03 12:44:22.000000000 +0200
@@ -262,9 +262,9 @@ toremote(const char *targ, int argc, cha
nospace();
(void)snprintf(bp, len, "%s -t %s", cmd, targ);
host = thost;
- rem = rcmd(&host, port, pwd->pw_name,
+ rem = rcmd_af(&host, port, pwd->pw_name,
tuser ? tuser : pwd->pw_name,
- bp, 0);
+ bp, 0, AF_UNSPEC);
if (rem < 0)
exit(1);
#ifdef IP_TOS
@@ -325,7 +325,8 @@ tolocal(int argc, char *argv[])
if (!(bp = malloc(len)))
nospace();
(void)snprintf(bp, len, "%s -f %s", cmd, src);
- rem = rcmd(&host, port, pwd->pw_name, suser, bp, 0);
+ rem = rcmd_af(&host, port, pwd->pw_name, suser, bp, 0,
+ AF_UNSPEC);
(void)free(bp);
if (rem < 0) {
++errs;
diff -up netkit-rsh-0.17/rlogind/network.c.ipv6 netkit-rsh-0.17/rlogind/network.c
--- netkit-rsh-0.17/rlogind/network.c.ipv6 1999-12-12 16:15:40.000000000 +0100
+++ netkit-rsh-0.17/rlogind/network.c 2008-10-03 12:44:22.000000000 +0200
@@ -88,47 +88,78 @@ local_domain(const char *h)
return(0);
}
+static int
+soaddr_eq_ip(const struct sockaddr *s1, const struct sockaddr *s2)
+{
+ if (s1->sa_family != s2->sa_family)
+ return 0;
+ if (s2->sa_family == AF_INET6)
+ return (memcmp(
+ (const void*)(
+ &((const struct sockaddr_in6 *)s1)->sin6_addr
+ ),
+ (const void*)(
+ &((const struct sockaddr_in6 *)s2)->sin6_addr
+ ),
+ sizeof(struct in6_addr))
+ == 0);
+ else
+ return (memcmp(
+ (const void*)(
+ &((const struct sockaddr_in *)s1)->sin_addr
+ ),
+ (const void*)(
+ &((const struct sockaddr_in *)s2)->sin_addr
+ ),
+ sizeof(struct in_addr))
+ == 0);
+}
static char *
-find_hostname(const struct sockaddr_in *fromp, int *hostokp)
+find_hostname(struct sockaddr *fromp, socklen_t fromlen,
+ char *portname, int *hostokp)
{
- struct hostent *hop;
+ int error;
char *hname;
+ char hname_buf[NI_MAXHOST];
int hostok = 0;
- hop = gethostbyaddr((const char *)&fromp->sin_addr,
- sizeof(struct in_addr), fromp->sin_family);
- if (hop == NULL) {
- hname = strdup(inet_ntoa(fromp->sin_addr));
- hostok = 1;
- }
- else if (check_all || local_domain(hop->h_name)) {
+ error = getnameinfo(fromp, fromlen,
+ hname_buf, sizeof(hname_buf), portname, NI_MAXSERV,
+ NI_NUMERICSERV);
+ assert(error == 0);
+
+ if (check_all || local_domain(hname_buf)) {
/*
- * If name returned by gethostbyaddr is in our domain,
+ * If name returned is in our domain,
* attempt to verify that we haven't been fooled by someone
* in a remote net; look up the name and check that this
* address corresponds to the name.
*/
- hname = strdup(hop->h_name);
- hop = gethostbyname(hname);
- if (hop) {
- for (; hop->h_addr_list[0]; hop->h_addr_list++) {
- if (!memcmp(hop->h_addr_list[0], &fromp->sin_addr,
- sizeof(fromp->sin_addr))) {
+ struct addrinfo hints;
+ struct addrinfo *res0, *res;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ error = getaddrinfo(hname_buf, NULL, &hints, &res);
+ assert(error == 0);
+
+ res0 = res;
+ while (res) {
+ if (soaddr_eq_ip(fromp, res->ai_addr)) {
hostok = 1;
break;
}
- }
- /* not clear if this is worthwhile */
- free(hname);
- hname = strdup(hop->h_name);
+ res = res->ai_next;
}
+ freeaddrinfo(res0);
}
else {
- hname = strdup(hop->h_name);
hostok = 1;
}
+ hname = strdup(hname_buf);
+
/*
* Actually it might be null if we're out of memory, but
* where do we go then? We'd have to bail anyhow.
@@ -145,14 +176,14 @@ find_hostname(const struct sockaddr_in *
char *
network_init(int f, int *hostokp)
{
- struct sockaddr_in from, *fromp;
+ struct sockaddr_storage from, *fromp;
socklen_t fromlen;
int on = 1;
char c;
char *hname;
+ char portname[NI_MAXSERV];
int port;
- from.sin_family = AF_INET;
fromlen = sizeof (from);
if (getpeername(f, (struct sockaddr *)&from, &fromlen) < 0) {
syslog(LOG_ERR,"Can't get peer name of remote host: %m");
@@ -177,13 +208,19 @@ network_init(int f, int *hostokp)
alarm(0);
- hname = find_hostname(fromp, hostokp);
+ hname = find_hostname((struct sockaddr *)fromp, fromlen,
+ portname, hostokp);
+ assert(hname != NULL);
- port = ntohs(fromp->sin_port);
- if (fromp->sin_family != AF_INET ||
+ port = atoi(portname);
+ if (! port) {
+ syslog(LOG_NOTICE, "Unknown port %s", portname);
+ fatal(f, "Permission denied", 0);
+ }
+ if ((fromp->ss_family != AF_INET && fromp->ss_family != AF_INET6) ||
port >= IPPORT_RESERVED || port < IPPORT_RESERVED/2) {
syslog(LOG_NOTICE, "Connection from %s on illegal port",
- inet_ntoa(fromp->sin_addr));
+ portname);
fatal(f, "Permission denied", 0);
}
diff -up netkit-rsh-0.17/rlogin/rlogin.c.ipv6 netkit-rsh-0.17/rlogin/rlogin.c
--- netkit-rsh-0.17/rlogin/rlogin.c.ipv6 2008-10-03 12:44:22.000000000 +0200
+++ netkit-rsh-0.17/rlogin/rlogin.c 2008-10-03 12:44:22.000000000 +0200
@@ -280,7 +280,7 @@ main(int argc, char **argv)
/* will use SIGUSR1 for window size hack, so hold it off */
omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
- rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
+ rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, term, 0, AF_UNSPEC);
if (rem < 0) exit(1);
diff -up netkit-rsh-0.17/rshd/rshd.c.ipv6 netkit-rsh-0.17/rshd/rshd.c
--- netkit-rsh-0.17/rshd/rshd.c.ipv6 2008-10-03 12:44:22.000000000 +0200
+++ netkit-rsh-0.17/rshd/rshd.c 2008-10-03 12:53:08.000000000 +0200
@@ -109,7 +109,7 @@ char *envinit[] =
extern char **environ;
static void error(const char *fmt, ...);
-static void doit(struct sockaddr_in *fromp);
+static void doit(struct sockaddr_storage *fromp, socklen_t fromlen);
static void getstr(char *buf, int cnt, const char *err);
extern int _check_rhosts_file;
@@ -284,19 +284,37 @@ static struct passwd *doauth(const char
#endif
}
-static const char *findhostname(struct sockaddr_in *fromp,
+static const char *findhostname(struct sockaddr *fromp,
+ socklen_t fromlen,
const char *remuser, const char *locuser,
const char *cmdbuf)
{
- struct hostent *hp;
const char *hostname;
+ char remote_address[INET6_ADDRSTRLEN];
+ char remote_hostname[NI_MAXHOST];
+ struct addrinfo hints;
+ struct addrinfo *res0, *res;
+
+ if (! inet_ntop(fromp->sa_family,
+ (( fromp->sa_family == AF_INET6 )
+ ? ( &((struct sockaddr_in6 *)fromp)->sin6_addr )
+ : ( &((struct sockaddr_in *)fromp)->sin_addr )),
+ remote_address, sizeof(remote_address))) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "Failed to retrieve the socket remote address");
+ exit(1);
+ }
- hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof (struct in_addr),
- fromp->sin_family);
+ if (getnameinfo(fromp, fromlen, remote_hostname, NI_MAXHOST,
+ NULL, 0, 0)) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "Failed to retrieve the hostname information for %s",
+ remote_address);
+ exit(1);
+ }
errno = ENOMEM; /* malloc (thus strdup) may not set it */
- if (hp) hostname = strdup(hp->h_name);
- else hostname = strdup(inet_ntoa(fromp->sin_addr));
+ hostname = strdup(remote_hostname);
if (hostname==NULL) {
/* out of memory? */
@@ -307,31 +325,43 @@ static const char *findhostname(struct s
/*
* Attempt to confirm the DNS.
*/
-#ifdef RES_DNSRCH
- _res.options &= ~RES_DNSRCH;
-#endif
- hp = gethostbyname(hostname);
- if (hp == NULL) {
- syslog(LOG_INFO, "Couldn't look up address for %s", hostname);
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ if (getaddrinfo(hostname, NULL, &hints, &res)) {
+ syslog(LOG_INFO, "Couldn't look up address for %s/%s",
+ hostname, remote_address);
fail("Couldn't get address for your host (%s)\n",
- remuser, inet_ntoa(fromp->sin_addr), locuser, cmdbuf);
- }
- while (hp->h_addr_list[0] != NULL) {
- if (!memcmp(hp->h_addr_list[0], &fromp->sin_addr,
- sizeof(fromp->sin_addr))) {
- return hostname;
+ remuser, hostname, locuser, cmdbuf);
+ }
+
+ res0 = res;
+ while (res) {
+ struct sockaddr *sa;
+ char res_address[INET6_ADDRSTRLEN];
+ sa = res->ai_addr;
+
+ if (inet_ntop(sa->sa_family,
+ (( sa->sa_family == AF_INET6 )
+ ? ( &((struct sockaddr_in6 *)sa)->sin6_addr )
+ : ( &((struct sockaddr_in *)sa)->sin_addr )),
+ res_address, sizeof(res_address))
+ && strcmp(remote_address, res_address) == 0) {
+ freeaddrinfo(res0);
+ return hostname;
}
- hp->h_addr_list++;
+ res = res->ai_next;
}
+ freeaddrinfo(res0);
+
syslog(LOG_NOTICE, "Host addr %s not listed for host %s",
- inet_ntoa(fromp->sin_addr), hp->h_name);
+ remote_address, hostname);
fail("Host address mismatch for %s\n",
- remuser, inet_ntoa(fromp->sin_addr), locuser, cmdbuf);
+ remuser, hostname, locuser, cmdbuf);
return NULL; /* not reachable */
}
static void
-doit(struct sockaddr_in *fromp)
+doit(struct sockaddr_storage *fromp, socklen_t fromlen)
{
char cmdbuf[ARG_MAX+1];
const char *theshell, *shellname;
@@ -351,8 +381,12 @@ doit(struct sockaddr_in *fromp)
alarm(0);
if (port != 0) {
+ struct sockaddr_storage second_connect;
int lport = IPPORT_RESERVED - 1;
- sock = rresvport(&lport);
+
+ memcpy((void *)&second_connect, (void *)fromp, fromlen);
+ sock = rresvport_af(&lport,
+ ((struct sockaddr *)&second_connect)->sa_family);
if (sock < 0) {
syslog(LOG_ERR, "can't get stderr port: %m");
exit(1);
@@ -361,10 +395,15 @@ doit(struct sockaddr_in *fromp)
syslog(LOG_ERR, "2nd port not reserved\n");
exit(1);
}
- fromp->sin_port = htons(port);
- if (connect(sock, (struct sockaddr *)fromp,
- sizeof(*fromp)) < 0) {
- syslog(LOG_INFO, "connect second port: %m");
+ if (((struct sockaddr *)&second_connect)->sa_family == AF_INET6)
+ ((struct sockaddr_in6 *)&second_connect)->sin6_port
+ = htons(port);
+ else
+ ((struct sockaddr_in *)&second_connect)->sin_port
+ = htons(port);
+ if (connect(sock, (struct sockaddr *)&second_connect,
+ fromlen) < 0) {
+ syslog(LOG_INFO, "connect second port %d: %m", port);
exit(1);
}
}
@@ -381,7 +420,8 @@ doit(struct sockaddr_in *fromp)
getstr(cmdbuf, sizeof(cmdbuf), "command");
if (!strcmp(locuser, "root")) paranoid = 1;
- hostname = findhostname(fromp, remuser, locuser, cmdbuf);
+ hostname = findhostname((struct sockaddr *)fromp, fromlen,
+ remuser, locuser, cmdbuf);
setpwent();
pwd = doauth(remuser, hostname, locuser);
@@ -496,15 +536,19 @@ doit(struct sockaddr_in *fromp)
exit(1);
}
-static void network_init(int fd, struct sockaddr_in *fromp)
+static void network_init(int fd,
+ struct sockaddr_storage *fromp, socklen_t *fromlenp)
{
struct linger linger;
- socklen_t fromlen;
+ char hostname[NI_MAXHOST];
+ char portname[NI_MAXSERV];
+ sa_family_t family;
+
+ int error;
int on=1;
int port;
- fromlen = sizeof(*fromp);
- if (getpeername(fd, (struct sockaddr *) fromp, &fromlen) < 0) {
+ if (getpeername(fd, (struct sockaddr *)fromp, fromlenp) < 0) {
syslog(LOG_ERR, "getpeername: %m");
_exit(1);
}
@@ -518,9 +562,20 @@ static void network_init(int fd, struct
sizeof (linger)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m");
- if (fromp->sin_family != AF_INET) {
+ family = ((struct sockaddr *)fromp)->sa_family;
+ if (family != AF_INET && family != AF_INET6) {
syslog(LOG_ERR, "malformed \"from\" address (af %d)\n",
- fromp->sin_family);
+ family);
+ exit(1);
+ }
+
+ error = getnameinfo((struct sockaddr *)fromp, *fromlenp,
+ hostname, sizeof(hostname), portname, sizeof(portname),
+ NI_NUMERICSERV);
+ if (error) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "Failed to retrieve address and port of the connection: %s",
+ gai_strerror(error));
exit(1);
}
#ifdef IP_OPTIONS
@@ -550,7 +605,7 @@ static void network_init(int fd, struct
syslog(LOG_NOTICE,
"Connection received from %s using IP options"
" (ignored): %s",
- inet_ntoa(fromp->sin_addr), lbuf);
+ hostname, lbuf);
if (setsockopt(0, ipproto, IP_OPTIONS, NULL, optsize) != 0) {
syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
@@ -563,10 +618,15 @@ static void network_init(int fd, struct
/*
* Check originating port for validity.
*/
- port = ntohs(fromp->sin_port);
+ port = atoi(portname);
+ if (! port) {
+ syslog(LOG_NOTICE|LOG_AUTH, "Unknown port %s", portname);
+ exit(1);
+ }
if (port >= IPPORT_RESERVED || port < IPPORT_RESERVED/2) {
- syslog(LOG_NOTICE|LOG_AUTH, "Connection from %s on illegal port",
- inet_ntoa(fromp->sin_addr));
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "Connection from %s from illegal port %s",
+ hostname, portname);
exit(1);
}
}
@@ -575,7 +635,8 @@ int
main(int argc, char *argv[])
{
int ch;
- struct sockaddr_in from;
+ struct sockaddr_storage from;
+ socklen_t fromlen;
_check_rhosts_file=1;
openlog("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
@@ -618,8 +679,9 @@ main(int argc, char *argv[])
"pam_rhosts_auth in /etc/pam.conf");
#endif /* USE_PAM */
- network_init(0, &from);
- doit(&from);
+ fromlen = sizeof(from);
+ network_init(0, &from, &fromlen);
+ doit(&from, fromlen);
return 0;
}
diff -up netkit-rsh-0.17/rsh/rsh.c.ipv6 netkit-rsh-0.17/rsh/rsh.c
--- netkit-rsh-0.17/rsh/rsh.c.ipv6 2000-07-23 06:16:24.000000000 +0200
+++ netkit-rsh-0.17/rsh/rsh.c 2008-10-03 12:44:22.000000000 +0200
@@ -163,7 +163,8 @@ main(int argc, char *argv[])
exit(1);
}
- rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2);
+ rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, &rfd2,
+ AF_UNSPEC);
if (rem < 0)
exit(1);