mirror of
https://github.com/kingk85/uFTP.git
synced 2025-07-25 13:16:12 +03:00
Working on ssl, passive mode seems ok active needs more work
This commit is contained in:
7
Makefile
7
Makefile
@ -11,7 +11,7 @@ OPTIMIZATION=-O3
|
|||||||
HEADERS=-I
|
HEADERS=-I
|
||||||
LIBPATH=./build/modules/
|
LIBPATH=./build/modules/
|
||||||
BUILDFILES=start uFTP end
|
BUILDFILES=start uFTP end
|
||||||
LIBS=-lpthread -lssl -lcrypto
|
#LIBS=-lpthread -lssl -lcrypto
|
||||||
|
|
||||||
|
|
||||||
#ENABLE_LARGE_FILE_SUPPORT=
|
#ENABLE_LARGE_FILE_SUPPORT=
|
||||||
@ -19,8 +19,9 @@ LIBS=-lpthread -lssl -lcrypto
|
|||||||
ENABLE_LARGE_FILE_SUPPORT=-D LARGE_FILE_SUPPORT_ENABLED -D _LARGEFILE64_SOURCE
|
ENABLE_LARGE_FILE_SUPPORT=-D LARGE_FILE_SUPPORT_ENABLED -D _LARGEFILE64_SOURCE
|
||||||
|
|
||||||
#ENABLE_OPENSSL_SUPPORT=
|
#ENABLE_OPENSSL_SUPPORT=
|
||||||
#TO ENABLE OPENSSL SUPPORT UNCOMMENT THE NEXT LINE
|
#TO ENABLE OPENSSL SUPPORT UNCOMMENT NEXT 2 LINES
|
||||||
ENABLE_OPENSSL_SUPPORT=-D OPENSSL_ENABLED
|
ENABLE_OPENSSL_SUPPORT=-D OPENSSL_ENABLED
|
||||||
|
LIBS=-lpthread -lssl -lcrypto
|
||||||
|
|
||||||
CFLAGS=$(CFLAGSTEMP) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT)
|
CFLAGS=$(CFLAGSTEMP) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT)
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ start:
|
|||||||
@echo CGI FILES: $(BUILDFILES)
|
@echo CGI FILES: $(BUILDFILES)
|
||||||
@rm -rf $(LIBPATH)*.o $(OUTPATH)uFTP
|
@rm -rf $(LIBPATH)*.o $(OUTPATH)uFTP
|
||||||
@echo "Clean ok"
|
@echo "Clean ok"
|
||||||
|
|
||||||
end:
|
end:
|
||||||
@echo Build process end
|
@echo Build process end
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/uFTP
BIN
build/uFTP
Binary file not shown.
@ -220,56 +220,42 @@ int parseCommandPass(ftpDataType * data, int socketId)
|
|||||||
|
|
||||||
int parseCommandAuth(ftpDataType * data, int socketId)
|
int parseCommandAuth(ftpDataType * data, int socketId)
|
||||||
{
|
{
|
||||||
int returnCode;
|
int returnCode, returnCodeTls;
|
||||||
|
|
||||||
#ifndef OPENSSL_ENABLED
|
#ifndef OPENSSL_ENABLED
|
||||||
returnCode = socketPrintf(data, socketId, "s", "502 Security extensions not implemented.\r\n");
|
returnCode = socketPrintf(data, socketId, "s", "502 Security extensions not implemented.\r\n");
|
||||||
if (returnCode <= 0)
|
if (returnCode <= 0)
|
||||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
|
|
||||||
return FTP_COMMAND_PROCESSED;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
|
|
||||||
returnCode = socketPrintf(data, socketId, "s", "234 AUTH TLS OK..\r\n");
|
returnCode = socketPrintf(data, socketId, "s", "234 AUTH TLS OK..\r\n");
|
||||||
if (returnCode <= 0)
|
if (returnCode <= 0)
|
||||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
|
|
||||||
data->clients[socketId].tlsIsEnabled = 1;
|
returnCode = SSL_set_fd(data->clients[socketId].ssl, data->clients[socketId].socketDescriptor);
|
||||||
|
|
||||||
printf("\n SSL_set_fd");
|
if (returnCode == 0)
|
||||||
fflush(0);
|
{
|
||||||
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
SSL_set_fd(data->clients[socketId].ssl, data->clients[socketId].socketDescriptor);
|
returnCodeTls = SSL_accept(data->clients[socketId].ssl);
|
||||||
|
data->clients[socketId].tlsNegotiatingTimeStart = (int)time(NULL);
|
||||||
|
|
||||||
printf("\n SSL_set_fd OK");
|
if (returnCodeTls <= 0)
|
||||||
fflush(0);
|
{
|
||||||
|
printf("\nSSL NOT YET ACCEPTED: %d", returnCodeTls);
|
||||||
int sslAcceptTimeout = 0;
|
data->clients[socketId].tlsIsEnabled = 0;
|
||||||
do {
|
data->clients[socketId].tlsIsNegotiating = 1;
|
||||||
returnCode = SSL_accept(data->clients[socketId].ssl);
|
}
|
||||||
|
else
|
||||||
printf("\n SSL_accept");
|
{
|
||||||
fflush(0);
|
printf("\nSSL ACCEPTED");
|
||||||
|
data->clients[socketId].tlsIsEnabled = 1;
|
||||||
printf("\nSSL waiting handshake %d.. return code = %d", sslAcceptTimeout, returnCode);
|
data->clients[socketId].tlsIsNegotiating = 0;
|
||||||
fflush(0);
|
}
|
||||||
if (returnCode <= 0) {
|
|
||||||
printf("\nSSL ERRORS");
|
|
||||||
fflush(0);
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("\nSSL ACCEPTED");
|
|
||||||
fflush(0);
|
|
||||||
}
|
|
||||||
sslAcceptTimeout++;
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
while(returnCode <=0 &&
|
|
||||||
sslAcceptTimeout < 3);
|
|
||||||
|
|
||||||
return FTP_COMMAND_PROCESSED;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -343,10 +329,15 @@ int parseCommandFeat(ftpDataType * data, int socketId)
|
|||||||
SPSV
|
SPSV
|
||||||
ESTP
|
ESTP
|
||||||
211 End.
|
211 End.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int returnCode;
|
int returnCode;
|
||||||
returnCode = socketPrintf(data, socketId, "s", "211-Extensions supported:\r\n PASV\r\nUTF8\r\nAUTH TLS\r\nPBSZ\r\nPROT\r\n211 End.\r\n");
|
#ifdef OPENSSL_ENABLED
|
||||||
|
returnCode = socketPrintf(data, socketId, "s", "211-Extensions supported:\r\nPASV\r\nUTF8\r\nAUTH TLS\r\nPBSZ\r\nPROT\r\n211 End.\r\n");
|
||||||
|
#endif
|
||||||
|
#ifndef OPENSSL_ENABLED
|
||||||
|
returnCode = socketPrintf(data, socketId, "s", "211-Extensions supported:\r\nPASV\r\nUTF8\r\n211 End.\r\n");
|
||||||
|
#endif
|
||||||
if (returnCode <= 0)
|
if (returnCode <= 0)
|
||||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
|
|
||||||
@ -395,9 +386,16 @@ int parseCommandCcc(ftpDataType * data, int socketId)
|
|||||||
|
|
||||||
if (returnCode <= 0)
|
if (returnCode <= 0)
|
||||||
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
returnCode = socketPrintf(data, socketId, "s", "500 command not supported\r\n");
|
||||||
|
|
||||||
|
if (returnCode <= 0)
|
||||||
|
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
return FTP_COMMAND_PROCESSED;
|
return FTP_COMMAND_PROCESSED;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int parseCommandPbsz(ftpDataType * data, int socketId)
|
int parseCommandPbsz(ftpDataType * data, int socketId)
|
||||||
@ -461,7 +459,7 @@ int parseCommandPasv(ftpDataType * data, int socketId)
|
|||||||
/* Create worker thread */
|
/* Create worker thread */
|
||||||
void *pReturn;
|
void *pReturn;
|
||||||
int returnCode;
|
int returnCode;
|
||||||
printf("\n data->clients[%d].workerData.workerThread = %d",socketId, (int)data->clients[socketId].workerData.workerThread);
|
//printf("\n data->clients[%d].workerData.workerThread = %d",socketId, (int)data->clients[socketId].workerData.workerThread);
|
||||||
|
|
||||||
if (data->clients[socketId].workerData.threadIsAlive == 1)
|
if (data->clients[socketId].workerData.threadIsAlive == 1)
|
||||||
{
|
{
|
||||||
@ -491,7 +489,7 @@ int parseCommandPort(ftpDataType * data, int socketId)
|
|||||||
theIpAndPort = getFtpCommandArg("PORT", data->clients[socketId].theCommandReceived, 0);
|
theIpAndPort = getFtpCommandArg("PORT", data->clients[socketId].theCommandReceived, 0);
|
||||||
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];
|
||||||
sprintf(data->clients[socketId].workerData.activeIpAddress, "%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]);
|
||||||
|
|
||||||
void *pReturn;
|
void *pReturn;
|
||||||
if (data->clients[socketId].workerData.threadIsAlive == 1)
|
if (data->clients[socketId].workerData.threadIsAlive == 1)
|
||||||
@ -574,9 +572,9 @@ int parseCommandList(ftpDataType * data, int socketId)
|
|||||||
theNameToList = getFtpCommandArg("LIST", data->clients[socketId].theCommandReceived, 1);
|
theNameToList = getFtpCommandArg("LIST", data->clients[socketId].theCommandReceived, 1);
|
||||||
getFtpCommandArgWithOptions("LIST", data->clients[socketId].theCommandReceived, &data->clients[socketId].workerData.ftpCommand);
|
getFtpCommandArgWithOptions("LIST", data->clients[socketId].theCommandReceived, &data->clients[socketId].workerData.ftpCommand);
|
||||||
|
|
||||||
printf("\nLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text);
|
///printf("\nLIST COMMAND ARG: %s", data->clients[socketId].workerData.ftpCommand.commandArgs.text);
|
||||||
printf("\nLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text);
|
//printf("\nLIST COMMAND OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text);
|
||||||
printf("\ntheNameToList: %s", theNameToList);
|
//printf("\ntheNameToList: %s", theNameToList);
|
||||||
|
|
||||||
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandArgs, 0);
|
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandArgs, 0);
|
||||||
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandOps, 0);
|
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandOps, 0);
|
||||||
@ -714,7 +712,7 @@ int parseCommandCwd(ftpDataType * data, int socketId)
|
|||||||
|
|
||||||
if (isSafePath == 1)
|
if (isSafePath == 1)
|
||||||
{
|
{
|
||||||
printf("\n The Path requested for CWD IS:%s", theSafePath.text);
|
//printf("\n The Path requested for CWD IS:%s", theSafePath.text);
|
||||||
setDynamicStringDataType(&absolutePathPrevious, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen);
|
setDynamicStringDataType(&absolutePathPrevious, data->clients[socketId].login.absolutePath.text, data->clients[socketId].login.absolutePath.textLen);
|
||||||
setDynamicStringDataType(&ftpPathPrevious, data->clients[socketId].login.ftpPath.text, data->clients[socketId].login.ftpPath.textLen);
|
setDynamicStringDataType(&ftpPathPrevious, data->clients[socketId].login.ftpPath.text, data->clients[socketId].login.ftpPath.textLen);
|
||||||
|
|
||||||
@ -1235,7 +1233,13 @@ long long int writeRetrFile(ftpDataType * data, int theSocketId, long long int s
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writtenSize = SSL_write(data->clients[theSocketId].workerData.ssl, buffer, readen);
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
if (data->clients[theSocketId].workerData.passiveModeOn == 1)
|
||||||
|
writtenSize = SSL_write(data->clients[theSocketId].workerData.serverSsl, buffer, readen);
|
||||||
|
else if (data->clients[theSocketId].workerData.activeModeOn == 1)
|
||||||
|
writtenSize = SSL_write(data->clients[theSocketId].workerData.clientSsl, buffer, readen);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writtenSize <= 0)
|
if (writtenSize <= 0)
|
||||||
@ -1364,6 +1368,7 @@ int getFtpCommandArgWithOptions(char * theCommand, char *theCommandString, ftpCo
|
|||||||
|
|
||||||
int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataType ownerShip)
|
int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataType ownerShip)
|
||||||
{
|
{
|
||||||
|
#define MAXIMUM_FILENAME_LEN 4096
|
||||||
#define STATUS_INCREASE 0
|
#define STATUS_INCREASE 0
|
||||||
#define STATUS_PERMISSIONS 1
|
#define STATUS_PERMISSIONS 1
|
||||||
#define STATUS_LOCAL_PATH 2
|
#define STATUS_LOCAL_PATH 2
|
||||||
@ -1372,14 +1377,14 @@ int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataTyp
|
|||||||
int returnCode = 0;
|
int returnCode = 0;
|
||||||
|
|
||||||
int status = STATUS_INCREASE;
|
int status = STATUS_INCREASE;
|
||||||
char thePermissionString[1024];
|
char thePermissionString[MAXIMUM_FILENAME_LEN];
|
||||||
char theLocalPath[1024];
|
char theLocalPath[MAXIMUM_FILENAME_LEN];
|
||||||
char theFinalFilename[2048];
|
char theFinalFilename[MAXIMUM_FILENAME_LEN];
|
||||||
int returnCodeSetPermissions, returnCodeSetOwnership;
|
int returnCodeSetPermissions, returnCodeSetOwnership;
|
||||||
|
|
||||||
memset(theLocalPath, 0, 1024);
|
memset(theLocalPath, 0, MAXIMUM_FILENAME_LEN);
|
||||||
memset(thePermissionString, 0, 1024);
|
memset(thePermissionString, 0, MAXIMUM_FILENAME_LEN);
|
||||||
memset(theFinalFilename, 0, 2048);
|
memset(theFinalFilename, 0, MAXIMUM_FILENAME_LEN);
|
||||||
int thePermissionStringCursor = 0, theLocalPathCursor = 0;
|
int thePermissionStringCursor = 0, theLocalPathCursor = 0;
|
||||||
|
|
||||||
while (permissionsCommand[permissionsCommandCursor] != '\r' &&
|
while (permissionsCommand[permissionsCommandCursor] != '\r' &&
|
||||||
@ -1401,14 +1406,14 @@ int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataTyp
|
|||||||
status = STATUS_LOCAL_PATH;
|
status = STATUS_LOCAL_PATH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (thePermissionStringCursor < 1024 )
|
if (thePermissionStringCursor < MAXIMUM_FILENAME_LEN )
|
||||||
thePermissionString[thePermissionStringCursor++] = permissionsCommand[permissionsCommandCursor];
|
thePermissionString[thePermissionStringCursor++] = permissionsCommand[permissionsCommandCursor];
|
||||||
else
|
else
|
||||||
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
|
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATUS_LOCAL_PATH:
|
case STATUS_LOCAL_PATH:
|
||||||
if (theLocalPathCursor < 1024)
|
if (theLocalPathCursor < MAXIMUM_FILENAME_LEN)
|
||||||
theLocalPath[theLocalPathCursor++] = permissionsCommand[permissionsCommandCursor];
|
theLocalPath[theLocalPathCursor++] = permissionsCommand[permissionsCommandCursor];
|
||||||
else
|
else
|
||||||
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
|
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
|
||||||
@ -1418,20 +1423,24 @@ int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataTyp
|
|||||||
permissionsCommandCursor++;
|
permissionsCommandCursor++;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(theFinalFilename, 0, 2048);
|
if ((strlen(basePath) + strlen(theLocalPath) + 2) >= MAXIMUM_FILENAME_LEN)
|
||||||
|
|
||||||
if ((strlen(basePath) + strlen(theLocalPath) + 2) >= 2048)
|
|
||||||
{
|
{
|
||||||
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
|
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basePath[strlen(basePath)-1] != '/')
|
if (basePath[strlen(basePath)-1] != '/')
|
||||||
{
|
{
|
||||||
sprintf(theFinalFilename, "%s/%s", basePath, theLocalPath);
|
returnCode = snprintf(theFinalFilename, MAXIMUM_FILENAME_LEN, "%s/%s", basePath, theLocalPath);
|
||||||
|
|
||||||
|
if (returnCode >= MAXIMUM_FILENAME_LEN)
|
||||||
|
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf(theFinalFilename, "%s%s", basePath, theLocalPath);
|
returnCode = snprintf(theFinalFilename, MAXIMUM_FILENAME_LEN, "%s%s", basePath, theLocalPath);
|
||||||
|
|
||||||
|
if (returnCode >= MAXIMUM_FILENAME_LEN)
|
||||||
|
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FILE_IsFile(theFinalFilename) != 1 &&
|
if (FILE_IsFile(theFinalFilename) != 1 &&
|
||||||
|
@ -54,12 +54,9 @@ int parseCommandAuth(ftpDataType * data, int socketId);
|
|||||||
int parseCommandPwd(ftpDataType * data, int socketId);
|
int parseCommandPwd(ftpDataType * data, int socketId);
|
||||||
int parseCommandSyst(ftpDataType * data, int socketId);
|
int parseCommandSyst(ftpDataType * data, int socketId);
|
||||||
int parseCommandFeat(ftpDataType * data, int socketId);
|
int parseCommandFeat(ftpDataType * data, int socketId);
|
||||||
|
|
||||||
int parseCommandProt(ftpDataType * data, int socketId);
|
int parseCommandProt(ftpDataType * data, int socketId);
|
||||||
int parseCommandCcc(ftpDataType * data, int socketId);
|
int parseCommandCcc(ftpDataType * data, int socketId);
|
||||||
int parseCommandPbsz(ftpDataType * data, int socketId);
|
int parseCommandPbsz(ftpDataType * data, int socketId);
|
||||||
|
|
||||||
|
|
||||||
int parseCommandStruF(ftpDataType * data, int socketId);
|
int parseCommandStruF(ftpDataType * data, int socketId);
|
||||||
int parseCommandTypeI(ftpDataType * data, int socketId);
|
int parseCommandTypeI(ftpDataType * data, int socketId);
|
||||||
int parseCommandModeS(ftpDataType * data, int socketId);
|
int parseCommandModeS(ftpDataType * data, int socketId);
|
||||||
|
27
ftpData.c
27
ftpData.c
@ -91,6 +91,7 @@ void setDynamicStringDataType(dynamicStringDataType *dynamicString, char *theStr
|
|||||||
|
|
||||||
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *loginData)
|
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *loginData)
|
||||||
{
|
{
|
||||||
|
#define STRING_SIZE 4096
|
||||||
int theLen, i;
|
int theLen, i;
|
||||||
char * theDirectoryNamePointer;
|
char * theDirectoryNamePointer;
|
||||||
theDirectoryNamePointer = theDirectoryName;
|
theDirectoryNamePointer = theDirectoryName;
|
||||||
@ -124,9 +125,9 @@ int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Check for /../
|
//Check for /../
|
||||||
char theDirectoryToCheck[2048];
|
char theDirectoryToCheck[STRING_SIZE];
|
||||||
int theDirectoryToCheckIndex = 0;
|
int theDirectoryToCheckIndex = 0;
|
||||||
memset(theDirectoryToCheck, 0, 2048);
|
memset(theDirectoryToCheck, 0, STRING_SIZE);
|
||||||
|
|
||||||
for (i = 0; i< theLen; i++)
|
for (i = 0; i< theLen; i++)
|
||||||
{
|
{
|
||||||
@ -140,11 +141,11 @@ int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
theDirectoryToCheckIndex = 0;
|
theDirectoryToCheckIndex = 0;
|
||||||
memset(theDirectoryToCheck, 0, 2048);
|
memset(theDirectoryToCheck, 0, STRING_SIZE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theDirectoryToCheckIndex<2048)
|
if (theDirectoryToCheckIndex<STRING_SIZE)
|
||||||
{
|
{
|
||||||
theDirectoryToCheck[theDirectoryToCheckIndex++] = theDirectoryName[i];
|
theDirectoryToCheck[theDirectoryToCheckIndex++] = theDirectoryName[i];
|
||||||
}
|
}
|
||||||
@ -216,7 +217,7 @@ void setRandomicPort(ftpDataType *data, int socketPosition)
|
|||||||
|
|
||||||
|
|
||||||
data->clients[socketPosition].workerData.connectionPort = randomicPort;
|
data->clients[socketPosition].workerData.connectionPort = randomicPort;
|
||||||
printf("data->clients[%d].workerData.connectionPort = %d", socketPosition, data->clients[socketPosition].workerData.connectionPort);
|
//printf("data->clients[%d].workerData.connectionPort = %d", socketPosition, data->clients[socketPosition].workerData.connectionPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumber, int commandType)
|
int writeListDataInfoToSocket(ftpDataType *ftpData, int clientId, int *filesNumber, int commandType)
|
||||||
@ -404,7 +405,10 @@ int searchInLoginFailsVector(void * loginFailsVector, void *element)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void cleanup_openssl()
|
||||||
|
{
|
||||||
|
EVP_cleanup();
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,7 +594,8 @@ void resetWorkerData(ftpDataType *data, int clientId, int isInitialization)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
SSL_free(data->clients[clientId].workerData.ssl);
|
SSL_free(data->clients[clientId].workerData.serverSsl);
|
||||||
|
SSL_free(data->clients[clientId].workerData.clientSsl);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -623,7 +628,8 @@ void resetWorkerData(ftpDataType *data, int clientId, int isInitialization)
|
|||||||
free(lastToDestroy);
|
free(lastToDestroy);
|
||||||
}
|
}
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
data->clients[clientId].workerData.ssl = SSL_new(data->ctx);
|
data->clients[clientId].workerData.serverSsl = SSL_new(data->serverCtx);
|
||||||
|
data->clients[clientId].workerData.clientSsl = SSL_new(data->clientCtx);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,7 +663,7 @@ void resetClientData(ftpDataType *data, int clientId, int isInitialization)
|
|||||||
printf("\nclientData->writeMutex init failed\n");
|
printf("\nclientData->writeMutex init failed\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
data->clients[clientId].tlsIsNegotiating = 0;
|
||||||
data->clients[clientId].tlsIsEnabled = 0;
|
data->clients[clientId].tlsIsEnabled = 0;
|
||||||
data->clients[clientId].dataChannelIsTls = 0;
|
data->clients[clientId].dataChannelIsTls = 0;
|
||||||
data->clients[clientId].socketDescriptor = -1;
|
data->clients[clientId].socketDescriptor = -1;
|
||||||
@ -694,11 +700,12 @@ void resetClientData(ftpDataType *data, int clientId, int isInitialization)
|
|||||||
cleanDynamicStringDataType(&data->clients[clientId].ftpCommand.commandOps, isInitialization);
|
cleanDynamicStringDataType(&data->clients[clientId].ftpCommand.commandOps, isInitialization);
|
||||||
|
|
||||||
data->clients[clientId].connectionTimeStamp = 0;
|
data->clients[clientId].connectionTimeStamp = 0;
|
||||||
|
data->clients[clientId].tlsNegotiatingTimeStart = 0;
|
||||||
data->clients[clientId].lastActivityTimeStamp = 0;
|
data->clients[clientId].lastActivityTimeStamp = 0;
|
||||||
|
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
//data->clients[clientId].workerData.ssl = SSL_new(data->ctx);
|
//data->clients[clientId].workerData.ssl = SSL_new(data->ctx);
|
||||||
data->clients[clientId].ssl = SSL_new(data->ctx);
|
data->clients[clientId].ssl = SSL_new(data->serverCtx);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
ftpData.h
20
ftpData.h
@ -32,8 +32,9 @@
|
|||||||
#include "library/dynamicVectors.h"
|
#include "library/dynamicVectors.h"
|
||||||
|
|
||||||
|
|
||||||
#define CLIENT_COMMAND_STRING_SIZE 2048
|
#define CLIENT_COMMAND_STRING_SIZE 4096
|
||||||
#define CLIENT_BUFFER_STRING_SIZE 2048
|
#define CLIENT_BUFFER_STRING_SIZE 4096
|
||||||
|
#define MAXIMUM_INODE_NAME 4096
|
||||||
|
|
||||||
#define LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE 1024
|
#define LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE 1024
|
||||||
|
|
||||||
@ -81,10 +82,11 @@ struct ftpParameters
|
|||||||
int singleInstanceModeOn;
|
int singleInstanceModeOn;
|
||||||
DYNV_VectorGenericDataType usersVector;
|
DYNV_VectorGenericDataType usersVector;
|
||||||
int maximumIdleInactivity;
|
int maximumIdleInactivity;
|
||||||
|
|
||||||
int maximumConnectionsPerIp;
|
int maximumConnectionsPerIp;
|
||||||
int maximumUserAndPassowrdLoginTries;
|
int maximumUserAndPassowrdLoginTries;
|
||||||
|
|
||||||
|
char certificatePath[MAXIMUM_INODE_NAME];
|
||||||
|
char privateCertificatePath[MAXIMUM_INODE_NAME];
|
||||||
} typedef ftpParameters_DataType;
|
} typedef ftpParameters_DataType;
|
||||||
|
|
||||||
struct dynamicStringData
|
struct dynamicStringData
|
||||||
@ -118,7 +120,8 @@ struct ipData
|
|||||||
struct workerData
|
struct workerData
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
SSL *ssl;
|
SSL *serverSsl;
|
||||||
|
SSL *clientSsl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int threadIsAlive;
|
int threadIsAlive;
|
||||||
@ -157,6 +160,8 @@ struct clientData
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int tlsIsEnabled;
|
int tlsIsEnabled;
|
||||||
|
int tlsIsNegotiating;
|
||||||
|
unsigned long long int tlsNegotiatingTimeStart;
|
||||||
int dataChannelIsTls;
|
int dataChannelIsTls;
|
||||||
pthread_mutex_t writeMutex;
|
pthread_mutex_t writeMutex;
|
||||||
|
|
||||||
@ -216,7 +221,8 @@ struct ConnectionParameters
|
|||||||
struct ftpData
|
struct ftpData
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *serverCtx;
|
||||||
|
SSL_CTX *clientCtx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int connectedClients;
|
int connectedClients;
|
||||||
@ -258,10 +264,8 @@ int writeListDataInfoToSocket(ftpDataType *data, int clientId, int *filesNumber,
|
|||||||
int searchInLoginFailsVector(void *loginFailsVector, void *element);
|
int searchInLoginFailsVector(void *loginFailsVector, void *element);
|
||||||
void deleteLoginFailsData(void *element);
|
void deleteLoginFailsData(void *element);
|
||||||
void deleteListDataInfoVector(void *TheElementToDelete);
|
void deleteListDataInfoVector(void *TheElementToDelete);
|
||||||
|
|
||||||
void resetWorkerData(ftpDataType *data, int clientId, int isInitialization);
|
void resetWorkerData(ftpDataType *data, int clientId, int isInitialization);
|
||||||
void resetClientData(ftpDataType *data, int clientId, int isInitialization);
|
void resetClientData(ftpDataType *data, int clientId, int isInitialization);
|
||||||
|
|
||||||
int compareStringCaseInsensitive(char *stringIn, char* stringRef, int stringLenght);
|
int compareStringCaseInsensitive(char *stringIn, char* stringRef, int stringLenght);
|
||||||
int isCharInString(char *theString, int stringLen, char theChar);
|
int isCharInString(char *theString, int stringLen, char theChar);
|
||||||
void destroyConfigurationVectorElement(void * data);
|
void destroyConfigurationVectorElement(void * data);
|
||||||
|
132
ftpServer.c
132
ftpServer.c
@ -26,7 +26,6 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -59,21 +58,24 @@ void workerCleanup(void *socketId)
|
|||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
||||||
{
|
{
|
||||||
printf("\nSSL worker Shutdown 1");
|
if(ftpData.clients[theSocketId].workerData.passiveModeOn == 1)
|
||||||
returnCode = SSL_shutdown(ftpData.clients[theSocketId].workerData.ssl);
|
|
||||||
printf(" return code : %d", returnCode);
|
|
||||||
|
|
||||||
if (returnCode < 0)
|
|
||||||
{
|
{
|
||||||
printf("SSL_shutdown failed return code %d", returnCode);
|
printf("\nSSL worker Shutdown 1");
|
||||||
}
|
returnCode = SSL_shutdown(ftpData.clients[theSocketId].workerData.serverSsl);
|
||||||
else if (returnCode == 0)
|
printf(" return code : %d", returnCode);
|
||||||
{
|
|
||||||
returnCode = SSL_shutdown(ftpData.clients[theSocketId].workerData.ssl);
|
|
||||||
|
|
||||||
if (returnCode <= 0)
|
if (returnCode < 0)
|
||||||
{
|
{
|
||||||
printf("SSL_shutdown (2nd time) failed");
|
printf("SSL_shutdown failed return code %d", returnCode);
|
||||||
|
}
|
||||||
|
else if (returnCode == 0)
|
||||||
|
{
|
||||||
|
returnCode = SSL_shutdown(ftpData.clients[theSocketId].workerData.serverSsl);
|
||||||
|
|
||||||
|
if (returnCode <= 0)
|
||||||
|
{
|
||||||
|
printf("SSL_shutdown (2nd time) failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,6 +111,7 @@ void *connectionWorkerHandle(void * socketId)
|
|||||||
|
|
||||||
tries--;
|
tries--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftpData.clients[theSocketId].workerData.passiveListeningSocket == -1)
|
if (ftpData.clients[theSocketId].workerData.passiveListeningSocket == -1)
|
||||||
{
|
{
|
||||||
ftpData.clients[theSocketId].closeTheClient = 1;
|
ftpData.clients[theSocketId].closeTheClient = 1;
|
||||||
@ -134,14 +137,24 @@ void *connectionWorkerHandle(void * socketId)
|
|||||||
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
SSL_set_fd(ftpData.clients[theSocketId].workerData.ssl, ftpData.clients[theSocketId].workerData.socketConnection);
|
returnCode = SSL_set_fd(ftpData.clients[theSocketId].workerData.serverSsl, ftpData.clients[theSocketId].workerData.socketConnection);
|
||||||
returnCode = SSL_accept(ftpData.clients[theSocketId].workerData.ssl);
|
|
||||||
if (returnCode <= 0) {
|
if (returnCode == 0)
|
||||||
printf("\nSSL ERRORS ON WORKER");
|
{
|
||||||
}
|
printf("\nSSL ERRORS ON WORKER SSL_set_fd");
|
||||||
else {
|
ftpData.clients[theSocketId].closeTheClient = 1;
|
||||||
printf("\nSSL ACCEPTED ON WORKER");
|
}
|
||||||
}
|
|
||||||
|
returnCode = SSL_accept(ftpData.clients[theSocketId].workerData.serverSsl);
|
||||||
|
if (returnCode <= 0) {
|
||||||
|
printf("\nSSL ERRORS ON WORKER");
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
ftpData.clients[theSocketId].closeTheClient = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("\nSSL ACCEPTED ON WORKER");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -157,6 +170,31 @@ void *connectionWorkerHandle(void * socketId)
|
|||||||
{
|
{
|
||||||
ftpData.clients[theSocketId].workerData.socketConnection = createActiveSocket(ftpData.clients[theSocketId].workerData.connectionPort, ftpData.clients[theSocketId].workerData.activeIpAddress);
|
ftpData.clients[theSocketId].workerData.socketConnection = createActiveSocket(ftpData.clients[theSocketId].workerData.connectionPort, ftpData.clients[theSocketId].workerData.activeIpAddress);
|
||||||
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
||||||
|
{
|
||||||
|
returnCode = SSL_set_fd(ftpData.clients[theSocketId].workerData.clientSsl, ftpData.clients[theSocketId].workerData.socketConnection);
|
||||||
|
|
||||||
|
if (returnCode == 0)
|
||||||
|
{
|
||||||
|
printf("\nSSL ERRORS ON WORKER SSL_set_fd");
|
||||||
|
ftpData.clients[theSocketId].closeTheClient = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
returnCode = SSL_connect(ftpData.clients[theSocketId].workerData.clientSsl);
|
||||||
|
if (returnCode <= 0)
|
||||||
|
{
|
||||||
|
printf("\nSSL ERRORS ON WORKER %d", returnCode);
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
//ftpData.clients[theSocketId].closeTheClient = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\nSSL ACCEPTED ON WORKER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ftpData.clients[theSocketId].workerData.socketConnection < 0)
|
if (ftpData.clients[theSocketId].workerData.socketConnection < 0)
|
||||||
{
|
{
|
||||||
ftpData.clients[theSocketId].closeTheClient = 1;
|
ftpData.clients[theSocketId].closeTheClient = 1;
|
||||||
@ -231,13 +269,20 @@ void *connectionWorkerHandle(void * socketId)
|
|||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ftpData.clients[theSocketId].dataChannelIsTls != 1)
|
if (ftpData.clients[theSocketId].dataChannelIsTls != 1)
|
||||||
{
|
{
|
||||||
ftpData.clients[theSocketId].workerData.bufferIndex = read(ftpData.clients[theSocketId].workerData.socketConnection, ftpData.clients[theSocketId].workerData.buffer, CLIENT_BUFFER_STRING_SIZE);
|
ftpData.clients[theSocketId].workerData.bufferIndex = read(ftpData.clients[theSocketId].workerData.socketConnection, ftpData.clients[theSocketId].workerData.buffer, CLIENT_BUFFER_STRING_SIZE);
|
||||||
}
|
}
|
||||||
else if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
else if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
|
||||||
{
|
{
|
||||||
ftpData.clients[theSocketId].workerData.bufferIndex = SSL_read(ftpData.clients[theSocketId].workerData.ssl, ftpData.clients[theSocketId].workerData.buffer, CLIENT_BUFFER_STRING_SIZE);
|
|
||||||
|
#ifdef OPENSSL_ENABLED
|
||||||
|
if (ftpData.clients[theSocketId].workerData.passiveModeOn == 1)
|
||||||
|
ftpData.clients[theSocketId].workerData.bufferIndex = SSL_read(ftpData.clients[theSocketId].workerData.serverSsl, ftpData.clients[theSocketId].workerData.buffer, CLIENT_BUFFER_STRING_SIZE);
|
||||||
|
else if(ftpData.clients[theSocketId].workerData.activeModeOn == 1)
|
||||||
|
ftpData.clients[theSocketId].workerData.bufferIndex = SSL_read(ftpData.clients[theSocketId].workerData.clientSsl, ftpData.clients[theSocketId].workerData.buffer, CLIENT_BUFFER_STRING_SIZE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -437,6 +482,36 @@ void runFtpServer(void)
|
|||||||
FD_ISSET(ftpData.clients[processingSock].socketDescriptor, &ftpData.connectionData.eset))
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
printf("\nTLS timeout closing the client time:%lld, start time: %lls..", (int)time(NULL), ftpData.clients[processingSock].tlsNegotiatingTimeStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\nSSL ACCEPTED");
|
||||||
|
ftpData.clients[processingSock].tlsIsEnabled = 1;
|
||||||
|
ftpData.clients[processingSock].tlsIsNegotiating = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ftpData.clients[processingSock].tlsIsEnabled == 1)
|
if (ftpData.clients[processingSock].tlsIsEnabled == 1)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
@ -483,7 +558,7 @@ void runFtpServer(void)
|
|||||||
if (ftpData.clients[processingSock].buffer[i] == '\n')
|
if (ftpData.clients[processingSock].buffer[i] == '\n')
|
||||||
{
|
{
|
||||||
ftpData.clients[processingSock].socketCommandReceived = 1;
|
ftpData.clients[processingSock].socketCommandReceived = 1;
|
||||||
printf("\n Processing the command: %s", ftpData.clients[processingSock].theCommandReceived);
|
//printf("\n Processing the command: %s", ftpData.clients[processingSock].theCommandReceived);
|
||||||
commandProcessStatus = processCommand(processingSock);
|
commandProcessStatus = processCommand(processingSock);
|
||||||
//Echo unrecognized commands
|
//Echo unrecognized commands
|
||||||
if (commandProcessStatus == FTP_COMMAND_NOT_RECONIZED)
|
if (commandProcessStatus == FTP_COMMAND_NOT_RECONIZED)
|
||||||
@ -539,8 +614,8 @@ void runFtpServer(void)
|
|||||||
static int processCommand(int processingElement)
|
static int processCommand(int processingElement)
|
||||||
{
|
{
|
||||||
int toReturn = 0;
|
int toReturn = 0;
|
||||||
printTimeStamp();
|
//printTimeStamp();
|
||||||
printf ("Command received from (%d): %s", processingElement, ftpData.clients[processingElement].theCommandReceived);
|
//printf ("Command received from (%d): %s", processingElement, ftpData.clients[processingElement].theCommandReceived);
|
||||||
|
|
||||||
cleanDynamicStringDataType(&ftpData.clients[processingElement].ftpCommand.commandArgs, 0);
|
cleanDynamicStringDataType(&ftpData.clients[processingElement].ftpCommand.commandArgs, 0);
|
||||||
cleanDynamicStringDataType(&ftpData.clients[processingElement].ftpCommand.commandOps, 0);
|
cleanDynamicStringDataType(&ftpData.clients[processingElement].ftpCommand.commandOps, 0);
|
||||||
@ -752,8 +827,9 @@ static int processCommand(int processingElement)
|
|||||||
void deallocateMemory(void)
|
void deallocateMemory(void)
|
||||||
{
|
{
|
||||||
printf("\n Deallocating the memory.. ");
|
printf("\n Deallocating the memory.. ");
|
||||||
#ifndef OPENSSL_ENABLED
|
|
||||||
SSL_CTX_free(ftpData.ctx);
|
#ifdef OPENSSL_ENABLED
|
||||||
cleanup_openssl();
|
SSL_CTX_free(ftpData.serverCtx);
|
||||||
|
cleanupOpenssl();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,7 @@
|
|||||||
|
|
||||||
#define MAX_FTP_CLIENTS 10
|
#define MAX_FTP_CLIENTS 10
|
||||||
#define UFTP_SERVER_VERSION "2.0.0 beta"
|
#define UFTP_SERVER_VERSION "2.0.0 beta"
|
||||||
#warning remove in final release, must be specified by makefile
|
|
||||||
#define OPENSSL_ENABLED
|
|
||||||
|
|
||||||
void runFtpServer(void);
|
void runFtpServer(void);
|
||||||
void *connectionWorkerHandle(void * socketId);
|
void *connectionWorkerHandle(void * socketId);
|
||||||
|
@ -74,15 +74,11 @@ void configurationRead(ftpParameters_DataType *ftpParameters)
|
|||||||
{
|
{
|
||||||
printf("\nReading configuration from \n -> %s \n", LOCAL_CONFIGURATION_FILENAME);
|
printf("\nReading configuration from \n -> %s \n", LOCAL_CONFIGURATION_FILENAME);
|
||||||
returnCode = readConfigurationFile(LOCAL_CONFIGURATION_FILENAME, &configParameters);
|
returnCode = readConfigurationFile(LOCAL_CONFIGURATION_FILENAME, &configParameters);
|
||||||
printf("\nDONE\n");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (FILE_IsFile(DEFAULT_CONFIGURATION_FILENAME) == 1)
|
else if (FILE_IsFile(DEFAULT_CONFIGURATION_FILENAME) == 1)
|
||||||
{
|
{
|
||||||
printf("\nReading configuration from \n -> %s\n", DEFAULT_CONFIGURATION_FILENAME);
|
printf("\nReading configuration from \n -> %s\n", DEFAULT_CONFIGURATION_FILENAME);
|
||||||
returnCode = readConfigurationFile(DEFAULT_CONFIGURATION_FILENAME, &configParameters);
|
returnCode = readConfigurationFile(DEFAULT_CONFIGURATION_FILENAME, &configParameters);
|
||||||
printf("\nDONE\n");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnCode == 1)
|
if (returnCode == 1)
|
||||||
@ -128,10 +124,11 @@ void initFtpData(ftpDataType *ftpData)
|
|||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
#warning OPENSSL ENABLED!
|
|
||||||
initOpenssl();
|
initOpenssl();
|
||||||
ftpData->ctx = createContext();
|
ftpData->serverCtx = createServerContext();
|
||||||
configureContext(ftpData->ctx);
|
ftpData->clientCtx = createClientContext();
|
||||||
|
configureContext(ftpData->serverCtx, ftpData->ftpParameters.certificatePath, ftpData->ftpParameters.privateCertificatePath);
|
||||||
|
configureContext(ftpData->clientCtx, ftpData->ftpParameters.certificatePath, ftpData->ftpParameters.privateCertificatePath);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ftpData->connectedClients = 0;
|
ftpData->connectedClients = 0;
|
||||||
@ -494,6 +491,31 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
|
|||||||
printf("\nFTP_SERVER_IP parameter not found in the configuration file, listening on all available networks");
|
printf("\nFTP_SERVER_IP parameter not found in the configuration file, listening on all available networks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
searchIndex = searchParameter("CERTIFICATE_PATH", parametersVector);
|
||||||
|
if (searchIndex != -1)
|
||||||
|
{
|
||||||
|
strcpy(ftpParameters->certificatePath, ((parameter_DataType *) parametersVector->Data[searchIndex])->value);
|
||||||
|
printf("\nCERTIFICATE_PATH: %s", ftpParameters->certificatePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(ftpParameters->certificatePath, "cert.pem");
|
||||||
|
printf("\nCERTIFICATE_PATH parameter not found in the configuration file, using the default value: %s", ftpParameters->certificatePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
searchIndex = searchParameter("PRIVATE_CERTIFICATE_PATH", parametersVector);
|
||||||
|
if (searchIndex != -1)
|
||||||
|
{
|
||||||
|
strcpy(ftpParameters->privateCertificatePath, ((parameter_DataType *) parametersVector->Data[searchIndex])->value);
|
||||||
|
printf("\nPRIVATE_CERTIFICATE_PATH: %s", ftpParameters->certificatePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(ftpParameters->privateCertificatePath, "key.pem");
|
||||||
|
printf("\nPRIVATE_CERTIFICATE_PATH parameter not found in the configuration file, using the default value: %s", ftpParameters->privateCertificatePath);
|
||||||
|
}
|
||||||
|
|
||||||
/* USER SETTINGS */
|
/* USER SETTINGS */
|
||||||
userIndex = 0;
|
userIndex = 0;
|
||||||
memset(userX, 0, PARAMETER_SIZE_LIMIT);
|
memset(userX, 0, PARAMETER_SIZE_LIMIT);
|
||||||
@ -505,14 +527,14 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
|
|||||||
DYNV_VectorGeneric_Init(&ftpParameters->usersVector);
|
DYNV_VectorGeneric_Init(&ftpParameters->usersVector);
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
int searchUserIndex, searchPasswordIndex, searchHomeIndex, searchUserOwnerIndex, searchGroupOwnerIndex;
|
int searchUserIndex, searchPasswordIndex, searchHomeIndex, searchUserOwnerIndex, searchGroupOwnerIndex, returnCode;
|
||||||
usersParameters_DataType userData;
|
usersParameters_DataType userData;
|
||||||
|
|
||||||
sprintf(userX, "USER_%d", userIndex);
|
returnCode = snprintf(userX, PARAMETER_SIZE_LIMIT, "USER_%d", userIndex);
|
||||||
sprintf(passwordX, "PASSWORD_%d", userIndex);
|
returnCode = snprintf(passwordX, PARAMETER_SIZE_LIMIT, "PASSWORD_%d", userIndex);
|
||||||
sprintf(homeX, "HOME_%d", userIndex);
|
returnCode = snprintf(homeX, PARAMETER_SIZE_LIMIT, "HOME_%d", userIndex);
|
||||||
sprintf(groupOwnerX, "GROUP_NAME_OWNER_%d", userIndex);
|
returnCode = snprintf(groupOwnerX, PARAMETER_SIZE_LIMIT, "GROUP_NAME_OWNER_%d", userIndex);
|
||||||
sprintf(userOwnerX, "USER_NAME_OWNER_%d", userIndex);
|
returnCode = snprintf(userOwnerX, PARAMETER_SIZE_LIMIT, "USER_NAME_OWNER_%d", userIndex);
|
||||||
userIndex++;
|
userIndex++;
|
||||||
|
|
||||||
searchUserIndex = searchParameter(userX, parametersVector);
|
searchUserIndex = searchParameter(userX, parametersVector);
|
||||||
|
@ -47,10 +47,10 @@ int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __f
|
|||||||
#define SOCKET_PRINTF_BUFFER 2048
|
#define SOCKET_PRINTF_BUFFER 2048
|
||||||
|
|
||||||
int bytesWritten = 0;
|
int bytesWritten = 0;
|
||||||
char theBuffer[2048];
|
char theBuffer[SOCKET_PRINTF_BUFFER];
|
||||||
int theStringSize = 0;
|
int theStringSize = 0;
|
||||||
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
printf("\nWriting to socket id %d, TLS %d: ", clientId, ftpData->clients[clientId].tlsIsEnabled);
|
//printf("\nWriting to socket id %d, TLS %d: ", clientId, ftpData->clients[clientId].tlsIsEnabled);
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, __fmt);
|
va_start(args, __fmt);
|
||||||
@ -132,7 +132,7 @@ int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __f
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s", theBuffer);
|
//printf("%s", theBuffer);
|
||||||
|
|
||||||
if (theReturnCode > 0)
|
if (theReturnCode > 0)
|
||||||
{
|
{
|
||||||
@ -162,10 +162,10 @@ int socketWorkerPrintf(ftpDataType * ftpData, int clientId, const char *__restri
|
|||||||
#define SOCKET_PRINTF_BUFFER 2048
|
#define SOCKET_PRINTF_BUFFER 2048
|
||||||
|
|
||||||
int bytesWritten = 0;
|
int bytesWritten = 0;
|
||||||
char theBuffer[2048];
|
char theBuffer[SOCKET_PRINTF_BUFFER];
|
||||||
int theStringSize = 0;
|
int theStringSize = 0;
|
||||||
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
memset(&theBuffer, 0, SOCKET_PRINTF_BUFFER);
|
||||||
printf("\nWriting to worker socket id %dd, TLS %d: ", clientId, ftpData->clients[clientId].dataChannelIsTls);
|
//printf("\nWriting to worker socket id %dd, TLS %d: ", clientId, ftpData->clients[clientId].dataChannelIsTls);
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, __fmt);
|
va_start(args, __fmt);
|
||||||
while (*__fmt != '\0')
|
while (*__fmt != '\0')
|
||||||
@ -239,12 +239,16 @@ int socketWorkerPrintf(ftpDataType * ftpData, int clientId, const char *__restri
|
|||||||
}
|
}
|
||||||
else if (ftpData->clients[clientId].dataChannelIsTls == 1)
|
else if (ftpData->clients[clientId].dataChannelIsTls == 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
theReturnCode = SSL_write(ftpData->clients[clientId].workerData.ssl, theBuffer, theStringSize);
|
if (ftpData->clients[clientId].workerData.passiveModeOn == 1)
|
||||||
|
theReturnCode = SSL_write(ftpData->clients[clientId].workerData.serverSsl, theBuffer, theStringSize);
|
||||||
|
else if (ftpData->clients[clientId].workerData.activeModeOn == 1)
|
||||||
|
theReturnCode = SSL_write(ftpData->clients[clientId].workerData.clientSsl, theBuffer, theStringSize);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s", theBuffer);
|
//printf("%s", theBuffer);
|
||||||
|
|
||||||
if (theReturnCode > 0)
|
if (theReturnCode > 0)
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,8 @@ int isProcessAlreadyRunning(void)
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int returnCode;
|
int returnCode;
|
||||||
char buf[16];
|
char buf[30];
|
||||||
|
memset(buf, 0,30);
|
||||||
fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
|
fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
@ -66,8 +67,8 @@ int isProcessAlreadyRunning(void)
|
|||||||
|
|
||||||
//printf("\nFILE_LockFile returnCode = %d", returnCode);
|
//printf("\nFILE_LockFile returnCode = %d", returnCode);
|
||||||
ftruncate(fd, 0);
|
ftruncate(fd, 0);
|
||||||
sprintf(buf, "%ld", (long)getpid());
|
returnCode = snprintf(buf, 100, "%ld", (long)getpid());
|
||||||
write(fd, buf, strlen(buf)+1);
|
returnCode = write(fd, buf, strlen(buf)+1);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,4 +134,4 @@ void daemonize(const char *cmd)
|
|||||||
fd0 = open("/dev/null", O_RDWR);
|
fd0 = open("/dev/null", O_RDWR);
|
||||||
fd1 = dup(0);
|
fd1 = dup(0);
|
||||||
fd2 = dup(0);
|
fd2 = dup(0);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, i
|
|||||||
|
|
||||||
if (FILE_IsDirectory(DirectoryInodeName))
|
if (FILE_IsDirectory(DirectoryInodeName))
|
||||||
{
|
{
|
||||||
printf("\nReading directory: %s", DirectoryInodeName);
|
//printf("\nReading directory: %s", DirectoryInodeName);
|
||||||
|
|
||||||
DIR *TheDirectory;
|
DIR *TheDirectory;
|
||||||
struct dirent *dir;
|
struct dirent *dir;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
#warning SSL ENABLED
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -32,11 +31,24 @@
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
#include "openSsl.h"
|
#include "openSsl.h"
|
||||||
|
#include "fileManagement.h"
|
||||||
|
|
||||||
|
BIO *outbio;
|
||||||
|
|
||||||
void initOpenssl()
|
void initOpenssl()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
outbio = NULL;
|
||||||
|
OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */
|
||||||
|
SSL_load_error_strings(); /* Bring in and register error messages */
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
OpenSSL_add_ssl_algorithms();
|
//OpenSSL_add_ssl_algorithms();
|
||||||
|
ERR_load_BIO_strings();
|
||||||
|
ERR_load_crypto_strings();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
outbio = BIO_new(BIO_s_file());
|
||||||
|
outbio = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||||
|
SSL_library_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanupOpenssl()
|
void cleanupOpenssl()
|
||||||
@ -44,36 +56,90 @@ void cleanupOpenssl()
|
|||||||
EVP_cleanup();
|
EVP_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_CTX *createContext()
|
SSL_CTX *createServerContext()
|
||||||
{
|
{
|
||||||
const SSL_METHOD *method;
|
const SSL_METHOD *method;
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
|
|
||||||
method = SSLv23_server_method();
|
method = TLS_server_method();
|
||||||
|
|
||||||
ctx = SSL_CTX_new(method);
|
ctx = SSL_CTX_new(method);
|
||||||
if (!ctx) {
|
if (!ctx)
|
||||||
perror("Unable to create SSL context");
|
{
|
||||||
ERR_print_errors_fp(stderr);
|
perror("Unable to create server SSL context");
|
||||||
exit(EXIT_FAILURE);
|
ERR_print_errors_fp(stderr);
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void configureContext(SSL_CTX *ctx)
|
SSL_CTX *createClientContext(void)
|
||||||
{
|
{
|
||||||
|
const SSL_METHOD *method;
|
||||||
|
SSL_CTX *ctx;
|
||||||
|
|
||||||
|
method = TLS_client_method(); /* Create new client-method instance */
|
||||||
|
ctx = SSL_CTX_new(method); /* Create new context */
|
||||||
|
if ( ctx == NULL )
|
||||||
|
{
|
||||||
|
perror("Unable to create server SSL context");
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
abort();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void configureContext(SSL_CTX *ctx, char *certificatePath, char* privateCertificatePath)
|
||||||
|
{
|
||||||
|
if (FILE_IsFile(certificatePath) != 1)
|
||||||
|
{
|
||||||
|
printf("\ncertificate file: %s not found!", certificatePath);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FILE_IsFile(privateCertificatePath) != 1)
|
||||||
|
{
|
||||||
|
printf("\ncertificate file: %s not found!", privateCertificatePath);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
SSL_CTX_set_ecdh_auto(ctx, 1);
|
SSL_CTX_set_ecdh_auto(ctx, 1);
|
||||||
|
|
||||||
/* Set the key and cert */
|
/* Set the key and cert */
|
||||||
if (SSL_CTX_use_certificate_file(ctx, "/home/ugo/NetBeansProjects/uFTP/cert.pem", SSL_FILETYPE_PEM) <= 0) {
|
if (SSL_CTX_use_certificate_file(ctx, certificatePath, SSL_FILETYPE_PEM) <= 0) {
|
||||||
ERR_print_errors_fp(stderr);
|
ERR_print_errors_fp(stderr);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SSL_CTX_use_PrivateKey_file(ctx, "/home/ugo/NetBeansProjects/uFTP/key.pem", SSL_FILETYPE_PEM) <= 0 ) {
|
if (SSL_CTX_use_PrivateKey_file(ctx, privateCertificatePath, SSL_FILETYPE_PEM) <= 0 ) {
|
||||||
ERR_print_errors_fp(stderr);
|
ERR_print_errors_fp(stderr);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ShowCerts(SSL* ssl)
|
||||||
|
{ X509 *cert;
|
||||||
|
char *line;
|
||||||
|
|
||||||
|
cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
|
||||||
|
if ( cert != NULL )
|
||||||
|
{
|
||||||
|
printf("Server certificates:\n");
|
||||||
|
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
|
||||||
|
printf("Subject: %s\n", line);
|
||||||
|
free(line); /* free the malloc'ed string */
|
||||||
|
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
|
||||||
|
printf("Issuer: %s\n", line);
|
||||||
|
free(line); /* free the malloc'ed string */
|
||||||
|
X509_free(cert); /* free the malloc'ed certificate copy */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("No certificates.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,23 +22,24 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef OPENSSL_ENABLED
|
#ifdef OPENSSL_ENABLED
|
||||||
#warning SSL ENABLED
|
|
||||||
#ifndef OPENSSL_H
|
#ifndef OPENSSL_H
|
||||||
#define OPENSSL_H
|
#define OPENSSL_H
|
||||||
|
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
#define TLS_NEGOTIATING_TIMEOUT 30
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void initOpenssl();
|
void initOpenssl();
|
||||||
void cleanupOpenssl();
|
void cleanupOpenssl();
|
||||||
SSL_CTX *createContext();
|
SSL_CTX *createServerContext();
|
||||||
void configureContext(SSL_CTX *ctx);
|
SSL_CTX *createClientContext();
|
||||||
|
void configureContext(SSL_CTX *ctx, char *certificatePath, char* privateCertificatePath);
|
||||||
|
void ShowCerts(SSL* ssl);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,6 +32,10 @@ MAX_CONNECTION_TRY_PER_IP = 10
|
|||||||
#THE IP ADDRESS WILL BE BLOCKED FOR 5 MINUTES AFTER WRONG LOGIN USERNAME AND PASSWORD
|
#THE IP ADDRESS WILL BE BLOCKED FOR 5 MINUTES AFTER WRONG LOGIN USERNAME AND PASSWORD
|
||||||
#0 TO DISABLE
|
#0 TO DISABLE
|
||||||
|
|
||||||
|
#TLS CERTIFICATE FILE PATH
|
||||||
|
CERTIFICATE_PATH=/home/ugo/NetBeansProjects/uFTP/cert.pem
|
||||||
|
PRIVATE_CERTIFICATE_PATH=/home/ugo/NetBeansProjects/uFTP/key.pem
|
||||||
|
|
||||||
#USERS
|
#USERS
|
||||||
#START FROM USER 0 TO XXX
|
#START FROM USER 0 TO XXX
|
||||||
USER_0 = username
|
USER_0 = username
|
||||||
|
Reference in New Issue
Block a user