mirror of
https://github.com/kingk85/uFTP.git
synced 2025-04-12 10:48:40 +03:00
Compare commits
17 Commits
v2.6.0stab
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7869d55f95 | ||
![]() |
4565a14d2c | ||
![]() |
6db29a0f33 | ||
![]() |
a2de9b1a7c | ||
![]() |
90f44e3a98 | ||
![]() |
ec5c155ccb | ||
![]() |
63251ca3e4 | ||
![]() |
509910642d | ||
![]() |
2f355d91d8 | ||
![]() |
8302e82366 | ||
![]() |
998b720fa5 | ||
![]() |
89e64c2ddc | ||
![]() |
5778081be9 | ||
![]() |
8f78c9e7f1 | ||
![]() |
38887ed633 | ||
![]() |
4c0b19e6d6 | ||
![]() |
d0191ca20d |
12
Makefile
12
Makefile
@ -16,7 +16,7 @@ ENDFLAG=
|
||||
#ENDFLAG=-static
|
||||
|
||||
#FOR RELEASE
|
||||
CFLAGSTEMP=-c -Wall -I.
|
||||
CFLAGSTEMP=-c -Wall -Wno-unused-variable -Wno-unused-but-set-variable -I.
|
||||
|
||||
OPTIMIZATION=-O3
|
||||
HEADERS=-I
|
||||
@ -33,13 +33,17 @@ ENABLE_OPENSSL_SUPPORT=
|
||||
#ENABLE_OPENSSL_SUPPORT=-D OPENSSL_ENABLED
|
||||
#LIBS=-lpthread -lssl -lcrypto
|
||||
|
||||
ENABLE_IPV6_SUPPORT=
|
||||
#TO ENABLE IPV6 support uncomment next line
|
||||
ENABLE_IPV6_SUPPORT=-D IPV6_ENABLED
|
||||
|
||||
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
|
||||
|
||||
CFLAGS=$(CFLAGSTEMP) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT) $(ENABLE_PAM_SUPPORT)
|
||||
CFLAGS=$(CFLAGSTEMP) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT) $(ENABLE_IPV6_SUPPORT) $(ENABLE_PAM_SUPPORT)
|
||||
|
||||
all: $(BUILDFILES)
|
||||
|
||||
@ -54,7 +58,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 log.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 $(LIBPATH)log.o -o $(OUTPATH)uFTP $(LIBS) $(PAM_AUTH_LIB) $(ENDFLAG)
|
||||
@$(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 $(LIBPATH)log.o -o $(OUTPATH)uFTP $(LIBS) $(PAM_AUTH_LIB) $(ENDFLAG)
|
||||
|
||||
daemon.o:
|
||||
@$(CC) $(CFLAGS) $(SOURCE_MODULES_PATH)daemon.c -o $(LIBPATH)daemon.o
|
||||
@ -83,7 +87,7 @@ fileManagement.o:
|
||||
signals.o:
|
||||
@$(CC) $(CFLAGS) $(SOURCE_MODULES_PATH)signals.c -o $(LIBPATH)signals.o
|
||||
|
||||
connection.o:
|
||||
connection.o: log.o
|
||||
@$(CC) $(CFLAGS) $(SOURCE_MODULES_PATH)connection.c -o $(LIBPATH)connection.o
|
||||
|
||||
log.o:
|
||||
|
@ -7,5 +7,5 @@ cp build/uFTP /var/www/html/uftpserver.com/downloads/binaries/latest/armhf/uFTP
|
||||
make clean
|
||||
make CC=musl-gcc ENDFLAG=-static
|
||||
cp build/uFTP /var/www/html/uftpserver.com/downloads/binaries/latest/x64/uFTP
|
||||
|
||||
cp uftpd.cfg /var/www/html/uftpserver.com/downloads/configuration_sample/uftpd.cfg
|
||||
cd build
|
@ -48,6 +48,9 @@
|
||||
#include "ftpCommandsElaborate.h"
|
||||
|
||||
#include "debugHelper.h"
|
||||
#include "library/log.h"
|
||||
|
||||
static int parse_eprt(const char *eprt_str, int *address_type, char *address, int *port);
|
||||
|
||||
/* Elaborate the User login command */
|
||||
int parseCommandUser(ftpDataType * data, int socketId)
|
||||
@ -179,7 +182,7 @@ int parseCommandPass(ftpDataType *data, int socketId)
|
||||
data->clients[socketId].closeTheClient = 1;
|
||||
returnCode = socketPrintf(data, socketId, "s", "430 Too many login failure detected, your ip will be blacklisted for 5 minutes\r\n");
|
||||
|
||||
char *theLogString[STRING_SZ_LARGE];
|
||||
char theLogString[STRING_SZ_LARGE];
|
||||
memset(theLogString, 0, STRING_SZ_LARGE);
|
||||
snprintf(theLogString, STRING_SZ_LARGE, "An ip %s has been blacklisted due too many password errors. Trying to login as user: %s ", data->clients[socketId].clientIpAddress, data->clients[socketId].login.name.text);
|
||||
addLog(theLogString, CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
@ -391,10 +394,10 @@ int parseCommandFeat(ftpDataType *data, int socketId)
|
||||
|
||||
int returnCode;
|
||||
#ifdef OPENSSL_ENABLED
|
||||
returnCode = socketPrintf(data, socketId, "s", "211-Extensions supported:\r\nPASV\r\nEPSV\r\nUTF8\r\nAUTH TLS\r\nPBSZ\r\nPROT\r\nSIZE\r\nMDTM\r\nREST\r\n211 End.\r\n");
|
||||
returnCode = socketPrintf(data, socketId, "s", "211-Extensions supported:\r\nPASV\r\nEPSV\r\nEPRT\r\nUTF8\r\nAUTH TLS\r\nPBSZ\r\nPROT\r\nSIZE\r\nMDTM\r\nREST\r\n211 End.\r\n");
|
||||
#endif
|
||||
#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");
|
||||
returnCode = socketPrintf(data, socketId, "s", "211-Extensions supported:\r\nPASV\r\nEPSV\r\nEPRT\r\nUTF8\r\nSIZE\r\nMDTM\r\nREST\r\n211 End.\r\n");
|
||||
#endif
|
||||
|
||||
if (returnCode <= 0)
|
||||
@ -545,8 +548,21 @@ int parseCommandPasv(ftpDataType *data, int socketId)
|
||||
void *pReturn;
|
||||
int returnCode;
|
||||
// my_printf("\n data->clients[%d].workerData.workerThread = %d",socketId, (int)data->clients[socketId].workerData.workerThread);
|
||||
|
||||
// my_printf("\n data->clients[%d].workerData.threadHasBeenCreated = %d", socketId, data->clients[socketId].workerData.threadHasBeenCreated);
|
||||
|
||||
if(data->clients[socketId].isIpV6 == 1)
|
||||
{
|
||||
returnCode = socketPrintf(data, socketId, "s", "500 Server use IPV6, use EPSV instead.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
addLog("socketPrintfError ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
if (data->clients[socketId].workerData.threadIsAlive == 1)
|
||||
{
|
||||
cancelWorker(data, socketId);
|
||||
@ -618,6 +634,9 @@ int parseCommandPort(ftpDataType *data, int socketId)
|
||||
int ipAddressBytes[4];
|
||||
int portBytes[2];
|
||||
theIpAndPort = getFtpCommandArg("PORT", data->clients[socketId].theCommandReceived, 0);
|
||||
|
||||
data->clients[socketId].workerData.addressType = 1;
|
||||
|
||||
sscanf(theIpAndPort, "%d,%d,%d,%d,%d,%d", &ipAddressBytes[0], &ipAddressBytes[1], &ipAddressBytes[2], &ipAddressBytes[3], &portBytes[0], &portBytes[1]);
|
||||
data->clients[socketId].workerData.connectionPort = (portBytes[0] * 256) + portBytes[1];
|
||||
returnCode = snprintf(data->clients[socketId].workerData.activeIpAddress, CLIENT_BUFFER_STRING_SIZE, "%d.%d.%d.%d", ipAddressBytes[0], ipAddressBytes[1], ipAddressBytes[2], ipAddressBytes[3]);
|
||||
@ -638,6 +657,8 @@ int parseCommandPort(ftpDataType *data, int socketId)
|
||||
data->clients[socketId].workerData.extendedPassiveModeOn = 0;
|
||||
data->clients[socketId].workerData.activeModeOn = 1;
|
||||
|
||||
my_printf("\n Port command received port: %d", data->clients[socketId].workerData.connectionPort);
|
||||
|
||||
returnCode = pthread_create(&data->clients[socketId].workerData.workerThread, NULL, connectionWorkerHandle, (void *)&data->clients[socketId].clientProgressiveNumber);
|
||||
|
||||
if (returnCode != 0)
|
||||
@ -1023,7 +1044,7 @@ int parseCommandRetr(ftpDataType *data, int socketId)
|
||||
{
|
||||
int isSafePath = 0;
|
||||
char *theNameToRetr;
|
||||
int returnCode;
|
||||
int returnCode = 0;
|
||||
|
||||
if(!data->clients[socketId].workerData.socketIsReadyForConnection)
|
||||
{
|
||||
@ -1317,11 +1338,8 @@ int parseCommandCwd(ftpDataType *data, int socketId)
|
||||
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.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)
|
||||
|
||||
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;
|
||||
@ -1335,6 +1353,10 @@ int parseCommandCwd(ftpDataType *data, int socketId)
|
||||
setDynamicStringDataType(&data->clients[socketId].login.ftpPath, theFtpPathPointer, strlen(theFtpPathPointer), &data->clients[socketId].memoryTable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setDynamicStringDataType(&data->clients[socketId].login.ftpPath, "/", 1, &data->clients[socketId].memoryTable);
|
||||
}
|
||||
|
||||
// my_printf("\ndata->clients[socketId].login.absolutePath = %s", data->clients[socketId].login.absolutePath.text);
|
||||
// my_printf("\ndata->clients[socketId].login.ftpPath = %s", data->clients[socketId].login.ftpPath.text);
|
||||
@ -2488,3 +2510,104 @@ int setPermissions(char *permissionsCommand, char *basePath, ownerShip_DataType
|
||||
|
||||
return FTP_CHMODE_COMMAND_RETURN_CODE_OK;
|
||||
}
|
||||
|
||||
|
||||
int parseCommandEprt(ftpDataType *data, int socketId)
|
||||
{
|
||||
int returnCode;
|
||||
|
||||
returnCode = parse_eprt(data->clients[socketId].theCommandReceived, &data->clients[socketId].workerData.addressType, data->clients[socketId].workerData.activeIpAddress, &data->clients[socketId].workerData.connectionPort);
|
||||
|
||||
if (returnCode < 0)
|
||||
{
|
||||
addLog("Error parsing EPRT", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
returnCode = socketPrintf(data, socketId, "s", "501 command syntax error\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
addLog("socketPrintfError ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IPV6_ENABLED
|
||||
if(data->clients[socketId].workerData.addressType == 2)
|
||||
{
|
||||
addLog("Error parsing EPRT", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
returnCode = socketPrintf(data, socketId, "s", "501 command syntax error no ipv6 supported in this version.\r\n");
|
||||
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
addLog("socketPrintfError ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *pReturn;
|
||||
if (data->clients[socketId].workerData.threadIsAlive == 1)
|
||||
{
|
||||
cancelWorker(data, socketId);
|
||||
}
|
||||
|
||||
if (data->clients[socketId].workerData.threadHasBeenCreated == 1)
|
||||
{
|
||||
returnCode = pthread_join(data->clients[socketId].workerData.workerThread, &pReturn);
|
||||
my_printf("\nPORT JOIN RETURN STATUS %d", returnCode);
|
||||
}
|
||||
|
||||
data->clients[socketId].workerData.passiveModeOn = 0;
|
||||
data->clients[socketId].workerData.extendedPassiveModeOn = 0;
|
||||
data->clients[socketId].workerData.activeModeOn = 1;
|
||||
|
||||
returnCode = pthread_create(&data->clients[socketId].workerData.workerThread, NULL, connectionWorkerHandle, (void *)&data->clients[socketId].clientProgressiveNumber);
|
||||
|
||||
if (returnCode != 0)
|
||||
{
|
||||
my_printfError("\nError in pthread_create %d", returnCode);
|
||||
addLog("Pthead create error restarting the server", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
exit(0);
|
||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return FTP_COMMAND_PROCESSED;
|
||||
}
|
||||
|
||||
|
||||
static int parse_eprt(const char *eprt_str, int *address_type, char *address, int *port)
|
||||
{
|
||||
if (eprt_str == NULL || address_type == NULL || address == NULL || port == NULL)
|
||||
{
|
||||
return -1; // Error: null pointer provided
|
||||
}
|
||||
|
||||
// Check for valid EPRT format: "EPRT |<address-type>| <address> | <port>"
|
||||
int scanned_items = sscanf(eprt_str, "EPRT |%d|%[^|]|%d", address_type, address, port);
|
||||
if (scanned_items != 3)
|
||||
{
|
||||
return -2; // Error: invalid EPRT format
|
||||
}
|
||||
|
||||
// Check for valid address type (1 or 2)
|
||||
if (*address_type != 1 && *address_type != 2)
|
||||
{
|
||||
return -3; // Error: invalid address type
|
||||
}
|
||||
|
||||
// Check for valid port number (positive integer)
|
||||
if (*port <= 0)
|
||||
{
|
||||
return -4; // Error: invalid port number
|
||||
}
|
||||
|
||||
|
||||
return 0; // Success
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ int parseCommandOpts(ftpDataType * data, int socketId);
|
||||
int parseCommandRnfr(ftpDataType * data, int socketId);
|
||||
int parseCommandRnto(ftpDataType * data, int socketId);
|
||||
int parseCommandAcct(ftpDataType * data, int socketId);
|
||||
|
||||
int parseCommandEprt(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);
|
||||
|
17
ftpData.c
17
ftpData.c
@ -42,6 +42,8 @@
|
||||
#include "library/dynamicMemory.h"
|
||||
|
||||
#include "debugHelper.h"
|
||||
#include "library/log.h"
|
||||
|
||||
|
||||
static int is_prefix(const char *str, const char *prefix);
|
||||
static char *my_realpath(const char *path, char *resolved_path);
|
||||
@ -299,6 +301,11 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
returnCode = socketWorkerPrintf(ftpData, clientId, "sds", "total ", fileAndFoldersCount ,"\r\n");
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
|
||||
for (x = 0; x < fileAndFoldersCount; x++)
|
||||
DYNMEM_free (fileList[x], memoryTable);
|
||||
|
||||
DYNMEM_free (fileList, memoryTable);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -344,6 +351,7 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
|
||||
if (data.isDirectory == 0 && data.isFile == 0 && data.isLink == 0)
|
||||
{
|
||||
DYNMEM_free (fileList[i], memoryTable);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -368,7 +376,7 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
my_printf("\n ********************** void inode permission string");
|
||||
}
|
||||
|
||||
if (data.isLink = 1 &&
|
||||
if (data.isLink == 1 &&
|
||||
data.inodePermissionString != NULL &&
|
||||
strlen(data.inodePermissionString) > 0 &&
|
||||
data.inodePermissionString[0] == 'l')
|
||||
@ -382,6 +390,7 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
FILE_AppendToString(&data.finalStringPath, " -> ", memoryTable);
|
||||
FILE_AppendToString(&data.finalStringPath, data.linkPath, memoryTable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
memset(data.lastModifiedDataString, 0, LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE);
|
||||
@ -390,7 +399,6 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
localtime_r(&data.lastModifiedData, &newtime);
|
||||
strftime(data.lastModifiedDataString, LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE, "%b %d %Y", &newtime);
|
||||
|
||||
|
||||
switch (commandType)
|
||||
{
|
||||
case COMMAND_TYPE_LIST:
|
||||
@ -492,7 +500,6 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
||||
DYNMEM_free (fileList, memoryTable);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fileList != NULL)
|
||||
@ -811,10 +818,6 @@ void resetClientData(ftpDataType *data, int clientId, int isInitialization)
|
||||
data->clients[clientId].closeTheClient = 0;
|
||||
data->clients[clientId].sockaddr_in_size = sizeof(struct sockaddr_in);
|
||||
data->clients[clientId].sockaddr_in_server_size = sizeof(struct sockaddr_in);
|
||||
data->clients[clientId].serverIpAddressInteger[0] = 0;
|
||||
data->clients[clientId].serverIpAddressInteger[1] = 0;
|
||||
data->clients[clientId].serverIpAddressInteger[2] = 0;
|
||||
data->clients[clientId].serverIpAddressInteger[3] = 0;
|
||||
|
||||
|
||||
memset(&data->clients[clientId].client_sockaddr_in, 0, data->clients[clientId].sockaddr_in_size);
|
||||
|
17
ftpData.h
17
ftpData.h
@ -87,7 +87,7 @@ struct usersParameters
|
||||
|
||||
struct ftpParameters
|
||||
{
|
||||
int ftpIpAddress[4];
|
||||
int ftpIpAddressV4[4];
|
||||
int port;
|
||||
int maxClients;
|
||||
int daemonModeOn;
|
||||
@ -150,6 +150,7 @@ struct workerData
|
||||
int threadIsAlive;
|
||||
int threadHasBeenCreated;
|
||||
int connectionPort;
|
||||
int addressType;
|
||||
int passiveModeOn;
|
||||
int extendedPassiveModeOn;
|
||||
int activeModeOn;
|
||||
@ -184,6 +185,7 @@ struct clientData
|
||||
SSL *ssl;
|
||||
#endif
|
||||
|
||||
int isIpV6;
|
||||
int tlsIsEnabled;
|
||||
int tlsIsNegotiating;
|
||||
unsigned long long int tlsNegotiatingTimeStart;
|
||||
@ -214,15 +216,20 @@ struct clientData
|
||||
loginDataType login;
|
||||
workerDataType workerData;
|
||||
|
||||
int sockaddr_in_size, sockaddr_in_server_size;
|
||||
socklen_t sockaddr_in_size, sockaddr_in_server_size;
|
||||
|
||||
#ifdef IPV6_ENABLED
|
||||
struct sockaddr_in6 client_sockaddr_in, server_sockaddr_in;
|
||||
#else
|
||||
struct sockaddr_in client_sockaddr_in, server_sockaddr_in;
|
||||
#endif
|
||||
|
||||
int clientPort;
|
||||
char clientIpAddress[INET_ADDRSTRLEN];
|
||||
char clientIpAddress[INET6_ADDRSTRLEN];
|
||||
|
||||
int serverPort;
|
||||
char serverIpAddress[INET_ADDRSTRLEN];
|
||||
int serverIpAddressInteger[4];
|
||||
char serverIpAddress[INET6_ADDRSTRLEN];
|
||||
int serverIpV4AddressInteger[4];
|
||||
ftpCommandDataType ftpCommand;
|
||||
int closeTheClient;
|
||||
|
||||
|
325
ftpServer.c
325
ftpServer.c
@ -129,7 +129,7 @@ void *connectionWorkerHandle(void * socketId)
|
||||
ftpData.clients[theSocketId].workerData.threadHasBeenCreated = 1;
|
||||
int returnCode;
|
||||
|
||||
my_printf("\nWORKER CREATED!");
|
||||
my_printf("\n ----------------- WORKER CREATED --------------!");
|
||||
|
||||
//Passive data connection mode
|
||||
if (ftpData.clients[theSocketId].workerData.passiveModeOn == 1)
|
||||
@ -167,7 +167,7 @@ void *connectionWorkerHandle(void * socketId)
|
||||
else
|
||||
{
|
||||
my_printf("\n Using server ip: %s", ftpData.ftpParameters.natIpAddress);
|
||||
returnCode = socketPrintf(&ftpData, theSocketId, "sdsdsdsdsdsds", "227 Entering Passive Mode (", ftpData.clients[theSocketId].serverIpAddressInteger[0], ",", ftpData.clients[theSocketId].serverIpAddressInteger[1], ",", ftpData.clients[theSocketId].serverIpAddressInteger[2], ",", ftpData.clients[theSocketId].serverIpAddressInteger[3], ",", (ftpData.clients[theSocketId].workerData.connectionPort / 256), ",", (ftpData.clients[theSocketId].workerData.connectionPort % 256), ")\r\n");
|
||||
returnCode = socketPrintf(&ftpData, theSocketId, "sdsdsdsdsdsds", "227 Entering Passive Mode (", ftpData.clients[theSocketId].serverIpV4AddressInteger[0], ",", ftpData.clients[theSocketId].serverIpV4AddressInteger[1], ",", ftpData.clients[theSocketId].serverIpV4AddressInteger[2], ",", ftpData.clients[theSocketId].serverIpV4AddressInteger[3], ",", (ftpData.clients[theSocketId].workerData.connectionPort / 256), ",", (ftpData.clients[theSocketId].workerData.connectionPort % 256), ")\r\n");
|
||||
}
|
||||
}
|
||||
else if (ftpData.clients[theSocketId].workerData.passiveModeOn == 1 && ftpData.clients[theSocketId].workerData.extendedPassiveModeOn == 1)
|
||||
@ -237,7 +237,13 @@ void *connectionWorkerHandle(void * socketId)
|
||||
}
|
||||
else if (ftpData.clients[theSocketId].workerData.activeModeOn == 1)
|
||||
{
|
||||
ftpData.clients[theSocketId].workerData.socketConnection = createActiveSocket(ftpData.clients[theSocketId].workerData.connectionPort, ftpData.clients[theSocketId].workerData.activeIpAddress);
|
||||
my_printf("\n ----------------- CREATING ACTIVE SOCKET --------------!");
|
||||
if (ftpData.clients[theSocketId].workerData.addressType == 1)
|
||||
ftpData.clients[theSocketId].workerData.socketConnection = createActiveSocket(ftpData.clients[theSocketId].workerData.connectionPort, ftpData.clients[theSocketId].workerData.activeIpAddress);
|
||||
#ifdef IPV6_ENABLED
|
||||
else if (ftpData.clients[theSocketId].workerData.addressType == 2)
|
||||
ftpData.clients[theSocketId].workerData.socketConnection = createActiveSocketV6(ftpData.clients[theSocketId].workerData.connectionPort, ftpData.clients[theSocketId].workerData.activeIpAddress);
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_ENABLED
|
||||
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
||||
@ -567,7 +573,7 @@ void runFtpServer(void)
|
||||
//Update watchdog timer
|
||||
updateWatchDogTime((int)time(NULL));
|
||||
|
||||
/*
|
||||
|
||||
my_printf("\nUsed memory : %lld", DYNMEM_GetTotalMemory());
|
||||
int memCount = 0;
|
||||
for (memCount = 0; memCount < ftpData.ftpParameters.maxClients; memCount++)
|
||||
@ -586,166 +592,162 @@ void runFtpServer(void)
|
||||
my_printf("\nftpData.clients[%d].workerData.directoryInfo.memoryTable = %s", memCount, ftpData.clients[memCount].workerData.directoryInfo.memoryTable->theName);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* waits for socket activity, if no activity then checks for client socket timeouts */
|
||||
if (selectWait(&ftpData) == 0)
|
||||
/* waits for socket activity, if no activity then checks for client socket timeouts */
|
||||
if (selectWait(&ftpData) == 0)
|
||||
{
|
||||
checkClientConnectionTimeout(&ftpData);
|
||||
flushLoginWrongTriesData(&ftpData);
|
||||
}
|
||||
|
||||
/*Main loop handle client commands */
|
||||
for (processingSock = 0; processingSock < ftpData.ftpParameters.maxClients; processingSock++)
|
||||
{
|
||||
/* close the connection if quit flag has been set */
|
||||
if (ftpData.clients[processingSock].closeTheClient == 1)
|
||||
{
|
||||
checkClientConnectionTimeout(&ftpData);
|
||||
flushLoginWrongTriesData(&ftpData);
|
||||
closeClient(&ftpData, processingSock);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*Main loop handle client commands */
|
||||
for (processingSock = 0; processingSock < ftpData.ftpParameters.maxClients; processingSock++)
|
||||
/* Check if there are client pending connections, accept the connection if possible otherwise reject */
|
||||
if ((returnCode = evaluateClientSocketConnection(&ftpData)) == 1)
|
||||
{
|
||||
/* close the connection if quit flag has been set */
|
||||
if (ftpData.clients[processingSock].closeTheClient == 1)
|
||||
{
|
||||
closeClient(&ftpData, processingSock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if there are client pending connections, accept the connection if possible otherwise reject */
|
||||
if ((returnCode = evaluateClientSocketConnection(&ftpData)) == 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* no data to check client is not connected, continue to check other clients */
|
||||
if (isClientConnected(&ftpData, processingSock) == 0)
|
||||
{
|
||||
/* socket is not conneted */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FD_ISSET(ftpData.clients[processingSock].socketDescriptor, &ftpData.connectionData.rset) ||
|
||||
FD_ISSET(ftpData.clients[processingSock].socketDescriptor, &ftpData.connectionData.eset))
|
||||
{
|
||||
|
||||
#ifdef OPENSSL_ENABLED
|
||||
if (ftpData.clients[processingSock].tlsIsNegotiating == 1)
|
||||
{
|
||||
returnCode = SSL_accept(ftpData.clients[processingSock].ssl);
|
||||
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
//my_printf("\nSSL NOT YET ACCEPTED: %d", returnCode);
|
||||
ftpData.clients[processingSock].tlsIsEnabled = 0;
|
||||
ftpData.clients[processingSock].tlsIsNegotiating = 1;
|
||||
|
||||
if ( ((int)time(NULL) - ftpData.clients[processingSock].tlsNegotiatingTimeStart) > TLS_NEGOTIATING_TIMEOUT )
|
||||
{
|
||||
ftpData.clients[processingSock].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
//my_printf("\nTLS timeout closing the client time:%lld, start time: %lld..", (int)time(NULL), ftpData.clients[processingSock].tlsNegotiatingTimeStart);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//my_printf("\nSSL ACCEPTED");
|
||||
ftpData.clients[processingSock].tlsIsEnabled = 1;
|
||||
ftpData.clients[processingSock].tlsIsNegotiating = 0;
|
||||
}
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ftpData.clients[processingSock].tlsIsEnabled == 1)
|
||||
{
|
||||
#ifdef OPENSSL_ENABLED
|
||||
ftpData.clients[processingSock].bufferIndex = SSL_read(ftpData.clients[processingSock].ssl, ftpData.clients[processingSock].buffer, CLIENT_BUFFER_STRING_SIZE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ftpData.clients[processingSock].bufferIndex = read(ftpData.clients[processingSock].socketDescriptor, ftpData.clients[processingSock].buffer, CLIENT_BUFFER_STRING_SIZE);
|
||||
}
|
||||
|
||||
//The client is not connected anymore
|
||||
if ((ftpData.clients[processingSock].bufferIndex) == 0)
|
||||
{
|
||||
//addLog("Client not connected anymore", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
closeClient(&ftpData, processingSock);
|
||||
}
|
||||
|
||||
//Debug print errors
|
||||
if (ftpData.clients[processingSock].bufferIndex < 0)
|
||||
{
|
||||
//ftpData.clients[processingSock].closeTheClient = 1;
|
||||
//addLog("Socket write error ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
//my_printfError("\n1 Errno = %d", errno);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Some commands has been received
|
||||
if (ftpData.clients[processingSock].bufferIndex > 0)
|
||||
{
|
||||
int i = 0;
|
||||
int commandProcessStatus = 0;
|
||||
for (i = 0; i < ftpData.clients[processingSock].bufferIndex; i++)
|
||||
{
|
||||
if (ftpData.clients[processingSock].commandIndex < CLIENT_COMMAND_STRING_SIZE)
|
||||
{
|
||||
if (ftpData.clients[processingSock].buffer[i] != '\r' && ftpData.clients[processingSock].buffer[i] != '\n')
|
||||
{
|
||||
ftpData.clients[processingSock].theCommandReceived[ftpData.clients[processingSock].commandIndex++] = ftpData.clients[processingSock].buffer[i];
|
||||
}
|
||||
|
||||
if (ftpData.clients[processingSock].buffer[i] == '\n')
|
||||
{
|
||||
ftpData.clients[processingSock].socketCommandReceived = 1;
|
||||
//my_printf("\n Processing the command: %s", ftpData.clients[processingSock].theCommandReceived);
|
||||
commandProcessStatus = processCommand(processingSock);
|
||||
//Echo unrecognized commands
|
||||
if (commandProcessStatus == FTP_COMMAND_NOT_RECONIZED)
|
||||
{
|
||||
int returnCode = 0;
|
||||
returnCode = socketPrintf(&ftpData, processingSock, "s", "500 Unknown command\r\n");
|
||||
if (returnCode < 0)
|
||||
{
|
||||
ftpData.clients[processingSock].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
my_printf("\n COMMAND NOT SUPPORTED ********* %s", ftpData.clients[processingSock].buffer);
|
||||
}
|
||||
else if (commandProcessStatus == FTP_COMMAND_PROCESSED)
|
||||
{
|
||||
ftpData.clients[processingSock].lastActivityTimeStamp = (int)time(NULL);
|
||||
}
|
||||
else if (commandProcessStatus == FTP_COMMAND_PROCESSED_WRITE_ERROR)
|
||||
{
|
||||
ftpData.clients[processingSock].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
my_printf("\n Write error WARNING!");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Command overflow can't be processed
|
||||
int returnCode;
|
||||
ftpData.clients[processingSock].commandIndex = 0;
|
||||
memset(ftpData.clients[processingSock].theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE+1);
|
||||
returnCode = socketPrintf(&ftpData, processingSock, "s", "500 Unknown command\r\n");
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
ftpData.clients[processingSock].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
my_printf("\n Command too long closing the client.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
usleep(100);
|
||||
memset(ftpData.clients[processingSock].buffer, 0, CLIENT_BUFFER_STRING_SIZE+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* no data to check client is not connected, continue to check other clients */
|
||||
if (isClientConnected(&ftpData, processingSock) == 0)
|
||||
{
|
||||
/* socket is not conneted */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FD_ISSET(ftpData.clients[processingSock].socketDescriptor, &ftpData.connectionData.rset) ||
|
||||
FD_ISSET(ftpData.clients[processingSock].socketDescriptor, &ftpData.connectionData.eset))
|
||||
{
|
||||
|
||||
#ifdef OPENSSL_ENABLED
|
||||
if (ftpData.clients[processingSock].tlsIsNegotiating == 1)
|
||||
{
|
||||
returnCode = SSL_accept(ftpData.clients[processingSock].ssl);
|
||||
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
//my_printf("\nSSL NOT YET ACCEPTED: %d", returnCode);
|
||||
ftpData.clients[processingSock].tlsIsEnabled = 0;
|
||||
ftpData.clients[processingSock].tlsIsNegotiating = 1;
|
||||
|
||||
if ( ((int)time(NULL) - ftpData.clients[processingSock].tlsNegotiatingTimeStart) > TLS_NEGOTIATING_TIMEOUT )
|
||||
{
|
||||
ftpData.clients[processingSock].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
//my_printf("\nTLS timeout closing the client time:%lld, start time: %lld..", (int)time(NULL), ftpData.clients[processingSock].tlsNegotiatingTimeStart);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//my_printf("\nSSL ACCEPTED");
|
||||
ftpData.clients[processingSock].tlsIsEnabled = 1;
|
||||
ftpData.clients[processingSock].tlsIsNegotiating = 0;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ftpData.clients[processingSock].tlsIsEnabled == 1)
|
||||
{
|
||||
#ifdef OPENSSL_ENABLED
|
||||
ftpData.clients[processingSock].bufferIndex = SSL_read(ftpData.clients[processingSock].ssl, ftpData.clients[processingSock].buffer, CLIENT_BUFFER_STRING_SIZE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ftpData.clients[processingSock].bufferIndex = read(ftpData.clients[processingSock].socketDescriptor, ftpData.clients[processingSock].buffer, CLIENT_BUFFER_STRING_SIZE);
|
||||
}
|
||||
|
||||
//The client is not connected anymore
|
||||
if ((ftpData.clients[processingSock].bufferIndex) == 0)
|
||||
{
|
||||
//addLog("Client not connected anymore", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
closeClient(&ftpData, processingSock);
|
||||
}
|
||||
|
||||
//Debug print errors
|
||||
if (ftpData.clients[processingSock].bufferIndex < 0)
|
||||
{
|
||||
//ftpData.clients[processingSock].closeTheClient = 1;
|
||||
//addLog("Socket write error ", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
//my_printfError("\n1 Errno = %d", errno);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Some commands has been received
|
||||
if (ftpData.clients[processingSock].bufferIndex > 0)
|
||||
{
|
||||
int i = 0;
|
||||
int commandProcessStatus = 0;
|
||||
for (i = 0; i < ftpData.clients[processingSock].bufferIndex; i++)
|
||||
{
|
||||
if (ftpData.clients[processingSock].commandIndex < CLIENT_COMMAND_STRING_SIZE)
|
||||
{
|
||||
if (ftpData.clients[processingSock].buffer[i] != '\r' && ftpData.clients[processingSock].buffer[i] != '\n')
|
||||
{
|
||||
ftpData.clients[processingSock].theCommandReceived[ftpData.clients[processingSock].commandIndex++] = ftpData.clients[processingSock].buffer[i];
|
||||
}
|
||||
|
||||
if (ftpData.clients[processingSock].buffer[i] == '\n')
|
||||
{
|
||||
ftpData.clients[processingSock].socketCommandReceived = 1;
|
||||
//my_printf("\n Processing the command: %s", ftpData.clients[processingSock].theCommandReceived);
|
||||
commandProcessStatus = processCommand(processingSock);
|
||||
//Echo unrecognized commands
|
||||
if (commandProcessStatus == FTP_COMMAND_NOT_RECONIZED)
|
||||
{
|
||||
int returnCode = 0;
|
||||
returnCode = socketPrintf(&ftpData, processingSock, "s", "500 Unknown command\r\n");
|
||||
if (returnCode < 0)
|
||||
{
|
||||
ftpData.clients[processingSock].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
my_printf("\n COMMAND NOT SUPPORTED ********* %s", ftpData.clients[processingSock].buffer);
|
||||
}
|
||||
else if (commandProcessStatus == FTP_COMMAND_PROCESSED)
|
||||
{
|
||||
ftpData.clients[processingSock].lastActivityTimeStamp = (int)time(NULL);
|
||||
}
|
||||
else if (commandProcessStatus == FTP_COMMAND_PROCESSED_WRITE_ERROR)
|
||||
{
|
||||
ftpData.clients[processingSock].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
my_printf("\n Write error WARNING!");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Command overflow can't be processed
|
||||
int returnCode;
|
||||
ftpData.clients[processingSock].commandIndex = 0;
|
||||
memset(ftpData.clients[processingSock].theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE+1);
|
||||
returnCode = socketPrintf(&ftpData, processingSock, "s", "500 Unknown command\r\n");
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
ftpData.clients[processingSock].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
my_printf("\n Command too long closing the client.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
usleep(100);
|
||||
memset(ftpData.clients[processingSock].buffer, 0, CLIENT_BUFFER_STRING_SIZE+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Server Close
|
||||
@ -863,9 +865,14 @@ static int processCommand(int processingElement)
|
||||
}
|
||||
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "PORT", strlen("PORT")) == 1)
|
||||
{
|
||||
//my_printf("\nPORT COMMAND RECEIVED");
|
||||
my_printf("\nPORT COMMAND RECEIVED");
|
||||
toReturn = parseCommandPort(&ftpData, processingElement);
|
||||
}
|
||||
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "EPRT", strlen("EPRT")) == 1)
|
||||
{
|
||||
my_printf("\nEPRT COMMAND RECEIVED");
|
||||
toReturn = parseCommandEprt(&ftpData, processingElement);
|
||||
}
|
||||
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "LIST", strlen("LIST")) == 1)
|
||||
{
|
||||
//my_printf("\nLIST COMMAND RECEIVED");
|
||||
|
@ -27,7 +27,7 @@
|
||||
#define FTPSERVER_H
|
||||
|
||||
#define MAX_FTP_CLIENTS 10
|
||||
#define UFTP_SERVER_VERSION "v2.6.0 stable"
|
||||
#define UFTP_SERVER_VERSION "v3.0.0 stable"
|
||||
|
||||
|
||||
void runFtpServer(void);
|
||||
|
@ -528,7 +528,7 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
|
||||
searchIndex = searchParameter("SERVER_IP", parametersVector);
|
||||
if (searchIndex != -1)
|
||||
{
|
||||
strncpy(&ftpParameters->natIpAddress, ((parameter_DataType *) parametersVector->Data[searchIndex])->value, STRING_SZ_SMALL);
|
||||
strncpy(ftpParameters->natIpAddress, ((parameter_DataType *) parametersVector->Data[searchIndex])->value, STRING_SZ_SMALL);
|
||||
my_printf("\n SERVER_IP parameter:%s", ftpParameters->natIpAddress);
|
||||
}
|
||||
else
|
||||
@ -552,10 +552,10 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
|
||||
searchIndex = searchParameter("FTP_SERVER_IP", parametersVector);
|
||||
if (searchIndex != -1)
|
||||
{
|
||||
sscanf (((parameter_DataType *) parametersVector->Data[searchIndex])->value,"%d.%d.%d.%d", &ftpParameters->ftpIpAddress[0],
|
||||
&ftpParameters->ftpIpAddress[1],
|
||||
&ftpParameters->ftpIpAddress[2],
|
||||
&ftpParameters->ftpIpAddress[3]);
|
||||
sscanf (((parameter_DataType *) parametersVector->Data[searchIndex])->value,"%d.%d.%d.%d", &ftpParameters->ftpIpAddressV4[0],
|
||||
&ftpParameters->ftpIpAddressV4[1],
|
||||
&ftpParameters->ftpIpAddressV4[2],
|
||||
&ftpParameters->ftpIpAddressV4[3]);
|
||||
//my_printf("\nFTP_SERVER_IP value: %d.%d.%d.%d", ftpParameters->ftpIpAddress[0],
|
||||
// ftpParameters->ftpIpAddress[1],
|
||||
// ftpParameters->ftpIpAddress[2],
|
||||
@ -563,10 +563,10 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
|
||||
}
|
||||
else
|
||||
{
|
||||
ftpParameters->ftpIpAddress[0] = 127;
|
||||
ftpParameters->ftpIpAddress[1] = 0;
|
||||
ftpParameters->ftpIpAddress[2] = 0;
|
||||
ftpParameters->ftpIpAddress[3] = 1;
|
||||
ftpParameters->ftpIpAddressV4[0] = 127;
|
||||
ftpParameters->ftpIpAddressV4[1] = 0;
|
||||
ftpParameters->ftpIpAddressV4[2] = 0;
|
||||
ftpParameters->ftpIpAddressV4[3] = 1;
|
||||
//my_printf("\nFTP_SERVER_IP parameter not found in the configuration file, listening on all available networks");
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,21 @@
|
||||
#include "../debugHelper.h"
|
||||
#include "../ftpData.h"
|
||||
#include "connection.h"
|
||||
#include "log.h"
|
||||
|
||||
static int is_ipv4_mapped_ipv6(const char *ip);
|
||||
|
||||
int is_ipv4_mapped_ipv6(const char *ip) {
|
||||
size_t prefix_len = strlen("::ffff:");
|
||||
|
||||
// Check if the address starts with the mapped address prefix
|
||||
if (strncmp(ip, "::ffff:", prefix_len) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if the remaining part is a valid IPv4 address using existing logic
|
||||
return 1;
|
||||
}
|
||||
|
||||
int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __fmt, ...)
|
||||
{
|
||||
@ -343,6 +358,146 @@ int getMaximumSocketFd(int mainSocket, ftpDataType * ftpData)
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
#ifdef IPV6_ENABLED
|
||||
|
||||
int createSocket(ftpDataType * ftpData)
|
||||
{
|
||||
//my_printf("\nCreating main socket on port %d", ftpData->ftpParameters.port);
|
||||
int sock = -1, errorCode = -1;
|
||||
struct sockaddr_in6 serveraddr;
|
||||
|
||||
//Socket creation IPV6
|
||||
if ((sock = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
perror("socket() failed");
|
||||
addLog("Socket creation failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//No blocking socket
|
||||
errorCode = fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
|
||||
int reuse = 1;
|
||||
|
||||
#ifdef SO_REUSEADDR
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) < 0)
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
addLog("socketopt failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
#endif
|
||||
|
||||
reuse = 1;
|
||||
#ifdef SO_REUSEPORT
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
addLog("setsocket error", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
memset(&serveraddr, 0, sizeof(serveraddr));
|
||||
serveraddr.sin6_family = AF_INET6;
|
||||
serveraddr.sin6_port = htons(ftpData->ftpParameters.port);
|
||||
serveraddr.sin6_addr = in6addr_any;
|
||||
|
||||
if (bind(sock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
|
||||
{
|
||||
close(sock);
|
||||
perror("bind() failed");
|
||||
addLog("bind failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Number of client allowed
|
||||
errorCode = listen(sock, ftpData->ftpParameters.maxClients + 1);
|
||||
if (errorCode < 0)
|
||||
{
|
||||
addLog("listen error", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
if (sock != -1)
|
||||
{
|
||||
close(sock);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int createPassiveSocket(int port)
|
||||
{
|
||||
int sock, returnCode;
|
||||
struct sockaddr_in6 serveraddr;
|
||||
|
||||
//Socket creation IPV6
|
||||
if ((sock = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
perror("socket() failed");
|
||||
addLog("socket failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&serveraddr, 0, sizeof(serveraddr));
|
||||
serveraddr.sin6_family = AF_INET6;
|
||||
serveraddr.sin6_port = htons(port);
|
||||
serveraddr.sin6_addr = in6addr_any;
|
||||
|
||||
int reuse = 1;
|
||||
|
||||
#ifdef SO_REUSEADDR
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
addLog("setsocketerror", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
#endif
|
||||
|
||||
reuse = 1;
|
||||
|
||||
#ifdef SO_REUSEPORT
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
addLog("set socket error", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
#endif
|
||||
|
||||
//Bind socket
|
||||
if (bind(sock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
|
||||
{
|
||||
close(sock);
|
||||
perror("bind() failed");
|
||||
addLog("bind failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Number of client allowed
|
||||
returnCode = listen(sock, 1);
|
||||
|
||||
if (returnCode == -1)
|
||||
{
|
||||
addLog("bind failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
my_printf("\n Could not listen %d errno = %d", sock, errno);
|
||||
|
||||
if (sock != -1)
|
||||
{
|
||||
close(sock);
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int createSocket(ftpDataType * ftpData)
|
||||
{
|
||||
//my_printf("\nCreating main socket on port %d", ftpData->ftpParameters.port);
|
||||
@ -473,18 +628,80 @@ int createPassiveSocket(int port)
|
||||
return sock;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IPV6_ENABLED
|
||||
int createActiveSocketV6(int port, char *ipAddress)
|
||||
{
|
||||
int sockfd;
|
||||
struct sockaddr_in6 serv_addr6;
|
||||
struct sockaddr *serv_addr_any;
|
||||
|
||||
// Creating socket
|
||||
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
my_printfError("Socket creation failed");
|
||||
addLog("Socket creation failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int reuse = 1;
|
||||
#ifdef SO_REUSEADDR
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
addLog("set socket error", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SO_REUSEPORT
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
|
||||
{
|
||||
perror("setsockopt(SO_REUSEADDR) failed");
|
||||
my_printfError("setsockopt(SO_REUSEADDR) failed");
|
||||
addLog("setsockopt error", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Prepare the sockaddr structure
|
||||
if (inet_pton(AF_INET6, ipAddress, &serv_addr6.sin6_addr) == 1)
|
||||
{
|
||||
serv_addr6.sin6_family = AF_INET6;
|
||||
serv_addr6.sin6_port = htons(port);
|
||||
serv_addr_any = (struct sockaddr *)&serv_addr6;
|
||||
}
|
||||
else
|
||||
{
|
||||
my_printfError("Invalid ip address");
|
||||
addLog("Invalid ip address", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Connect to server
|
||||
if (connect(sockfd, serv_addr_any, sizeof(serv_addr6)) < 0)
|
||||
{
|
||||
my_printfError("Connection failed");
|
||||
addLog("Connection failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
#endif
|
||||
|
||||
int createActiveSocket(int port, char *ipAddress)
|
||||
{
|
||||
int sockfd;
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
//my_printf("\n Connection socket is going to start ip: %s:%d \n", ipAddress, port);
|
||||
my_printf("\n Connection socket is going to start ip: %s:%d \n", ipAddress, port);
|
||||
memset(&serv_addr, 0, sizeof(struct sockaddr_in));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(port);
|
||||
if(inet_pton(AF_INET, ipAddress, &serv_addr.sin_addr)<=0)
|
||||
{
|
||||
my_printf("\n inet_pton error occured\n");
|
||||
my_printf("\n inet_pton error occured at address: %s:%d\n", ipAddress, port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -713,6 +930,139 @@ int getAvailableClientSocketIndex(ftpDataType * ftpData)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef IPV6_ENABLED
|
||||
|
||||
#warning IPV6 IS ENABLED
|
||||
int evaluateClientSocketConnection(ftpDataType * ftpData)
|
||||
{
|
||||
char str[INET6_ADDRSTRLEN];
|
||||
|
||||
if (FD_ISSET(ftpData->connectionData.theMainSocket, &ftpData->connectionData.rset))
|
||||
{
|
||||
int availableSocketIndex;
|
||||
if ((availableSocketIndex = getAvailableClientSocketIndex(ftpData)) != -1) //get available socket
|
||||
{
|
||||
if ((ftpData->clients[availableSocketIndex].socketDescriptor = accept(ftpData->connectionData.theMainSocket, (struct sockaddr *)&ftpData->clients[availableSocketIndex].client_sockaddr_in, (socklen_t*)&ftpData->clients[availableSocketIndex].sockaddr_in_size)) !=- 1)
|
||||
{
|
||||
int error, numberOfConnectionFromSameIp, i;
|
||||
numberOfConnectionFromSameIp = 0;
|
||||
ftpData->connectedClients++;
|
||||
ftpData->clients[availableSocketIndex].socketIsConnected = 1;
|
||||
|
||||
error = fcntl(ftpData->clients[availableSocketIndex].socketDescriptor, F_SETFL, O_NONBLOCK);
|
||||
|
||||
fdAdd(ftpData, availableSocketIndex);
|
||||
|
||||
// - - //
|
||||
ftpData->clients[availableSocketIndex].sockaddr_in_server_size = sizeof(ftpData->clients[availableSocketIndex].server_sockaddr_in);
|
||||
ftpData->clients[availableSocketIndex].sockaddr_in_size = sizeof(ftpData->clients[availableSocketIndex].client_sockaddr_in);
|
||||
|
||||
getpeername(ftpData->clients[availableSocketIndex].socketDescriptor, (struct sockaddr *)&ftpData->clients[availableSocketIndex].client_sockaddr_in, &ftpData->clients[availableSocketIndex].sockaddr_in_size);
|
||||
if(inet_ntop(AF_INET6, &ftpData->clients[availableSocketIndex].client_sockaddr_in.sin6_addr, ftpData->clients[availableSocketIndex].clientIpAddress, sizeof(ftpData->clients[availableSocketIndex].clientIpAddress)))
|
||||
{
|
||||
ftpData->clients[availableSocketIndex].clientPort = (int) ntohs(ftpData->clients[availableSocketIndex].client_sockaddr_in.sin6_port);
|
||||
}
|
||||
|
||||
|
||||
getsockname(ftpData->clients[availableSocketIndex].socketDescriptor, (struct sockaddr *)&ftpData->clients[availableSocketIndex].server_sockaddr_in, &ftpData->clients[availableSocketIndex].sockaddr_in_server_size);
|
||||
if(inet_ntop(AF_INET6, &ftpData->clients[availableSocketIndex].server_sockaddr_in.sin6_addr, ftpData->clients[availableSocketIndex].serverIpAddress, sizeof(ftpData->clients[availableSocketIndex].serverIpAddress)))
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
if (is_ipv4_mapped_ipv6(ftpData->clients[availableSocketIndex].clientIpAddress))
|
||||
{
|
||||
|
||||
sscanf (ftpData->clients[availableSocketIndex].serverIpAddress,"::ffff:%d.%d.%d.%d", &ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[0],
|
||||
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[1],
|
||||
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[2],
|
||||
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// Check if it's an IPv4-mapped address
|
||||
if (is_ipv4_mapped_ipv6(ftpData->clients[availableSocketIndex].clientIpAddress))
|
||||
{
|
||||
ftpData->clients[availableSocketIndex].isIpV6 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftpData->clients[availableSocketIndex].isIpV6 = 1;
|
||||
}
|
||||
|
||||
|
||||
ftpData->clients[availableSocketIndex].connectionTimeStamp = (int)time(NULL);
|
||||
ftpData->clients[availableSocketIndex].lastActivityTimeStamp = (int)time(NULL);
|
||||
|
||||
for (i = 0; i <ftpData->ftpParameters.maxClients; i++)
|
||||
{
|
||||
if (i == availableSocketIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(ftpData->clients[availableSocketIndex].clientIpAddress, ftpData->clients[i].clientIpAddress) == 0) {
|
||||
numberOfConnectionFromSameIp++;
|
||||
}
|
||||
}
|
||||
if (ftpData->ftpParameters.maximumConnectionsPerIp > 0 &&
|
||||
numberOfConnectionFromSameIp >= ftpData->ftpParameters.maximumConnectionsPerIp)
|
||||
{
|
||||
int theReturnCode = socketPrintf(ftpData, availableSocketIndex, "sss", "530 too many connection from your ip address ", ftpData->clients[availableSocketIndex].clientIpAddress, " \r\n");
|
||||
ftpData->clients[availableSocketIndex].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
else
|
||||
{
|
||||
int returnCode = socketPrintf(ftpData, availableSocketIndex, "s", ftpData->welcomeMessage);
|
||||
if (returnCode <= 0)
|
||||
{
|
||||
ftpData->clients[availableSocketIndex].closeTheClient = 1;
|
||||
addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Errors while accepting, socket will be closed
|
||||
ftpData->clients[availableSocketIndex].closeTheClient = 1;
|
||||
//addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
//my_printf("\n2 Errno = %d", errno);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int socketRefuseFd;
|
||||
struct sockaddr_in6 socketRefuse_sockaddr_in;
|
||||
socklen_t socketRefuse_in_size = sizeof(socketRefuse_sockaddr_in);
|
||||
if ((socketRefuseFd = accept(ftpData->connectionData.theMainSocket, (struct sockaddr *)&socketRefuse_sockaddr_in, &socketRefuse_in_size))!=-1)
|
||||
{
|
||||
int theReturnCode = 0;
|
||||
char *messageToWrite = "10068 Server reached the maximum number of connection, please try later.\r\n";
|
||||
write(socketRefuseFd, messageToWrite, strlen(messageToWrite));
|
||||
shutdown(socketRefuseFd, SHUT_RDWR);
|
||||
theReturnCode = close(socketRefuseFd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//No new socket
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int evaluateClientSocketConnection(ftpDataType * ftpData)
|
||||
{
|
||||
if (FD_ISSET(ftpData->connectionData.theMainSocket, &ftpData->connectionData.rset))
|
||||
@ -739,10 +1089,10 @@ int evaluateClientSocketConnection(ftpDataType * ftpData)
|
||||
//my_printf("\n Server IP: %s", ftpData->clients[availableSocketIndex].serverIpAddress);
|
||||
//my_printf("Server: New client connected with id: %d", availableSocketIndex);
|
||||
//my_printf("\nServer: Clients connected: %d", ftpData->connectedClients);
|
||||
sscanf (ftpData->clients[availableSocketIndex].serverIpAddress,"%d.%d.%d.%d", &ftpData->clients[availableSocketIndex].serverIpAddressInteger[0],
|
||||
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[1],
|
||||
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[2],
|
||||
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[3]);
|
||||
sscanf (ftpData->clients[availableSocketIndex].serverIpAddress,"%d.%d.%d.%d", &ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[0],
|
||||
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[1],
|
||||
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[2],
|
||||
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[3]);
|
||||
|
||||
inet_ntop(AF_INET,
|
||||
&(ftpData->clients[availableSocketIndex].client_sockaddr_in.sin_addr),
|
||||
@ -817,3 +1167,5 @@ int evaluateClientSocketConnection(ftpDataType * ftpData)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -36,6 +36,11 @@ int getMaximumSocketFd(int mainSocket, ftpDataType * data);
|
||||
int createSocket(ftpDataType * ftpData);
|
||||
int createPassiveSocket(int port);
|
||||
int createActiveSocket(int port, char *ipAddress);
|
||||
|
||||
#ifdef IPV6_ENABLED
|
||||
int createActiveSocketV6(int port, char *ipAddress);
|
||||
#endif
|
||||
|
||||
void fdInit(ftpDataType * ftpData);
|
||||
void fdAdd(ftpDataType * ftpData, int index);
|
||||
void fdRemove(ftpDataType * ftpData, int index);
|
||||
|
@ -204,7 +204,7 @@ int FILE_IsLink( char* path)
|
||||
}
|
||||
|
||||
/* Check if a file is valid */
|
||||
int FILE_IsFile(const char *TheFileName, int checkExist)
|
||||
int FILE_IsFile(char *TheFileName, int checkExist)
|
||||
{
|
||||
FILE *TheFile;
|
||||
|
||||
@ -263,17 +263,17 @@ void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, i
|
||||
if ((dir->d_name[0] == '.' && commandOps == NULL) || (dir->d_name[0] == '.' && commandOps[0] != 'a' && commandOps[0] != 'A'))
|
||||
continue;
|
||||
|
||||
char *thePathToCheck[PATH_MAX];
|
||||
char thePathToCheck[PATH_MAX];
|
||||
memset(thePathToCheck, 0, PATH_MAX);
|
||||
|
||||
strcpy(thePathToCheck, DirectoryInodeName);
|
||||
strcat(thePathToCheck, "/");
|
||||
strcat(thePathToCheck, dir->d_name);
|
||||
|
||||
printf("\n ************* thePathToCheck = %s", thePathToCheck);
|
||||
|
||||
if (checkIfInodeExist == 1 && FILE_CheckIfLinkExist(thePathToCheck) == 0)
|
||||
{
|
||||
printf("--> Not valid!");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -750,7 +750,7 @@ char * FILE_GetGroupOwner(char *fileName, DYNMEM_MemoryTable_DataType **memoryTa
|
||||
}
|
||||
|
||||
|
||||
char * FILE_AppendStringToFile(char *fileName, char *theString)
|
||||
void FILE_AppendStringToFile(char *fileName, char *theString)
|
||||
{
|
||||
FILE *fp = fopen(fileName, "a");
|
||||
if (fp == NULL)
|
||||
|
@ -58,7 +58,7 @@
|
||||
long long int FILE_GetFileSize(FILE *theFilePointer);
|
||||
long int FILE_GetAvailableSpace(const char* ThePath);
|
||||
long long int FILE_GetFileSizeFromPath(char *TheFileName);
|
||||
int FILE_IsFile(const char *theFileName, int checkExist);
|
||||
int FILE_IsFile(char *theFileName, int checkExist);
|
||||
int FILE_IsDirectory (char *directory_path, int checkExist);
|
||||
int FILE_IsLink (char *directory_path);
|
||||
void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, int * filesandfolders, int recursive, char* commandOps, int checkIfInodeExist, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
@ -71,7 +71,7 @@
|
||||
char * FILE_GetListPermissionsString(char *file, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
char * FILE_GetOwner(char *fileName, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
char * FILE_GetGroupOwner(char *fileName, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
char * FILE_AppendStringToFile(char *fileName, char *theString);
|
||||
void FILE_AppendStringToFile(char *fileName, char *theString);
|
||||
time_t FILE_GetLastModifiedData(char *path);
|
||||
void FILE_AppendToString(char ** sourceString, char *theString, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
void FILE_DirectoryToParent(char ** sourceString, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define LOG_LINE_SIZE 1024 + PATH_MAX
|
||||
#define LOG_FILENAME_PREFIX "uftpLog_"
|
||||
|
||||
static void logThread(void * arg);
|
||||
static void *logThread(void * arg);
|
||||
|
||||
static DYNV_VectorString_DataType logQueue;
|
||||
static DYNV_VectorString_DataType workerQueue;
|
||||
@ -104,7 +104,7 @@ static int delete_old_logs(const char* folder_path, int days_to_keep)
|
||||
if (strftime(timeToday, sizeof(timeToday), "%Y-%m-%d", info) == 0)
|
||||
{
|
||||
my_printfError("strftime error");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
n_of_day_today = is_date_format(timeToday);
|
||||
@ -158,7 +158,7 @@ static int delete_old_logs(const char* folder_path, int days_to_keep)
|
||||
}
|
||||
|
||||
// STATIC SECTION
|
||||
static void logThread(void * arg)
|
||||
static void *logThread(void * arg)
|
||||
{
|
||||
|
||||
int lastDay;
|
||||
@ -181,7 +181,7 @@ static void logThread(void * arg)
|
||||
if (strftime(dayString, sizeof(dayString), "%d", info) == 0)
|
||||
{
|
||||
my_printfError("strftime error");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
day = atoi(dayString);
|
||||
@ -195,7 +195,7 @@ static void logThread(void * arg)
|
||||
if (strftime(logName, sizeof(logName), LOG_FILENAME_PREFIX"%Y-%m-%d", info) == 0)
|
||||
{
|
||||
my_printfError("strftime error");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy(theLogFilename, logFolder, PATH_MAX);
|
||||
@ -240,7 +240,7 @@ int logInit(char * folder, int numberOfLogFiles)
|
||||
logFilesNumber = numberOfLogFiles;
|
||||
|
||||
if (logFilesNumber <= 0)
|
||||
return;
|
||||
return -1;
|
||||
|
||||
delete_old_logs(folder, numberOfLogFiles);
|
||||
|
||||
@ -252,7 +252,7 @@ int logInit(char * folder, int numberOfLogFiles)
|
||||
// Initialize the mutex
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
|
||||
returnCode = pthread_create(&pLogThread, NULL, &logThread, NULL);
|
||||
returnCode = pthread_create(&pLogThread, NULL, logThread, NULL);
|
||||
if (returnCode != 0)
|
||||
{
|
||||
addLog("Pthead create error restarting the server", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||
@ -270,7 +270,7 @@ int logInit(char * folder, int numberOfLogFiles)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void addLog(char* logString, char * currFile, int currLine, char * currFunction)
|
||||
void addLog(char* logString, char * currFile, int currLine, const char * currFunction)
|
||||
{
|
||||
|
||||
if (logFilesNumber <= 0)
|
||||
|
@ -26,6 +26,6 @@
|
||||
#define LOG_H
|
||||
|
||||
int logInit(char * folder, int numberOfLogFiles);
|
||||
void addLog(char* logString, char * currFile, int currLine, char * currFunction);
|
||||
void addLog(char* logString, char * currFile, int currLine, const char * currFunction);
|
||||
|
||||
#endif
|
@ -33,7 +33,7 @@
|
||||
#include "openSsl.h"
|
||||
#include "fileManagement.h"
|
||||
#include "../debugHelper.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
|
||||
#define MUTEX_TYPE pthread_mutex_t
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "../ftpServer.h"
|
||||
#include "../debugHelper.h"
|
||||
#include "log.h"
|
||||
|
||||
static void ignore_sigpipe(void);
|
||||
|
||||
|
65
uftpd.cfg
65
uftpd.cfg
@ -1,67 +1,68 @@
|
||||
#FTP CONFIGURATION SAMPLE "/etc/uftpd.cfg"
|
||||
# FTP CONFIGURATION SAMPLE "/etc/uftpd.cfg"
|
||||
|
||||
#######################################################
|
||||
# UFTP SERVER SETTINGS #
|
||||
#######################################################
|
||||
|
||||
#MAXIMUM ALLOWED CONNECTIONS ON THE SERVER
|
||||
MAXIMUM_ALLOWED_FTP_CONNECTION = 30
|
||||
# NOTES:
|
||||
# restart uFTP to apply the configuration after changing parameters
|
||||
|
||||
#TCP/IP PORT SETTINGS (DEFAULT 21)
|
||||
# Maximum allowed FTP connections on the server
|
||||
MAXIMUM_ALLOWED_FTP_CONNECTION = 50
|
||||
|
||||
# TCP/IP port settings (default: 21)
|
||||
FTP_PORT = 21
|
||||
|
||||
#Allow only one server instance (true or false)
|
||||
# Allow only one server instance (true or false)
|
||||
SINGLE_INSTANCE = true
|
||||
|
||||
#Run in background, daemon mode ok
|
||||
# Run in background daemon mode (true or false)
|
||||
DAEMON_MODE = true
|
||||
|
||||
# Folder where to save the logs, use the same format below, the folder must terminate with /
|
||||
# Folder where logs are saved; must end with a '/'
|
||||
LOG_FOLDER = /var/log/
|
||||
|
||||
# Maximum number of logs to keep, if 0 log functionality is disabled
|
||||
# Maximum number of logs to keep; set to 0 to disable logging
|
||||
MAXIMUM_LOG_FILES = 0
|
||||
|
||||
# Idle timeout in seconds, client are disconnected for inactivity after the
|
||||
# specified amount of time in seconds, set to 0 to disable
|
||||
IDLE_MAX_TIMEOUT = 3600
|
||||
# Idle timeout in seconds; clients are disconnected after this period of inactivity; set to 0 to disable
|
||||
# some clients may fail if the timeout is too high https://github.com/kingk85/uFTP/issues/29
|
||||
IDLE_MAX_TIMEOUT = 330
|
||||
|
||||
#MAX CONNECTIONS PER IP
|
||||
#LIMIT THE MAXIMUM NUMBER OF CONNECTION FOR EACH IP ADDRESS
|
||||
# 0 TO DISABLE
|
||||
# Maximum connections per IP address; set to 0 to disable
|
||||
MAX_CONNECTION_NUMBER_PER_IP = 10
|
||||
|
||||
#MAX LOGIN TRY PER IP
|
||||
#THE IP ADDRESS WILL BE BLOCKED FOR 5 MINUTES AFTER WRONG LOGIN USERNAME AND PASSWORD
|
||||
#0 TO DISABLE
|
||||
# Maximum login attempts per IP (anti bruteforce feature); IP will be blocked for 5 minutes after exceeding this number of failed login attempts; set to 0 to disable
|
||||
MAX_CONNECTION_TRY_PER_IP = 10
|
||||
|
||||
#USE THE SERVER IP PARAMETER IF THE FTP SERVER IS UNDER NAT
|
||||
#SERVER IP SHOULD BE SET TO ROUTER IP IN THIS CASE
|
||||
#IF NOT IN USE LEAVE IT COMMENTED OR BLANK
|
||||
#USE , instad of . eg: 192,168,1,1
|
||||
# Server IP address for NAT configurations; use commas instead of periods (e.g., 192,168,1,1); leave commented or blank if not used
|
||||
#SERVER_IP = 192,168,1,1
|
||||
|
||||
#TLS CERTIFICATE FILE PATH
|
||||
# TLS certificate file paths
|
||||
CERTIFICATE_PATH=/etc/uFTP/cert.pem
|
||||
PRIVATE_CERTIFICATE_PATH=/etc/uFTP/key.pem
|
||||
|
||||
#Enable system authentication based on /etc/passwd
|
||||
#and /etc/shadow
|
||||
# Enable system authentication based on /etc/passwd and /etc/shadow (true or false)
|
||||
ENABLE_PAM_AUTH = false
|
||||
|
||||
# Force usage of the TLS
|
||||
# If enabled, only TLS connections will be allowed
|
||||
# Force usage of TLS; if enabled, only TLS connections are allowed (true or false)
|
||||
FORCE_TLS = false
|
||||
|
||||
#
|
||||
# Random port for passive FTP connections range
|
||||
#
|
||||
# Random port range for passive FTP connections
|
||||
RANDOM_PORT_START = 10000
|
||||
RANDOM_PORT_END = 50000
|
||||
|
||||
#USERS
|
||||
#START FROM USER 0 TO XXX
|
||||
#######################################################
|
||||
# USER SETTINGS #
|
||||
#######################################################
|
||||
|
||||
# Define users with the following parameters:
|
||||
# USER_<n> = username
|
||||
# PASSWORD_<n> = password
|
||||
# HOME_<n> = home directory
|
||||
# GROUP_NAME_OWNER_<n> = group ownership for new files (optional)
|
||||
# USER_NAME_OWNER_<n> = user ownership for new files (optional)
|
||||
|
||||
USER_0 = username
|
||||
PASSWORD_0 = password
|
||||
HOME_0 = /
|
||||
@ -78,7 +79,7 @@ USER_2 = anotherUsername
|
||||
PASSWORD_2 = anotherPassowrd
|
||||
HOME_2 = /
|
||||
|
||||
#blocked user that are not allowed to login
|
||||
# Blocked users who are not allowed to log in
|
||||
BLOCK_USER_0 = user1
|
||||
BLOCK_USER_1 = user2
|
||||
BLOCK_USER_2 = user3
|
||||
|
Reference in New Issue
Block a user