support ftp Multiple user root directory and access control

yao0718 29171383 at qq.com
Thu Jul 21 08:18:35 UTC 2016


hi, I add Multiple user root  directory and access control for rtems,I have test it on my board, can somebody interesting about it and test more?
--- ./base/ftpd.c	2016-03-11 11:39:41.752551200 +0800
+++ ./ftpd.c	2016-07-21 16:10:59.308281000 +0800
@@ -189,7 +189,7 @@
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
-
+ 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -266,6 +266,8 @@
   rtems_id            tid;         /* Task id */
   char                *user;       /* user name (0 if not supplied) */
   char                *pass;       /* password (0 if not supplied) */
+  int                 access;      /* access for session */
+  struct  rtems_ftpd_user_list *p_user;
   bool                auth;        /* true if user/pass was valid, false if not or not supplied */
 } FTPD_SessionInfo_t;
 
@@ -325,15 +327,15 @@
  */
 
 static int
-can_read(void)
+can_read(int access)
 {
-  return (ftpd_access & FTPD_NO_READ) == 0;
+  return (access & FTPD_NO_READ) == 0;
 }
 
 static int
-can_write(void)
+can_write(int access)
 {
-  return (ftpd_access & FTPD_NO_WRITE) == 0;
+  return (access & FTPD_NO_WRITE) == 0;
 }
 
 /*
@@ -783,7 +785,7 @@
   struct stat         stat_buf;
   int                 res = 0;
 
-  if(!can_read() || !info->auth)
+  if(!can_read(info->access) || !info->auth)
   {
     send_reply(info, 550, "Access denied.");
     return;
@@ -927,7 +929,7 @@
   typedef ssize_t (*WriteProc)(int, void const*, size_t);
   WriteProc              wrt = &write;
 
-  if(!can_write() || !info->auth)
+  if(!can_write(info->access) || !info->auth)
   {
     send_reply(info, 550, "Access denied.");
     return;
@@ -1667,6 +1669,33 @@
     *p++ = '\0';
 }
 
+
+/*find user list and chroot and set access mode for session*/
+static  void  check_user_access_ctrl(FTPD_SessionInfo_t *info)
+{
+    struct  rtems_ftpd_user_list   *p_head = info->p_user; 
+    if((!info->user)||(!p_head))
+		return;
+	while(p_head->user)
+	{
+       if(!strcmp(info->user,p_head->user))
+	   {
+          if((!p_head->pass)||(!info->pass)||
+			  (!strcmp(info->pass,p_head->pass)))
+		  {     
+               info->access = p_head->access;
+               if((p_head->root)&& (p_head->root[0] == '/'))
+			   {
+			       chroot(p_head->root);				   
+			   }
+			   break;
+		  }
+	   }
+	   p_head++;
+	}
+}
+
+
 /*
  * exec_command
  *
@@ -1688,6 +1717,7 @@
 {
   char fname[FTPD_BUFSIZE];
   int wrong_command = 0;
+  
 
   fname[0] = '\0';
 
@@ -1755,7 +1785,10 @@
   {
     sscanf(args, "%254s", fname);
     if (info->user)
+	{
       free(info->user);
+	  info->user = NULL;
+	}
     if (info->pass)
       free(info->pass);
     info->pass = NULL;
@@ -1766,6 +1799,7 @@
       send_reply(info, 331, "User name okay, need password.");
     } else {
       info->auth = true;
+      check_user_access_ctrl(info);
       send_reply(info, 230, "User logged in.");
     }
   }
@@ -1784,13 +1818,14 @@
         send_reply(info, 530, "Not logged in.");
       } else {
         info->auth = true;
+        check_user_access_ctrl(info);
         send_reply(info, 230, "User logged in.");
       }
     }
   }
   else if (!strcmp("DELE", cmd))
   {
-    if(!can_write() || !info->auth)
+    if(!can_write(info->access) || !info->auth)
     {
       send_reply(info, 550, "Access denied.");
     }
@@ -1813,7 +1848,7 @@
     {
       int mask;
 
-      if(!can_write() || !info->auth)
+      if(!can_write(info->access) || !info->auth)
       {
         send_reply(info, 550, "Access denied.");
       }
@@ -1832,7 +1867,7 @@
   }
   else if (!strcmp("RMD", cmd))
   {
-    if(!can_write() || !info->auth)
+    if(!can_write(info->access) || !info->auth)
     {
       send_reply(info, 550, "Access denied.");
     }
@@ -1849,7 +1884,7 @@
   }
   else if (!strcmp("MKD", cmd))
   {
-    if(!can_write() || !info->auth)
+    if(!can_write(info->access) || !info->auth)
     {
       send_reply(info, 550, "Access denied.");
     }
@@ -1907,7 +1942,11 @@
   int chroot_made = 0;
 
   rtems_libio_set_private_env();
-
+  
+  /*add list for individual user access control*/
+  info->p_user = rtems_ftpd_configuration.user_ctrl_list;
+  info->access = rtems_ftpd_configuration.access; 
+  
   /* chroot() can fail here because the directory may not exist yet. */
   chroot_made = chroot(ftpd_root) == 0;
 

--- ./base/ftpd.h	2016-03-11 11:39:41.760052200 +0800
+++ ./ftpd.h	2016-07-21 16:11:02.474638800 +0800
@@ -6,7 +6,7 @@
 #define _RTEMS_FTPD_H
 
 #include <rtems/rtems/tasks.h>
-
+ 
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -38,6 +38,18 @@
    rtems_ftpd_hookfunction hook_function;
 };
 
+
+/*add  more lever control access for different user and password*/
+
+struct  rtems_ftpd_user_list
+{
+	char const *root;
+	char const *user;
+	char const *pass;
+    int         access;
+};
+
+
 struct rtems_ftpd_configuration
 {
    rtems_task_priority     priority;           /* FTPD task priority  */
@@ -54,6 +66,7 @@
                                                   3 - browse-only */
    rtems_shell_login_check_t login;            /* Login check or 0 to ignore
                                                   user/passwd. */
+   struct  rtems_ftpd_user_list   *user_ctrl_list;
 };
 
 /*









usage example:


#define INCLUDE_FTPD_MULT_USER_ACCESS_CTRL
#define  DEFAULT_FTPD_USER   "admin"
#define  DEFAULT_FTPD_PASS    "123"
#ifdef  INCLUDE_FTPD_MULT_USER_ACCESS_CTRL
static struct rtems_ftpd_user_list rtems_ftpd_user_ctrl_list[] =
{
	{	"/", "admin", "admin", 0}, /*admin user for access all*/
	{	"/mnt/data", "read", "read", 1}, /*read user for read /mnt/data only*/
	{	"/mnt/etc", "look", "look", 3}, /* look user for brower etc only*/
	{	"/mnt", "mine", "mine", 0}, /*mine user for access /mnt only*/
	{	0, 0, 0, 0},};
#endif
static bool rtems_ftpd_login_check(const char *user, const char *passphrase)
{
#ifdef  INCLUDE_FTPD_MULT_USER_ACCESS_CTRL
	struct rtems_ftpd_user_list *p_head = rtems_ftpd_user_ctrl_list;
#endif
	if ((user == NULL) || (passphrase == NULL))
		return false;


	if ((!strcmp(user, DEFAULT_FTPD_USER))
			&& (!strcmp(passphrase, DEFAULT_FTPD_PASS)))
		return true;
#ifdef  INCLUDE_FTPD_MULT_USER_ACCESS_CTRL
	while (p_head->user)
	{
		if ((!strcmp(user, p_head->user))
				&& (!strcmp(passphrase, p_head->pass)))
		return true;


		p_head++;
	}
#endif
	return false;
}


/************************************************************************************************
 * ftpd support
 */


struct rtems_ftpd_configuration rtems_ftpd_configuration =
{ .priority = 199, .max_hook_filesize = 32768, .port = 21, .hooks = 0, .root =
		"/mnt", .tasks_count = 4, .idle = 60, .access = 0, .login =0,
	//	rtems_ftpd_login_check,
#ifdef  INCLUDE_FTPD_MULT_USER_ACCESS_CTRL
        .user_ctrl_list = rtems_ftpd_user_ctrl_list
#endif
};


void net_ftpd_init(void)
{
	rtems_initialize_ftpd();
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20160721/ea5694e6/attachment-0001.html>


More information about the devel mailing list