commit-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Inetutils branch, master, updated. inetutils-1_9-3-g01dd21c


From: Mats Erik Andersson
Subject: [SCM] GNU Inetutils branch, master, updated. inetutils-1_9-3-g01dd21c
Date: Tue, 03 Jan 2012 00:31:45 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Inetutils ".

The branch, master has been updated
       via  01dd21c666c3fdaf16b1c9d01ac9ae6c03f0297b (commit)
       via  ed4ff5db997369d08959501dbad771ba08dbe795 (commit)
      from  99c71142f24033c2027a846df7c68be60f0625ef (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=01dd21c666c3fdaf16b1c9d01ac9ae6c03f0297b


commit 01dd21c666c3fdaf16b1c9d01ac9ae6c03f0297b
Author: Mats Erik Andersson <address@hidden>
Date:   Tue Jan 3 00:45:44 2012 +0100

    ftpd: Internal address family independence.

diff --git a/ChangeLog b/ChangeLog
index 6135e5d..ed413e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2012-01-03  Mats Erik Andersson <address@hidden>
+
+       Internal address structure rewrite for `ftpd'.
+
+       * ftpd/extern.h (data_dest, his_addr): Change to `struct 
sockaddr_storage'.
+       (server_mode): New prototype: second argument `struct sockaddr *'.
+       * ftpd/ftpcmd.y (cmd): Use casts to `struct sockaddr_in' to evaluate
+       sub case `host_port'.
+       (yylex) [HAVE_SETPROCTITLE]: Compare to numeric naught, not NULL.
+       * ftpd/ftpd.c (data_dest, his_addr, ctrl_addr, data_source, pasv_addr):
+       Change to `struct sockaddr_storage'.
+       (main): Apply updated server_mode().
+       (main, getdatasock, dataconn): Set IP_TOS only for AF_INET.
+       (dataconn, passive): Copy addresses using memcpy().
+       (statfilecmd): Change SIN to `struct sockaddr_storage'.
+       (statcmd): Casts as `struct sockaddr_in' needed for A and P.
+       (passive): Clear port number depending on address family.
+       Reply with 229 for EPSV/IPv6 and 227 for PASV.
+       * ftpd/server_mode.c (check_host): Activate AF_INET6 case.
+       (server_mode): Second argument is 'struct sockaddr *', must be
+       initiated before call, and returns actual address length.
+       New variable SAVED_ADDRLEN.  Changed call due to these two.
+
 2012-01-02  Mats Erik Andersson <address@hidden>
 
        Initial address family abstraction for `ftpd'.
diff --git a/ftpd/extern.h b/ftpd/extern.h
index 758e553..d9103fb 100644
--- a/ftpd/extern.h
+++ b/ftpd/extern.h
@@ -89,9 +89,9 @@ extern char *sgetsave (const char *);
 
 /* Exported from ftpd.c.  */
 jmp_buf errcatch;
-extern struct sockaddr_in data_dest;
+extern struct sockaddr_storage data_dest;
 extern socklen_t data_dest_len;
-extern struct sockaddr_in his_addr;
+extern struct sockaddr_storage his_addr;
 extern socklen_t his_addrlen;
 extern int logged_in;
 extern struct passwd *pw;
@@ -113,7 +113,7 @@ extern char tmpline[];
 extern off_t restart_point;
 
 /* Exported from server_mode.c.  */
-extern int server_mode (const char *pidfile, struct sockaddr_in *phis_addr,
+extern int server_mode (const char *pidfile, struct sockaddr *phis_addr,
                        socklen_t *phis_addrlen, char *argv[]);
 
 /* Credential for the request.  */
diff --git a/ftpd/ftpcmd.y b/ftpd/ftpcmd.y
index 3f27a53..62bbcbc 100644
--- a/ftpd/ftpcmd.y
+++ b/ftpd/ftpcmd.y
@@ -182,10 +182,10 @@ cmd
                                pdata = -1;
                        }
                        if ($2) {
-                               if (memcmp (&his_addr.sin_addr,
-                                       &data_dest.sin_addr,
-                                       sizeof (data_dest.sin_addr)) == 0 &&
-                                       ntohs (data_dest.sin_port) >
+                               if (memcmp (&((struct sockaddr_in *) 
&his_addr)->sin_addr,
+                                       &((struct sockaddr_in *) 
&data_dest)->sin_addr,
+                                       sizeof (struct in_addr)) == 0 &&
+                                       ntohs (((struct sockaddr_in *) 
&data_dest)->sin_port) >
                                        IPPORT_RESERVED) {
                                        reply (200, "PORT command successful.");
                                }
@@ -995,7 +995,7 @@ yylex(void)
                        }
                         alarm(0);
 #ifdef HAVE_SETPROCTITLE
-                       if (strncasecmp(cbuf, "PASS", 4) != NULL)
+                       if (strncasecmp(cbuf, "PASS", 4) != 0)
                                setproctitle("%s: %s", proctitle, cbuf);
 #endif /* HAVE_SETPROCTITLE */
                        if ((cp = strchr(cbuf, '\r'))) {
diff --git a/ftpd/ftpd.c b/ftpd/ftpd.c
index f483131..dfba2fe 100644
--- a/ftpd/ftpd.c
+++ b/ftpd/ftpd.c
@@ -122,9 +122,9 @@ extern int fclose (FILE *);
 #endif
 
 /* Exported to ftpcmd.h.  */
-struct sockaddr_in data_dest;  /* Data port.  */
+struct sockaddr_storage data_dest;     /* Data port.  */
 socklen_t data_dest_len;
-struct sockaddr_in his_addr;   /* Peer address.  */
+struct sockaddr_storage his_addr;      /* Peer address.  */
 socklen_t his_addrlen;
 int logging;                   /* Enable log to syslog.  */
 int type = TYPE_A;             /* Default TYPE_A.  */
@@ -143,11 +143,11 @@ char portstr[8];          /* Numeric port as string.  */
 /* Requester credentials.  */
 struct credentials cred;
 
-static struct sockaddr_in ctrl_addr;   /* Control address.  */
+static struct sockaddr_storage ctrl_addr;      /* Control address.  */
 static socklen_t ctrl_addrlen;
-static struct sockaddr_in data_source; /* Port address.  */
+static struct sockaddr_storage data_source;    /* Port address.  */
 static socklen_t data_source_len;
-static struct sockaddr_in pasv_addr;   /* Pasv address.  */
+static struct sockaddr_storage pasv_addr;      /* Pasv address.  */
 static socklen_t pasv_addrlen;
 
 static int data = -1;          /* Port data connection socket.  */
@@ -457,7 +457,9 @@ main (int argc, char *argv[], char **envp)
            argv[--argc] = NULL;
          }
 #endif
-      if (server_mode (pid_file, &his_addr, &his_addrlen, argv) < 0)
+      his_addrlen = sizeof (his_addr);
+      if (server_mode (pid_file, (struct sockaddr *) &his_addr,
+                       &his_addrlen, argv) < 0)
        exit (EXIT_FAILURE);
     }
   else
@@ -493,12 +495,13 @@ main (int argc, char *argv[], char **envp)
 
 #if defined IP_TOS && defined IPTOS_LOWDELAY && defined IPPROTO_IP
   /* To  minimize delays for interactive traffic.  */
-  {
-    int tos = IPTOS_LOWDELAY;
-    if (setsockopt (STDIN_FILENO, IPPROTO_IP, IP_TOS,
+  if (ctrl_addr.ss_family == AF_INET)
+    {
+      int tos = IPTOS_LOWDELAY;
+      if (setsockopt (STDIN_FILENO, IPPROTO_IP, IP_TOS,
                    (char *) &tos, sizeof (int)) < 0)
-      syslog (LOG_WARNING, "setsockopt (IP_TOS): %m");
-  }
+       syslog (LOG_WARNING, "setsockopt (IP_TOS): %m");
+    }
 #endif
 
 #ifdef SO_OOBINLINE
@@ -1022,7 +1025,7 @@ getdatasock (const char *mode)
   if (data >= 0)
     return fdopen (data, mode);
   seteuid ((uid_t) 0);
-  s = socket (ctrl_addr.sin_family, SOCK_STREAM, 0);
+  s = socket (ctrl_addr.ss_family, SOCK_STREAM, 0);
   if (s < 0)
     goto bad;
 
@@ -1049,11 +1052,12 @@ getdatasock (const char *mode)
   seteuid ((uid_t) cred.uid);
 
 #if defined IP_TOS && defined IPTOS_THROUGHPUT && defined IPPROTO_IP
-  {
-    int on = IPTOS_THROUGHPUT;
-    if (setsockopt (s, IPPROTO_IP, IP_TOS, (char *) &on, sizeof (int)) < 0)
-      syslog (LOG_WARNING, "setsockopt (IP_TOS): %m");
-  }
+  if (ctrl_addr.ss_family == AF_INET)
+    {
+      int on = IPTOS_THROUGHPUT;
+      if (setsockopt (s, IPPROTO_IP, IP_TOS, (char *) &on, sizeof (int)) < 0)
+       syslog (LOG_WARNING, "setsockopt (IP_TOS): %m");
+    }
 #endif
 
   return (fdopen (s, mode));
@@ -1100,10 +1104,11 @@ dataconn (const char *name, off_t size, const char 
*mode)
       pdata = s;
 #if defined IP_TOS && defined IPTOS_THROUGHPUT && defined IPPROTO_IP
       /* Optimize throughput.  */
-      {
-       int tos = IPTOS_THROUGHPUT;
-       setsockopt (s, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof (int));
-      }
+      if (from.ss_family == AF_INET)
+       {
+         int tos = IPTOS_THROUGHPUT;
+         setsockopt (s, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof (int));
+       }
 #endif
 #ifdef SO_KEEPALIVE
       /* Set keepalives on the socket to detect dropped conns.  */
@@ -1126,7 +1131,7 @@ dataconn (const char *name, off_t size, const char *mode)
     }
   if (usedefault)
     {
-      data_dest = his_addr;
+      memcpy (&data_dest, &his_addr, sizeof (data_dest));
       data_dest_len = his_addrlen;
     }
   usedefault = 1;
@@ -1428,7 +1433,7 @@ statfilecmd (const char *filename)
 void
 statcmd (void)
 {
-  struct sockaddr_in *sin;
+  struct sockaddr_storage *sin;
   unsigned char *a, *p;
 
   lreply (211, "%s FTP server status:", hostname);
@@ -1479,8 +1484,8 @@ statcmd (void)
       printf ("     PORT");
       sin = &data_dest;
     printaddr:
-      a = (unsigned char *) & sin->sin_addr;
-      p = (unsigned char *) & sin->sin_port;
+      a = (unsigned char *) & ((struct sockaddr_in *) sin)->sin_addr;
+      p = (unsigned char *) & ((struct sockaddr_in *) sin)->sin_port;
 #define UC(b) (((int) b) & 0xff)
       printf (" (%d,%d,%d,%d,%d,%d)\r\n", UC (a[0]),
              UC (a[1]), UC (a[2]), UC (a[3]), UC (p[0]), UC (p[1]));
@@ -1734,15 +1739,20 @@ passive (void)
 {
   char *p, *a;
 
-  pdata = socket (ctrl_addr.sin_family, SOCK_STREAM, 0);
+  pdata = socket (ctrl_addr.ss_family, SOCK_STREAM, 0);
   if (pdata < 0)
     {
       perror_reply (425, "Can't open passive connection");
       return;
     }
-  pasv_addr = ctrl_addr;
+  memcpy (&pasv_addr, &ctrl_addr, sizeof (pasv_addr));
   pasv_addrlen = ctrl_addrlen;
-  pasv_addr.sin_port = 0;
+  /* Erase the port number.  */
+  if (pasv_addr.ss_family == AF_INET6)
+    ((struct sockaddr_in6 *) &pasv_addr)->sin6_port = 0;
+  else /* !AF_INET6 */
+    ((struct sockaddr_in *) &pasv_addr)->sin_port = 0;
+
   seteuid ((uid_t) 0);
   if (bind (pdata, (struct sockaddr *) &pasv_addr, pasv_addrlen) < 0)
     {
@@ -1755,14 +1765,24 @@ passive (void)
     goto pasv_error;
   if (listen (pdata, 1) < 0)
     goto pasv_error;
-  a = (char *) &pasv_addr.sin_addr;
-  p = (char *) &pasv_addr.sin_port;
+
+  if (pasv_addr.ss_family == AF_INET6)
+    {
+      reply (229, "Extended Passive Mode OK (|||%u|)",
+            ((struct sockaddr_in6 *) &pasv_addr)->sin6_port);
+      return;
+    }
+  else
+    {
+      a = (char *) &((struct sockaddr_in *) &pasv_addr)->sin_addr;
+      p = (char *) &((struct sockaddr_in *) &pasv_addr)->sin_port;
 
 #define UC(b) (((int) b) & 0xff)
 
-  reply (227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC (a[0]),
-        UC (a[1]), UC (a[2]), UC (a[3]), UC (p[0]), UC (p[1]));
-  return;
+      reply (227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC (a[0]),
+            UC (a[1]), UC (a[2]), UC (a[3]), UC (p[0]), UC (p[1]));
+      return;
+    }
 
 pasv_error:
   close (pdata);
diff --git a/ftpd/server_mode.c b/ftpd/server_mode.c
index 84820d0..6ef6ef4 100644
--- a/ftpd/server_mode.c
+++ b/ftpd/server_mode.c
@@ -57,7 +57,7 @@ check_host (struct sockaddr *sa, socklen_t len)
   char name[NI_MAXHOST];
 
   if (sa->sa_family != AF_INET
-      /* && sa->sa_family != AF_INET6 */)
+      && sa->sa_family != AF_INET6)
     return 1;
 
   (void) getnameinfo(sa, len, addr, sizeof (addr), NULL, 0, NI_NUMERICHOST);
@@ -93,14 +93,18 @@ reapchild (int signo _GL_UNUSED_PARAMETER)
   errno = save_errno;
 }
 
+/* The parameter '*phis_addrlen' must be initiated
+   with the space available at calling time.
+   The actually used space will then be returned.  */
 int
-server_mode (const char *pidfile, struct sockaddr_in *phis_addr,
+server_mode (const char *pidfile, struct sockaddr *phis_addr,
             socklen_t *phis_addrlen, char *argv[])
 {
   int ctl_sock, fd;
   struct servent *sv;
   int port, err;
   char portstr[8];
+  socklen_t saved_addrlen = *phis_addrlen;
   struct addrinfo hints, *res, *ai;
 
   /* Become a daemon.  */
@@ -189,8 +193,8 @@ server_mode (const char *pidfile, struct sockaddr_in 
*phis_addr,
      children to handle them.  */
   while (1)
     {
-      *phis_addrlen = sizeof (*phis_addr);
-      fd = accept (ctl_sock, (struct sockaddr *) phis_addr, phis_addrlen);
+      *phis_addrlen = saved_addrlen;
+      fd = accept (ctl_sock, phis_addr, phis_addrlen);
       if (fork () == 0)                /* child */
        {
          dup2 (fd, 0);
@@ -203,7 +207,7 @@ server_mode (const char *pidfile, struct sockaddr_in 
*phis_addr,
 
 #ifdef WITH_WRAP
   /* In the child.  */
-  if (!check_host ((struct sockaddr *) phis_addr, *phis_addrlen))
+  if (!check_host (phis_addr, *phis_addrlen))
     return -1;
 #endif
 

http://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=ed4ff5db997369d08959501dbad771ba08dbe795


commit ed4ff5db997369d08959501dbad771ba08dbe795
Author: Mats Erik Andersson <address@hidden>
Date:   Mon Jan 2 22:29:14 2012 +0100

    ftpd: First step for address independence.

diff --git a/ChangeLog b/ChangeLog
index 16cbaa6..6135e5d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2012-01-02  Mats Erik Andersson <address@hidden>
+
+       Initial address family abstraction for `ftpd'.
+
+       * ftpd/extern.h: Include <netinet/in.h>.
+       (data_dest_len, his_addr_len): New socklen_t variables.
+       (server_mode): Use a socklen_t argument.
+       * ftpd/ftpcmd.y: Include <netdb.h>.
+       (cmd) [unix || __unix__]: SYS_TYPE must recognize __unix__.
+       (host_port): Use getaddrinfo to initiate DATA_DEST.
+       * ftpd/ftpd.c (data_set_len, his_addrlen, addrstr, portstr,
+       ctrl_addrlen, data_source_len, pasv_addrlen): New variables.
+       [HAVE_LIBWRAP] (check_host): Prototype extended with socklen_t.
+       (dolog): Likewise.
+       (main): Use HIS_ADDRLEN, CTRL_ADDRLEN instead of local ADDRLEN.
+       Changed calls to server_mode and dolog due to new prototypes.
+       (getdatasock): Address family determined by CTRL_ADDR.  Inherit
+       fields in DATA_SOURCE from CTRL_ADDR, and DATA_SOURCE_LEN from
+       CTRL_ADDRLEN.  Dynamic address length to bind().
+       (dataconn): Use FROM as `struct sockaddr_storage.  Change socket
+       descriptor S to be `int'.  Assign DATA_DEST and DATA_DEST_LEN
+       in a block.  Use getnameinfo for error message.  Dynamic socket
+       length in connect().
+       (statcmd): Lookup using getnameinfo().
+       (dolog): New prototype, extended by `socklen_t'.  Likewise.
+       (passive): Removed variable LEN, now using length and family stored
+       in address variables, which are global.
+       * ftpd/server_mode.c (check_host): New prototype: adding `socklen_t'.
+       Removed SIN, HP. New variables ERR, NAME.  Lookup uses getnameinfo().
+       (server_mode): New prototype: adding `socklen_t'.  Delete SERVER_ADDR.
+       New varables ERR, PORTSTR, HINTS, RES, AI.  Lookup uses getaddrinfo
+       and a loop to get listener.  Server loop removes ADDRLEN, now setting
+       address length by use of PHIS_ADDRLEN.
+
 2011-12-31  Alfred M. Szmidt  <address@hidden>
 
        inetutils 1.9
diff --git a/ftpd/extern.h b/ftpd/extern.h
index 8fee0a2..758e553 100644
--- a/ftpd/extern.h
+++ b/ftpd/extern.h
@@ -51,6 +51,7 @@
 #include <setjmp.h>
 #include <getopt.h>
 #include <sys/types.h>
+#include <netinet/in.h>
 
 extern void cwd (const char *);
 extern int checkuser (const char *filename, const char *name);
@@ -89,7 +90,9 @@ extern char *sgetsave (const char *);
 /* Exported from ftpd.c.  */
 jmp_buf errcatch;
 extern struct sockaddr_in data_dest;
+extern socklen_t data_dest_len;
 extern struct sockaddr_in his_addr;
+extern socklen_t his_addrlen;
 extern int logged_in;
 extern struct passwd *pw;
 extern int guest;
@@ -111,7 +114,7 @@ extern off_t restart_point;
 
 /* Exported from server_mode.c.  */
 extern int server_mode (const char *pidfile, struct sockaddr_in *phis_addr,
-                       char *argv[]);
+                       socklen_t *phis_addrlen, char *argv[]);
 
 /* Credential for the request.  */
 struct credentials
diff --git a/ftpd/ftpcmd.y b/ftpd/ftpcmd.y
index 879b4c5..3f27a53 100644
--- a/ftpd/ftpcmd.y
+++ b/ftpd/ftpcmd.y
@@ -62,6 +62,7 @@
 #include <sys/stat.h>
 
 #include <netinet/in.h>
+#include <netdb.h>
 #include <arpa/ftp.h>
 
 #include <ctype.h>
@@ -493,7 +494,7 @@ cmd
 #endif
 #endif
 
-#ifdef unix
+#if defined unix || defined __unix__
                        sys_type = "UNIX";
 #else
                        sys_type = "UNKNOWN";
@@ -608,16 +609,29 @@ host_port
        : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
                NUMBER COMMA NUMBER
                {
-                       char *a, *p;
-
-                       a = (char *)&data_dest.sin_addr;
-                       a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
-                       p = (char *)&data_dest.sin_port;
-                       p[0] = $9; p[1] = $11;
-                       data_dest.sin_family = AF_INET;
-#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-                       data_dest.sin_len = sizeof (struct sockaddr_in);
+                       int err;
+                       char a[INET_ADDRSTRLEN], p[8];
+                       struct addrinfo hints, *res;
+
+                       snprintf (a, sizeof (a), "%u.%u.%u.%u",
+                               $1 & 0xff, $3 & 0xff, $5 & 0xff, $7 & 0xff);
+                       snprintf (p, sizeof (p), "%u",
+                               (($9 & 0xff) << 8) + ($11 & 0xff));
+                       memset (&hints, 0, sizeof (hints));
+                       hints.ai_family = AF_INET;
+                       hints.ai_socktype = SOCK_STREAM;
+#ifdef AI_ADDRCONFIG
+                       hints.ai_flags = AI_ADDRCONFIG;
 #endif
+                       err = getaddrinfo (a, p, &hints, &res);
+                       if (err)
+                         reply (550, "Address failure: %s,%s", a, p);
+                       else
+                         {
+                           memcpy (&data_dest, res->ai_addr, res->ai_addrlen);
+                           data_dest_len = res->ai_addrlen;
+                           freeaddrinfo (res);
+                         }
                }
        ;
 
diff --git a/ftpd/ftpd.c b/ftpd/ftpd.c
index f7e945c..f483131 100644
--- a/ftpd/ftpd.c
+++ b/ftpd/ftpd.c
@@ -123,7 +123,9 @@ extern int fclose (FILE *);
 
 /* Exported to ftpcmd.h.  */
 struct sockaddr_in data_dest;  /* Data port.  */
+socklen_t data_dest_len;
 struct sockaddr_in his_addr;   /* Peer address.  */
+socklen_t his_addrlen;
 int logging;                   /* Enable log to syslog.  */
 int type = TYPE_A;             /* Default TYPE_A.  */
 int form = FORM_N;             /* Default FORM_N.  */
@@ -135,13 +137,18 @@ int pdata = -1;                   /* For passive mode.  */
 char *hostname;                        /* Who we are.  */
 int usedefault = 1;            /* For data transfers.  */
 char tmpline[7];               /* Temp buffer use in OOB.  */
+char addrstr[NI_MAXHOST];      /* Host name or address string.  */
+char portstr[8];               /* Numeric port as string.  */
 
 /* Requester credentials.  */
 struct credentials cred;
 
 static struct sockaddr_in ctrl_addr;   /* Control address.  */
+static socklen_t ctrl_addrlen;
 static struct sockaddr_in data_source; /* Port address.  */
+static socklen_t data_source_len;
 static struct sockaddr_in pasv_addr;   /* Pasv address.  */
+static socklen_t pasv_addrlen;
 
 static int data = -1;          /* Port data connection socket.  */
 static jmp_buf urgcatch;
@@ -230,12 +237,12 @@ extern int yyparse (void);
 
 static void ack (const char *);
 #ifdef HAVE_LIBWRAP
-static int check_host (struct sockaddr *sa);
+static int check_host (struct sockaddr *sa, socklen_t len);
 #endif
 static void complete_login (struct credentials *);
 static char *curdir (void);
 static FILE *dataconn (const char *, off_t, const char *);
-static void dolog (struct sockaddr_in *, struct credentials *);
+static void dolog (struct sockaddr *, socklen_t, struct credentials *);
 static void end_login (struct credentials *);
 static FILE *getdatasock (const char *);
 static char *gunique (const char *);
@@ -450,14 +457,14 @@ main (int argc, char *argv[], char **envp)
            argv[--argc] = NULL;
          }
 #endif
-      if (server_mode (pid_file, &his_addr, argv) < 0)
+      if (server_mode (pid_file, &his_addr, &his_addrlen, argv) < 0)
        exit (EXIT_FAILURE);
     }
   else
     {
-      socklen_t addrlen = sizeof (his_addr);
+      his_addrlen = sizeof (his_addr);
       if (getpeername (STDIN_FILENO, (struct sockaddr *) &his_addr,
-                      &addrlen) < 0)
+                      &his_addrlen) < 0)
        {
          syslog (LOG_ERR, "getpeername (%s): %m", program_name);
          exit (EXIT_FAILURE);
@@ -475,9 +482,9 @@ main (int argc, char *argv[], char **envp)
 
   /* Get info on the ctrl connection.  */
   {
-    socklen_t addrlen = sizeof (ctrl_addr);
+    ctrl_addrlen = sizeof (ctrl_addr);
     if (getsockname (STDIN_FILENO, (struct sockaddr *) &ctrl_addr,
-                    &addrlen) < 0)
+                    &ctrl_addrlen) < 0)
       {
        syslog (LOG_ERR, "getsockname (%s): %m", program_name);
        exit (EXIT_FAILURE);
@@ -519,7 +526,7 @@ main (int argc, char *argv[], char **envp)
     syslog (LOG_ERR, "fcntl F_SETOWN: %m");
 #endif
 
-  dolog (&his_addr, &cred);
+  dolog ((struct sockaddr *) &his_addr, his_addrlen, &cred);
 
   /* Deal with login disable.  */
   if (display_file (PATH_NOLOGIN, 530) == 0)
@@ -1015,7 +1022,7 @@ getdatasock (const char *mode)
   if (data >= 0)
     return fdopen (data, mode);
   seteuid ((uid_t) 0);
-  s = socket (AF_INET, SOCK_STREAM, 0);
+  s = socket (ctrl_addr.sin_family, SOCK_STREAM, 0);
   if (s < 0)
     goto bad;
 
@@ -1028,15 +1035,12 @@ getdatasock (const char *mode)
   }
 
   /* anchor socket to avoid multi-homing problems */
-  data_source.sin_family = AF_INET;
-  data_source.sin_addr = ctrl_addr.sin_addr;
-#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-  data_source.sin_len = sizeof (struct sockaddr_in);
-#endif
+  memcpy (&data_source, &ctrl_addr, sizeof (data_source));
+  data_source_len = ctrl_addrlen;
+
   for (tries = 1;; tries++)
     {
-      if (bind (s, (struct sockaddr *) &data_source,
-               sizeof (data_source)) >= 0)
+      if (bind (s, (struct sockaddr *) &data_source, data_source_len) >= 0)
        break;
       if (errno != EADDRINUSE || tries > 10)
        goto bad;
@@ -1077,8 +1081,8 @@ dataconn (const char *name, off_t size, const char *mode)
     *sizebuf = '\0';
   if (pdata >= 0)
     {
-      struct sockaddr_in from;
-      socklen_t s;
+      struct sockaddr_storage from;
+      int s;
       socklen_t fromlen = sizeof (from);
 
       signal (SIGALRM, toolong);
@@ -1121,19 +1125,25 @@ dataconn (const char *name, off_t size, const char 
*mode)
       return fdopen (data, mode);
     }
   if (usedefault)
-    data_dest = his_addr;
+    {
+      data_dest = his_addr;
+      data_dest_len = his_addrlen;
+    }
   usedefault = 1;
   file = getdatasock (mode);
   if (file == NULL)
     {
-      reply (425, "Can't create data socket (%s,%d): %s.",
-            inet_ntoa (data_source.sin_addr),
-            ntohs (data_source.sin_port), strerror (errno));
+      int oerrno = errno;
+      (void) getnameinfo ((struct sockaddr *) &data_source, data_source_len,
+                         addrstr, sizeof (addrstr),
+                         portstr, sizeof (portstr),
+                         NI_NUMERICSERV);
+      reply (425, "Can't create data socket (%s,%s): %s.",
+            addrstr, portstr, strerror (oerrno));
       return NULL;
     }
   data = fileno (file);
-  while (connect (data, (struct sockaddr *) &data_dest,
-                 sizeof (data_dest)) < 0)
+  while (connect (data, (struct sockaddr *) &data_dest, data_dest_len) < 0)
     {
       if (errno == EADDRINUSE && retry < swaitmax)
        {
@@ -1425,8 +1435,10 @@ statcmd (void)
   if (!no_version)
     printf ("     ftpd (%s) %s\r\n", PACKAGE_NAME, PACKAGE_VERSION);
   printf ("     Connected to %s", cred.remotehost);
+  (void) getnameinfo ((struct sockaddr *) &his_addr, his_addrlen,
+                     addrstr, sizeof (addrstr), NULL, 0, NI_NUMERICHOST);
   if (!isdigit (cred.remotehost[0]))
-    printf (" (%s)", inet_ntoa (his_addr.sin_addr));
+    printf (" (%s)", addrstr);
   printf ("\r\n");
   if (cred.logged_in)
     {
@@ -1645,19 +1657,12 @@ renamecmd (const char *from, const char *to)
 }
 
 static void
-dolog (struct sockaddr_in *sin, struct credentials *pcred)
+dolog (struct sockaddr *sa, socklen_t salen, struct credentials *pcred)
 {
-  const char *name;
-  struct hostent *hp = gethostbyaddr ((char *) &sin->sin_addr,
-                                     sizeof (struct in_addr), AF_INET);
-
-  if (hp)
-    name = hp->h_name;
-  else
-    name = inet_ntoa (sin->sin_addr);
+  (void) getnameinfo (sa, salen, addrstr, sizeof (addrstr), NULL, 0, 0);
 
   free (pcred->remotehost);
-  pcred->remotehost = sgetsave (name);
+  pcred->remotehost = sgetsave (addrstr);
 
 #ifdef HAVE_SETPROCTITLE
   snprintf (proctitle, sizeof (proctitle), "%s: connected",
@@ -1727,26 +1732,26 @@ myoob (int signo _GL_UNUSED_PARAMETER)
 void
 passive (void)
 {
-  socklen_t len;
   char *p, *a;
 
-  pdata = socket (AF_INET, SOCK_STREAM, 0);
+  pdata = socket (ctrl_addr.sin_family, SOCK_STREAM, 0);
   if (pdata < 0)
     {
       perror_reply (425, "Can't open passive connection");
       return;
     }
   pasv_addr = ctrl_addr;
+  pasv_addrlen = ctrl_addrlen;
   pasv_addr.sin_port = 0;
   seteuid ((uid_t) 0);
-  if (bind (pdata, (struct sockaddr *) &pasv_addr, sizeof (pasv_addr)) < 0)
+  if (bind (pdata, (struct sockaddr *) &pasv_addr, pasv_addrlen) < 0)
     {
       seteuid ((uid_t) cred.uid);
       goto pasv_error;
     }
   seteuid ((uid_t) cred.uid);
-  len = sizeof (pasv_addr);
-  if (getsockname (pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
+  pasv_addrlen = sizeof (pasv_addr);
+  if (getsockname (pdata, (struct sockaddr *) &pasv_addr, &pasv_addrlen) < 0)
     goto pasv_error;
   if (listen (pdata, 1) < 0)
     goto pasv_error;
diff --git a/ftpd/server_mode.c b/ftpd/server_mode.c
index d8ca5a6..84820d0 100644
--- a/ftpd/server_mode.c
+++ b/ftpd/server_mode.c
@@ -50,25 +50,24 @@ int allow_severity = LOG_INFO;
 int deny_severity = LOG_NOTICE;
 
 static int
-check_host (struct sockaddr *sa)
+check_host (struct sockaddr *sa, socklen_t len)
 {
-  struct sockaddr_in *sin;
-  struct hostent *hp;
-  char *addr;
+  int err;
+  char addr[INET6_ADDRSTRLEN];
+  char name[NI_MAXHOST];
 
-  if (sa->sa_family != AF_INET)
+  if (sa->sa_family != AF_INET
+      /* && sa->sa_family != AF_INET6 */)
     return 1;
 
-  sin = (struct sockaddr_in *) sa;
-  hp = gethostbyaddr ((char *) &sin->sin_addr,
-                     sizeof (struct in_addr), AF_INET);
-  addr = inet_ntoa (sin->sin_addr);
-  if (hp)
+  (void) getnameinfo(sa, len, addr, sizeof (addr), NULL, 0, NI_NUMERICHOST);
+  err = getnameinfo(sa, len, name, sizeof (name), NULL, 0, NI_NAMEREQD);
+  if (!err)
     {
-      if (!hosts_ctl ("ftpd", hp->h_name, addr, STRING_UNKNOWN))
+      if (!hosts_ctl ("ftpd", name, addr, STRING_UNKNOWN))
        {
          syslog (LOG_NOTICE, "tcpwrappers rejected: %s [%s]",
-                 hp->h_name, addr);
+                 name, addr);
          return 0;
        }
     }
@@ -95,12 +94,14 @@ reapchild (int signo _GL_UNUSED_PARAMETER)
 }
 
 int
-server_mode (const char *pidfile, struct sockaddr_in *phis_addr, char *argv[])
+server_mode (const char *pidfile, struct sockaddr_in *phis_addr,
+            socklen_t *phis_addrlen, char *argv[])
 {
   int ctl_sock, fd;
   struct servent *sv;
-  int port;
-  static struct sockaddr_in server_addr;       /* Our address.  */
+  int port, err;
+  char portstr[8];
+  struct addrinfo hints, *res, *ai;
 
   /* Become a daemon.  */
   if (daemon (1, 1) < 0)
@@ -113,38 +114,61 @@ server_mode (const char *pidfile, struct sockaddr_in 
*phis_addr, char *argv[])
   /* Get port for ftp/tcp.  */
   sv = getservbyname ("ftp", "tcp");
   port = (sv == NULL) ? DEFPORT : ntohs (sv->s_port);
+  snprintf (portstr, sizeof (portstr), "%u", port);
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_family = AF_INET;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = AI_PASSIVE;
+#ifdef AI_ADDRCONFIG
+  hints.ai_flags |= AI_ADDRCONFIG;
+#endif
 
-  /* Open socket, bind and start listen.  */
-  ctl_sock = socket (AF_INET, SOCK_STREAM, 0);
-  if (ctl_sock < 0)
+  err = getaddrinfo (NULL, portstr, &hints, &res);
+  if (err)
     {
-      syslog (LOG_ERR, "control socket: %m");
+      syslog (LOG_ERR, "control socket: %s", gai_strerror (err));
       return -1;
     }
+  /* Attempt to open socket, bind and start listen.  */
+  for (ai = res; ai; ai = ai->ai_next)
+    {
+      ctl_sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+      if (ctl_sock < 0)
+       continue;
 
-  /* Enable local address reuse.  */
-  {
-    int on = 1;
-    if (setsockopt (ctl_sock, SOL_SOCKET, SO_REUSEADDR,
-                   (char *) &on, sizeof (on)) < 0)
-      syslog (LOG_ERR, "control setsockopt: %m");
-  }
+      /* Enable local address reuse.  */
+      {
+       int on = 1;
+       if (setsockopt (ctl_sock, SOL_SOCKET, SO_REUSEADDR,
+                       (char *) &on, sizeof (on)) < 0)
+         syslog (LOG_ERR, "control setsockopt: %m");
+      }
 
-  memset (&server_addr, 0, sizeof server_addr);
-  server_addr.sin_family = AF_INET;
-  server_addr.sin_port = htons (port);
-#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-  server_addr.sin_len = sizeof (struct sockaddr_in);
-#endif
+      if (bind (ctl_sock, ai->ai_addr, ai->ai_addrlen))
+       {
+         close (ctl_sock);
+         ctl_sock = -1;
+         continue;
+       }
 
-  if (bind (ctl_sock, (struct sockaddr *) &server_addr, sizeof server_addr))
-    {
-      syslog (LOG_ERR, "control bind: %m");
-      return -1;
+      if (listen (ctl_sock, 32) < 0)
+       {
+         close (ctl_sock);
+         ctl_sock = -1;
+         continue;
+       }
+
+      /* Accept the first choice!  */
+      break;
     }
-  if (listen (ctl_sock, 32) < 0)
+
+  if (res)
+    freeaddrinfo (res);
+
+  if (ai == NULL)
     {
-      syslog (LOG_ERR, "control listen: %m");
+      syslog (LOG_ERR, "control socket: %m");
       return -1;
     }
 
@@ -165,8 +189,8 @@ server_mode (const char *pidfile, struct sockaddr_in 
*phis_addr, char *argv[])
      children to handle them.  */
   while (1)
     {
-      socklen_t addrlen = sizeof (*phis_addr);
-      fd = accept (ctl_sock, (struct sockaddr *) phis_addr, &addrlen);
+      *phis_addrlen = sizeof (*phis_addr);
+      fd = accept (ctl_sock, (struct sockaddr *) phis_addr, phis_addrlen);
       if (fork () == 0)                /* child */
        {
          dup2 (fd, 0);
@@ -179,7 +203,7 @@ server_mode (const char *pidfile, struct sockaddr_in 
*phis_addr, char *argv[])
 
 #ifdef WITH_WRAP
   /* In the child.  */
-  if (!check_host ((struct sockaddr *) phis_addr))
+  if (!check_host ((struct sockaddr *) phis_addr, *phis_addrlen))
     return -1;
 #endif
 

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog          |   57 ++++++++++++++++++
 ftpd/extern.h      |   11 ++-
 ftpd/ftpcmd.y      |   44 +++++++++-----
 ftpd/ftpd.c        |  163 ++++++++++++++++++++++++++++++----------------------
 ftpd/server_mode.c |  110 ++++++++++++++++++++++-------------
 5 files changed, 256 insertions(+), 129 deletions(-)


hooks/post-receive
-- 
GNU Inetutils 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]