diff --git a/build/modules/configRead.o b/build/modules/configRead.o index 7190a6f..742e093 100644 Binary files a/build/modules/configRead.o and b/build/modules/configRead.o differ diff --git a/build/modules/fileManagement.o b/build/modules/fileManagement.o index 59b2942..586d560 100644 Binary files a/build/modules/fileManagement.o and b/build/modules/fileManagement.o differ diff --git a/build/modules/ftpCommandElaborate.o b/build/modules/ftpCommandElaborate.o index 1ce033c..e832c39 100644 Binary files a/build/modules/ftpCommandElaborate.o and b/build/modules/ftpCommandElaborate.o differ diff --git a/build/modules/ftpData.o b/build/modules/ftpData.o index 10df161..1177c77 100644 Binary files a/build/modules/ftpData.o and b/build/modules/ftpData.o differ diff --git a/build/modules/ftpServer.o b/build/modules/ftpServer.o index f7a8df3..393fab9 100644 Binary files a/build/modules/ftpServer.o and b/build/modules/ftpServer.o differ diff --git a/build/uFTP b/build/uFTP index 3ab8ee4..a8be5e8 100755 Binary files a/build/uFTP and b/build/uFTP differ diff --git a/ftpCommandElaborate.c b/ftpCommandElaborate.c index 5301473..b6c8be9 100644 --- a/ftpCommandElaborate.c +++ b/ftpCommandElaborate.c @@ -167,6 +167,8 @@ int parseCommandPass(ftpDataType * data, int socketId) returnCode = socketPrintf(data, socketId, "s", "230 Login Ok.\r\n"); if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; + + return 1; } @@ -205,6 +207,11 @@ int parseCommandPass(ftpDataType * data, int socketId) data->clients[socketId].login.ownerShip.uid = ((usersParameters_DataType *) data->ftpParameters.usersVector.Data[searchUserNameIndex])->ownerShip.uid; data->clients[socketId].login.userLoggedIn = 1; + + printf("\ndata->clients[socketId].login.ownerShip.ownerShipSet = %d", data->clients[socketId].login.ownerShip.ownerShipSet); + printf("\ndata->clients[socketId].login.ownerShip.gid = %d", data->clients[socketId].login.ownerShip.gid); + 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; @@ -281,9 +288,11 @@ int parseCommandAuth(ftpDataType * data, int socketId) int parseCommandPwd(ftpDataType * data, int socketId) { + printf("\n pwd is %s", data->clients[socketId].login.ftpPath.text); int returnCode; returnCode = socketPrintf(data, socketId, "sss", "257 \"", data->clients[socketId].login.ftpPath.text ,"\" is your current location\r\n"); + if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; @@ -697,7 +706,7 @@ int parseCommandStor(ftpDataType * data, int socketId) char *theNameToStor; theNameToStor = getFtpCommandArg("STOR", data->clients[socketId].theCommandReceived, 0); cleanDynamicStringDataType(&data->clients[socketId].fileToStor, 0, &data->clients[socketId].memoryTable); - + if (strlen(theNameToStor) > 0) { isSafePath = getSafePath(&data->clients[socketId].fileToStor, theNameToStor, &data->clients[socketId].login, &data->clients[socketId].memoryTable); @@ -741,7 +750,7 @@ int parseCommandCwd(ftpDataType * data, int socketId) if (isSafePath == 1) { - //printf("\n The Path requested for CWD IS:%s", theSafePath.text); + printf("\n The Path requested for CWD IS:%s", theSafePath.text); setDynamicStringDataType(&absolutePathPrevious, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen, &data->clients[socketId].memoryTable); setDynamicStringDataType(&ftpPathPrevious, data->clients[socketId].login.ftpPath.text, data->clients[socketId].login.ftpPath.textLen, &data->clients[socketId].memoryTable); @@ -779,15 +788,26 @@ int parseCommandCwd(ftpDataType * data, int socketId) } } - if (FILE_IsDirectory(data->clients[socketId].login.absolutePath.text) == 1) + printf("\nCheck the directory: %s", data->clients[socketId].login.absolutePath.text); + + if (FILE_IsDirectory(data->clients[socketId].login.absolutePath.text) == 1 ) { - returnCode = socketPrintf(data, socketId, "sss", "250 OK. Current directory is ", data->clients[socketId].login.ftpPath.text, "\r\n"); + 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"); + } + else + { + returnCode = socketPrintf(data, socketId, "sss", "530 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": no permissions\r\n"); + 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); + } } 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"); 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); - returnCode = socketPrintf(data, socketId, "sss", "530 Can't change directory to ", data->clients[socketId].login.absolutePath.text, ": No such file or directory\r\n"); } cleanDynamicStringDataType(&absolutePathPrevious, 0, &data->clients[socketId].memoryTable); @@ -941,21 +961,35 @@ int parseCommandDele(ftpDataType * data, int socketId) //printf("\nThe file to delete is: %s", deleFileName.text); if (FILE_IsFile(deleFileName.text) == 1) { - returnStatus = remove(deleFileName.text); - - if (returnStatus == -1) - { - returnCode = socketPrintf(data, socketId, "sss", "550 Could not delete the file: ", theFileToDelete, " some errors occurred\r\n"); - } - else - { - returnCode = socketPrintf(data, socketId, "sss", "250 Deleted ", theFileToDelete, "\r\n"); - } - functionReturnCode = FTP_COMMAND_PROCESSED; + if ((checkUserFilePermissions(deleFileName.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) == FILE_PERMISSION_W) + { + returnStatus = remove(deleFileName.text); - if (returnCode <= 0) - functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR; + if (returnStatus == -1) + { + returnCode = socketPrintf(data, socketId, "sss", "550 Could not delete the file: ", theFileToDelete, " some errors occurred\r\n"); + } + else + { + returnCode = socketPrintf(data, socketId, "sss", "250 Deleted ", theFileToDelete, "\r\n"); + } + + functionReturnCode = FTP_COMMAND_PROCESSED; + + if (returnCode <= 0) + functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR; + + } + else + { + returnCode = socketPrintf(data, socketId, "sss", "550 Could not delete the file: ", theFileToDelete, " no permissions\r\n"); + + functionReturnCode = FTP_COMMAND_PROCESSED; + + if (returnCode <= 0) + functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR; + } } else { @@ -1028,21 +1062,32 @@ int parseCommandRmd(ftpDataType * data, int socketId) { if (FILE_IsDirectory(rmdFileName.text) == 1) { - returnStatus = rmdir(rmdFileName.text); + if ((checkUserFilePermissions(rmdFileName.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) == FILE_PERMISSION_W) + { + returnStatus = rmdir(rmdFileName.text); - if (returnStatus == -1) - { - returnCode = socketPrintf(data, socketId, "s", "550 Could not remove the directory, some errors occurred.\r\n"); - } - else - { - returnCode = socketPrintf(data, socketId, "s", "250 The directory was successfully removed\r\n"); - } + if (returnStatus == -1) + { + returnCode = socketPrintf(data, socketId, "s", "550 Could not remove the directory, some errors occurred.\r\n"); + } + else + { + returnCode = socketPrintf(data, socketId, "s", "250 The directory was successfully removed\r\n"); + } - functionReturnCode = FTP_COMMAND_PROCESSED; + functionReturnCode = FTP_COMMAND_PROCESSED; - if (returnCode <= 0) - functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR; + if (returnCode <= 0) + functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR; + } + else + { + returnCode = socketPrintf(data, socketId, "s", "550 Could not delete the directory: No permissions\r\n"); + functionReturnCode = FTP_COMMAND_PROCESSED; + + if (returnCode <= 0) + functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR; + } } else { diff --git a/ftpServer.c b/ftpServer.c index 0ccc732..c6d9d38 100644 --- a/ftpServer.c +++ b/ftpServer.c @@ -379,6 +379,19 @@ 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; + printf("\n Closing the client 8"); + pthread_exit(NULL); + } + break; + } + returnCode = socketPrintf(&ftpData, theSocketId, "s", "150 Accepted data connection\r\n"); if (returnCode <= 0) { @@ -418,6 +431,18 @@ 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; + 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; @@ -683,7 +708,7 @@ static int processCommand(int processingElement) { int toReturn = 0; //printTimeStamp(); - //printf ("Command received from (%d): %s", processingElement, ftpData.clients[processingElement].theCommandReceived); + printf ("\nCommand received from (%d): %s", processingElement, ftpData.clients[processingElement].theCommandReceived); cleanDynamicStringDataType(&ftpData.clients[processingElement].ftpCommand.commandArgs, 0, &ftpData.clients[processingElement].memoryTable); cleanDynamicStringDataType(&ftpData.clients[processingElement].ftpCommand.commandOps, 0, &ftpData.clients[processingElement].memoryTable); diff --git a/library/auth.c b/library/auth.c index 0973187..8bfb661 100644 --- a/library/auth.c +++ b/library/auth.c @@ -78,14 +78,28 @@ void loginCheck(char *name, char *password, loginDataType *login, DYNMEM_MemoryT if (pass == NULL) { - cleanLoginData(login, 0, &*memoryTable); + login->userLoggedIn = 0; + return; } else { //printf("Authenticate with %s - %s through system\n", login, password); setDynamicStringDataType(&login->name, name, strlen(name), &*memoryTable); - setDynamicStringDataType(&login->homePath, pass->pw_dir, strlen(pass->pw_dir), &*memoryTable); + //setDynamicStringDataType(&login->homePath, pass->pw_dir, strlen(pass->pw_dir), &*memoryTable); + setDynamicStringDataType(&login->homePath, "/", 1, &*memoryTable); setDynamicStringDataType(&login->absolutePath, pass->pw_dir, strlen(pass->pw_dir), &*memoryTable); + + /* + if (login->homePath.text[login->homePath.textLen-1] != '/') + { + appendToDynamicStringDataType(&login->homePath, "/", 1, &*memoryTable); + } + + if (login->absolutePath.text[login->absolutePath.textLen-1] != '/') + { + appendToDynamicStringDataType(&login->absolutePath, "/", 1, &*memoryTable); + }*/ + setDynamicStringDataType(&login->ftpPath, "/", strlen("/"), &*memoryTable); login->ownerShip.uid = pass->pw_gid; @@ -98,6 +112,8 @@ void loginCheck(char *name, char *password, loginDataType *login, DYNMEM_MemoryT printf("\nDir: %s", pass->pw_dir); printf("\nGid: %d", pass->pw_gid); printf("\nUid: %d", pass->pw_uid); + printf("\nlogin->homePath.text: %s", login->homePath.text); + printf("\nlogin->absolutePath.text: %s", login->absolutePath.text); } } else diff --git a/library/configRead.c b/library/configRead.c index bd47d6b..7f8a62f 100644 --- a/library/configRead.c +++ b/library/configRead.c @@ -603,11 +603,25 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve userData.ownerShip.gid = FILE_getGID(userData.ownerShip.groupOwnerString); userData.ownerShip.uid = FILE_getUID(userData.ownerShip.userOwnerString); - userData.ownerShip.ownerShipSet = 1; + + + if (userData.ownerShip.gid != -1 && + userData.ownerShip.uid != -1) + { + userData.ownerShip.ownerShipSet = 1; + } + else + { + userData.ownerShip.gid = 0; + userData.ownerShip.uid = 0; + userData.ownerShip.ownerShipSet = 0; + } } else { userData.ownerShip.ownerShipSet = 0; + userData.ownerShip.gid = 0; + userData.ownerShip.uid = 0; userData.ownerShip.groupOwnerString = NULL; userData.ownerShip.userOwnerString = NULL; } diff --git a/library/fileManagement.c b/library/fileManagement.c index 47fda72..0754b67 100644 --- a/library/fileManagement.c +++ b/library/fileManagement.c @@ -546,7 +546,7 @@ char * FILE_GetListPermissionsString(char *file, DYNMEM_MemoryTable_DataType ** modeval[8] = (perm & S_IWOTH) ? 'w' : '-'; modeval[9] = (perm & S_IXOTH) ? 'x' : '-'; modeval[10] = '\0'; - + if(lstat(file, &stl) == 0) { if (S_ISLNK(stl.st_mode)) @@ -561,6 +561,51 @@ char * FILE_GetListPermissionsString(char *file, DYNMEM_MemoryTable_DataType ** return modeval; } + +int checkUserFilePermissions(char *fileName, int uid, int gid) +{ + + if (uid == 0 || gid == 0) + { + return FILE_PERMISSION_RW; + } + + static int init = 0; + if (init == 0) + { + + } + + init = 1; + + int filePermissions = FILE_PERMISSION_NO_RW; + int returnCode = 0; + char *toReturn; + struct stat info; + + if ((returnCode = stat(fileName, &info)) == -1) + { + return -1; + } + + if (info.st_uid == uid || + info.st_gid == gid) + { + filePermissions = FILE_PERMISSION_RW; + } + else + { + mode_t perm = info.st_mode; + if ((perm & S_IROTH)) + filePermissions |= FILE_PERMISSION_R; + + if ((perm & S_IWOTH)) + filePermissions |= FILE_PERMISSION_W; + } + + return filePermissions; +} + char * FILE_GetOwner(char *fileName, DYNMEM_MemoryTable_DataType **memoryTable) { int returnCode = 0; diff --git a/library/fileManagement.h b/library/fileManagement.h index b0cd101..f332b1b 100644 --- a/library/fileManagement.h +++ b/library/fileManagement.h @@ -32,10 +32,17 @@ #define FILE_MAX_LINE_LENGHT 512 #define FILE_MAX_PAR_VAR_SIZE 256 + + #define FILE_PERMISSION_NO_RW 0 + #define FILE_PERMISSION_R 1 + #define FILE_PERMISSION_W 2 + #define FILE_PERMISSION_RW 3 + + typedef struct FILE_StringParameterDataStruct { - char Name[FILE_MAX_PAR_VAR_SIZE]; - char Value[FILE_MAX_PAR_VAR_SIZE]; + char Name[FILE_MAX_PAR_VAR_SIZE]; + char Value[FILE_MAX_PAR_VAR_SIZE]; } FILE_StringParameter_DataType; @@ -73,5 +80,6 @@ gid_t FILE_getGID(const char *group_name); void FILE_checkAllOpenedFD(void); int fd_is_valid(int fd); + int checkUserFilePermissions(char *fileName, int uid, int gid); #define GEN_FILE_MANAGEMENT_TYPES #endif