working on pam permissions

This commit is contained in:
Ugo Cirmignani
2018-12-31 16:12:43 +01:00
parent e0779f0d0c
commit f1f0d6000a
18 changed files with 190 additions and 91 deletions

View File

@ -20,12 +20,18 @@ ENABLE_LARGE_FILE_SUPPORT=-D LARGE_FILE_SUPPORT_ENABLED -D _LARGEFILE64_SOURCE
ENABLE_OPENSSL_SUPPORT=
#TO ENABLE OPENSSL SUPPORT UNCOMMENT NEXT 2 LINES
ENABLE_OPENSSL_SUPPORT=-D OPENSSL_ENABLED
LIBS=-lpthread -lssl -lcrypto -lpam
LIBS=-lpthread -lssl -lcrypto
ENABLE_PAM_SUPPORT=
PAM_AUTH_LIB=
#TO ENABLE PAM AUTH UNCOMMENT NEXT TWO LINES
ENABLE_PAM_SUPPORT= -D PAM_SUPPORT_ENABLED
PAM_AUTH_LIB= -lpam
#USER PAM AUTH
#-lpam
CFLAGS=$(CFLAGSTEMP) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT)
CFLAGS=$(CFLAGSTEMP) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT) $(ENABLE_PAM_SUPPORT)
all: $(BUILDFILES)
@ -40,7 +46,7 @@ end:
@echo Build process end
uFTP: uFTP.c fileManagement.o configRead.o logFunctions.o ftpCommandElaborate.o ftpData.o ftpServer.o daemon.o signals.o connection.o openSsl.o dynamicMemory.o errorHandling.o auth.o
@$(CC) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT) uFTP.c $(LIBPATH)dynamicVectors.o $(LIBPATH)fileManagement.o $(LIBPATH)configRead.o $(LIBPATH)logFunctions.o $(LIBPATH)ftpCommandElaborate.o $(LIBPATH)ftpData.o $(LIBPATH)ftpServer.o $(LIBPATH)daemon.o $(LIBPATH)signals.o $(LIBPATH)connection.o $(LIBPATH)openSsl.o $(LIBPATH)dynamicMemory.o $(LIBPATH)errorHandling.o $(LIBPATH)auth.o -o $(OUTPATH)uFTP $(LIBS)
@$(CC) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT) uFTP.c $(LIBPATH)dynamicVectors.o $(LIBPATH)fileManagement.o $(LIBPATH)configRead.o $(LIBPATH)logFunctions.o $(LIBPATH)ftpCommandElaborate.o $(LIBPATH)ftpData.o $(LIBPATH)ftpServer.o $(LIBPATH)daemon.o $(LIBPATH)signals.o $(LIBPATH)connection.o $(LIBPATH)openSsl.o $(LIBPATH)dynamicMemory.o $(LIBPATH)errorHandling.o $(LIBPATH)auth.o -o $(OUTPATH)uFTP $(LIBS) $(PAM_AUTH_LIB)
daemon.o:
@$(CC) $(CFLAGS) $(SOURCE_MODULES_PATH)daemon.c -o $(LIBPATH)daemon.o

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -159,16 +159,19 @@ int parseCommandPass(ftpDataType * data, int socketId)
printf("\nLogin try with user %s, password %s", data->clients[socketId].login.name.text, thePass);
//PAM AUTH METHOD
loginCheck( data->clients[socketId].login.name.text, thePass, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
if (data->clients[socketId].login.userLoggedIn == 1)
//PAM AUTH METHOD IF ENABLED
if (data->ftpParameters.pamAuthEnabled == 1)
{
printf("\n User logged with PAM ok!");
returnCode = socketPrintf(data, socketId, "s", "230 Login Ok.\r\n");
if (returnCode <= 0)
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
loginCheck( data->clients[socketId].login.name.text, thePass, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
if (data->clients[socketId].login.userLoggedIn == 1)
{
printf("\n User logged with PAM ok!");
returnCode = socketPrintf(data, socketId, "s", "230 Login Ok.\r\n");
if (returnCode <= 0)
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
return 1;
return 1;
}
}
@ -742,10 +745,13 @@ int parseCommandCwd(ftpDataType * data, int socketId)
thePath = getFtpCommandArg("CWD", data->clients[socketId].theCommandReceived, 0);
printf("\ncdw requested path: %s", thePath);
if (strlen(thePath) > 0)
{
//printf("Memory data address 1st call : %lld", &data->clients[socketId].memoryTable);
isSafePath = getSafePath(&theSafePath, thePath, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
printf("\ncdw safe path: %s", theSafePath.text);
}
if (isSafePath == 1)
@ -754,41 +760,36 @@ int parseCommandCwd(ftpDataType * data, int socketId)
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);
if (theSafePath.text[0] != '/')
{
if (data->clients[socketId].login.absolutePath.text[data->clients[socketId].login.absolutePath.textLen-1] != '/')
appendToDynamicStringDataType(&data->clients[socketId].login.absolutePath, "/", 1, &data->clients[socketId].memoryTable);
cleanDynamicStringDataType(&data->clients[socketId].login.ftpPath, 0, &data->clients[socketId].memoryTable);
cleanDynamicStringDataType(&data->clients[socketId].login.absolutePath, 0, &data->clients[socketId].memoryTable);
setDynamicStringDataType(&data->clients[socketId].login.absolutePath, theSafePath.text, theSafePath.textLen, &data->clients[socketId].memoryTable);
if (data->clients[socketId].login.ftpPath.text[data->clients[socketId].login.ftpPath.textLen-1] != '/')
appendToDynamicStringDataType(&data->clients[socketId].login.ftpPath, "/", 1, &data->clients[socketId].memoryTable);
if (data->clients[socketId].login.absolutePath.textLen == data->clients[socketId].login.homePath.textLen)
{
setDynamicStringDataType(&data->clients[socketId].login.ftpPath, "/", 1, &data->clients[socketId].memoryTable);
}
else if (data->clients[socketId].login.absolutePath.textLen > data->clients[socketId].login.homePath.textLen)
{
char *theFtpPathPointer = data->clients[socketId].login.absolutePath.text;
theFtpPathPointer += data->clients[socketId].login.homePath.textLen;
if (theFtpPathPointer[0] != '/')
{
setDynamicStringDataType(&data->clients[socketId].login.ftpPath, "/", 1, &data->clients[socketId].memoryTable);
appendToDynamicStringDataType(&data->clients[socketId].login.ftpPath, theFtpPathPointer, strlen(theFtpPathPointer), &data->clients[socketId].memoryTable);
}
else
{
setDynamicStringDataType(&data->clients[socketId].login.ftpPath, theFtpPathPointer, strlen(theFtpPathPointer), &data->clients[socketId].memoryTable);
}
}
appendToDynamicStringDataType(&data->clients[socketId].login.absolutePath, theSafePath.text, theSafePath.textLen, &data->clients[socketId].memoryTable);
appendToDynamicStringDataType(&data->clients[socketId].login.ftpPath, theSafePath.text, theSafePath.textLen, &data->clients[socketId].memoryTable);
}
else if (theSafePath.text[0] == '/')
{
cleanDynamicStringDataType(&data->clients[socketId].login.ftpPath, 0, &data->clients[socketId].memoryTable);
cleanDynamicStringDataType(&data->clients[socketId].login.absolutePath, 0, &data->clients[socketId].memoryTable);
setDynamicStringDataType(&data->clients[socketId].login.ftpPath, theSafePath.text, theSafePath.textLen, &data->clients[socketId].memoryTable);
setDynamicStringDataType(&data->clients[socketId].login.absolutePath, data->clients[socketId].login.homePath.text, data->clients[socketId].login.homePath.textLen, &data->clients[socketId].memoryTable);
printf("\ndata->clients[socketId].login.absolutePath = %s", data->clients[socketId].login.absolutePath.text);
printf("\ndata->clients[socketId].login.ftpPath = %s", data->clients[socketId].login.ftpPath.text);
printf("\nChecking the directory: %s", data->clients[socketId].login.absolutePath.text);
fflush(0);
if (strlen(theSafePath.text)> 0)
{
char *theDirPointer = theSafePath.text;
if (data->clients[socketId].login.absolutePath.text[data->clients[socketId].login.absolutePath.textLen-1] == '/')
{
while(theDirPointer[0] == '/')
theDirPointer++;
}
if (strlen(theDirPointer) > 0)
appendToDynamicStringDataType(&data->clients[socketId].login.absolutePath, theDirPointer, strlen(theDirPointer), &data->clients[socketId].memoryTable);
}
}
printf("\nCheck the directory: %s", data->clients[socketId].login.absolutePath.text);
if (FILE_IsDirectory(data->clients[socketId].login.absolutePath.text) == 1 )
{
@ -882,17 +883,49 @@ int parseCommandMkd(ftpDataType * data, int socketId)
theDirectoryFilename = getFtpCommandArg("MKD", data->clients[socketId].theCommandReceived, 0);
cleanDynamicStringDataType(&mkdFileName, 1, &data->clients[socketId].memoryTable);
isSafePath = getSafePath(&mkdFileName, theDirectoryFilename, &data->clients[socketId].login, &data->clients[socketId].memoryTable);
if (isSafePath == 1)
{
int returnStatus;
returnStatus = mkdir(mkdFileName.text, S_IRWXU | S_IRWXG | S_IRWXO);
if ((checkParentDirectoryPermissions(mkdFileName.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) == FILE_PERMISSION_W)
{
int returnStatus;
returnStatus = mkdir(mkdFileName.text, S_IRWXU | S_IRWXG | S_IRWXO);
if (returnStatus == -1)
{
returnCode = socketPrintf(data, socketId, "sss", "550 error while creating directory ", theDirectoryFilename, "\r\n");
if (returnStatus == -1)
{
returnCode = socketPrintf(data, socketId, "sss", "550 error while creating directory ", theDirectoryFilename, "\r\n");
if (returnCode <= 0)
{
functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR;
}
else
{
functionReturnCode = FTP_COMMAND_PROCESSED;
}
}
else
{
if (data->clients[socketId].login.ownerShip.ownerShipSet == 1)
{
returnStatus = FILE_doChownFromUidGid(mkdFileName.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid);
}
returnCode = socketPrintf(data, socketId, "sss", "257 \"", theDirectoryFilename, "\" : The directory was successfully created\r\n");
if (returnCode <= 0)
{
functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR;
}
else
{
functionReturnCode = FTP_COMMAND_PROCESSED;
}
}
}
else
{
returnCode = socketPrintf(data, socketId, "sss", "550 no permition to create directory ", theDirectoryFilename, "\r\n");
if (returnCode <= 0)
{
functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR;
@ -901,25 +934,8 @@ int parseCommandMkd(ftpDataType * data, int socketId)
{
functionReturnCode = FTP_COMMAND_PROCESSED;
}
}
else
{
if (data->clients[socketId].login.ownerShip.ownerShipSet == 1)
{
returnStatus = FILE_doChownFromUidGid(mkdFileName.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid);
}
}
returnCode = socketPrintf(data, socketId, "sss", "257 \"", theDirectoryFilename, "\" : The directory was successfully created\r\n");
if (returnCode <= 0)
{
functionReturnCode = FTP_COMMAND_PROCESSED_WRITE_ERROR;
}
else
{
functionReturnCode = FTP_COMMAND_PROCESSED;
}
}
}
else
{
@ -1200,15 +1216,24 @@ int parseCommandRnto(ftpDataType * data, int socketId)
if (FILE_IsFile(data->clients[socketId].renameFromFile.text) == 1 ||
FILE_IsDirectory(data->clients[socketId].renameFromFile.text) == 1)
{
returnCode = rename (data->clients[socketId].renameFromFile.text, data->clients[socketId].renameToFile.text);
if (returnCode == 0)
{
returnCode = socketPrintf(data, socketId, "s", "250 File successfully renamed or moved\r\n");
}
else
{
returnCode = socketPrintf(data, socketId, "s", "503 Error Renaming the file\r\n");
}
if ((checkUserFilePermissions(data->clients[socketId].renameFromFile.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) == FILE_PERMISSION_W &&
(checkParentDirectoryPermissions(data->clients[socketId].renameToFile.text, data->clients[socketId].login.ownerShip.uid, data->clients[socketId].login.ownerShip.gid) & FILE_PERMISSION_W) == FILE_PERMISSION_W)
{
returnCode = rename (data->clients[socketId].renameFromFile.text, data->clients[socketId].renameToFile.text);
if (returnCode == 0)
{
returnCode = socketPrintf(data, socketId, "s", "250 File successfully renamed or moved\r\n");
}
else
{
returnCode = socketPrintf(data, socketId, "s", "503 Error Renaming the file\r\n");
}
}
else
{
returnCode = socketPrintf(data, socketId, "s", "550 No permissions to rename the file\r\n");
}
}
else
{

View File

@ -93,6 +93,8 @@ void setDynamicStringDataType(dynamicStringDataType *dynamicString, char *theStr
}
}
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *loginData, DYNMEM_MemoryTable_DataType **memoryTable)
{
#define STRING_SIZE 4096

View File

@ -85,9 +85,9 @@ struct ftpParameters
int maximumIdleInactivity;
int maximumConnectionsPerIp;
int maximumUserAndPassowrdLoginTries;
char certificatePath[MAXIMUM_INODE_NAME];
char privateCertificatePath[MAXIMUM_INODE_NAME];
int pamAuthEnabled;
} typedef ftpParameters_DataType;
struct dynamicStringData
@ -120,10 +120,10 @@ struct ipData
struct workerData
{
#ifdef OPENSSL_ENABLED
SSL *serverSsl;
SSL *clientSsl;
#endif
#ifdef OPENSSL_ENABLED
SSL *serverSsl;
SSL *clientSsl;
#endif
int threadIsAlive;
int threadHasBeenCreated;
@ -262,6 +262,7 @@ struct ftpListData
void cleanLoginData(loginDataType *loginData, int init, DYNMEM_MemoryTable_DataType **memoryTable);
void cleanDynamicStringDataType(dynamicStringDataType *dynamicString, int init, DYNMEM_MemoryTable_DataType **memoryTable);
void setDynamicStringDataType(dynamicStringDataType *dynamicString, char *theString, int stringLen, DYNMEM_MemoryTable_DataType **memoryTable);
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *theHomePath, DYNMEM_MemoryTable_DataType **memoryTable);
void appendToDynamicStringDataType(dynamicStringDataType *dynamicString, char *theString, int stringLen, DYNMEM_MemoryTable_DataType **memoryTable);

View File

@ -278,6 +278,20 @@ void *connectionWorkerHandle(void * socketId)
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;
printf("\n Closing the client 6");
pthread_exit(NULL);
}
break;
}
#ifdef LARGE_FILE_SUPPORT_ENABLED
//#warning LARGE FILE SUPPORT IS ENABLED!
ftpData.clients[theSocketId].workerData.theStorFile = fopen64(ftpData.clients[theSocketId].fileToStor.text, "wb");
@ -883,7 +897,6 @@ static int processCommand(int processingElement)
{
// printf("\nRNFR command received");
toReturn = parseCommandRnfr(&ftpData, processingElement);
}
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "RNTO", strlen("RNTO")) == 1)
{

View File

@ -85,11 +85,11 @@ void loginCheck(char *name, char *password, loginDataType *login, DYNMEM_MemoryT
{
//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, "/", 1, &*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);
setDynamicStringDataType(&login->ftpPath, "/", strlen("/"), &*memoryTable);
/*
if (login->homePath.text[login->homePath.textLen-1] != '/')
{
appendToDynamicStringDataType(&login->homePath, "/", 1, &*memoryTable);
@ -98,9 +98,9 @@ void loginCheck(char *name, char *password, loginDataType *login, DYNMEM_MemoryT
if (login->absolutePath.text[login->absolutePath.textLen-1] != '/')
{
appendToDynamicStringDataType(&login->absolutePath, "/", 1, &*memoryTable);
}*/
}
setDynamicStringDataType(&login->ftpPath, "/", strlen("/"), &*memoryTable);
//setDynamicStringDataType(&login->ftpPath, "/", strlen("/"), &*memoryTable);
login->ownerShip.uid = pass->pw_gid;
login->ownerShip.gid = pass->pw_uid;

View File

@ -475,6 +475,18 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
// printf("\nSINGLE_INSTANCE parameter not found in the configuration file, using the default value: %d", ftpParameters->singleInstanceModeOn);
}
ftpParameters->pamAuthEnabled = 0;
searchIndex = searchParameter("ENABLE_PAM_AUTH", parametersVector);
if (searchIndex != -1)
{
if(compareStringCaseInsensitive(((parameter_DataType *) parametersVector->Data[searchIndex])->value, "true", strlen("true")) == 1)
ftpParameters->pamAuthEnabled = 1;
}
else
{
// printf("\nENABLE_PAM_AUTH parameter not found in the configuration file, using the default value: %d", ftpParameters->pamAuthEnabled);
}
ftpParameters->maximumIdleInactivity = 3600;
searchIndex = searchParameter("IDLE_MAX_TIMEOUT", parametersVector);
if (searchIndex != -1)

View File

@ -52,7 +52,7 @@ int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __f
int theStringSize = 0, theCommandSize = 0;
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
memset(&commandBuffer, 0, COMMAND_BUFFER);
//printf("\nWriting to socket id %d, TLS %d: ", clientId, ftpData->clients[clientId].tlsIsEnabled);
printf("\nWriting to socket id %d, TLS %d: ", clientId, ftpData->clients[clientId].tlsIsEnabled);
pthread_mutex_lock(&ftpData->clients[clientId].writeMutex);
@ -140,7 +140,7 @@ int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __f
#endif
}
//printf("\n%s", commandBuffer);
printf("\n%s", commandBuffer);
pthread_mutex_unlock(&ftpData->clients[clientId].writeMutex);

View File

@ -561,12 +561,42 @@ char * FILE_GetListPermissionsString(char *file, DYNMEM_MemoryTable_DataType **
return modeval;
}
int checkParentDirectoryPermissions(char *fileName, int uid, int gid)
{
char theFileName[4096];
memset(theFileName, 0, 4096);
int i;
int theFileNameLen = 0;
int theLen = strlen(fileName);
int theParentLen = 0;
for (i = 0; i < theLen; i++)
{
if (fileName[i] == '/')
{
theParentLen = i;
}
}
for (i = 0; i < theParentLen; i++)
{
if (i < 4096)
theFileName[theFileNameLen++] = fileName[i];
}
printf ("\n checking parent permissions on : %s", theFileName);
fflush(0);
return checkUserFilePermissions(theFileName, uid, gid);
}
int checkUserFilePermissions(char *fileName, int uid, int gid)
{
if (uid == 0 || gid == 0)
{
printf("\n User is root");
return FILE_PERMISSION_RW;
}
@ -591,16 +621,21 @@ int checkUserFilePermissions(char *fileName, int uid, int gid)
if (info.st_uid == uid ||
info.st_gid == gid)
{
printf("\n User is owner");
filePermissions = FILE_PERMISSION_RW;
}
else
{
mode_t perm = info.st_mode;
if ((perm & S_IROTH))
if ((perm & S_IROTH)){
printf("\nfile can be readen");
filePermissions |= FILE_PERMISSION_R;
}
if ((perm & S_IWOTH))
if ((perm & S_IWOTH)){
printf("\nfile can be written");
filePermissions |= FILE_PERMISSION_W;
}
}
return filePermissions;

View File

@ -81,5 +81,6 @@
void FILE_checkAllOpenedFD(void);
int fd_is_valid(int fd);
int checkUserFilePermissions(char *fileName, int uid, int gid);
int checkParentDirectoryPermissions(char *fileName, int uid, int gid);
#define GEN_FILE_MANAGEMENT_TYPES
#endif

View File

@ -34,6 +34,10 @@ MAX_CONNECTION_TRY_PER_IP = 10
CERTIFICATE_PATH=/etc/uFTP/cert.pem
PRIVATE_CERTIFICATE_PATH=/etc/uFTP/key.pem
#Enable system authentication based on /etc/passwd
#and /etc/passwd
ENABLE_PAM_AUTH = true
#USERS
#START FROM USER 0 TO XXX
USER_0 = username