mirror of
https://github.com/kingk85/uFTP.git
synced 2025-04-20 00:18:57 +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
|
#ENDFLAG=-static
|
||||||
|
|
||||||
#FOR RELEASE
|
#FOR RELEASE
|
||||||
CFLAGSTEMP=-c -Wall -I.
|
CFLAGSTEMP=-c -Wall -Wno-unused-variable -Wno-unused-but-set-variable -I.
|
||||||
|
|
||||||
OPTIMIZATION=-O3
|
OPTIMIZATION=-O3
|
||||||
HEADERS=-I
|
HEADERS=-I
|
||||||
@ -33,13 +33,17 @@ ENABLE_OPENSSL_SUPPORT=
|
|||||||
#ENABLE_OPENSSL_SUPPORT=-D OPENSSL_ENABLED
|
#ENABLE_OPENSSL_SUPPORT=-D OPENSSL_ENABLED
|
||||||
#LIBS=-lpthread -lssl -lcrypto
|
#LIBS=-lpthread -lssl -lcrypto
|
||||||
|
|
||||||
|
ENABLE_IPV6_SUPPORT=
|
||||||
|
#TO ENABLE IPV6 support uncomment next line
|
||||||
|
ENABLE_IPV6_SUPPORT=-D IPV6_ENABLED
|
||||||
|
|
||||||
ENABLE_PAM_SUPPORT=
|
ENABLE_PAM_SUPPORT=
|
||||||
PAM_AUTH_LIB=
|
PAM_AUTH_LIB=
|
||||||
#TO ENABLE PAM AUTH UNCOMMENT NEXT TWO LINES
|
#TO ENABLE PAM AUTH UNCOMMENT NEXT TWO LINES
|
||||||
#ENABLE_PAM_SUPPORT= -D PAM_SUPPORT_ENABLED
|
#ENABLE_PAM_SUPPORT= -D PAM_SUPPORT_ENABLED
|
||||||
#PAM_AUTH_LIB= -lpam
|
#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)
|
all: $(BUILDFILES)
|
||||||
|
|
||||||
@ -54,7 +58,7 @@ end:
|
|||||||
@echo Build process 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
|
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:
|
daemon.o:
|
||||||
@$(CC) $(CFLAGS) $(SOURCE_MODULES_PATH)daemon.c -o $(LIBPATH)daemon.o
|
@$(CC) $(CFLAGS) $(SOURCE_MODULES_PATH)daemon.c -o $(LIBPATH)daemon.o
|
||||||
@ -83,7 +87,7 @@ fileManagement.o:
|
|||||||
signals.o:
|
signals.o:
|
||||||
@$(CC) $(CFLAGS) $(SOURCE_MODULES_PATH)signals.c -o $(LIBPATH)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
|
@$(CC) $(CFLAGS) $(SOURCE_MODULES_PATH)connection.c -o $(LIBPATH)connection.o
|
||||||
|
|
||||||
log.o:
|
log.o:
|
||||||
|
@ -7,5 +7,5 @@ cp build/uFTP /var/www/html/uftpserver.com/downloads/binaries/latest/armhf/uFTP
|
|||||||
make clean
|
make clean
|
||||||
make CC=musl-gcc ENDFLAG=-static
|
make CC=musl-gcc ENDFLAG=-static
|
||||||
cp build/uFTP /var/www/html/uftpserver.com/downloads/binaries/latest/x64/uFTP
|
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
|
cd build
|
@ -48,6 +48,9 @@
|
|||||||
#include "ftpCommandsElaborate.h"
|
#include "ftpCommandsElaborate.h"
|
||||||
|
|
||||||
#include "debugHelper.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 */
|
/* Elaborate the User login command */
|
||||||
int parseCommandUser(ftpDataType * data, int socketId)
|
int parseCommandUser(ftpDataType * data, int socketId)
|
||||||
@ -179,7 +182,7 @@ int parseCommandPass(ftpDataType *data, int socketId)
|
|||||||
data->clients[socketId].closeTheClient = 1;
|
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");
|
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);
|
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);
|
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);
|
addLog(theLogString, CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
||||||
@ -391,10 +394,10 @@ int parseCommandFeat(ftpDataType *data, int socketId)
|
|||||||
|
|
||||||
int returnCode;
|
int returnCode;
|
||||||
#ifdef OPENSSL_ENABLED
|
#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
|
#endif
|
||||||
#ifndef OPENSSL_ENABLED
|
#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
|
#endif
|
||||||
|
|
||||||
if (returnCode <= 0)
|
if (returnCode <= 0)
|
||||||
@ -545,8 +548,21 @@ int parseCommandPasv(ftpDataType *data, int socketId)
|
|||||||
void *pReturn;
|
void *pReturn;
|
||||||
int returnCode;
|
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.workerThread = %d",socketId, (int)data->clients[socketId].workerData.workerThread);
|
||||||
|
|
||||||
// my_printf("\n data->clients[%d].workerData.threadHasBeenCreated = %d", socketId, data->clients[socketId].workerData.threadHasBeenCreated);
|
// 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)
|
if (data->clients[socketId].workerData.threadIsAlive == 1)
|
||||||
{
|
{
|
||||||
cancelWorker(data, socketId);
|
cancelWorker(data, socketId);
|
||||||
@ -618,6 +634,9 @@ int parseCommandPort(ftpDataType *data, int socketId)
|
|||||||
int ipAddressBytes[4];
|
int ipAddressBytes[4];
|
||||||
int portBytes[2];
|
int portBytes[2];
|
||||||
theIpAndPort = getFtpCommandArg("PORT", data->clients[socketId].theCommandReceived, 0);
|
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]);
|
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];
|
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]);
|
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.extendedPassiveModeOn = 0;
|
||||||
data->clients[socketId].workerData.activeModeOn = 1;
|
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);
|
returnCode = pthread_create(&data->clients[socketId].workerData.workerThread, NULL, connectionWorkerHandle, (void *)&data->clients[socketId].clientProgressiveNumber);
|
||||||
|
|
||||||
if (returnCode != 0)
|
if (returnCode != 0)
|
||||||
@ -1023,7 +1044,7 @@ int parseCommandRetr(ftpDataType *data, int socketId)
|
|||||||
{
|
{
|
||||||
int isSafePath = 0;
|
int isSafePath = 0;
|
||||||
char *theNameToRetr;
|
char *theNameToRetr;
|
||||||
int returnCode;
|
int returnCode = 0;
|
||||||
|
|
||||||
if(!data->clients[socketId].workerData.socketIsReadyForConnection)
|
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);
|
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);
|
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)
|
|
||||||
{
|
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;
|
char *theFtpPathPointer = data->clients[socketId].login.absolutePath.text;
|
||||||
theFtpPathPointer += data->clients[socketId].login.homePath.textLen;
|
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);
|
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.absolutePath = %s", data->clients[socketId].login.absolutePath.text);
|
||||||
// my_printf("\ndata->clients[socketId].login.ftpPath = %s", data->clients[socketId].login.ftpPath.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;
|
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 parseCommandRnfr(ftpDataType * data, int socketId);
|
||||||
int parseCommandRnto(ftpDataType * data, int socketId);
|
int parseCommandRnto(ftpDataType * data, int socketId);
|
||||||
int parseCommandAcct(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);
|
long long int writeRetrFile(ftpDataType * data, int theSocketId, long long int startFrom, FILE *retrFP);
|
||||||
char *getFtpCommandArg(char * theCommand, char *theCommandString, int skipArgs);
|
char *getFtpCommandArg(char * theCommand, char *theCommandString, int skipArgs);
|
||||||
|
17
ftpData.c
17
ftpData.c
@ -42,6 +42,8 @@
|
|||||||
#include "library/dynamicMemory.h"
|
#include "library/dynamicMemory.h"
|
||||||
|
|
||||||
#include "debugHelper.h"
|
#include "debugHelper.h"
|
||||||
|
#include "library/log.h"
|
||||||
|
|
||||||
|
|
||||||
static int is_prefix(const char *str, const char *prefix);
|
static int is_prefix(const char *str, const char *prefix);
|
||||||
static char *my_realpath(const char *path, char *resolved_path);
|
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");
|
returnCode = socketWorkerPrintf(ftpData, clientId, "sds", "total ", fileAndFoldersCount ,"\r\n");
|
||||||
if (returnCode <= 0)
|
if (returnCode <= 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
for (x = 0; x < fileAndFoldersCount; x++)
|
||||||
|
DYNMEM_free (fileList[x], memoryTable);
|
||||||
|
|
||||||
|
DYNMEM_free (fileList, memoryTable);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,6 +351,7 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
|||||||
|
|
||||||
if (data.isDirectory == 0 && data.isFile == 0 && data.isLink == 0)
|
if (data.isDirectory == 0 && data.isFile == 0 && data.isLink == 0)
|
||||||
{
|
{
|
||||||
|
DYNMEM_free (fileList[i], memoryTable);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +376,7 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
|||||||
my_printf("\n ********************** void inode permission string");
|
my_printf("\n ********************** void inode permission string");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.isLink = 1 &&
|
if (data.isLink == 1 &&
|
||||||
data.inodePermissionString != NULL &&
|
data.inodePermissionString != NULL &&
|
||||||
strlen(data.inodePermissionString) > 0 &&
|
strlen(data.inodePermissionString) > 0 &&
|
||||||
data.inodePermissionString[0] == 'l')
|
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, " -> ", memoryTable);
|
||||||
FILE_AppendToString(&data.finalStringPath, data.linkPath, memoryTable);
|
FILE_AppendToString(&data.finalStringPath, data.linkPath, memoryTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(data.lastModifiedDataString, 0, LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE);
|
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);
|
localtime_r(&data.lastModifiedData, &newtime);
|
||||||
strftime(data.lastModifiedDataString, LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE, "%b %d %Y", &newtime);
|
strftime(data.lastModifiedDataString, LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE, "%b %d %Y", &newtime);
|
||||||
|
|
||||||
|
|
||||||
switch (commandType)
|
switch (commandType)
|
||||||
{
|
{
|
||||||
case COMMAND_TYPE_LIST:
|
case COMMAND_TYPE_LIST:
|
||||||
@ -492,7 +500,6 @@ int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumb
|
|||||||
DYNMEM_free (fileList, memoryTable);
|
DYNMEM_free (fileList, memoryTable);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileList != NULL)
|
if (fileList != NULL)
|
||||||
@ -811,10 +818,6 @@ void resetClientData(ftpDataType *data, int clientId, int isInitialization)
|
|||||||
data->clients[clientId].closeTheClient = 0;
|
data->clients[clientId].closeTheClient = 0;
|
||||||
data->clients[clientId].sockaddr_in_size = sizeof(struct sockaddr_in);
|
data->clients[clientId].sockaddr_in_size = sizeof(struct sockaddr_in);
|
||||||
data->clients[clientId].sockaddr_in_server_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);
|
memset(&data->clients[clientId].client_sockaddr_in, 0, data->clients[clientId].sockaddr_in_size);
|
||||||
|
19
ftpData.h
19
ftpData.h
@ -87,7 +87,7 @@ struct usersParameters
|
|||||||
|
|
||||||
struct ftpParameters
|
struct ftpParameters
|
||||||
{
|
{
|
||||||
int ftpIpAddress[4];
|
int ftpIpAddressV4[4];
|
||||||
int port;
|
int port;
|
||||||
int maxClients;
|
int maxClients;
|
||||||
int daemonModeOn;
|
int daemonModeOn;
|
||||||
@ -150,6 +150,7 @@ struct workerData
|
|||||||
int threadIsAlive;
|
int threadIsAlive;
|
||||||
int threadHasBeenCreated;
|
int threadHasBeenCreated;
|
||||||
int connectionPort;
|
int connectionPort;
|
||||||
|
int addressType;
|
||||||
int passiveModeOn;
|
int passiveModeOn;
|
||||||
int extendedPassiveModeOn;
|
int extendedPassiveModeOn;
|
||||||
int activeModeOn;
|
int activeModeOn;
|
||||||
@ -184,6 +185,7 @@ struct clientData
|
|||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int isIpV6;
|
||||||
int tlsIsEnabled;
|
int tlsIsEnabled;
|
||||||
int tlsIsNegotiating;
|
int tlsIsNegotiating;
|
||||||
unsigned long long int tlsNegotiatingTimeStart;
|
unsigned long long int tlsNegotiatingTimeStart;
|
||||||
@ -214,15 +216,20 @@ struct clientData
|
|||||||
loginDataType login;
|
loginDataType login;
|
||||||
workerDataType workerData;
|
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;
|
struct sockaddr_in client_sockaddr_in, server_sockaddr_in;
|
||||||
|
#endif
|
||||||
|
|
||||||
int clientPort;
|
int clientPort;
|
||||||
char clientIpAddress[INET_ADDRSTRLEN];
|
char clientIpAddress[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
int serverPort;
|
int serverPort;
|
||||||
char serverIpAddress[INET_ADDRSTRLEN];
|
char serverIpAddress[INET6_ADDRSTRLEN];
|
||||||
int serverIpAddressInteger[4];
|
int serverIpV4AddressInteger[4];
|
||||||
ftpCommandDataType ftpCommand;
|
ftpCommandDataType ftpCommand;
|
||||||
int closeTheClient;
|
int closeTheClient;
|
||||||
|
|
||||||
|
325
ftpServer.c
325
ftpServer.c
@ -129,7 +129,7 @@ void *connectionWorkerHandle(void * socketId)
|
|||||||
ftpData.clients[theSocketId].workerData.threadHasBeenCreated = 1;
|
ftpData.clients[theSocketId].workerData.threadHasBeenCreated = 1;
|
||||||
int returnCode;
|
int returnCode;
|
||||||
|
|
||||||
my_printf("\nWORKER CREATED!");
|
my_printf("\n ----------------- WORKER CREATED --------------!");
|
||||||
|
|
||||||
//Passive data connection mode
|
//Passive data connection mode
|
||||||
if (ftpData.clients[theSocketId].workerData.passiveModeOn == 1)
|
if (ftpData.clients[theSocketId].workerData.passiveModeOn == 1)
|
||||||
@ -167,7 +167,7 @@ void *connectionWorkerHandle(void * socketId)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_printf("\n Using server ip: %s", ftpData.ftpParameters.natIpAddress);
|
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)
|
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)
|
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
|
#ifdef OPENSSL_ENABLED
|
||||||
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
||||||
@ -567,7 +573,7 @@ void runFtpServer(void)
|
|||||||
//Update watchdog timer
|
//Update watchdog timer
|
||||||
updateWatchDogTime((int)time(NULL));
|
updateWatchDogTime((int)time(NULL));
|
||||||
|
|
||||||
/*
|
|
||||||
my_printf("\nUsed memory : %lld", DYNMEM_GetTotalMemory());
|
my_printf("\nUsed memory : %lld", DYNMEM_GetTotalMemory());
|
||||||
int memCount = 0;
|
int memCount = 0;
|
||||||
for (memCount = 0; memCount < ftpData.ftpParameters.maxClients; memCount++)
|
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);
|
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 */
|
/* waits for socket activity, if no activity then checks for client socket timeouts */
|
||||||
if (selectWait(&ftpData) == 0)
|
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);
|
closeClient(&ftpData, processingSock);
|
||||||
flushLoginWrongTriesData(&ftpData);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if there are client pending connections, accept the connection if possible otherwise reject */
|
||||||
|
if ((returnCode = evaluateClientSocketConnection(&ftpData)) == 1)
|
||||||
/*Main loop handle client commands */
|
|
||||||
for (processingSock = 0; processingSock < ftpData.ftpParameters.maxClients; processingSock++)
|
|
||||||
{
|
{
|
||||||
/* close the connection if quit flag has been set */
|
break;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/* 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
|
//Server Close
|
||||||
@ -863,9 +865,14 @@ static int processCommand(int processingElement)
|
|||||||
}
|
}
|
||||||
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "PORT", strlen("PORT")) == 1)
|
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);
|
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)
|
else if(compareStringCaseInsensitive(ftpData.clients[processingElement].theCommandReceived, "LIST", strlen("LIST")) == 1)
|
||||||
{
|
{
|
||||||
//my_printf("\nLIST COMMAND RECEIVED");
|
//my_printf("\nLIST COMMAND RECEIVED");
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#define FTPSERVER_H
|
#define FTPSERVER_H
|
||||||
|
|
||||||
#define MAX_FTP_CLIENTS 10
|
#define MAX_FTP_CLIENTS 10
|
||||||
#define UFTP_SERVER_VERSION "v2.6.0 stable"
|
#define UFTP_SERVER_VERSION "v3.0.0 stable"
|
||||||
|
|
||||||
|
|
||||||
void runFtpServer(void);
|
void runFtpServer(void);
|
||||||
|
@ -528,7 +528,7 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
|
|||||||
searchIndex = searchParameter("SERVER_IP", parametersVector);
|
searchIndex = searchParameter("SERVER_IP", parametersVector);
|
||||||
if (searchIndex != -1)
|
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);
|
my_printf("\n SERVER_IP parameter:%s", ftpParameters->natIpAddress);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -552,10 +552,10 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
|
|||||||
searchIndex = searchParameter("FTP_SERVER_IP", parametersVector);
|
searchIndex = searchParameter("FTP_SERVER_IP", parametersVector);
|
||||||
if (searchIndex != -1)
|
if (searchIndex != -1)
|
||||||
{
|
{
|
||||||
sscanf (((parameter_DataType *) parametersVector->Data[searchIndex])->value,"%d.%d.%d.%d", &ftpParameters->ftpIpAddress[0],
|
sscanf (((parameter_DataType *) parametersVector->Data[searchIndex])->value,"%d.%d.%d.%d", &ftpParameters->ftpIpAddressV4[0],
|
||||||
&ftpParameters->ftpIpAddress[1],
|
&ftpParameters->ftpIpAddressV4[1],
|
||||||
&ftpParameters->ftpIpAddress[2],
|
&ftpParameters->ftpIpAddressV4[2],
|
||||||
&ftpParameters->ftpIpAddress[3]);
|
&ftpParameters->ftpIpAddressV4[3]);
|
||||||
//my_printf("\nFTP_SERVER_IP value: %d.%d.%d.%d", ftpParameters->ftpIpAddress[0],
|
//my_printf("\nFTP_SERVER_IP value: %d.%d.%d.%d", ftpParameters->ftpIpAddress[0],
|
||||||
// ftpParameters->ftpIpAddress[1],
|
// ftpParameters->ftpIpAddress[1],
|
||||||
// ftpParameters->ftpIpAddress[2],
|
// ftpParameters->ftpIpAddress[2],
|
||||||
@ -563,10 +563,10 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ftpParameters->ftpIpAddress[0] = 127;
|
ftpParameters->ftpIpAddressV4[0] = 127;
|
||||||
ftpParameters->ftpIpAddress[1] = 0;
|
ftpParameters->ftpIpAddressV4[1] = 0;
|
||||||
ftpParameters->ftpIpAddress[2] = 0;
|
ftpParameters->ftpIpAddressV4[2] = 0;
|
||||||
ftpParameters->ftpIpAddress[3] = 1;
|
ftpParameters->ftpIpAddressV4[3] = 1;
|
||||||
//my_printf("\nFTP_SERVER_IP parameter not found in the configuration file, listening on all available networks");
|
//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 "../debugHelper.h"
|
||||||
#include "../ftpData.h"
|
#include "../ftpData.h"
|
||||||
#include "connection.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, ...)
|
int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __fmt, ...)
|
||||||
{
|
{
|
||||||
@ -343,6 +358,146 @@ int getMaximumSocketFd(int mainSocket, ftpDataType * ftpData)
|
|||||||
return toReturn;
|
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)
|
int createSocket(ftpDataType * ftpData)
|
||||||
{
|
{
|
||||||
//my_printf("\nCreating main socket on port %d", ftpData->ftpParameters.port);
|
//my_printf("\nCreating main socket on port %d", ftpData->ftpParameters.port);
|
||||||
@ -473,18 +628,80 @@ int createPassiveSocket(int port)
|
|||||||
return sock;
|
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 createActiveSocket(int port, char *ipAddress)
|
||||||
{
|
{
|
||||||
int sockfd;
|
int sockfd;
|
||||||
struct sockaddr_in serv_addr;
|
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));
|
memset(&serv_addr, 0, sizeof(struct sockaddr_in));
|
||||||
serv_addr.sin_family = AF_INET;
|
serv_addr.sin_family = AF_INET;
|
||||||
serv_addr.sin_port = htons(port);
|
serv_addr.sin_port = htons(port);
|
||||||
if(inet_pton(AF_INET, ipAddress, &serv_addr.sin_addr)<=0)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -713,6 +930,139 @@ int getAvailableClientSocketIndex(ftpDataType * ftpData)
|
|||||||
return -1;
|
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)
|
int evaluateClientSocketConnection(ftpDataType * ftpData)
|
||||||
{
|
{
|
||||||
if (FD_ISSET(ftpData->connectionData.theMainSocket, &ftpData->connectionData.rset))
|
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("\n Server IP: %s", ftpData->clients[availableSocketIndex].serverIpAddress);
|
||||||
//my_printf("Server: New client connected with id: %d", availableSocketIndex);
|
//my_printf("Server: New client connected with id: %d", availableSocketIndex);
|
||||||
//my_printf("\nServer: Clients connected: %d", ftpData->connectedClients);
|
//my_printf("\nServer: Clients connected: %d", ftpData->connectedClients);
|
||||||
sscanf (ftpData->clients[availableSocketIndex].serverIpAddress,"%d.%d.%d.%d", &ftpData->clients[availableSocketIndex].serverIpAddressInteger[0],
|
sscanf (ftpData->clients[availableSocketIndex].serverIpAddress,"%d.%d.%d.%d", &ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[0],
|
||||||
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[1],
|
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[1],
|
||||||
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[2],
|
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[2],
|
||||||
&ftpData->clients[availableSocketIndex].serverIpAddressInteger[3]);
|
&ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[3]);
|
||||||
|
|
||||||
inet_ntop(AF_INET,
|
inet_ntop(AF_INET,
|
||||||
&(ftpData->clients[availableSocketIndex].client_sockaddr_in.sin_addr),
|
&(ftpData->clients[availableSocketIndex].client_sockaddr_in.sin_addr),
|
||||||
@ -817,3 +1167,5 @@ int evaluateClientSocketConnection(ftpDataType * ftpData)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -36,6 +36,11 @@ int getMaximumSocketFd(int mainSocket, ftpDataType * data);
|
|||||||
int createSocket(ftpDataType * ftpData);
|
int createSocket(ftpDataType * ftpData);
|
||||||
int createPassiveSocket(int port);
|
int createPassiveSocket(int port);
|
||||||
int createActiveSocket(int port, char *ipAddress);
|
int createActiveSocket(int port, char *ipAddress);
|
||||||
|
|
||||||
|
#ifdef IPV6_ENABLED
|
||||||
|
int createActiveSocketV6(int port, char *ipAddress);
|
||||||
|
#endif
|
||||||
|
|
||||||
void fdInit(ftpDataType * ftpData);
|
void fdInit(ftpDataType * ftpData);
|
||||||
void fdAdd(ftpDataType * ftpData, int index);
|
void fdAdd(ftpDataType * ftpData, int index);
|
||||||
void fdRemove(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 */
|
/* Check if a file is valid */
|
||||||
int FILE_IsFile(const char *TheFileName, int checkExist)
|
int FILE_IsFile(char *TheFileName, int checkExist)
|
||||||
{
|
{
|
||||||
FILE *TheFile;
|
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'))
|
if ((dir->d_name[0] == '.' && commandOps == NULL) || (dir->d_name[0] == '.' && commandOps[0] != 'a' && commandOps[0] != 'A'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *thePathToCheck[PATH_MAX];
|
char thePathToCheck[PATH_MAX];
|
||||||
memset(thePathToCheck, 0, PATH_MAX);
|
memset(thePathToCheck, 0, PATH_MAX);
|
||||||
|
|
||||||
strcpy(thePathToCheck, DirectoryInodeName);
|
strcpy(thePathToCheck, DirectoryInodeName);
|
||||||
strcat(thePathToCheck, "/");
|
strcat(thePathToCheck, "/");
|
||||||
strcat(thePathToCheck, dir->d_name);
|
strcat(thePathToCheck, dir->d_name);
|
||||||
|
|
||||||
printf("\n ************* thePathToCheck = %s", thePathToCheck);
|
|
||||||
if (checkIfInodeExist == 1 && FILE_CheckIfLinkExist(thePathToCheck) == 0)
|
if (checkIfInodeExist == 1 && FILE_CheckIfLinkExist(thePathToCheck) == 0)
|
||||||
{
|
{
|
||||||
printf("--> Not valid!");
|
|
||||||
continue;
|
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");
|
FILE *fp = fopen(fileName, "a");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
long long int FILE_GetFileSize(FILE *theFilePointer);
|
long long int FILE_GetFileSize(FILE *theFilePointer);
|
||||||
long int FILE_GetAvailableSpace(const char* ThePath);
|
long int FILE_GetAvailableSpace(const char* ThePath);
|
||||||
long long int FILE_GetFileSizeFromPath(char *TheFileName);
|
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_IsDirectory (char *directory_path, int checkExist);
|
||||||
int FILE_IsLink (char *directory_path);
|
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);
|
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_GetListPermissionsString(char *file, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||||
char * FILE_GetOwner(char *fileName, DYNMEM_MemoryTable_DataType ** memoryTable);
|
char * FILE_GetOwner(char *fileName, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||||
char * FILE_GetGroupOwner(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);
|
time_t FILE_GetLastModifiedData(char *path);
|
||||||
void FILE_AppendToString(char ** sourceString, char *theString, DYNMEM_MemoryTable_DataType ** memoryTable);
|
void FILE_AppendToString(char ** sourceString, char *theString, DYNMEM_MemoryTable_DataType ** memoryTable);
|
||||||
void FILE_DirectoryToParent(char ** sourceString, 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_LINE_SIZE 1024 + PATH_MAX
|
||||||
#define LOG_FILENAME_PREFIX "uftpLog_"
|
#define LOG_FILENAME_PREFIX "uftpLog_"
|
||||||
|
|
||||||
static void logThread(void * arg);
|
static void *logThread(void * arg);
|
||||||
|
|
||||||
static DYNV_VectorString_DataType logQueue;
|
static DYNV_VectorString_DataType logQueue;
|
||||||
static DYNV_VectorString_DataType workerQueue;
|
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)
|
if (strftime(timeToday, sizeof(timeToday), "%Y-%m-%d", info) == 0)
|
||||||
{
|
{
|
||||||
my_printfError("strftime error");
|
my_printfError("strftime error");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_of_day_today = is_date_format(timeToday);
|
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 SECTION
|
||||||
static void logThread(void * arg)
|
static void *logThread(void * arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
int lastDay;
|
int lastDay;
|
||||||
@ -181,7 +181,7 @@ static void logThread(void * arg)
|
|||||||
if (strftime(dayString, sizeof(dayString), "%d", info) == 0)
|
if (strftime(dayString, sizeof(dayString), "%d", info) == 0)
|
||||||
{
|
{
|
||||||
my_printfError("strftime error");
|
my_printfError("strftime error");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
day = atoi(dayString);
|
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)
|
if (strftime(logName, sizeof(logName), LOG_FILENAME_PREFIX"%Y-%m-%d", info) == 0)
|
||||||
{
|
{
|
||||||
my_printfError("strftime error");
|
my_printfError("strftime error");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(theLogFilename, logFolder, PATH_MAX);
|
strncpy(theLogFilename, logFolder, PATH_MAX);
|
||||||
@ -240,7 +240,7 @@ int logInit(char * folder, int numberOfLogFiles)
|
|||||||
logFilesNumber = numberOfLogFiles;
|
logFilesNumber = numberOfLogFiles;
|
||||||
|
|
||||||
if (logFilesNumber <= 0)
|
if (logFilesNumber <= 0)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
delete_old_logs(folder, numberOfLogFiles);
|
delete_old_logs(folder, numberOfLogFiles);
|
||||||
|
|
||||||
@ -252,7 +252,7 @@ int logInit(char * folder, int numberOfLogFiles)
|
|||||||
// Initialize the mutex
|
// Initialize the mutex
|
||||||
pthread_mutex_init(&mutex, NULL);
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
|
||||||
returnCode = pthread_create(&pLogThread, NULL, &logThread, NULL);
|
returnCode = pthread_create(&pLogThread, NULL, logThread, NULL);
|
||||||
if (returnCode != 0)
|
if (returnCode != 0)
|
||||||
{
|
{
|
||||||
addLog("Pthead create error restarting the server", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC);
|
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;
|
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)
|
if (logFilesNumber <= 0)
|
||||||
|
@ -26,6 +26,6 @@
|
|||||||
#define LOG_H
|
#define LOG_H
|
||||||
|
|
||||||
int logInit(char * folder, int numberOfLogFiles);
|
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
|
#endif
|
@ -33,7 +33,7 @@
|
|||||||
#include "openSsl.h"
|
#include "openSsl.h"
|
||||||
#include "fileManagement.h"
|
#include "fileManagement.h"
|
||||||
#include "../debugHelper.h"
|
#include "../debugHelper.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
|
||||||
#define MUTEX_TYPE pthread_mutex_t
|
#define MUTEX_TYPE pthread_mutex_t
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "../ftpServer.h"
|
#include "../ftpServer.h"
|
||||||
#include "../debugHelper.h"
|
#include "../debugHelper.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
static void ignore_sigpipe(void);
|
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 #
|
# UFTP SERVER SETTINGS #
|
||||||
#######################################################
|
#######################################################
|
||||||
|
|
||||||
#MAXIMUM ALLOWED CONNECTIONS ON THE SERVER
|
# NOTES:
|
||||||
MAXIMUM_ALLOWED_FTP_CONNECTION = 30
|
# 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
|
FTP_PORT = 21
|
||||||
|
|
||||||
#Allow only one server instance (true or false)
|
# Allow only one server instance (true or false)
|
||||||
SINGLE_INSTANCE = true
|
SINGLE_INSTANCE = true
|
||||||
|
|
||||||
#Run in background, daemon mode ok
|
# Run in background daemon mode (true or false)
|
||||||
DAEMON_MODE = true
|
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/
|
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
|
MAXIMUM_LOG_FILES = 0
|
||||||
|
|
||||||
# Idle timeout in seconds, client are disconnected for inactivity after the
|
# Idle timeout in seconds; clients are disconnected after this period of inactivity; set to 0 to disable
|
||||||
# specified amount of time in seconds, 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 = 3600
|
IDLE_MAX_TIMEOUT = 330
|
||||||
|
|
||||||
#MAX CONNECTIONS PER IP
|
# Maximum connections per IP address; set to 0 to disable
|
||||||
#LIMIT THE MAXIMUM NUMBER OF CONNECTION FOR EACH IP ADDRESS
|
|
||||||
# 0 TO DISABLE
|
|
||||||
MAX_CONNECTION_NUMBER_PER_IP = 10
|
MAX_CONNECTION_NUMBER_PER_IP = 10
|
||||||
|
|
||||||
#MAX LOGIN TRY PER IP
|
# 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
|
||||||
#THE IP ADDRESS WILL BE BLOCKED FOR 5 MINUTES AFTER WRONG LOGIN USERNAME AND PASSWORD
|
|
||||||
#0 TO DISABLE
|
|
||||||
MAX_CONNECTION_TRY_PER_IP = 10
|
MAX_CONNECTION_TRY_PER_IP = 10
|
||||||
|
|
||||||
#USE THE SERVER IP PARAMETER IF THE FTP SERVER IS UNDER NAT
|
# 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 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 = 192,168,1,1
|
#SERVER_IP = 192,168,1,1
|
||||||
|
|
||||||
#TLS CERTIFICATE FILE PATH
|
# TLS certificate file paths
|
||||||
CERTIFICATE_PATH=/etc/uFTP/cert.pem
|
CERTIFICATE_PATH=/etc/uFTP/cert.pem
|
||||||
PRIVATE_CERTIFICATE_PATH=/etc/uFTP/key.pem
|
PRIVATE_CERTIFICATE_PATH=/etc/uFTP/key.pem
|
||||||
|
|
||||||
#Enable system authentication based on /etc/passwd
|
# Enable system authentication based on /etc/passwd and /etc/shadow (true or false)
|
||||||
#and /etc/shadow
|
|
||||||
ENABLE_PAM_AUTH = false
|
ENABLE_PAM_AUTH = false
|
||||||
|
|
||||||
# Force usage of the TLS
|
# Force usage of TLS; if enabled, only TLS connections are allowed (true or false)
|
||||||
# If enabled, only TLS connections will be allowed
|
|
||||||
FORCE_TLS = false
|
FORCE_TLS = false
|
||||||
|
|
||||||
#
|
# Random port range for passive FTP connections
|
||||||
# Random port for passive FTP connections range
|
|
||||||
#
|
|
||||||
RANDOM_PORT_START = 10000
|
RANDOM_PORT_START = 10000
|
||||||
RANDOM_PORT_END = 50000
|
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
|
USER_0 = username
|
||||||
PASSWORD_0 = password
|
PASSWORD_0 = password
|
||||||
HOME_0 = /
|
HOME_0 = /
|
||||||
@ -78,7 +79,7 @@ USER_2 = anotherUsername
|
|||||||
PASSWORD_2 = anotherPassowrd
|
PASSWORD_2 = anotherPassowrd
|
||||||
HOME_2 = /
|
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_0 = user1
|
||||||
BLOCK_USER_1 = user2
|
BLOCK_USER_1 = user2
|
||||||
BLOCK_USER_2 = user3
|
BLOCK_USER_2 = user3
|
||||||
|
Reference in New Issue
Block a user