diff --git a/debugHelper.h b/debugHelper.h index 388c56c..c8b2913 100644 --- a/debugHelper.h +++ b/debugHelper.h @@ -1,8 +1,8 @@ #ifndef ENABLE_PRINTF_MODULE // Uncomment next line to enable debug printf - // #define ENABLE_PRINTF - // #define ENABLE_PRINTF_ERROR + #define ENABLE_PRINTF + #define ENABLE_PRINTF_ERROR #define CURRENT_FILE __FILE__ #define CURRENT_LINE __LINE__ diff --git a/ftpCommandElaborate.c b/ftpCommandElaborate.c index a78678d..5027670 100755 --- a/ftpCommandElaborate.c +++ b/ftpCommandElaborate.c @@ -50,6 +50,8 @@ #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) { @@ -632,6 +634,9 @@ int parseCommandPort(ftpDataType *data, int socketId) int ipAddressBytes[4]; int portBytes[2]; theIpAndPort = getFtpCommandArg("PORT", data->clients[socketId].theCommandReceived, 0); + + printf("\n theIpAndPort = %s", theIpAndPort); + 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]); @@ -2502,3 +2507,86 @@ 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; + } + } + + 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 ||
| " + 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 +} diff --git a/ftpCommandsElaborate.h b/ftpCommandsElaborate.h index 3e76ad7..8c8cf92 100755 --- a/ftpCommandsElaborate.h +++ b/ftpCommandsElaborate.h @@ -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); diff --git a/ftpData.h b/ftpData.h index afad402..a10f4f0 100755 --- a/ftpData.h +++ b/ftpData.h @@ -150,6 +150,7 @@ struct workerData int threadIsAlive; int threadHasBeenCreated; int connectionPort; + int addressType; int passiveModeOn; int extendedPassiveModeOn; int activeModeOn; diff --git a/ftpServer.c b/ftpServer.c index ded31a5..a18c0a8 100755 --- a/ftpServer.c +++ b/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) @@ -237,8 +237,12 @@ 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); + else if (ftpData.clients[theSocketId].workerData.addressType == 2) + ftpData.clients[theSocketId].workerData.socketConnection = createActiveSocketV6(ftpData.clients[theSocketId].workerData.connectionPort, ftpData.clients[theSocketId].workerData.activeIpAddress); + #ifdef OPENSSL_ENABLED if (ftpData.clients[theSocketId].dataChannelIsTls == 1) { @@ -859,9 +863,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"); diff --git a/library/connection.c b/library/connection.c index e977492..b8d911a 100755 --- a/library/connection.c +++ b/library/connection.c @@ -632,18 +632,77 @@ int createPassiveSocket(int port) #endif + +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; +} + 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; } @@ -695,6 +754,7 @@ int createActiveSocket(int port, char *ipAddress) return sockfd; } + void fdInit(ftpDataType * ftpData) { FD_ZERO(&ftpData->connectionData.rset); @@ -872,9 +932,9 @@ int getAvailableClientSocketIndex(ftpDataType * ftpData) return -1; } -#define IPV6_ENABLED #ifdef IPV6_ENABLED + #warning IPV6 IS ENABLED int evaluateClientSocketConnection(ftpDataType * ftpData) { diff --git a/library/connection.h b/library/connection.h index 7f95c7d..f2e5136 100755 --- a/library/connection.h +++ b/library/connection.h @@ -36,6 +36,7 @@ int getMaximumSocketFd(int mainSocket, ftpDataType * data); int createSocket(ftpDataType * ftpData); int createPassiveSocket(int port); int createActiveSocket(int port, char *ipAddress); +int createActiveSocketV6(int port, char *ipAddress); void fdInit(ftpDataType * ftpData); void fdAdd(ftpDataType * ftpData, int index); void fdRemove(ftpDataType * ftpData, int index);