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.
451 lines
14 KiB
451 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);
|
|
|