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_1-191-g430bc


From: Mats Erik Andersson
Subject: [SCM] GNU Inetutils branch, master, updated. inetutils-1_9_1-191-g430bcdd
Date: Thu, 18 Oct 2012 20:43:28 +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  430bcddb8ca05fe57a9fbe1119732f9b77b58fe3 (commit)
       via  d8342b4732138dae5c5de6ea16d2ffd77a4b03a0 (commit)
      from  171cec6e1ded44e7a6e394d8728c5a8cf2562940 (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=430bcddb8ca05fe57a9fbe1119732f9b77b58fe3


commit 430bcddb8ca05fe57a9fbe1119732f9b77b58fe3
Author: Mats Erik Andersson <address@hidden>
Date:   Thu Oct 18 22:37:51 2012 +0200

    ftpd: User session close down.

diff --git a/ChangeLog b/ChangeLog
index bd9878f..4a3b957 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2012-10-18  Mats Erik Andersson  <address@hidden>
 
+       ftpd: Properly close a user session.
+
+       * ftpd/ftpd.c (dologout): Call end_login().
+       * ftpd/pam.c (pam_doit): Call finishing pam_end()
+       only if ERROR is not PAM_SUCCESS.
+
+2012-10-18  Mats Erik Andersson  <address@hidden>
+
        ftpd: Security audit.
 
        * ftpd/auth.c (auth_user): Declare ERR at top.
diff --git a/ftpd/ftpd.c b/ftpd/ftpd.c
index 10a7871..5ba5e24 100644
--- a/ftpd/ftpd.c
+++ b/ftpd/ftpd.c
@@ -1784,17 +1784,13 @@ dolog (struct sockaddr *sa, socklen_t salen, struct 
credentials *pcred)
 void
 dologout (int status)
 {
-  /* Racing condition with SIGURG: If SIGURG is receive
-     here, it will jump back has root in the main loop
+  /* Race condition with SIGURG: If SIGURG is received
+     here, it will jump back has root in the main loop.
      David Greenman:address@hidden  */
   transflag = 0;
+  end_login (&cred);
 
-  if (cred.logged_in)
-    {
-      seteuid ((uid_t) 0);
-      logwtmp_keep_open (ttyline, "", "");
-    }
-  /* beware of flushing buffers after a SIGPIPE */
+  /* Beware of flushing buffers after a SIGPIPE.  */
   _exit (status);
 }
 
diff --git a/ftpd/pam.c b/ftpd/pam.c
index 6f4fe00..babb48d 100644
--- a/ftpd/pam.c
+++ b/ftpd/pam.c
@@ -208,8 +208,11 @@ pam_doit (struct credentials *pcred)
            }
        }
     }
-  pam_end (pamh, error);
-  pamh = 0;
+  if (error != PAM_SUCCESS)
+    {
+      pam_end (pamh, error);
+      pamh = NULL;
+    }
 
   return (error != PAM_SUCCESS);
 }
@@ -220,10 +223,10 @@ pam_user (const char *username, struct credentials *pcred)
 {
   int error;
 
-  if (pamh != 0)
+  if (pamh != NULL)
     {
       pam_end (pamh, PAM_ABORT);
-      pamh = 0;
+      pamh = NULL;
     }
 
   free (pcred->name);

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


commit d8342b4732138dae5c5de6ea16d2ffd77a4b03a0
Author: Mats Erik Andersson <address@hidden>
Date:   Thu Oct 18 21:26:10 2012 +0200

    ftpd: Prevent privilege escalation.

diff --git a/ChangeLog b/ChangeLog
index 61e492d..bd9878f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2012-10-18  Mats Erik Andersson  <address@hidden>
+
+       ftpd: Security audit.
+
+       * ftpd/auth.c (auth_user): Declare ERR at top.
+       Replace most `return` inside switch block by `break`.
+       Put call checkuser(PATH_FTPCHROOT) at function end
+       whenever authentication succeeded, thus making it
+       reachable for all authentication modes.
+
+       * ftpd/ftpd.c: Include <xgetcwd.h>.
+       (curdir, makedir, removedir): Remove prototype xgetcwd().
+       (main): Call localhost() before sending welcome msg.
+       (complete_login): New variable CWD.  Set EUID before
+       calling chdir() for real users.  Call xgetcwd() and
+       set HOME in environment for all kinds of user.
+       (end_login): Reset `pcred->logged_in`.
+       (getdatasock, passive): Call _exit() at failure of
+       seteuid(cred.uid).
+
+       ftp: Self documentating code.
+
+       * ftp/ftp.c (getreply): Make ARPA's reply codes
+       explicit.  Let N carry these codes, not an ASCII
+       character value.
+
 2012-10-11  Mats Erik Andersson  <address@hidden>
 
        rlogind: Server and realm detection.
diff --git a/ftp/ftp.c b/ftp/ftp.c
index 43dbb36..5c4eba2 100644
--- a/ftp/ftp.c
+++ b/ftp/ftp.c
@@ -450,10 +450,10 @@ getreply (int expecteof)
                  fflush (stdout);
                }
              code = 421;
-             return (4);
+             return (TRANSIENT);
            }
          if (c != '\r' && (verbose > 0 ||
-                           (verbose > -1 && n == '5' && dig > 4)))
+                           (verbose > -1 && n == ERROR && dig > 4)))
            {
              if (proxflag && (dig == 1 || (dig == 5 && verbose == 0)))
                printf ("%s:", hostname);
@@ -482,11 +482,11 @@ getreply (int expecteof)
              continuation++;
            }
          if (n == 0)
-           n = c;
+           n = c - '0';        /* Extract ARPA's reply code.  */
          if (cp < &reply_string[sizeof (reply_string) - 1])
            *cp++ = c;
        }
-      if (verbose > 0 || (verbose > -1 && n == '5'))
+      if (verbose > 0 || (verbose > -1 && n == ERROR))
        {
          putchar (c);
          fflush (stdout);
@@ -498,14 +498,14 @@ getreply (int expecteof)
          continue;
        }
       *cp = '\0';
-      if (n != '1')
+      if (n != PRELIM)
        cpend = 0;
       signal (SIGINT, oldintr);
       if (code == 421 || originalcode == 421)
        lostpeer (0);
       if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
        (*oldintr) (SIGINT);
-      return (n - '0');
+      return n;
     }
 }
 
diff --git a/ftpd/auth.c b/ftpd/auth.c
index 1270faa..db9668d 100644
--- a/ftpd/auth.c
+++ b/ftpd/auth.c
@@ -47,25 +47,31 @@
 int
 auth_user (const char *name, struct credentials *pcred)
 {
+  int err = 0;         /* Never remove initialisation!  */
+
   pcred->guest = 0;
 
   switch (pcred->auth_type)
     {
 #ifdef WITH_LINUX_PAM
     case AUTH_TYPE_PAM:
-      return pam_user (name, pcred);
+      err = pam_user (name, pcred);
+      break;
 #endif
 #ifdef WITH_KERBEROS
     case AUTH_TYPE_KERBEROS:
-      return -1;
+      err = -1;
+      break;
 #endif
 #ifdef WITH_KERBEROS5
     case AUTH_TYPE_KERBEROS5:
-      return -1;
+      err = -1;
+      break;
 #endif
 #ifdef WITH_OPIE
     case AUTH_TYPE_OPIE:
-      return -1;
+      err = -1;
+      break;
 #endif
     case AUTH_TYPE_PASSWD:
     default:
@@ -80,7 +86,6 @@ auth_user (const char *name, struct credentials *pcred)
        /* check for anonymous logging */
        if (strcmp (name, "ftp") == 0 || strcmp (name, "anonymous") == 0)
          {
-           int err = 0;
            if (checkuser (PATH_FTPUSERS, "ftp")
                || checkuser (PATH_FTPUSERS, "anonymous"))
              {
@@ -120,7 +125,7 @@ auth_user (const char *name, struct credentials *pcred)
            if (cp == NULL || checkuser (PATH_FTPUSERS, name))
              {
                sprintf (pcred->message, "User %s access denied.", name);
-               return 1;
+               err = 1;
              }
          }
        else
@@ -129,13 +134,16 @@ auth_user (const char *name, struct credentials *pcred)
            pcred->message = NULL;
            return 1;
          }
-       pcred->dochroot = checkuser (PATH_FTPCHROOT, pcred->name);
        snprintf (pcred->message, len,
                  "Password required for %s.", pcred->name);
-       return 0;
+       err = 0;
       }
     }
-  return -1;
+
+  if (err == 0)
+    pcred->dochroot = checkuser (PATH_FTPCHROOT, pcred->name);
+
+  return err;
 }
 
 int
diff --git a/ftpd/ftpd.c b/ftpd/ftpd.c
index d8a63d9..10a7871 100644
--- a/ftpd/ftpd.c
+++ b/ftpd/ftpd.c
@@ -98,6 +98,7 @@
 #include <glob.h>
 #include <argp.h>
 #include <error.h>
+#include <xgetcwd.h>
 
 #include <progname.h>
 #include <libinetutils.h>
@@ -556,14 +557,14 @@ main (int argc, char *argv[], char **envp)
       exit (EXIT_SUCCESS);
     }
 
-  /* Display a Welcome message if exists,
-     N.B. reply(220,) must follow.  */
-  display_file (PATH_FTPWELCOME, 220);
-
   hostname = localhost ();
   if (!hostname)
     perror_reply (550, "Local resource failure: malloc");
 
+  /* Display a Welcome message if it exists.
+     N.B. a reply(220,) must follow as continuation.  */
+  display_file (PATH_FTPWELCOME, 220);
+
   /* Tell them we're ready to roll.  */
   if (!no_version)
     reply (220, "%s FTP server (%s %s) ready.",
@@ -584,7 +585,7 @@ static char *
 curdir (void)
 {
   static char *path = 0;
-  extern char *xgetcwd (void);
+
   free (path);
   path = xgetcwd ();
   if (!path)
@@ -645,6 +646,8 @@ sgetsave (const char *s)
 static void
 complete_login (struct credentials *pcred)
 {
+  char *cwd;
+
   if (setegid ((gid_t) pcred->gid) < 0)
     {
       reply (550, "Can't set gid.");
@@ -677,28 +680,38 @@ complete_login (struct credentials *pcred)
          reply (550, "Can't change root.");
          goto bad;
        }
-      setenv ("HOME", pcred->homedir, 1);
     }
-  else if (chdir (pcred->rootdir) < 0)
+
+  if (seteuid ((uid_t) pcred->uid) < 0)
     {
-      if (chdir ("/") < 0)
+      reply (550, "Can't set uid.");
+      goto bad;
+    }
+
+  if (!pcred->guest && !pcred->dochroot)       /* Remaining case.  */
+    {
+      if (chdir (pcred->rootdir) < 0)
        {
-         reply (530, "User %s: can't change directory to %s.",
-                pcred->name, pcred->homedir);
-         goto bad;
+         if (chdir ("/") < 0)
+           {
+             reply (530, "User %s: can't change directory to %s.",
+                    pcred->name, pcred->homedir);
+             goto bad;
+           }
+
+         lreply (230, "No directory! Logging in with home=/");
        }
-      else
-       lreply (230, "No directory! Logging in with home=/");
     }
 
-  if (seteuid ((uid_t) pcred->uid) < 0)
+  cwd = xgetcwd ();
+  if (cwd)
     {
-      reply (550, "Can't set uid.");
-      goto bad;
+      setenv ("HOME", cwd, 1);
+      free (cwd);
     }
 
   /* Display a login message, if it exists.
-     N.B. reply(230,) must follow the message.  */
+     N.B. a reply(230,) must follow after this message.  */
   display_file (PATH_FTPLOGINMESG, 230);
 
   if (pcred->guest)
@@ -832,6 +845,7 @@ end_login (struct credentials *pcred)
   memset (pcred, 0, sizeof (*pcred));
   pcred->remotehost = remotehost;
   pcred->auth_type = atype;
+  pcred->logged_in = 0;
 }
 
 void
@@ -1091,7 +1105,8 @@ getdatasock (const char *mode)
        goto bad;
       sleep (tries);
     }
-  seteuid ((uid_t) cred.uid);
+  if (seteuid ((uid_t) cred.uid) != 0)
+    _exit (EXIT_FAILURE);
 
 #if defined IP_TOS && defined IPTOS_THROUGHPUT && defined IPPROTO_IP
   if (ctrl_addr.ss_family == AF_INET)
@@ -1106,7 +1121,8 @@ getdatasock (const char *mode)
 bad:
   /* Return the real value of errno (close may change it) */
   t = errno;
-  seteuid ((uid_t) cred.uid);
+  if (seteuid ((uid_t) cred.uid) != 0)
+    _exit (EXIT_FAILURE);;
   close (s);
   errno = t;
   return NULL;
@@ -1675,8 +1691,6 @@ cwd (const char *path)
 void
 makedir (const char *name)
 {
-  extern char *xgetcwd (void);
-
   LOGCMD ("mkdir", name);
   if (mkdir (name, 0777) < 0)
     perror_reply (550, name);
@@ -1712,8 +1726,8 @@ removedir (const char *name)
 void
 pwd (void)
 {
-  extern char *xgetcwd (void);
   char *path = xgetcwd ();
+
   if (path)
     {
       reply (257, "\"%s\" is current directory.", path);
@@ -1850,10 +1864,12 @@ passive (int epsv, int af)
   seteuid ((uid_t) 0);
   if (bind (pdata, (struct sockaddr *) &pasv_addr, pasv_addrlen) < 0)
     {
-      seteuid ((uid_t) cred.uid);
+      if (seteuid ((uid_t) cred.uid))
+       _exit (EXIT_FAILURE);
       goto pasv_error;
     }
-  seteuid ((uid_t) cred.uid);
+  if (seteuid ((uid_t) cred.uid))
+    _exit (EXIT_FAILURE);
   pasv_addrlen = sizeof (pasv_addr);
   if (getsockname (pdata, (struct sockaddr *) &pasv_addr, &pasv_addrlen) < 0)
     goto pasv_error;

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

Summary of changes:
 ChangeLog   |   34 ++++++++++++++++++++++++++
 ftp/ftp.c   |   12 ++++----
 ftpd/auth.c |   26 +++++++++++++-------
 ftpd/ftpd.c |   76 ++++++++++++++++++++++++++++++++++------------------------
 ftpd/pam.c  |   11 +++++---
 5 files changed, 108 insertions(+), 51 deletions(-)


hooks/post-receive
-- 
GNU Inetutils 



reply via email to

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