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

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]);