diff --git a/ftpCommandElaborate.c b/ftpCommandElaborate.c index b8de6d2..6d558d5 100755 --- a/ftpCommandElaborate.c +++ b/ftpCommandElaborate.c @@ -61,7 +61,7 @@ int parseCommandUser(ftpDataType * data, int socketId) } else { - if (strlen(theUserName) >= 1) + if (strnlen(theUserName, 1) >= 1) { setDynamicStringDataType(&data->clients[socketId].login.name, theUserName, strlen(theUserName), &data->clients[socketId].memoryTable); returnCode = socketPrintf(data, socketId, "s", "331 User ok, Waiting for the password.\r\n"); @@ -91,37 +91,38 @@ int parseCommandSite(ftpDataType *data, int socketId) switch (setPermissionsReturnCode) { - case FTP_CHMODE_COMMAND_RETURN_CODE_OK: - { - returnCode = socketPrintf(data, socketId, "s", "200 Permissions changed\r\n"); - } - break; + case FTP_CHMODE_COMMAND_RETURN_CODE_OK: + { + returnCode = socketPrintf(data, socketId, "s", "200 Permissions changed\r\n"); + } + break; - case FTP_CHMODE_COMMAND_RETURN_CODE_NO_FILE: - { - returnCode = socketPrintf(data, socketId, "s", "550 chmod no such file\r\n"); - } - break; + case FTP_CHMODE_COMMAND_RETURN_CODE_NO_FILE: + { + returnCode = socketPrintf(data, socketId, "s", "550 chmod no such file\r\n"); + } + break; - case FTP_CHMODE_COMMAND_RETURN_CODE_NO_PERMISSIONS: - { - returnCode = socketPrintf(data, socketId, "s", "550 Some errors occurred while changing file permissions.\r\n"); - } - break; + case FTP_CHMODE_COMMAND_RETURN_CODE_NO_PERMISSIONS: + { + returnCode = socketPrintf(data, socketId, "s", "550 Some errors occurred while changing file permissions.\r\n"); + } + break; - case FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG: - default: - return FTP_COMMAND_PROCESSED_WRITE_ERROR; + case FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG: + default: + return FTP_COMMAND_PROCESSED_WRITE_ERROR; } } else { returnCode = socketPrintf(data, socketId, "s", "500 unknown extension\r\n"); - if (returnCode <= 0) - return FTP_COMMAND_PROCESSED_WRITE_ERROR; } + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } @@ -156,7 +157,7 @@ int parseCommandPass(ftpDataType *data, int socketId) } } - if (strlen(thePass) >= 1) + if (strnlen(thePass, 1) >= 1) { // my_printf("\nLogin try with user %s, password %s", data->clients[socketId].login.name.text, thePass); @@ -217,6 +218,7 @@ int parseCommandPass(ftpDataType *data, int socketId) my_printf("\ndata->clients[socketId].login.ownerShip.uid = %d", data->clients[socketId].login.ownerShip.uid); returnCode = socketPrintf(data, socketId, "s", "230 Login Ok.\r\n"); + if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; } @@ -239,6 +241,7 @@ int parseCommandPass(ftpDataType *data, int socketId) } returnCode = socketPrintf(data, socketId, "s", "430 Invalid username or password\r\n"); + if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; return 1; @@ -251,6 +254,7 @@ int parseCommandAuth(ftpDataType *data, int socketId) #ifndef OPENSSL_ENABLED returnCode = socketPrintf(data, socketId, "s", "502 Security extensions not implemented.\r\n"); + if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; #endif @@ -258,6 +262,7 @@ int parseCommandAuth(ftpDataType *data, int socketId) #ifdef OPENSSL_ENABLED returnCode = socketPrintf(data, socketId, "s", "234 AUTH TLS OK..\r\n"); + if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; @@ -304,6 +309,7 @@ int parseCommandSyst(ftpDataType *data, int socketId) { int returnCode; returnCode = socketPrintf(data, socketId, "s", "215 UNIX Type: L8\r\n"); + if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; @@ -328,6 +334,7 @@ int parseCommandFeat(ftpDataType *data, int socketId) #ifndef OPENSSL_ENABLED returnCode = socketPrintf(data, socketId, "s", "211-Extensions supported:\r\nPASV\r\nEPSV\r\nUTF8\r\nSIZE\r\nMDTM\r\nREST\r\n211 End.\r\n"); #endif + if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; @@ -396,6 +403,7 @@ int parseCommandPbsz(ftpDataType *data, int socketId) thePbszSize = getFtpCommandArg("PBSZ", data->clients[socketId].theCommandReceived, 0); returnCode = socketPrintf(data, socketId, "sss", "200 PBSZ set to ", thePbszSize, "\r\n"); + if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; @@ -588,20 +596,9 @@ int parseCommandAbor(ftpDataType *data, int socketId) int parseCommandList(ftpDataType *data, int socketId) { /* - -1 List one file per line -A List all files except "." and ".." -a List all files including those whose names start with "." - -C List entries by columns - -d List directory entries instead of directory contents - -F Append file type indicator (one of "*", "/", "=", "@" or "|") to names - -h Print file sizes in human-readable format (e.g. 1K, 234M, 2G) - -L List files pointed to by symlinks - -l Use a long listing format - -n List numeric UIDs/GIDs instead of user/group names - -R List subdirectories recursively - -r Sort filenames in reverse order - -S Sort by file size - -t Sort by modification time + */ int isSafePath = 0; @@ -611,23 +608,29 @@ int parseCommandList(ftpDataType *data, int socketId) if(!data->clients[socketId].workerData.socketIsReadyForConnection) { returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } + cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandArgs, 0, &data->clients[socketId].workerData.memoryTable); + cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandOps, 0, &data->clients[socketId].workerData.memoryTable); + theNameToList = getFtpCommandArg("LIST", data->clients[socketId].theCommandReceived, 1); getFtpCommandArgWithOptions("LIST", data->clients[socketId].theCommandReceived, &data->clients[socketId].workerData.ftpCommand, &data->clients[socketId].workerData.memoryTable); - // if (data->clients[socketId].workerData.ftpCommand.commandArgs.text != NULL) - // my_printf("\nLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text); - // if (data->clients[socketId].workerData.ftpCommand.commandOps.text != NULL) - // my_printf("\nLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text); - // my_printf("\ntheNameToList: %s", theNameToList); - cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandArgs, 0, &data->clients[socketId].workerData.memoryTable); - cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandOps, 0, &data->clients[socketId].workerData.memoryTable); + if (data->clients[socketId].workerData.ftpCommand.commandArgs.text != NULL) + my_printf("\nLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text); + if (data->clients[socketId].workerData.ftpCommand.commandOps.text != NULL) + my_printf("\nLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text); + + cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable); - if (strlen(theNameToList) > 0) + if (strnlen(theNameToList, 1) > 0) { isSafePath = getSafePath(&data->clients[socketId].listPath, theNameToList, &data->clients[socketId].login, &data->clients[socketId].memoryTable); } @@ -644,6 +647,10 @@ int parseCommandList(ftpDataType *data, int socketId) cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable); setDynamicStringDataType(&data->clients[socketId].listPath, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen, &data->clients[socketId].memoryTable); returnCode = socketPrintf(data, socketId, "s", "550 wrong path\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } @@ -652,6 +659,10 @@ int parseCommandList(ftpDataType *data, int socketId) cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable); setDynamicStringDataType(&data->clients[socketId].listPath, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen, &data->clients[socketId].memoryTable); returnCode = socketPrintf(data, socketId, "s", "550 no permissions.\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } @@ -675,17 +686,24 @@ int parseCommandNlst(ftpDataType *data, int socketId) if(!data->clients[socketId].workerData.socketIsReadyForConnection) { returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } + cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandArgs, 0, &data->clients[socketId].workerData.memoryTable); + cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandOps, 0, &data->clients[socketId].workerData.memoryTable); + theNameToNlist = getFtpCommandArg("NLIST", data->clients[socketId].theCommandReceived, 1); cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable); - // my_printf("\nNLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text); - // my_printf("\nNLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text); - // my_printf("\ntheNameToNlist: %s", theNameToNlist); + my_printf("\nNLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text); + my_printf("\nNLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text); + my_printf("\ntheNameToNlist: %s", theNameToNlist); - if (strlen(theNameToNlist) > 0) + if (strnlen(theNameToNlist,1) > 0) { isSafePath = getSafePath(&data->clients[socketId].listPath, theNameToNlist, &data->clients[socketId].login, &data->clients[socketId].memoryTable); } @@ -701,6 +719,10 @@ int parseCommandNlst(ftpDataType *data, int socketId) cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable); setDynamicStringDataType(&data->clients[socketId].listPath, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen, &data->clients[socketId].memoryTable); returnCode = socketPrintf(data, socketId, "s", "550 wrong path.\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } @@ -709,6 +731,11 @@ int parseCommandNlst(ftpDataType *data, int socketId) cleanDynamicStringDataType(&data->clients[socketId].listPath, 0, &data->clients[socketId].memoryTable); setDynamicStringDataType(&data->clients[socketId].listPath, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen, &data->clients[socketId].memoryTable); returnCode = socketPrintf(data, socketId, "s", "550 no permissions.\r\n"); + + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } @@ -732,13 +759,18 @@ int parseCommandRetr(ftpDataType *data, int socketId) if(!data->clients[socketId].workerData.socketIsReadyForConnection) { returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n"); + + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } theNameToRetr = getFtpCommandArg("RETR", data->clients[socketId].theCommandReceived, 0); cleanDynamicStringDataType(&data->clients[socketId].fileToRetr, 0, &data->clients[socketId].memoryTable); - if (strlen(theNameToRetr) > 0) + if (strnlen(theNameToRetr, 1) > 0) { isSafePath = getSafePath(&data->clients[socketId].fileToRetr, theNameToRetr, &data->clients[socketId].login, &data->clients[socketId].memoryTable); } @@ -746,6 +778,17 @@ int parseCommandRetr(ftpDataType *data, int socketId) if (isSafePath == 1 && FILE_IsFile(data->clients[socketId].fileToRetr.text) == 1) { + + if ((checkUserFilePermissions(data->clients[socketId].fileToRetr.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_R) != FILE_PERMISSION_R) + { + int writeReturn = socketPrintf(data, socketId, "s", "550 no reading permission on the file\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + + return FTP_COMMAND_PROCESSED; + } + pthread_mutex_lock(&data->clients[socketId].conditionMutex); memset(data->clients[socketId].workerData.theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE+1); @@ -759,6 +802,10 @@ int parseCommandRetr(ftpDataType *data, int socketId) else { returnCode = socketPrintf(data, socketId, "s", "550 Failed to open file.\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } @@ -774,20 +821,32 @@ int parseCommandStor(ftpDataType *data, int socketId) if(!data->clients[socketId].workerData.socketIsReadyForConnection) { returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n"); - return FTP_COMMAND_PROCESSED; - } + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + + return FTP_COMMAND_PROCESSED; + } theNameToStor = getFtpCommandArg("STOR", data->clients[socketId].theCommandReceived, 0); cleanDynamicStringDataType(&data->clients[socketId].fileToStor, 0, &data->clients[socketId].memoryTable); - - if (strlen(theNameToStor) > 0) + if (strnlen(theNameToStor, 1) > 0) { isSafePath = getSafePath(&data->clients[socketId].fileToStor, theNameToStor, &data->clients[socketId].login, &data->clients[socketId].memoryTable); } if (isSafePath == 1) { + if ((checkParentDirectoryPermissions(data->clients[socketId].fileToStor.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) != FILE_PERMISSION_W) + { + returnCode = socketPrintf(data, socketId, "s", "550 No permissions to write the file\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + + return FTP_COMMAND_PROCESSED; + } + pthread_mutex_lock(&data->clients[socketId].conditionMutex); memset(data->clients[socketId].workerData.theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE+1); strncpy(data->clients[socketId].workerData.theCommandReceived, data->clients[socketId].theCommandReceived, CLIENT_COMMAND_STRING_SIZE); @@ -798,6 +857,11 @@ int parseCommandStor(ftpDataType *data, int socketId) else { returnCode = socketPrintf(data, socketId, "s", "550 Wrong path.\r\n"); + + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } @@ -813,19 +877,35 @@ int parseCommandAppe(ftpDataType *data, int socketId) if(!data->clients[socketId].workerData.socketIsReadyForConnection) { returnCode = socketPrintf(data, socketId, "s", "425 Use PORT or PASV first.\r\n"); + + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } theNameToStor = getFtpCommandArg("APPE", data->clients[socketId].theCommandReceived, 0); cleanDynamicStringDataType(&data->clients[socketId].fileToStor, 0, &data->clients[socketId].memoryTable); - if (strlen(theNameToStor) > 0) + if (strnlen(theNameToStor, 1) > 0) { isSafePath = getSafePath(&data->clients[socketId].fileToStor, theNameToStor, &data->clients[socketId].login, &data->clients[socketId].memoryTable); } if (isSafePath == 1) { + + if ((checkParentDirectoryPermissions(data->clients[socketId].fileToStor.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) != FILE_PERMISSION_W) + { + returnCode = socketPrintf(data, socketId, "s", "550 No permissions to write the file\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + + return FTP_COMMAND_PROCESSED; + } + pthread_mutex_lock(&data->clients[socketId].conditionMutex); memset(data->clients[socketId].workerData.theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE+1); strncpy(data->clients[socketId].workerData.theCommandReceived, data->clients[socketId].theCommandReceived, CLIENT_COMMAND_STRING_SIZE); @@ -836,6 +916,10 @@ int parseCommandAppe(ftpDataType *data, int socketId) else { returnCode = socketPrintf(data, socketId, "s", "550 Wrong path.\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } @@ -857,7 +941,7 @@ int parseCommandCwd(ftpDataType *data, int socketId) //my_printf("\ncdw requested path: %s", thePath); - if (strlen(thePath) > 0) + if (strnlen(thePath, 1) > 0) { // my_printf("Memory data address 1st call : %lld", &data->clients[socketId].memoryTable); isSafePath = getSafePath(&theSafePath, thePath, &data->clients[socketId].login, &data->clients[socketId].memoryTable); @@ -902,10 +986,17 @@ int parseCommandCwd(ftpDataType *data, int socketId) if ((checkUserFilePermissions(data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_R) == FILE_PERMISSION_R) { returnCode = socketPrintf(data, socketId, "sss", "250 OK. Current directory is ", data->clients[socketId].login.ftpPath.text, "\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; } else { returnCode = socketPrintf(data, socketId, "sss", "530 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": no permissions\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + setDynamicStringDataType(&data->clients[socketId].login.absolutePath, absolutePathPrevious.text, absolutePathPrevious.textLen, &data->clients[socketId].memoryTable); setDynamicStringDataType(&data->clients[socketId].login.ftpPath, ftpPathPrevious.text, ftpPathPrevious.textLen, &data->clients[socketId].memoryTable); } @@ -913,6 +1004,10 @@ int parseCommandCwd(ftpDataType *data, int socketId) else { returnCode = socketPrintf(data, socketId, "sss", "530 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": No such file or directory\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + setDynamicStringDataType(&data->clients[socketId].login.absolutePath, absolutePathPrevious.text, absolutePathPrevious.textLen, &data->clients[socketId].memoryTable); setDynamicStringDataType(&data->clients[socketId].login.ftpPath, ftpPathPrevious.text, ftpPathPrevious.textLen, &data->clients[socketId].memoryTable); } @@ -932,6 +1027,10 @@ int parseCommandCwd(ftpDataType *data, int socketId) cleanDynamicStringDataType(&ftpPathPrevious, 0, &data->clients[socketId].memoryTable); cleanDynamicStringDataType(&theSafePath, 0, &data->clients[socketId].memoryTable); returnCode = socketPrintf(data, socketId, "s", "550 Wrong path.\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + return FTP_COMMAND_PROCESSED; } } @@ -1050,6 +1149,9 @@ int parseCommandMkd(ftpDataType *data, int socketId) { cleanDynamicStringDataType(&mkdFileName, 0, &data->clients[socketId].memoryTable); returnCode = socketPrintf(data, socketId, "s", "550 Wrong path.\r\n"); + + if (returnCode <= 0) + functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR; functionReturnCode = FTP_COMMAND_PROCESSED; } @@ -1449,6 +1551,19 @@ int parseCommandCdup(ftpDataType *data, int socketId) return FTP_COMMAND_PROCESSED; } +int parseCommandAcct(ftpDataType *data, int socketId) +{ + int returnCode; + + returnCode = socketPrintf(data, socketId, "s", "502 ACCT not implemented.\r\n"); + + if (returnCode <= 0) + return FTP_COMMAND_PROCESSED_WRITE_ERROR; + + return FTP_COMMAND_PROCESSED; +} + + long long int writeRetrFile(ftpDataType *data, int theSocketId, long long int startFrom, FILE *retrFP) { long long int readen = 0; diff --git a/ftpCommandsElaborate.h b/ftpCommandsElaborate.h index 404d72c..64b614b 100755 --- a/ftpCommandsElaborate.h +++ b/ftpCommandsElaborate.h @@ -88,6 +88,8 @@ int parseCommandMdtm(ftpDataType * data, int socketId); int parseCommandOpts(ftpDataType * data, int socketId); int parseCommandRnfr(ftpDataType * data, int socketId); int parseCommandRnto(ftpDataType * data, int socketId); +int parseCommandAcct(ftpDataType * data, int socketId); + long long int writeRetrFile(ftpDataType * data, int theSocketId, long long int startFrom, FILE *retrFP); char *getFtpCommandArg(char * theCommand, char *theCommandString, int skipArgs); diff --git a/ftpData.c b/ftpData.c index 5543eef..a16d262 100755 --- a/ftpData.c +++ b/ftpData.c @@ -225,13 +225,17 @@ void setRandomicPort(ftpDataType *data, int socketPosition) int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumber, int commandType, DYNMEM_MemoryTable_DataType **memoryTable) { - - + // a --> include . and .. + // A --> do not include . and .. + // nothing --> no hidden no . and no .. my_printf("\nFILE_GetDirectoryInodeList arg path: %s", ftpData->clients[clientId].listPath.text); + my_printf("\nftpData->clients[clientId].workerData.ftpCommand.commandArgs: %s", ftpData->clients[clientId].workerData.ftpCommand.commandArgs.text); + my_printf("\nftpData->clients[clientId].workerData.ftpCommand.commandOps: %s", ftpData->clients[clientId].workerData.ftpCommand.commandOps.text); + int i, x, returnCode; int fileAndFoldersCount = 0; char **fileList = NULL; - FILE_GetDirectoryInodeList(ftpData->clients[clientId].listPath.text, &fileList, &fileAndFoldersCount, 0, memoryTable); + FILE_GetDirectoryInodeList(ftpData->clients[clientId].listPath.text, &fileList, &fileAndFoldersCount, 0, ftpData->clients[clientId].workerData.ftpCommand.commandOps.text, memoryTable); *filesNumber = fileAndFoldersCount; returnCode = socketWorkerPrintf(ftpData, clientId, "sds", "total ", fileAndFoldersCount ,"\r\n"); @@ -279,8 +283,7 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb //my_printf("\nNot a directory, not a file, broken link"); continue; } - - + //my_printf("\nFILE SIZE : %lld", data.fileSize); data.owner = FILE_GetOwner(fileList[i], memoryTable); @@ -428,7 +431,7 @@ void getListDataInfo(char * thePath, DYNV_VectorGenericDataType *directoryInfo, int i; int fileAndFoldersCount = 0; ftpListDataType data; - FILE_GetDirectoryInodeList(thePath, &data.fileList, &fileAndFoldersCount, 0, memoryTable); + FILE_GetDirectoryInodeList(thePath, &data.fileList, &fileAndFoldersCount, 0, "Z", memoryTable); //my_printf("\nNUMBER OF FILES: %d", fileAndFoldersCount); //fflush(0); @@ -533,7 +536,6 @@ void getListDataInfo(char * thePath, DYNV_VectorGenericDataType *directoryInfo, void deleteListDataInfoVector(DYNV_VectorGenericDataType *theVector) { - int i; for (i = 0; i < theVector->Size; i++) { @@ -576,7 +578,6 @@ void cancelWorker(ftpDataType *data, int clientId) void resetWorkerData(ftpDataType *data, int clientId, int isInitialization) { - my_printf("\nReset of worker id: %d", clientId); data->clients[clientId].workerData.connectionPort = 0; data->clients[clientId].workerData.passiveModeOn = 0; diff --git a/ftpServer.c b/ftpServer.c index 9f125eb..694b4f5 100755 --- a/ftpServer.c +++ b/ftpServer.c @@ -289,39 +289,18 @@ void *connectionWorkerHandle(void * socketId) my_printf("\nWorker %d is waiting for commands!", theSocketId); //Conditional lock on tconditionVariablehread actions pthread_mutex_lock(&ftpData.clients[theSocketId].conditionMutex); - //int sleepTime = 1000; while (ftpData.clients[theSocketId].workerData.commandReceived == 0) { - //usleep(sleepTime); - //if (sleepTime < 200000) - //{ - //sleepTime+= 1000; - //} pthread_cond_wait(&ftpData.clients[theSocketId].conditionVariable, &ftpData.clients[theSocketId].conditionMutex); } pthread_mutex_unlock(&ftpData.clients[theSocketId].conditionMutex); - //my_printf("\nWorker %d unlocked", theSocketId); if (ftpData.clients[theSocketId].workerData.commandReceived == 1 && (compareStringCaseInsensitive(ftpData.clients[theSocketId].workerData.theCommandReceived, "STOR", strlen("STOR")) == 1 || compareStringCaseInsensitive(ftpData.clients[theSocketId].workerData.theCommandReceived, "APPE", strlen("APPE")) == 1) && ftpData.clients[theSocketId].fileToStor.textLen > 0) { - if ((checkParentDirectoryPermissions(ftpData.clients[theSocketId].fileToStor.text, ftpData.clients[theSocketId].login.ownerShip.uid, ftpData.clients[theSocketId].login.ownerShip.gid) & FILE_PERMISSION_W) != FILE_PERMISSION_W) - { - returnCode = socketPrintf(&ftpData, theSocketId, "s", "550 No permissions to write the file\r\n"); - - if (returnCode <= 0) - { - ftpData.clients[theSocketId].closeTheClient = 1; - my_printf("\n Closing the client 6"); - pthread_exit(NULL); - } - - break; - } - if (compareStringCaseInsensitive(ftpData.clients[theSocketId].workerData.theCommandReceived, "APPE", strlen("APPE")) == 1) { #ifdef LARGE_FILE_SUPPORT_ENABLED @@ -438,18 +417,6 @@ void *connectionWorkerHandle(void * socketId) else if (compareStringCaseInsensitive(ftpData.clients[theSocketId].workerData.theCommandReceived, "NLST", strlen("NLST")) == 1) theCommandType = COMMAND_TYPE_NLST; - if ((checkUserFilePermissions(ftpData.clients[theSocketId].listPath.text, ftpData.clients[theSocketId].login.ownerShip.uid, ftpData.clients[theSocketId].login.ownerShip.gid) & FILE_PERMISSION_R) != FILE_PERMISSION_R) - { - returnCode = socketPrintf(&ftpData, theSocketId, "s", "550 No permissions\r\n"); - if (returnCode <= 0) - { - ftpData.clients[theSocketId].closeTheClient = 1; - my_printf("\n Closing the client 8"); - pthread_exit(NULL); - } - break; - } - returnCode = socketPrintf(&ftpData, theSocketId, "s", "150 Accepted data connection\r\n"); if (returnCode <= 0) { @@ -458,7 +425,6 @@ void *connectionWorkerHandle(void * socketId) pthread_exit(NULL); } - //returnCode = writeListDataInfoToSocket(ftpData.clients[theSocketId].listPath.text, ftpData.clients[theSocketId].workerData.socketConnection, &theFiles, theCommandType); returnCode = writeListDataInfoToSocket(&ftpData, theSocketId, &theFiles, theCommandType, &ftpData.clients[theSocketId].workerData.memoryTable); if (returnCode <= 0) { @@ -489,19 +455,6 @@ void *connectionWorkerHandle(void * socketId) pthread_exit(NULL); } - if ((checkUserFilePermissions(ftpData.clients[theSocketId].fileToRetr.text, ftpData.clients[theSocketId].login.ownerShip.uid, ftpData.clients[theSocketId].login.ownerShip.gid) & FILE_PERMISSION_R) != FILE_PERMISSION_R) - { - writeReturn = socketPrintf(&ftpData, theSocketId, "s", "550 no reading permission on the file\r\n"); - if (writeReturn <= 0) - { - ftpData.clients[theSocketId].closeTheClient = 1; - my_printf("\n Closing the client 12"); - pthread_exit(NULL); - } - - break; - } - writenSize = writeRetrFile(&ftpData, theSocketId, ftpData.clients[theSocketId].workerData.retrRestartAtByte, ftpData.clients[theSocketId].workerData.theStorFile); ftpData.clients[theSocketId].workerData.retrRestartAtByte = 0; @@ -985,6 +938,11 @@ static int processCommand(int processingElement) //my_printf("\nNOOP command received"); toReturn = parseCommandNoop(&ftpData, processingElement); } + else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "ACCT", strlen("ACCT")) == 1) + { + //my_printf("\nNOOP command received"); + toReturn = parseCommandAcct(&ftpData, processingElement); + } else { ; //Parse unsupported command not needed diff --git a/library/daemon.c b/library/daemon.c index e1e94f0..2c099c5 100755 --- a/library/daemon.c +++ b/library/daemon.c @@ -73,7 +73,7 @@ int isProcessAlreadyRunning(void) //my_printf("\nFILE_LockFile returnCode = %d", returnCode); ftruncate(fd, 0); returnCode = snprintf(buf, 100, "%ld", (long)getpid()); - returnCode = write(fd, buf, strlen(buf)+1); + returnCode = write(fd, buf, strnlen(buf, 100)+1); return 0; } diff --git a/library/fileManagement.c b/library/fileManagement.c index 033587c..7215c00 100755 --- a/library/fileManagement.c +++ b/library/fileManagement.c @@ -202,41 +202,42 @@ int FILE_IsFile(const char *TheFileName) return 0; } -void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * FilesandFolders, int Recursive, DYNMEM_MemoryTable_DataType ** memoryTable) +void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * FilesandFolders, int Recursive, char * commandOps, DYNMEM_MemoryTable_DataType ** memoryTable) { int FileAndFolderIndex = *FilesandFolders; my_printf("\nLIST DETAILS OF: %s", DirectoryInodeName); + my_printf("\ncommandOps: %s", commandOps); //Allocate the array for the 1st time if (*InodeList == NULL) { (*InodeList) = (char **) DYNMEM_malloc(sizeof(char *), memoryTable, "InodeList"); } - if (FILE_IsDirectory(DirectoryInodeName)) { - - DIR *TheDirectory; struct dirent *dir; TheDirectory = opendir(DirectoryInodeName); if (TheDirectory) { - - while ((dir = readdir(TheDirectory)) != NULL) { - if ( dir->d_name[0] == '.' && strlen(dir->d_name) == 1) + + if ( dir->d_name[0] == '.' && strnlen(dir->d_name, 2) == 1) continue; - if ( dir->d_name[0] == '.' && dir->d_name[1] == '.' && strlen(dir->d_name) == 2) + if ( dir->d_name[0] == '.' && dir->d_name[1] == '.' && strnlen(dir->d_name, 3) == 2) continue; + //Skips all files and dir starting with . + if ((dir->d_name[0] == '.' && commandOps == NULL) || (dir->d_name[0] == '.' && commandOps[0] != 'a' && commandOps[0] != 'A')) + continue; + //Set the row to needed size int ReallocSize = sizeof(char *) * (FileAndFolderIndex+1)+1; (*InodeList) = (char ** ) DYNMEM_realloc((*InodeList), ReallocSize, memoryTable); - size_t nsize = strlen(dir->d_name) * sizeof(char) + strlen(DirectoryInodeName) * sizeof(char) + 2; + size_t nsize = strnlen(dir->d_name, 256) * sizeof(char) + strlen(DirectoryInodeName) * sizeof(char) + 2; //Allocate the path string size (*InodeList)[FileAndFolderIndex] = (char *) DYNMEM_malloc (nsize , memoryTable, "InodeList"); strcpy((*InodeList)[FileAndFolderIndex], DirectoryInodeName ); @@ -248,7 +249,7 @@ void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, i if ( Recursive == 1 && FILE_IsDirectory((*InodeList)[*FilesandFolders-1]) == 1 ) { - FILE_GetDirectoryInodeList ( (*InodeList)[FileAndFolderIndex-1], InodeList, FilesandFolders, Recursive, memoryTable); + FILE_GetDirectoryInodeList ( (*InodeList)[FileAndFolderIndex-1], InodeList, FilesandFolders, Recursive, "Z", memoryTable); FileAndFolderIndex = (*FilesandFolders); } @@ -291,10 +292,10 @@ int FILE_GetDirectoryInodeCount(char * DirectoryInodeName) { while ((dir = readdir(TheDirectory)) != NULL) { - if ( dir->d_name[0] == '.' && strlen(dir->d_name) == 1) + if ( dir->d_name[0] == '.' && strnlen(dir->d_name, 2) == 1) continue; - if ( dir->d_name[0] == '.' && dir->d_name[1] == '.' && strlen(dir->d_name) == 2) + if ( dir->d_name[0] == '.' && dir->d_name[1] == '.' && strnlen(dir->d_name, 3) == 2) continue; FileAndFolderIndex++; diff --git a/library/fileManagement.h b/library/fileManagement.h index 224a4d4..16782d5 100755 --- a/library/fileManagement.h +++ b/library/fileManagement.h @@ -60,7 +60,7 @@ long long int FILE_GetFileSizeFromPath(char *TheFileName); int FILE_IsFile(const char *theFileName); int FILE_IsDirectory (char *directory_path); - void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * filesandfolders, int recursive, DYNMEM_MemoryTable_DataType ** memoryTable); + void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * filesandfolders, int recursive, char* commandOps, DYNMEM_MemoryTable_DataType ** memoryTable); int FILE_GetDirectoryInodeCount(char * DirectoryInodeName); int FILE_GetStringFromFile(char * filename, char **file_content, DYNMEM_MemoryTable_DataType ** memoryTable); void FILE_ReadStringParameters(char * filename, DYNV_VectorGenericDataType *ParametersVector); diff --git a/uftpd.cfg b/uftpd.cfg index 64fd79e..ebb1987 100755 --- a/uftpd.cfg +++ b/uftpd.cfg @@ -36,7 +36,6 @@ MAX_CONNECTION_TRY_PER_IP = 10 #USE , instad of . eg: 192,168,1,1 #SERVER_IP = 192,168,1,1 - #TLS CERTIFICATE FILE PATH CERTIFICATE_PATH=/etc/uFTP/cert.pem PRIVATE_CERTIFICATE_PATH=/etc/uFTP/key.pem