netutils/ftpd: add option to login to FTPD using FSUTILS_PASSWD

Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
Petro Karashchenko 2022-03-28 13:46:07 +02:00 committed by Xiang Xiao
parent e3df21cd4c
commit c1dfaf42ff
4 changed files with 242 additions and 217 deletions

View File

@ -69,7 +69,7 @@ static const struct fptd_account_s g_ftpdaccounts[] =
* Public Data * Public Data
****************************************************************************/ ****************************************************************************/
/* To minimize the probability of name collisitions, all FTPD example /* To minimize the probability of name collisions, all FTPD example
* global data is maintained in a single instance of a structure. * global data is maintained in a single instance of a structure.
*/ */

View File

@ -13,7 +13,17 @@ config NETUTILS_FTPD
if NETUTILS_FTPD if NETUTILS_FTPD
config FTPD_WORKERSTACKSIZE config FTPD_WORKERSTACKSIZE
int "FTPD client thread stack size" int "FTPD server thread stack size"
default DEFAULT_TASK_STACKSIZE default DEFAULT_TASK_STACKSIZE
config FTPD_LOGIN_PASSWD
bool "Verify FTPD server login with encrypted password file"
default n
depends on FSUTILS_PASSWD
---help---
Use the content of an encrypted password file to verify user
credentials. This option requires that you have selected
CONFIG_FSUTILS_PASSWD to enable the access methods of
apps/fsutils/passwd.
endif endif

View File

@ -64,6 +64,8 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include "fsutils/passwd.h"
#include "netutils/ftpd.h" #include "netutils/ftpd.h"
#include "ftpd.h" #include "ftpd.h"
@ -86,8 +88,7 @@ static int ftpd_account_sethome(FAR struct ftpd_account_s *account,
static FAR struct ftpd_account_s * static FAR struct ftpd_account_s *
ftpd_account_search_user(FAR struct ftpd_session_s *session, ftpd_account_search_user(FAR struct ftpd_session_s *session,
FAR const char *user); FAR const char *user);
static FAR struct ftpd_account_s * static bool ftpd_account_login(FAR struct ftpd_session_s *session,
ftpd_account_login(FAR struct ftpd_session_s *session,
FAR const char *user, FAR const char *passwd); FAR const char *user, FAR const char *passwd);
/* Parsing functions */ /* Parsing functions */
@ -95,7 +96,8 @@ static FAR struct ftpd_account_s *
static FAR char *ftpd_strtok(bool skipspace, FAR const char *delimiters, static FAR char *ftpd_strtok(bool skipspace, FAR const char *delimiters,
FAR char **str); FAR char **str);
static FAR char *ftpd_strtok_alloc(bool skipspace, static FAR char *ftpd_strtok_alloc(bool skipspace,
FAR const char *delimiters, FAR const char **str); FAR const char *delimiters,
FAR const char **str);
/* Socket helpers */ /* Socket helpers */
@ -135,8 +137,9 @@ static off_t ftpd_offsatoi(FAR const char *filename, off_t offset);
static int ftpd_stream(FAR struct ftpd_session_s *session, int cmdtype); static int ftpd_stream(FAR struct ftpd_session_s *session, int cmdtype);
static uint8_t ftpd_listoption(FAR char **param); static uint8_t ftpd_listoption(FAR char **param);
static int ftpd_listbuffer(FAR struct ftpd_session_s *session, static int ftpd_listbuffer(FAR struct ftpd_session_s *session,
FAR char *path, FAR struct stat *st, FAR char *buffer, FAR char *path, FAR struct stat *st,
size_t buflen, unsigned int opton); FAR char *buffer, size_t buflen,
unsigned int opton);
static int fptd_listscan(FAR struct ftpd_session_s *session, static int fptd_listscan(FAR struct ftpd_session_s *session,
FAR char *path, unsigned int opton); FAR char *path, unsigned int opton);
static int ftpd_list(FAR struct ftpd_session_s *session, static int ftpd_list(FAR struct ftpd_session_s *session,
@ -284,21 +287,21 @@ static FAR struct ftpd_account_s *ftpd_account_new(FAR const char *user,
/* Get the size of the allocation */ /* Get the size of the allocation */
allocsize = sizeof(struct ftpd_account_s); if (user == NULL)
if (!user)
{ {
usersize = 0; usersize = 0;
} }
else else
{ {
usersize = strlen(user); usersize = strlen(user) + 1;
allocsize += usersize + 1;
} }
allocsize = sizeof(struct ftpd_account_s) + usersize;
/* Allocate the account and user string */ /* Allocate the account and user string */
ret = (struct ftpd_account_s *)zalloc(allocsize); ret = (struct ftpd_account_s *)zalloc(allocsize);
if (!ret) if (ret == NULL)
{ {
nerr("ERROR: Failed to allocate account\n"); nerr("ERROR: Failed to allocate account\n");
return NULL; return NULL;
@ -308,7 +311,7 @@ static FAR struct ftpd_account_s *ftpd_account_new(FAR const char *user,
ret->flags = accountflags; ret->flags = accountflags;
if (user) if (user != NULL)
{ {
ret->user = (FAR char *)&ret[1]; ret->user = (FAR char *)&ret[1];
strcpy(ret->user, user); strcpy(ret->user, user);
@ -328,26 +331,26 @@ static void ftpd_account_free(FAR struct ftpd_account_s *account)
/* Back up to the first entry in the list */ /* Back up to the first entry in the list */
while (account->blink) while (account->blink != NULL)
{ {
account = account->blink; account = account->blink;
} }
/* Then free the entire list */ /* Then free the entire list */
while (account) while (account != NULL)
{ {
prev = account; prev = account;
account = account->flink; account = account->flink;
/* Free the home path and the password */ /* Free the home path and the password */
if (prev->home) if (prev->home != NULL)
{ {
free(prev->home); free(prev->home);
} }
if (prev->password) if (prev->password != NULL)
{ {
free(prev->password); free(prev->password);
} }
@ -371,10 +374,10 @@ static int ftpd_account_setpassword(FAR struct ftpd_account_s *account,
/* Make of copy of the password string (if it is non-null) */ /* Make of copy of the password string (if it is non-null) */
temp = NULL; temp = NULL;
if (passwd) if (passwd != NULL)
{ {
temp = strdup(passwd); temp = strdup(passwd);
if (!temp) if (temp == NULL)
{ {
return -ENOMEM; return -ENOMEM;
} }
@ -382,7 +385,7 @@ static int ftpd_account_setpassword(FAR struct ftpd_account_s *account,
/* Free any existing password string */ /* Free any existing password string */
if (account->password) if (account->password != NULL)
{ {
free(account->password); free(account->password);
} }
@ -407,7 +410,7 @@ static int ftpd_account_add(FAR struct ftpd_server_s *server,
/* Find the beginning of the list */ /* Find the beginning of the list */
head = account; head = account;
while (head->blink) while (head->blink != NULL)
{ {
head = head->blink; head = head->blink;
} }
@ -415,14 +418,14 @@ static int ftpd_account_add(FAR struct ftpd_server_s *server,
/* Find the tail of the list */ /* Find the tail of the list */
tail = account; tail = account;
while (tail->flink) while (tail->flink != NULL)
{ {
tail = tail->flink; tail = tail->flink;
} }
/* Handle the case where the list is empty */ /* Handle the case where the list is empty */
if (!server->head) if (server->head == NULL)
{ {
server->head = head; server->head = head;
} }
@ -445,15 +448,15 @@ static int ftpd_account_sethome(FAR struct ftpd_account_s *account,
{ {
FAR char *temp; FAR char *temp;
DEBUGASSERT(account); DEBUGASSERT(account != NULL);
/* Make a copy of the home path string (unless it is NULL) */ /* Make a copy of the home path string (unless it is NULL) */
temp = NULL; temp = NULL;
if (home) if (home != NULL)
{ {
temp = strdup(home); temp = strdup(home);
if (!temp) if (temp == NULL)
{ {
return -ENOMEM; return -ENOMEM;
} }
@ -461,7 +464,7 @@ static int ftpd_account_sethome(FAR struct ftpd_account_s *account,
/* Free any existing home path string */ /* Free any existing home path string */
if (account->home) if (account->home != NULL)
{ {
free(account->home); free(account->home);
} }
@ -485,22 +488,22 @@ ftpd_account_search_user(FAR struct ftpd_session_s *session,
uint8_t accountflags; uint8_t accountflags;
account = session->head; account = session->head;
while (account) while (account != NULL)
{ {
accountflags = account->flags; accountflags = account->flags;
/* Check if the account has a user */ /* Check if the account has a user */
if (!account->user) if (account->user == NULL)
{ {
/* No.. The account has no user, was a user name provided? */ /* No.. The account has no user, was a user name provided? */
if (!user) if (user == NULL)
{ {
/* Yes.. create the account */ /* No.. create the account */
newaccount = ftpd_account_new(NULL, accountflags); newaccount = ftpd_account_new(NULL, accountflags);
if (newaccount) if (newaccount != NULL)
{ {
if (ftpd_account_setpassword(newaccount, if (ftpd_account_setpassword(newaccount,
account->password) < 0) account->password) < 0)
@ -521,7 +524,7 @@ ftpd_account_search_user(FAR struct ftpd_session_s *session,
/* Was a user name provided? */ /* Was a user name provided? */
else if (user) else if (user != NULL)
{ {
/* Check if matches the user name on the account */ /* Check if matches the user name on the account */
@ -530,7 +533,7 @@ ftpd_account_search_user(FAR struct ftpd_session_s *session,
/* Yes.. create the account */ /* Yes.. create the account */
newaccount = ftpd_account_new(account->user, accountflags); newaccount = ftpd_account_new(account->user, accountflags);
if (newaccount) if (newaccount != NULL)
{ {
if (ftpd_account_setpassword(newaccount, if (ftpd_account_setpassword(newaccount,
account->password) != 0) account->password) != 0)
@ -562,23 +565,33 @@ ftpd_account_search_user(FAR struct ftpd_session_s *session,
* Name: ftpd_account_login * Name: ftpd_account_login
****************************************************************************/ ****************************************************************************/
static FAR struct ftpd_account_s * static bool ftpd_account_login(FAR struct ftpd_session_s *session,
ftpd_account_login(FAR struct ftpd_session_s *session,
FAR const char *user, FAR const char *passwd) FAR const char *user, FAR const char *passwd)
{ {
FAR struct ftpd_account_s *account; FAR char *home = NULL;
uint8_t flags;
#if defined(CONFIG_FTPD_LOGIN_PASSWD)
if (user != NULL && passwd != NULL &&
PASSWORD_VERIFY_MATCH(passwd_verify(user, passwd)))
{
flags = FTPD_ACCOUNTFLAG_ADMIN;
}
else
#endif
{
FAR struct ftpd_account_s *account = NULL;
bool pwvalid; bool pwvalid;
FAR char *home;
account = ftpd_account_search_user(session, user); account = ftpd_account_search_user(session, user);
if (!account) if (account == NULL)
{ {
return NULL; return false;
} }
if (!account->password) if (account->password == NULL)
{ {
if (!passwd) if (passwd == NULL)
{ {
pwvalid = true; pwvalid = true;
} }
@ -591,7 +604,7 @@ ftpd_account_login(FAR struct ftpd_session_s *session,
pwvalid = false; pwvalid = false;
} }
} }
else if (!passwd) else if (passwd == NULL)
{ {
pwvalid = false; pwvalid = false;
} }
@ -607,32 +620,48 @@ ftpd_account_login(FAR struct ftpd_session_s *session,
if (!pwvalid) if (!pwvalid)
{ {
ftpd_account_free(account); ftpd_account_free(account);
return NULL; return false;
} }
home = account->home; if (account->home != NULL)
if (!home) {
home = strdup(account->home);
}
flags = account->flags;
ftpd_account_free(account);
}
if (home == NULL)
{ {
home = getenv("HOME"); home = getenv("HOME");
if (home == NULL)
{
home = strdup("/");
}
else
{
home = strdup(home);
}
} }
if ((account->flags & FTPD_ACCOUNTFLAG_ADMIN) != 0) if ((flags & FTPD_ACCOUNTFLAG_ADMIN) != 0)
{ {
/* admin user */ /* admin user */
session->home = strdup("/"); session->home = strdup("/");
session->work = strdup(!home ? "/" : home); session->work = home;
} }
else else
{ {
/* normal user */ /* normal user */
session->home = strdup(!home ? "/" : home); session->home = home;
session->work = strdup("/"); session->work = strdup("/");
} }
ftpd_account_free(account); return true;
return account;
} }
/**************************************************************************** /****************************************************************************
@ -750,7 +779,7 @@ static FAR char *ftpd_strtok_alloc(bool skipspace,
tokenlen = (size_t)(right - left); tokenlen = (size_t)(right - left);
ret = (FAR char *)malloc(tokenlen + 1); ret = (FAR char *)malloc(tokenlen + 1);
if (ret) if (ret != NULL)
{ {
if (tokenlen > 0) if (tokenlen > 0)
{ {
@ -980,7 +1009,7 @@ static ssize_t ftpd_response(int sd, int timeout, FAR const char *fmt, ...)
vasprintf(&buffer, fmt, ap); vasprintf(&buffer, fmt, ap);
va_end(ap); va_end(ap);
if (!buffer) if (buffer == NULL)
{ {
return -ENOMEM; return -ENOMEM;
} }
@ -1123,7 +1152,7 @@ static FAR struct ftpd_server_s *ftpd_openserver(int port,
/* Allocate the server instance */ /* Allocate the server instance */
server = (FAR struct ftpd_server_s *)zalloc(sizeof(struct ftpd_server_s)); server = (FAR struct ftpd_server_s *)zalloc(sizeof(struct ftpd_server_s));
if (!server) if (server == NULL)
{ {
nerr("ERROR: Failed to allocate server\n"); nerr("ERROR: Failed to allocate server\n");
return NULL; return NULL;
@ -1212,7 +1241,7 @@ static int ftpd_pathignore(FAR struct ftpd_pathnode_s *currpath)
FAR struct ftpd_pathnode_s *node; FAR struct ftpd_pathnode_s *node;
size_t namelen; size_t namelen;
namelen = !currpath->name ? 0 : strlen(currpath->name); namelen = currpath->name == NULL ? 0 : strlen(currpath->name);
if (namelen == 0) if (namelen == 0)
{ {
@ -1229,11 +1258,11 @@ static int ftpd_pathignore(FAR struct ftpd_pathnode_s *currpath)
currpath->ignore = true; currpath->ignore = true;
node = currpath->blink; node = currpath->blink;
while (node) while (node != NULL)
{ {
if (!node->ignore) if (!node->ignore)
{ {
namelen = !node->name ? 0 : strlen(node->name); namelen = node->name == NULL ? 0 : strlen(node->name);
if (namelen > 0) if (namelen > 0)
{ {
@ -1266,12 +1295,12 @@ static void ftpd_nodefree(FAR struct ftpd_pathnode_s *node)
{ {
FAR struct ftpd_pathnode_s *prev; FAR struct ftpd_pathnode_s *prev;
while (node) while (node != NULL)
{ {
prev = node; prev = node;
node = node->flink; node = node->flink;
if (prev->name) if (prev->name != NULL)
{ {
free(prev->name); free(prev->name);
} }
@ -1291,7 +1320,7 @@ static FAR struct ftpd_pathnode_s *ftpd_path2node(FAR const char *path)
FAR struct ftpd_pathnode_s *newnode; FAR struct ftpd_pathnode_s *newnode;
FAR char *name; FAR char *name;
if (!path) if (path == NULL)
{ {
return NULL; return NULL;
} }
@ -1299,7 +1328,7 @@ static FAR struct ftpd_pathnode_s *ftpd_path2node(FAR const char *path)
while (path[0] != '\0') while (path[0] != '\0')
{ {
name = ftpd_strtok_alloc(false, "/\\", &path); name = ftpd_strtok_alloc(false, "/\\", &path);
if (!name) if (name == NULL)
{ {
break; break;
} }
@ -1311,7 +1340,7 @@ static FAR struct ftpd_pathnode_s *ftpd_path2node(FAR const char *path)
newnode = (FAR struct ftpd_pathnode_s *) newnode = (FAR struct ftpd_pathnode_s *)
malloc(sizeof(struct ftpd_pathnode_s)); malloc(sizeof(struct ftpd_pathnode_s));
if (!newnode) if (newnode == NULL)
{ {
free(name); free(name);
ftpd_nodefree(head); ftpd_nodefree(head);
@ -1323,7 +1352,7 @@ static FAR struct ftpd_pathnode_s *ftpd_path2node(FAR const char *path)
newnode->ignore = false; newnode->ignore = false;
newnode->name = name; newnode->name = name;
if (!tail) if (tail == NULL)
{ {
head = newnode; head = newnode;
} }
@ -1353,14 +1382,14 @@ static FAR char *ftpd_node2path(FAR struct ftpd_pathnode_s *node,
FAR size_t allocsize; FAR size_t allocsize;
FAR size_t namelen; FAR size_t namelen;
if (!node) if (node == NULL)
{ {
return NULL; return NULL;
} }
allocsize = 0; allocsize = 0;
node1 = node; node1 = node;
while (node1) while (node1 != NULL)
{ {
if (strip) if (strip)
{ {
@ -1372,7 +1401,7 @@ static FAR char *ftpd_node2path(FAR struct ftpd_pathnode_s *node,
} }
node2 = node1->flink; node2 = node1->flink;
while (strip && node2) while (strip && node2 != NULL)
{ {
if (!node2->ignore) if (!node2->ignore)
{ {
@ -1382,8 +1411,8 @@ static FAR char *ftpd_node2path(FAR struct ftpd_pathnode_s *node,
node2 = node2->flink; node2 = node2->flink;
} }
namelen = !node1->name ? 0 : strlen(node1->name); namelen = node1->name == NULL ? 0 : strlen(node1->name);
if (!node2) if (node2 == NULL)
{ {
if (namelen <= 0) if (namelen <= 0)
{ {
@ -1403,16 +1432,16 @@ static FAR char *ftpd_node2path(FAR struct ftpd_pathnode_s *node,
} }
path = (FAR char *)malloc(allocsize); path = (FAR char *)malloc(allocsize);
if (!path) if (path == NULL)
{ {
return NULL; return NULL;
} }
allocsize = 0; allocsize = 0;
node1 = node; node1 = node;
while (node1) while (node1 != NULL)
{ {
if (strip != 0) if (strip)
{ {
if (node1->ignore) if (node1->ignore)
{ {
@ -1422,7 +1451,7 @@ static FAR char *ftpd_node2path(FAR struct ftpd_pathnode_s *node,
} }
node2 = node1->flink; node2 = node1->flink;
while (strip && node2) while (strip && node2 != NULL)
{ {
if (!node2->ignore) if (!node2->ignore)
{ {
@ -1432,9 +1461,9 @@ static FAR char *ftpd_node2path(FAR struct ftpd_pathnode_s *node,
node2 = node2->flink; node2 = node2->flink;
} }
namelen = !node1->name ? 0 : strlen(node1->name); namelen = node1->name == NULL ? 0 : strlen(node1->name);
if (!node2) if (node2 == NULL)
{ {
if (namelen <= 0) if (namelen <= 0)
{ {
@ -1468,16 +1497,16 @@ ftpd_nodeappend(FAR struct ftpd_pathnode_s *head,
if (override) if (override)
{ {
if (node && node->name && strlen(node->name) <= 0) if (node != NULL && node->name != NULL && strlen(node->name) <= 0)
{ {
ftpd_nodefree(head); ftpd_nodefree(head);
head = NULL; head = NULL;
} }
} }
if (!head) if (head == NULL)
{ {
if (node) if (node != NULL)
{ {
node->blink = NULL; node->blink = NULL;
} }
@ -1486,7 +1515,7 @@ ftpd_nodeappend(FAR struct ftpd_pathnode_s *head,
node = NULL; node = NULL;
} }
if (node) if (node != NULL)
{ {
temp = head; temp = head;
while (temp->flink) while (temp->flink)
@ -1501,7 +1530,7 @@ ftpd_nodeappend(FAR struct ftpd_pathnode_s *head,
/* clear ignore */ /* clear ignore */
temp = head; temp = head;
while (temp) while (temp != NULL)
{ {
temp->ignore = false; temp->ignore = false;
temp = temp->flink; temp = temp->flink;
@ -1510,7 +1539,7 @@ ftpd_nodeappend(FAR struct ftpd_pathnode_s *head,
/* restrip */ /* restrip */
temp = head; temp = head;
while (temp) while (temp != NULL)
{ {
ftpd_pathignore(temp); ftpd_pathignore(temp);
temp = temp->flink; temp = temp->flink;
@ -1533,18 +1562,18 @@ static int ftpd_getpath(FAR struct ftpd_session_s *session,
FAR char *abspath_local; FAR char *abspath_local;
FAR char *workpath_local; FAR char *workpath_local;
if (abspath) if (abspath != NULL)
{ {
*abspath = NULL; *abspath = NULL;
} }
if (workpath) if (workpath != NULL)
{ {
*workpath = NULL; *workpath = NULL;
} }
worknode = ftpd_path2node(!session->work ? "" : session->work); worknode = ftpd_path2node(session->work == NULL ? "" : session->work);
if (!worknode) if (worknode == NULL)
{ {
return -ENOMEM; return -ENOMEM;
} }
@ -1553,14 +1582,14 @@ static int ftpd_getpath(FAR struct ftpd_session_s *session,
worknode = ftpd_nodeappend(worknode, appendnode, true); worknode = ftpd_nodeappend(worknode, appendnode, true);
workpath_local = ftpd_node2path(worknode, 1); workpath_local = ftpd_node2path(worknode, 1);
if (!workpath_local) if (workpath_local == NULL)
{ {
ftpd_nodefree(worknode); ftpd_nodefree(worknode);
return -ENOMEM; return -ENOMEM;
} }
abspath_node = ftpd_path2node(!session->home ? "" : session->home); abspath_node = ftpd_path2node(!session->home ? "" : session->home);
if (!abspath_node) if (abspath_node == NULL)
{ {
free(workpath_local); free(workpath_local);
ftpd_nodefree(worknode); ftpd_nodefree(worknode);
@ -1571,7 +1600,7 @@ static int ftpd_getpath(FAR struct ftpd_session_s *session,
abspath_node = ftpd_nodeappend(abspath_node, appendnode, false); abspath_node = ftpd_nodeappend(abspath_node, appendnode, false);
abspath_local = ftpd_node2path(abspath_node, 1); abspath_local = ftpd_node2path(abspath_node, 1);
if (!abspath_local) if (abspath_local == NULL)
{ {
free(workpath_local); free(workpath_local);
ftpd_nodefree(abspath_node); ftpd_nodefree(abspath_node);
@ -1579,7 +1608,7 @@ static int ftpd_getpath(FAR struct ftpd_session_s *session,
return -ENOMEM; return -ENOMEM;
} }
if (!workpath) if (workpath == NULL)
{ {
free(workpath_local); free(workpath_local);
} }
@ -1588,7 +1617,7 @@ static int ftpd_getpath(FAR struct ftpd_session_s *session,
*workpath = workpath_local; *workpath = workpath_local;
} }
if (!abspath) if (abspath == NULL)
{ {
free(abspath_local); free(abspath_local);
} }
@ -1671,7 +1700,7 @@ static off_t ftpd_offsatoi(FAR const char *filename, off_t offset)
int ch; int ch;
outstream = fopen(filename, "r"); outstream = fopen(filename, "r");
if (!outstream) if (outstream == NULL)
{ {
int errval = errno; int errval = errno;
nerr("ERROR: Failed to open %s: %d\n", filename, errval); nerr("ERROR: Failed to open %s: %d\n", filename, errval);
@ -2312,10 +2341,10 @@ static int ftpd_listbuffer(FAR struct ftpd_session_s *session,
int namelen; int namelen;
temp = (FAR char *)malloc(PATH_MAX + 1); temp = (FAR char *)malloc(PATH_MAX + 1);
if (temp) if (temp != NULL)
{ {
namelen = readlink(path, temp, PATH_MAX); namelen = readlink(path, temp, PATH_MAX);
if (namelen != (-1))\ if (namelen != -1)
{ {
temp[namelen] = '\0'; temp[namelen] = '\0';
} }
@ -2374,7 +2403,7 @@ static int fptd_listscan(FAR struct ftpd_session_s *session, FAR char *path,
} }
dir = opendir(path); dir = opendir(path);
if (!dir) if (dir == NULL)
{ {
int errval = errno; int errval = errno;
nerr("ERROR: opendir() failed: %d\n", errval); nerr("ERROR: opendir() failed: %d\n", errval);
@ -2384,7 +2413,7 @@ static int fptd_listscan(FAR struct ftpd_session_s *session, FAR char *path,
for (; ; ) for (; ; )
{ {
entry = readdir(dir); entry = readdir(dir);
if (!entry) if (entry == NULL)
{ {
break; break;
} }
@ -2398,7 +2427,7 @@ static int fptd_listscan(FAR struct ftpd_session_s *session, FAR char *path,
} }
asprintf(&temp, "%s/%s", path, entry->d_name); asprintf(&temp, "%s/%s", path, entry->d_name);
if (!temp) if (temp == NULL)
{ {
continue; continue;
} }
@ -2463,13 +2492,13 @@ static int ftpd_command_user(FAR struct ftpd_session_s *session)
/* Free session strings */ /* Free session strings */
if (session->user) if (session->user != NULL)
{ {
free(session->user); free(session->user);
session->user = NULL; session->user = NULL;
} }
if (session->renamefrom) if (session->renamefrom != NULL)
{ {
free(session->renamefrom); free(session->renamefrom);
session->renamefrom = NULL; session->renamefrom = NULL;
@ -2478,7 +2507,7 @@ static int ftpd_command_user(FAR struct ftpd_session_s *session)
/* Set up the new user */ /* Set up the new user */
session->user = strdup(session->param); session->user = strdup(session->param);
if (!session->user) if (session->user == NULL)
{ {
return ftpd_response(session->cmd.sd, session->txtimeout, return ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 451, ' ', "Memory exhausted !"); g_respfmt1, 451, ' ', "Memory exhausted !");
@ -2488,37 +2517,31 @@ static int ftpd_command_user(FAR struct ftpd_session_s *session)
/* If there is no account information, then no login is required. */ /* If there is no account information, then no login is required. */
if (!session->head) if (session->head == NULL)
{ {
FAR char *home; FAR char *home;
home = getenv("HOME"); home = getenv("HOME");
session->curr = NULL; session->loggedin = false;
session->home = strdup(!home ? "/" : home); session->home = strdup(home == NULL ? "/" : home);
session->work = strdup("/"); session->work = strdup("/");
ret = ftpd_response(session->cmd.sd, session->txtimeout, return ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 230, ' ', "Login successful."); g_respfmt1, 230, ' ', "Login successful.");
if (ret < 0)
{
session->curr = NULL;
}
return ret;
} }
/* Try to login with no password. This will work if no password is /* Try to login with no password. This will work if no password is
* required for the account. * required for the account.
*/ */
session->curr = ftpd_account_login(session, session->param, NULL); session->loggedin = ftpd_account_login(session, session->param, NULL);
if (session->curr) if (session->loggedin)
{ {
ret = ftpd_response(session->cmd.sd, session->txtimeout, ret = ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 230, ' ', "Login successful."); g_respfmt1, 230, ' ', "Login successful.");
if (ret < 0) if (ret < 0)
{ {
session->curr = NULL; session->loggedin = false;
} }
return ret; return ret;
@ -2539,20 +2562,21 @@ static int ftpd_command_pass(FAR struct ftpd_session_s *session)
{ {
int ret; int ret;
if (!session->user) if (session->user == NULL)
{ {
return ftpd_response(session->cmd.sd, session->txtimeout, return ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 530, ' ', "Please login with USER !"); g_respfmt1, 530, ' ', "Please login with USER !");
} }
session->curr = ftpd_account_login(session, session->user, session->param); session->loggedin = ftpd_account_login(session, session->user,
if (session->curr) session->param);
if (session->loggedin)
{ {
ret = ftpd_response(session->cmd.sd, session->txtimeout, ret = ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 230, ' ', "Login successful."); g_respfmt1, 230, ' ', "Login successful.");
if (ret < 0) if (ret < 0)
{ {
session->curr = NULL; session->loggedin = false;
} }
return ret; return ret;
@ -2867,7 +2891,7 @@ static int ftpd_command_eprt(FAR struct ftpd_session_s *session)
for (index = 0; index < count && *str != '\0'; index++) for (index = 0; index < count && *str != '\0'; index++)
{ {
field[index] = ftpd_strtok_alloc(true, ",|)", &str); field[index] = ftpd_strtok_alloc(true, ",|)", &str);
if (!field[index]) if (field[index] == NULL)
{ {
break; break;
} }
@ -2882,15 +2906,14 @@ static int ftpd_command_eprt(FAR struct ftpd_session_s *session)
{ {
for (index = 0; index < count; index++) for (index = 0; index < count; index++)
{ {
if (field[index]) if (field[index] != NULL)
{ {
free(field[index]); free(field[index]);
} }
} }
ftpd_response(session->cmd.sd, session->txtimeout, ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 502, ' ', g_respfmt1, 502, ' ', "EPRT command not implemented !");
"EPRT command not implemented !");
return -EINVAL; return -EINVAL;
} }
@ -2927,7 +2950,7 @@ static int ftpd_command_eprt(FAR struct ftpd_session_s *session)
for (index = 0; index < count; index++) for (index = 0; index < count; index++)
{ {
if (field[index]) if (field[index] != NULL)
{ {
free(field[index]); free(field[index]);
} }
@ -2936,8 +2959,7 @@ static int ftpd_command_eprt(FAR struct ftpd_session_s *session)
if (family == AF_UNSPEC) if (family == AF_UNSPEC)
{ {
ftpd_response(session->cmd.sd, session->txtimeout, ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 502, ' ', g_respfmt1, 502, ' ', "EPRT command not implemented !");
"EPRT command not implemented !");
return -EINVAL; return -EINVAL;
} }
@ -2953,14 +2975,7 @@ static int ftpd_command_pwd(FAR struct ftpd_session_s *session)
{ {
FAR const char *workpath; FAR const char *workpath;
if (!session->work) workpath = session->work == NULL ? "" : session->work;
{
workpath = "";
}
else
{
workpath = session->work;
}
return ftpd_response(session->cmd.sd, session->txtimeout, return ftpd_response(session->cmd.sd, session->txtimeout,
"%03u%c\"%s\" is current directory.\r\n", "%03u%c\"%s\" is current directory.\r\n",
@ -3558,7 +3573,7 @@ static int ftpd_command_size(FAR struct ftpd_session_s *session)
} }
outstream = fopen(path, "r"); outstream = fopen(path, "r");
if (!outstream) if (outstream == NULL)
{ {
ret = -errno; ret = -errno;
ftpd_response(session->cmd.sd, session->txtimeout, ftpd_response(session->cmd.sd, session->txtimeout,
@ -3625,7 +3640,7 @@ static int ftpd_command_rnfr(FAR struct ftpd_session_s *session)
struct stat st; struct stat st;
int ret; int ret;
if (session->renamefrom) if (session->renamefrom != NULL)
{ {
free(session->renamefrom); free(session->renamefrom);
session->renamefrom = NULL; session->renamefrom = NULL;
@ -3664,7 +3679,7 @@ static int ftpd_command_rnto(FAR struct ftpd_session_s *session)
FAR char *abspath; FAR char *abspath;
int ret; int ret;
if (!session->renamefrom) if (session->renamefrom == NULL)
{ {
ftpd_response(session->cmd.sd, session->txtimeout, ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 550, ' ', "RNTO error !"); g_respfmt1, 550, ' ', "RNTO error !");
@ -3783,7 +3798,7 @@ static int ftpd_command_mdtm(FAR struct ftpd_session_s *session)
free(abspath); free(abspath);
memcpy(&tm, gmtime(&st.st_mtime), sizeof(tm)); gmtime_r(&st.st_mtime, &tm);
return ftpd_response(session->cmd.sd, session->txtimeout, return ftpd_response(session->cmd.sd, session->txtimeout,
"%03u%c%04u%02u%02u%02u%02u%02u\r\n", 213, ' ', "%03u%c%04u%02u%02u%02u%02u%02u\r\n", 213, ' ',
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
@ -3834,7 +3849,7 @@ static int ftpd_command_opts(FAR struct ftpd_session_s *session)
} }
lang = getenv("LANG"); lang = getenv("LANG");
if (lang) if (lang != NULL)
{ {
if (strcasestr(lang, "UTF8") || strcasestr(lang, "UTF-8")) if (strcasestr(lang, "UTF8") || strcasestr(lang, "UTF-8"))
{ {
@ -3888,9 +3903,9 @@ static int ftpd_command_help(FAR struct ftpd_session_s *session)
int ret; int ret;
index = 0; index = 0;
while (g_ftpdhelp[index]) while (g_ftpdhelp[index] != NULL)
{ {
if (index == 0 || !g_ftpdhelp[index + 1]) if (index == 0 || g_ftpdhelp[index + 1] == NULL)
{ {
ret = ftpd_response(session->cmd.sd, session->txtimeout, ret = ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 214, g_respfmt1, 214,
@ -3924,7 +3939,7 @@ static int ftpd_command(FAR struct ftpd_session_s *session)
/* Search the command table for a matching command */ /* Search the command table for a matching command */
for (index = 0; g_ftpdcmdtab[index].command; index++) for (index = 0; g_ftpdcmdtab[index].command != NULL; index++)
{ {
/* Does the command string match this entry? */ /* Does the command string match this entry? */
@ -3936,7 +3951,7 @@ static int ftpd_command(FAR struct ftpd_session_s *session)
{ {
/* Yes... Check if the user is logged in */ /* Yes... Check if the user is logged in */
if (!session->curr && session->head) if (!session->loggedin && (session->head != NULL))
{ {
return ftpd_response(session->cmd.sd, session->txtimeout, return ftpd_response(session->cmd.sd, session->txtimeout,
g_respfmt1, 530, ' ', g_respfmt1, 530, ' ',
@ -3946,7 +3961,7 @@ static int ftpd_command(FAR struct ftpd_session_s *session)
/* Check if there is a handler for the command */ /* Check if there is a handler for the command */
if (g_ftpdcmdtab[index].handler) if (g_ftpdcmdtab[index].handler != NULL)
{ {
/* Yess.. invoke the command handler. */ /* Yess.. invoke the command handler. */
@ -4032,22 +4047,22 @@ static void ftpd_freesession(FAR struct ftpd_session_s *session)
{ {
/* Free resources */ /* Free resources */
if (session->renamefrom) if (session->renamefrom != NULL)
{ {
free(session->renamefrom); free(session->renamefrom);
} }
if (session->work) if (session->work != NULL)
{ {
free(session->work); free(session->work);
} }
if (session->home) if (session->home != NULL)
{ {
free(session->home); free(session->home);
} }
if (session->user) if (session->user != NULL)
{ {
free(session->user); free(session->user);
} }
@ -4057,14 +4072,14 @@ static void ftpd_freesession(FAR struct ftpd_session_s *session)
close(session->fd); close(session->fd);
} }
if (session->data.buffer) if (session->data.buffer != NULL)
{ {
free(session->data.buffer); free(session->data.buffer);
} }
ftpd_dataclose(session); ftpd_dataclose(session);
if (session->cmd.buffer) if (session->cmd.buffer != NULL)
{ {
free(session->cmd.buffer); free(session->cmd.buffer);
} }
@ -4260,7 +4275,7 @@ FTPD_SESSION ftpd_open(sa_family_t family)
FAR struct ftpd_server_s *server; FAR struct ftpd_server_s *server;
server = ftpd_openserver(21, family); server = ftpd_openserver(21, family);
if (!server) if (server == NULL)
{ {
server = ftpd_openserver(2211, family); server = ftpd_openserver(2211, family);
} }
@ -4301,7 +4316,7 @@ int ftpd_adduser(FTPD_SESSION handle, uint8_t accountflags,
DEBUGASSERT(handle); DEBUGASSERT(handle);
newaccount = ftpd_account_new(user, accountflags); newaccount = ftpd_account_new(user, accountflags);
if (!newaccount) if (newaccount == NULL)
{ {
nerr("ERROR: Failed to allocate memory to the account\n"); nerr("ERROR: Failed to allocate memory to the account\n");
ret = -ENOMEM; ret = -ENOMEM;
@ -4375,7 +4390,7 @@ int ftpd_session(FTPD_SESSION handle, int timeout)
session = (FAR struct ftpd_session_s *) session = (FAR struct ftpd_session_s *)
zalloc(sizeof(struct ftpd_session_s)); zalloc(sizeof(struct ftpd_session_s));
if (!session) if (session == NULL)
{ {
nerr("ERROR: Failed to allocate session\n"); nerr("ERROR: Failed to allocate session\n");
ret = -ENOMEM; ret = -ENOMEM;
@ -4386,13 +4401,13 @@ int ftpd_session(FTPD_SESSION handle, int timeout)
session->server = server; session->server = server;
session->head = server->head; session->head = server->head;
session->curr = NULL; session->loggedin = false;
session->flags = 0; session->flags = 0;
session->txtimeout = -1; session->txtimeout = -1;
session->rxtimeout = -1; session->rxtimeout = -1;
session->cmd.sd = (int)(-1); session->cmd.sd = -1;
session->cmd.addrlen = (socklen_t)sizeof(session->cmd.addr); session->cmd.addrlen = sizeof(session->cmd.addr);
session->cmd.buflen = (size_t)CONFIG_FTPD_CMDBUFFERSIZE; session->cmd.buflen = CONFIG_FTPD_CMDBUFFERSIZE;
session->cmd.buffer = NULL; session->cmd.buffer = NULL;
session->command = NULL; session->command = NULL;
session->param = NULL; session->param = NULL;
@ -4411,7 +4426,7 @@ int ftpd_session(FTPD_SESSION handle, int timeout)
/* Allocate a command buffer */ /* Allocate a command buffer */
session->cmd.buffer = (FAR char *)malloc(session->cmd.buflen); session->cmd.buffer = (FAR char *)malloc(session->cmd.buflen);
if (!session->cmd.buffer) if (session->cmd.buffer == NULL)
{ {
nerr("ERROR: Failed to allocate command buffer\n"); nerr("ERROR: Failed to allocate command buffer\n");
ret = -ENOMEM; ret = -ENOMEM;
@ -4421,7 +4436,7 @@ int ftpd_session(FTPD_SESSION handle, int timeout)
/* Allocate a data buffer */ /* Allocate a data buffer */
session->data.buffer = (FAR char *)malloc(session->data.buflen); session->data.buffer = (FAR char *)malloc(session->data.buflen);
if (!session->data.buffer) if (session->data.buffer == NULL)
{ {
nerr("ERROR: Failed to allocate data buffer\n"); nerr("ERROR: Failed to allocate data buffer\n");
ret = -ENOMEM; ret = -ENOMEM;

View File

@ -120,7 +120,7 @@ struct ftpd_session_s
{ {
FAR struct ftpd_server_s *server; FAR struct ftpd_server_s *server;
FAR struct ftpd_account_s *head; FAR struct ftpd_account_s *head;
FAR struct ftpd_account_s *curr; bool loggedin;
uint8_t flags; /* See TPD_SESSIONFLAG_* definitions */ uint8_t flags; /* See TPD_SESSIONFLAG_* definitions */
int rxtimeout; int rxtimeout;
int txtimeout; int txtimeout;