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.
148 lines
4.7 KiB
148 lines
4.7 KiB
diff -up netkit-rsh-0.17/rexecd/rexecd.c.ipv6-rexec netkit-rsh-0.17/rexecd/rexecd.c |
|
--- netkit-rsh-0.17/rexecd/rexecd.c.ipv6-rexec 2013-07-15 17:31:07.678365071 +0200 |
|
+++ netkit-rsh-0.17/rexecd/rexecd.c 2013-07-15 17:32:17.010346615 +0200 |
|
@@ -114,7 +114,7 @@ int deny_severity = LOG_WARNING; |
|
*/ |
|
|
|
static void fatal(const char *); |
|
-static void doit(struct sockaddr_in *fromp); |
|
+static void doit(struct sockaddr_storage *fromp); |
|
static void getstr(char *buf, int cnt, const char *err); |
|
|
|
static const char *remote = NULL; |
|
@@ -122,7 +122,7 @@ static const char *remote = NULL; |
|
int |
|
main(int argc, char **argv) |
|
{ |
|
- struct sockaddr_in from; |
|
+ struct sockaddr_storage from; |
|
socklen_t fromlen; |
|
|
|
(void)argc; |
|
@@ -136,6 +136,29 @@ main(int argc, char **argv) |
|
|
|
openlog(argv[0], LOG_PID, LOG_DAEMON); |
|
|
|
+ /* handle situation when connected peer *doesn't have* native IPv6 address but systemd/xinetd |
|
+ * is listening on AF_INET6 socket on our behalf and fds we are given corresponds to AF_INET6 socket |
|
+ */ |
|
+ if (from.ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *) &from)->sin6_addr)) { |
|
+ struct addrinfo *res, hints = {}; |
|
+ char client_addr[INET6_ADDRSTRLEN] = {}; |
|
+ char client_port[6] = {}; |
|
+ |
|
+ inet_ntop(AF_INET6, &((struct sockaddr_in6 *) &from)->sin6_addr, |
|
+ client_addr, sizeof(client_addr)); |
|
+ |
|
+ sprintf(client_port, "%d", ntohs(((struct sockaddr_in6 *) &from)->sin6_port)); |
|
+ |
|
+ hints.ai_family = AF_INET; |
|
+ hints.ai_socktype = SOCK_STREAM; |
|
+ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; |
|
+ |
|
+ getaddrinfo(client_addr, client_port, &hints, &res); |
|
+ |
|
+ memcpy(&from, res->ai_addr, sizeof(struct sockaddr_in)); |
|
+ freeaddrinfo(res); |
|
+ } |
|
+ |
|
#ifdef TCP_WRAPPER |
|
/* Find out and report the remote host name. */ |
|
/* I don't think this works. -- dholland */ |
|
@@ -146,19 +169,42 @@ main(int argc, char **argv) |
|
if (argc > 1 && argv[1] && strcmp(argv[1], "-D")==0) |
|
{ |
|
/* use IP in logs -- this is workaround */ |
|
- remote = strdup(inet_ntoa(from.sin_addr)); |
|
+ char remote_addr[INET6_ADDRSTRLEN] = {}; |
|
+ |
|
+ if (from.ss_family == AF_INET) |
|
+ remote = inet_ntop(AF_INET, &((struct sockaddr_in *) &from)->sin_addr, remote_addr, INET_ADDRSTRLEN); |
|
+ else |
|
+ remote = inet_ntop(AF_INET6, &((struct sockaddr_in6 *) &from)->sin6_addr, remote_addr, INET6_ADDRSTRLEN); |
|
+ |
|
+ if (remote) { |
|
+ remote = strdup(remote); |
|
+ if (!remote) { |
|
+ fprintf(stderr, "rexecd: strdup: %s\n", strerror(errno)); |
|
+ return 1; |
|
+ } |
|
+ } else { |
|
+ fprintf(stderr, "rexecd: inet_ntop: %s\n", strerror(errno)); |
|
+ return 1; |
|
+ } |
|
} |
|
else |
|
{ |
|
- struct hostent *h = gethostbyaddr((const char *)&from.sin_addr, |
|
- sizeof(struct in_addr), |
|
- AF_INET); |
|
- if (!h || !h->h_name) { |
|
- write(0, "\1Where are you?\n", 16); |
|
+ int r; |
|
+ char remote_hostname[NI_MAXHOST] = {}; |
|
+ |
|
+ r = getnameinfo((struct sockaddr *) &from, sizeof(struct sockaddr_storage), remote_hostname, NI_MAXHOST, NULL, NULL, 0); |
|
+ |
|
+ if (r) { |
|
+ fprintf(stderr, "rexecd: getnameinfo: %s\n", gai_strerror(r)); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ remote = strdup(remote_hostname); |
|
+ if (!remote) { |
|
+ fprintf(stderr, "rexecd: strdup: %s\n", strerror(errno)); |
|
return 1; |
|
} |
|
- /* Be advised that this may be utter nonsense. */ |
|
- remote = strdup(h->h_name); |
|
+ |
|
} |
|
#endif |
|
syslog(allow_severity, "connect from %.128s", remote); |
|
@@ -233,7 +279,7 @@ static struct pam_conv PAM_conversation |
|
|
|
|
|
static void |
|
-doit(struct sockaddr_in *fromp) |
|
+doit(struct sockaddr_storage *fromp) |
|
{ |
|
char *cmdbuf; |
|
long cmdbuflen; |
|
@@ -298,7 +344,7 @@ doit(struct sockaddr_in *fromp) |
|
We must connect back to the client here if a port was provided. KRH |
|
*/ |
|
if (port != 0) { |
|
- s = socket(AF_INET, SOCK_STREAM, 0); |
|
+ s = socket(fromp->ss_family, SOCK_STREAM, 0); |
|
if (s < 0) |
|
exit(1); |
|
|
|
@@ -308,7 +354,12 @@ doit(struct sockaddr_in *fromp) |
|
exit(1); |
|
#endif |
|
alarm(60); |
|
- fromp->sin_port = htons(port); |
|
+ |
|
+ if (fromp->ss_family == AF_INET) |
|
+ ((struct sockaddr_in *) fromp)->sin_port = htons(port); |
|
+ else |
|
+ ((struct sockaddr_in6 *) fromp)->sin6_port = htons(port); |
|
+ |
|
if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) |
|
exit(1); |
|
alarm(0); |
|
diff -up netkit-rsh-0.17/rexec/rexec.c.ipv6-rexec netkit-rsh-0.17/rexec/rexec.c |
|
--- netkit-rsh-0.17/rexec/rexec.c.ipv6-rexec 2013-07-15 17:31:07.686365068 +0200 |
|
+++ netkit-rsh-0.17/rexec/rexec.c 2013-07-15 17:31:07.698365065 +0200 |
|
@@ -194,8 +194,8 @@ int main(int argc, char *argv[]) |
|
exit(1); |
|
} |
|
|
|
- if ( (sock = rexec(&host, port_exec, user_name, passwd, command, |
|
- p_to_aux_sock)) < 0 ) |
|
+ if ( (sock = rexec_af(&host, port_exec, user_name, passwd, command, |
|
+ p_to_aux_sock, AF_UNSPEC)) < 0 ) |
|
{ |
|
fprintf(stderr,"%s: Error in rexec system call,\n",argv[0]); |
|
fprintf(stderr,"%s: (The following system error may itself be in error)\n",argv[0]);
|
|
|