Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37810970
en ru br
Репозитории ALT
S:0.17-alt5.1
4.1: 0.17-alt2
4.0: 0.17-ipl9mdk
3.0: 0.17-ipl9mdk
www.altlinux.org/Changes

Группа :: Сети/Удалённый доступ
Пакет: rsh

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: netkit-rsh-0.17-ipv6.patch
Скачать


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);
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin