ftpd authentication [PATCH] ftpd: NOMMU/chroot fix

Morten Kvistgaard MK at pch-engineering.dk
Tue Jun 24 12:25:11 UTC 2014


Hello Bernhard,

The first patch for ftpd authentication is a bug fix for NOMMU platforms. 

You need a working jail in order for the authentication to make sense. (And I've got a NOMMU platform.) The patch has been tested on both NOMMU and normal platforms. 

The patches are in collaboration with walter harms. 

Btw, the vsftpd might be nice (and rather big!), but it takes very little code to add basic authentication to the busybox ftpd. (Many other busybox apps has the same.)

Regards,
Morten Kvistgaard

---
networking/ftpd.c | 44 ++++++++++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/networking/ftpd.c b/networking/ftpd.c index 33db964..960984b 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -617,21 +617,29 @@ handle_retr(void)
static int
popen_ls(const char *opt)
{
-                           const char *argv[5];
                            struct fd_pair outfd;
                            pid_t pid;
+#if BB_MMU
+                          #define FTP_ARG_NO 2
+                          const char *argv[4];

-                           argv[0] = "ftpd";
+                          argv[0] = "ls";
                            argv[1] = opt; /* "-l" or "-1" */
-#if BB_MMU
-                           argv[2] = "--";
+                          argv[2] = G.ftp_arg;
+                          argv[3] = NULL;
#else
-                           /* NOMMU ftpd ls helper chdirs to argv[2],
-                           * preventing peer from seeing real root. */
-                           argv[2] = xrealloc_getcwd_or_warn(NULL);
+                          #define FTP_ARG_NO 4
+                          const char *argv[6];
+
+                          argv[0] = "ftpd";
+                          argv[1] = opt; /* "-l" or "-1" */
+                          /* NOMMU ftpd ls helper chdirs to argv[3],
+     * preventing peer from seeing real root. */
+                          argv[2] = G.chroot_dir;
+                          argv[3] = xrealloc_getcwd_or_warn(NULL);
+                          argv[4] = G.ftp_arg;
+                          argv[5] = NULL;
#endif
-                           argv[3] = G.ftp_arg;
-                           argv[4] = NULL;

                             /* Improve compatibility with non-RFC conforming FTP clients
                             * which send e.g. "LIST -l", "LIST -la", "LIST -aL".
@@ -642,7 +650,7 @@ popen_ls(const char *opt)
                                                         const char *tmp = strchr(G.ftp_arg, ' ');
                                                         if (tmp) /* skip the space */
                                                                                      tmp++;
-                                                        argv[3] = tmp;
+                                                       argv[FTP_ARG_NO] = tmp;
                            }

                             xpiped_pair(outfd);
@@ -659,6 +667,7 @@ popen_ls(const char *opt)
                                                          * relative to current directory */
                                                         if (fchdir(G.root_fd) != 0)
                                                                                      _exit(127);
+                                                       xchroot(".");   /* will break out of jail */
                                                         /*close(G.root_fd); - close_on_exec_on() took care of this */  #endif
                                                         /* NB: close _first_, then move fd! */ @@ -685,7 +694,7 @@ popen_ls(const char *opt)
                            /* parent */
                            close(outfd.wr);
#if !BB_MMU
-                           free((char*)argv[2]);
+                          free((char*)argv[3]);
#endif
                            return outfd.rd;
}
@@ -1085,6 +1094,7 @@ enum {
                            const_PASV = mk_const4('P', 'A', 'S', 'V'),
                            const_PORT = mk_const4('P', 'O', 'R', 'T'),
                            const_PWD  = mk_const3('P', 'W', 'D'),
+                          const_XPWD = mk_const4('X', 'P', 'W', 'D'),                              /* Deprecated, but still used by some clients. Eg. Windows ftp (cmd) */
                            const_QUIT = mk_const4('Q', 'U', 'I', 'T'),
                            const_REST = mk_const4('R', 'E', 'S', 'T'),
                            const_RETR = mk_const4('R', 'E', 'T', 'R'), @@ -1135,8 +1145,14 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
/* TODO: pass -n? It prevents user/group resolution, which may not work in chroot anyway */
/* TODO: pass -A? It shows dot files */
/* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */
-                                                        xchdir(argv[2]);
-                                                        argv[2] = (char*)"--";
+
+                                                       /* set chroot and current dir */
+                                                       xchroot(argv[2]);
+                                                       xchdir(argv[3]);
+                                                       argv[2] = argv[4];
+                                                       argv[3] = NULL;
+                                                       argv[4] = NULL;
+
                                                         /* memset(&G, 0, sizeof(G)); - ls_main does it */
                                                         return ls_main(argc, argv);
                            }
@@ -1292,7 +1308,7 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
                                                                                      WRITE_OK(FTP_ALLOOK);
                                                         else if (cmdval == const_SYST)
                                                                                      cmdio_write_raw(STR(FTP_SYSTOK)" UNIX Type: L8\r\n");
-                                                        else if (cmdval == const_PWD)
+                                                       else if (cmdval == const_PWD || cmdval == const_XPWD)
                                                                                      handle_pwd();
                                                         else if (cmdval == const_CWD)
                                                                                      handle_cwd();
--
1.9.3


 
 
--
This message has been scanned for viruses and dangerous content by CronLab
(www.cronlab.com), and is believed to be clean.



More information about the busybox mailing list