Hi,

$Subject is truth because of gethostbyname call from paxutils which works
for ipv4 only.  We should use getaddrinfo these days for checking for
existing hostname/ip address.

Steps to reproduce (linux):

  $ sudo ifconfig em1 inet6 add         aaaa:aaaa:2:1::aaaa:1/64
  $ sudo route -A inet6 add default gw  aaaa:aaaa:2:1::1
  $ sudo su - -c 'echo "aaaa:aaaa:2:1::aaaa:1 test_domain"  >> /etc/hosts'
  $ ping6 test_domain 
  PING test_domain(test_domain) 56 data bytes
  64 bytes from test_domain: icmp_seq=1 ttl=64 time=0.047 ms
  ^C
  --- test_domain ping statistics ---
  1 packets transmitted, 1 received, 0% packet loss, time 0ms
  rtt min/avg/max/mdev = 0.047/0.047/0.047/0.000 ms
  $ # Configure tar with $RSH & --with-rmt pointing to correct binaries
  $ RSH=/usr/bin/ssh ./configure --with-rmt=/usr/sbin/rmt
  $ ./src/tar -cvf test_domain:/tmp/test.tar Makefile
  tar: Cannot connect to test_domain: resolve failed

Fix for paxutils attached.

Pavel
>From 55b126fe51e443eef1191f43b91c319135489453 Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <[email protected]>
Date: Wed, 29 Jan 2014 12:29:20 +0100
Subject: [PATCH] paxutils: use getaddrinfo instead of gethostbyname

Also validate the hostname a little - check for empty address
allows us to catch the bad ipv6 usage, like:
tar -tf username@::1:/tmp/archive.tar

* am/system.m4 (PU_SYSTEM): Call gl_GETADDRINFO.
* gnulib.modules: Require getaddrinfo module.
* lib/rtapelib.c (try_resolve_hostname): New function.
(rmt_open__): Handle empty (or bad) hostname;  Call rather the
try_resolve_hostname insteadd off gethostbyname.
---
 am/system.m4   |  1 +
 gnulib.modules |  1 +
 lib/rtapelib.c | 16 ++++++++++++++--
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/am/system.m4 b/am/system.m4
index bafedda..cf026d6 100644
--- a/am/system.m4
+++ b/am/system.m4
@@ -26,6 +26,7 @@ AC_DEFUN([PU_SYSTEM],[
   AC_CHECK_FUNCS_ONCE(lstat mkfifo setlocale)
   AC_REQUIRE([gl_INTTOSTR])
   AC_REQUIRE([gl_STDINT_H])
+  AC_REQUIRE([gl_GETADDRINFO])
 
   AC_SEARCH_LIBS(gethostbyname, nsl)
 ])
diff --git a/gnulib.modules b/gnulib.modules
index d3d6b71..9d0c6bd 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -6,6 +6,7 @@ configmake
 dirname
 fseeko
 full-write
+getaddrinfo
 gettext
 getopt-gnu
 gitlog-to-changelog
diff --git a/lib/rtapelib.c b/lib/rtapelib.c
index 7213031..6559c5c 100644
--- a/lib/rtapelib.c
+++ b/lib/rtapelib.c
@@ -352,6 +352,15 @@ encode_oflag (char *buf, int oflag)
   if (oflag & O_TRUNC) strcat (buf, "|O_TRUNC");
 }
 
+static int
+try_resolve_hostname (const char *remote_host)
+{
+  struct addrinfo *s;
+  int r = !getaddrinfo (remote_host, NULL, NULL, &s);
+  freeaddrinfo (s);
+  return r;
+}
+
 /* Open a file (a magnetic tape device?) on the system specified in
    FILE_NAME, as the given user. FILE_NAME has the form `[USER@]HOST:FILE'.
    OPEN_MODE is O_RDONLY, O_WRONLY, etc.  If successful, return the
@@ -424,8 +433,11 @@ rmt_open__ (const char *file_name, int open_mode, int bias,
 	}
   }
 
-  /* FIXME: Should somewhat validate the decoding, here.  */
-  if (gethostbyname (remote_host) == NULL)
+  /* FIXME: We should somewhat more validate the decoding here.  */
+  if (!remote_host[0])
+    error (EXIT_ON_EXEC_ERROR, 0, _("No hostname specified, use FQDM or ipv4"));
+
+  if (!try_resolve_hostname (remote_host))
     error (EXIT_ON_EXEC_ERROR, 0, _("Cannot connect to %s: resolve failed"),
 	   remote_host);
 
-- 
1.8.5.3

Reply via email to