Working on ssl, passive mode seems ok active needs more work

This commit is contained in:
Ugo Cirmignani
2018-12-08 19:37:50 +01:00
parent 959f1f4d41
commit 7808041587
23 changed files with 346 additions and 155 deletions

View File

@ -11,7 +11,7 @@ OPTIMIZATION=-O3
HEADERS=-I
LIBPATH=./build/modules/
BUILDFILES=start uFTP end
LIBS=-lpthread -lssl -lcrypto
#LIBS=-lpthread -lssl -lcrypto
#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_OPENSSL_SUPPORT=
#TO ENABLE OPENSSL SUPPORT UNCOMMENT THE NEXT LINE
#TO ENABLE OPENSSL SUPPORT UNCOMMENT NEXT 2 LINES
ENABLE_OPENSSL_SUPPORT=-D OPENSSL_ENABLED
LIBS=-lpthread -lssl -lcrypto
CFLAGS=$(CFLAGSTEMP) $(ENABLE_LARGE_FILE_SUPPORT) $(ENABLE_OPENSSL_SUPPORT)
@ -32,7 +33,7 @@ start:
@echo CGI FILES: $(BUILDFILES)
@rm -rf $(LIBPATH)*.o $(OUTPATH)uFTP
@echo "Clean ok"
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.

Binary file not shown.

View File

@ -220,56 +220,42 @@ int parseCommandPass(ftpDataType * data, int socketId)
int parseCommandAuth(ftpDataType * data, int socketId)
{
int returnCode;
int returnCode, returnCodeTls;
#ifndef OPENSSL_ENABLED
returnCode = socketPrintf(data, socketId, "s", "502 Security extensions not implemented.\r\n");
if (returnCode <= 0)
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
return FTP_COMMAND_PROCESSED;
#endif
#ifdef OPENSSL_ENABLED
returnCode = socketPrintf(data, socketId, "s", "234 AUTH TLS OK..\r\n");
if (returnCode <= 0)
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");
fflush(0);
if (returnCode == 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");
fflush(0);
int sslAcceptTimeout = 0;
do {
returnCode = SSL_accept(data->clients[socketId].ssl);
printf("\n SSL_accept");
fflush(0);
printf("\nSSL waiting handshake %d.. return code = %d", sslAcceptTimeout, returnCode);
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;
if (returnCodeTls <= 0)
{
printf("\nSSL NOT YET ACCEPTED: %d", returnCodeTls);
data->clients[socketId].tlsIsEnabled = 0;
data->clients[socketId].tlsIsNegotiating = 1;
}
else
{
printf("\nSSL ACCEPTED");
data->clients[socketId].tlsIsEnabled = 1;
data->clients[socketId].tlsIsNegotiating = 0;
}
#endif
@ -343,10 +329,15 @@ int parseCommandFeat(ftpDataType * data, int socketId)
SPSV
ESTP
211 End.
*/
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)
return FTP_COMMAND_PROCESSED_WRITE_ERROR;
@ -395,9 +386,16 @@ int parseCommandCcc(ftpDataType * data, int socketId)
if (returnCode <= 0)
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;
#endif
}
int parseCommandPbsz(ftpDataType * data, int socketId)
@ -461,7 +459,7 @@ int parseCommandPasv(ftpDataType * data, int socketId)
/* Create worker thread */
void *pReturn;
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)
{
@ -491,7 +489,7 @@ int parseCommandPort(ftpDataType * data, int socketId)
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]);
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;
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);
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 OPS: %s", data->clients[socketId].workerData.ftpCommand.commandOps.text);
printf("\ntheNameToList: %s", theNameToList);
///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("\ntheNameToList: %s", theNameToList);
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandArgs, 0);
cleanDynamicStringDataType(&data->clients[socketId].workerData.ftpCommand.commandOps, 0);
@ -714,7 +712,7 @@ int parseCommandCwd(ftpDataType * data, int socketId)
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(&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
{
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)
@ -1364,6 +1368,7 @@ int getFtpCommandArgWithOptions(char * theCommand, char *theCommandString, ftpCo
int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataType ownerShip)
{
#define MAXIMUM_FILENAME_LEN 4096
#define STATUS_INCREASE 0
#define STATUS_PERMISSIONS 1
#define STATUS_LOCAL_PATH 2
@ -1372,14 +1377,14 @@ int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataTyp
int returnCode = 0;
int status = STATUS_INCREASE;
char thePermissionString[1024];
char theLocalPath[1024];
char theFinalFilename[2048];
char thePermissionString[MAXIMUM_FILENAME_LEN];
char theLocalPath[MAXIMUM_FILENAME_LEN];
char theFinalFilename[MAXIMUM_FILENAME_LEN];
int returnCodeSetPermissions, returnCodeSetOwnership;
memset(theLocalPath, 0, 1024);
memset(thePermissionString, 0, 1024);
memset(theFinalFilename, 0, 2048);
memset(theLocalPath, 0, MAXIMUM_FILENAME_LEN);
memset(thePermissionString, 0, MAXIMUM_FILENAME_LEN);
memset(theFinalFilename, 0, MAXIMUM_FILENAME_LEN);
int thePermissionStringCursor = 0, theLocalPathCursor = 0;
while (permissionsCommand[permissionsCommandCursor] != '\r' &&
@ -1401,14 +1406,14 @@ int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataTyp
status = STATUS_LOCAL_PATH;
break;
}
if (thePermissionStringCursor < 1024 )
if (thePermissionStringCursor < MAXIMUM_FILENAME_LEN )
thePermissionString[thePermissionStringCursor++] = permissionsCommand[permissionsCommandCursor];
else
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
break;
case STATUS_LOCAL_PATH:
if (theLocalPathCursor < 1024)
if (theLocalPathCursor < MAXIMUM_FILENAME_LEN)
theLocalPath[theLocalPathCursor++] = permissionsCommand[permissionsCommandCursor];
else
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
@ -1418,20 +1423,24 @@ int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataTyp
permissionsCommandCursor++;
}
memset(theFinalFilename, 0, 2048);
if ((strlen(basePath) + strlen(theLocalPath) + 2) >= 2048)
if ((strlen(basePath) + strlen(theLocalPath) + 2) >= MAXIMUM_FILENAME_LEN)
{
return FTP_CHMODE_COMMAND_RETURN_NAME_TOO_LONG;
}
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
{
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 &&

View File

@ -54,12 +54,9 @@ int parseCommandAuth(ftpDataType * data, int socketId);
int parseCommandPwd(ftpDataType * data, int socketId);
int parseCommandSyst(ftpDataType * data, int socketId);
int parseCommandFeat(ftpDataType * data, int socketId);
int parseCommandProt(ftpDataType * data, int socketId);
int parseCommandCcc(ftpDataType * data, int socketId);
int parseCommandPbsz(ftpDataType * data, int socketId);
int parseCommandStruF(ftpDataType * data, int socketId);
int parseCommandTypeI(ftpDataType * data, int socketId);
int parseCommandModeS(ftpDataType * data, int socketId);

View File

@ -91,6 +91,7 @@ void setDynamicStringDataType(dynamicStringDataType *dynamicString, char *theStr
int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDataType *loginData)
{
#define STRING_SIZE 4096
int theLen, i;
char * theDirectoryNamePointer;
theDirectoryNamePointer = theDirectoryName;
@ -124,9 +125,9 @@ int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDa
}
//Check for /../
char theDirectoryToCheck[2048];
char theDirectoryToCheck[STRING_SIZE];
int theDirectoryToCheckIndex = 0;
memset(theDirectoryToCheck, 0, 2048);
memset(theDirectoryToCheck, 0, STRING_SIZE);
for (i = 0; i< theLen; i++)
{
@ -140,11 +141,11 @@ int getSafePath(dynamicStringDataType *safePath, char *theDirectoryName, loginDa
}
theDirectoryToCheckIndex = 0;
memset(theDirectoryToCheck, 0, 2048);
memset(theDirectoryToCheck, 0, STRING_SIZE);
continue;
}
if (theDirectoryToCheckIndex<2048)
if (theDirectoryToCheckIndex<STRING_SIZE)
{
theDirectoryToCheck[theDirectoryToCheckIndex++] = theDirectoryName[i];
}
@ -216,7 +217,7 @@ void setRandomicPort(ftpDataType *data, int socketPosition)
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)
@ -404,7 +405,10 @@ int searchInLoginFailsVector(void * loginFailsVector, void *element)
return i;
}
}
void cleanup_openssl()
{
EVP_cleanup();
}
return -1;
}
@ -590,7 +594,8 @@ void resetWorkerData(ftpDataType *data, int clientId, int isInitialization)
}
#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
}
else
@ -623,7 +628,8 @@ void resetWorkerData(ftpDataType *data, int clientId, int isInitialization)
free(lastToDestroy);
}
#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
}
@ -657,7 +663,7 @@ void resetClientData(ftpDataType *data, int clientId, int isInitialization)
printf("\nclientData->writeMutex init failed\n");
exit(0);
}
data->clients[clientId].tlsIsNegotiating = 0;
data->clients[clientId].tlsIsEnabled = 0;
data->clients[clientId].dataChannelIsTls = 0;
data->clients[clientId].socketDescriptor = -1;
@ -694,11 +700,12 @@ void resetClientData(ftpDataType *data, int clientId, int isInitialization)
cleanDynamicStringDataType(&data->clients[clientId].ftpCommand.commandOps, isInitialization);
data->clients[clientId].connectionTimeStamp = 0;
data->clients[clientId].tlsNegotiatingTimeStart = 0;
data->clients[clientId].lastActivityTimeStamp = 0;
#ifdef OPENSSL_ENABLED
//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
}

View File

@ -32,8 +32,9 @@
#include "library/dynamicVectors.h"
#define CLIENT_COMMAND_STRING_SIZE 2048
#define CLIENT_BUFFER_STRING_SIZE 2048
#define CLIENT_COMMAND_STRING_SIZE 4096
#define CLIENT_BUFFER_STRING_SIZE 4096
#define MAXIMUM_INODE_NAME 4096
#define LIST_DATA_TYPE_MODIFIED_DATA_STR_SIZE 1024
@ -81,10 +82,11 @@ struct ftpParameters
int singleInstanceModeOn;
DYNV_VectorGenericDataType usersVector;
int maximumIdleInactivity;
int maximumConnectionsPerIp;
int maximumUserAndPassowrdLoginTries;
char certificatePath[MAXIMUM_INODE_NAME];
char privateCertificatePath[MAXIMUM_INODE_NAME];
} typedef ftpParameters_DataType;
struct dynamicStringData
@ -118,7 +120,8 @@ struct ipData
struct workerData
{
#ifdef OPENSSL_ENABLED
SSL *ssl;
SSL *serverSsl;
SSL *clientSsl;
#endif
int threadIsAlive;
@ -157,6 +160,8 @@ struct clientData
#endif
int tlsIsEnabled;
int tlsIsNegotiating;
unsigned long long int tlsNegotiatingTimeStart;
int dataChannelIsTls;
pthread_mutex_t writeMutex;
@ -216,7 +221,8 @@ struct ConnectionParameters
struct ftpData
{
#ifdef OPENSSL_ENABLED
SSL_CTX *ctx;
SSL_CTX *serverCtx;
SSL_CTX *clientCtx;
#endif
int connectedClients;
@ -258,10 +264,8 @@ int writeListDataInfoToSocket(ftpDataType *data, int clientId, int *filesNumber,
int searchInLoginFailsVector(void *loginFailsVector, void *element);
void deleteLoginFailsData(void *element);
void deleteListDataInfoVector(void *TheElementToDelete);
void resetWorkerData(ftpDataType *data, int clientId, int isInitialization);
void resetClientData(ftpDataType *data, int clientId, int isInitialization);
int compareStringCaseInsensitive(char *stringIn, char* stringRef, int stringLenght);
int isCharInString(char *theString, int stringLen, char theChar);
void destroyConfigurationVectorElement(void * data);

View File

@ -26,7 +26,6 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
@ -59,21 +58,24 @@ void workerCleanup(void *socketId)
#ifdef OPENSSL_ENABLED
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
{
printf("\nSSL worker Shutdown 1");
returnCode = SSL_shutdown(ftpData.clients[theSocketId].workerData.ssl);
printf(" return code : %d", returnCode);
if (returnCode < 0)
if(ftpData.clients[theSocketId].workerData.passiveModeOn == 1)
{
printf("SSL_shutdown failed return code %d", returnCode);
}
else if (returnCode == 0)
{
returnCode = SSL_shutdown(ftpData.clients[theSocketId].workerData.ssl);
printf("\nSSL worker Shutdown 1");
returnCode = SSL_shutdown(ftpData.clients[theSocketId].workerData.serverSsl);
printf(" return code : %d", returnCode);
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--;
}
if (ftpData.clients[theSocketId].workerData.passiveListeningSocket == -1)
{
ftpData.clients[theSocketId].closeTheClient = 1;
@ -134,14 +137,24 @@ void *connectionWorkerHandle(void * socketId)
if (ftpData.clients[theSocketId].dataChannelIsTls == 1)
{
SSL_set_fd(ftpData.clients[theSocketId].workerData.ssl, ftpData.clients[theSocketId].workerData.socketConnection);
returnCode = SSL_accept(ftpData.clients[theSocketId].workerData.ssl);
if (returnCode <= 0) {
printf("\nSSL ERRORS ON WORKER");
}
else {
printf("\nSSL ACCEPTED ON WORKER");
}
returnCode = SSL_set_fd(ftpData.clients[theSocketId].workerData.serverSsl, ftpData.clients[theSocketId].workerData.socketConnection);
if (returnCode == 0)
{
printf("\nSSL ERRORS ON WORKER SSL_set_fd");
ftpData.clients[theSocketId].closeTheClient = 1;
}
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
}
@ -157,6 +170,31 @@ void *connectionWorkerHandle(void * socketId)
{
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)
{
ftpData.clients[theSocketId].closeTheClient = 1;
@ -231,13 +269,20 @@ void *connectionWorkerHandle(void * socketId)
while(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);
}
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
{
@ -437,6 +482,36 @@ void runFtpServer(void)
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)
{
#ifdef OPENSSL_ENABLED
@ -483,7 +558,7 @@ void runFtpServer(void)
if (ftpData.clients[processingSock].buffer[i] == '\n')
{
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);
//Echo unrecognized commands
if (commandProcessStatus == FTP_COMMAND_NOT_RECONIZED)
@ -539,8 +614,8 @@ void runFtpServer(void)
static int processCommand(int processingElement)
{
int toReturn = 0;
printTimeStamp();
printf ("Command received from (%d): %s", processingElement, ftpData.clients[processingElement].theCommandReceived);
//printTimeStamp();
//printf ("Command received from (%d): %s", processingElement, ftpData.clients[processingElement].theCommandReceived);
cleanDynamicStringDataType(&ftpData.clients[processingElement].ftpCommand.commandArgs, 0);
cleanDynamicStringDataType(&ftpData.clients[processingElement].ftpCommand.commandOps, 0);
@ -752,8 +827,9 @@ static int processCommand(int processingElement)
void deallocateMemory(void)
{
printf("\n Deallocating the memory.. ");
#ifndef OPENSSL_ENABLED
SSL_CTX_free(ftpData.ctx);
cleanup_openssl();
#ifdef OPENSSL_ENABLED
SSL_CTX_free(ftpData.serverCtx);
cleanupOpenssl();
#endif
}

View File

@ -28,8 +28,7 @@
#define MAX_FTP_CLIENTS 10
#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 *connectionWorkerHandle(void * socketId);

View File

@ -74,15 +74,11 @@ void configurationRead(ftpParameters_DataType *ftpParameters)
{
printf("\nReading configuration from \n -> %s \n", LOCAL_CONFIGURATION_FILENAME);
returnCode = readConfigurationFile(LOCAL_CONFIGURATION_FILENAME, &configParameters);
printf("\nDONE\n");
}
else if (FILE_IsFile(DEFAULT_CONFIGURATION_FILENAME) == 1)
{
printf("\nReading configuration from \n -> %s\n", DEFAULT_CONFIGURATION_FILENAME);
returnCode = readConfigurationFile(DEFAULT_CONFIGURATION_FILENAME, &configParameters);
printf("\nDONE\n");
}
if (returnCode == 1)
@ -128,10 +124,11 @@ void initFtpData(ftpDataType *ftpData)
srand(time(NULL));
#ifdef OPENSSL_ENABLED
#warning OPENSSL ENABLED!
initOpenssl();
ftpData->ctx = createContext();
configureContext(ftpData->ctx);
ftpData->serverCtx = createServerContext();
ftpData->clientCtx = createClientContext();
configureContext(ftpData->serverCtx, ftpData->ftpParameters.certificatePath, ftpData->ftpParameters.privateCertificatePath);
configureContext(ftpData->clientCtx, ftpData->ftpParameters.certificatePath, ftpData->ftpParameters.privateCertificatePath);
#endif
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");
}
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 */
userIndex = 0;
memset(userX, 0, PARAMETER_SIZE_LIMIT);
@ -505,14 +527,14 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve
DYNV_VectorGeneric_Init(&ftpParameters->usersVector);
while(1)
{
int searchUserIndex, searchPasswordIndex, searchHomeIndex, searchUserOwnerIndex, searchGroupOwnerIndex;
int searchUserIndex, searchPasswordIndex, searchHomeIndex, searchUserOwnerIndex, searchGroupOwnerIndex, returnCode;
usersParameters_DataType userData;
sprintf(userX, "USER_%d", userIndex);
sprintf(passwordX, "PASSWORD_%d", userIndex);
sprintf(homeX, "HOME_%d", userIndex);
sprintf(groupOwnerX, "GROUP_NAME_OWNER_%d", userIndex);
sprintf(userOwnerX, "USER_NAME_OWNER_%d", userIndex);
returnCode = snprintf(userX, PARAMETER_SIZE_LIMIT, "USER_%d", userIndex);
returnCode = snprintf(passwordX, PARAMETER_SIZE_LIMIT, "PASSWORD_%d", userIndex);
returnCode = snprintf(homeX, PARAMETER_SIZE_LIMIT, "HOME_%d", userIndex);
returnCode = snprintf(groupOwnerX, PARAMETER_SIZE_LIMIT, "GROUP_NAME_OWNER_%d", userIndex);
returnCode = snprintf(userOwnerX, PARAMETER_SIZE_LIMIT, "USER_NAME_OWNER_%d", userIndex);
userIndex++;
searchUserIndex = searchParameter(userX, parametersVector);

View File

@ -47,10 +47,10 @@ int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __f
#define SOCKET_PRINTF_BUFFER 2048
int bytesWritten = 0;
char theBuffer[2048];
char theBuffer[SOCKET_PRINTF_BUFFER];
int theStringSize = 0;
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_start(args, __fmt);
@ -132,7 +132,7 @@ int socketPrintf(ftpDataType * ftpData, int clientId, const char *__restrict __f
#endif
}
printf("%s", theBuffer);
//printf("%s", theBuffer);
if (theReturnCode > 0)
{
@ -162,10 +162,10 @@ int socketWorkerPrintf(ftpDataType * ftpData, int clientId, const char *__restri
#define SOCKET_PRINTF_BUFFER 2048
int bytesWritten = 0;
char theBuffer[2048];
char theBuffer[SOCKET_PRINTF_BUFFER];
int theStringSize = 0;
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_start(args, __fmt);
while (*__fmt != '\0')
@ -239,12 +239,16 @@ int socketWorkerPrintf(ftpDataType * ftpData, int clientId, const char *__restri
}
else if (ftpData->clients[clientId].dataChannelIsTls == 1)
{
#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
}
printf("%s", theBuffer);
//printf("%s", theBuffer);
if (theReturnCode > 0)
{

View File

@ -44,7 +44,8 @@ int isProcessAlreadyRunning(void)
{
int fd;
int returnCode;
char buf[16];
char buf[30];
memset(buf, 0,30);
fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
if (fd < 0)
{
@ -66,8 +67,8 @@ int isProcessAlreadyRunning(void)
//printf("\nFILE_LockFile returnCode = %d", returnCode);
ftruncate(fd, 0);
sprintf(buf, "%ld", (long)getpid());
write(fd, buf, strlen(buf)+1);
returnCode = snprintf(buf, 100, "%ld", (long)getpid());
returnCode = write(fd, buf, strlen(buf)+1);
return(0);
}
@ -133,4 +134,4 @@ void daemonize(const char *cmd)
fd0 = open("/dev/null", O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
}
}

View File

@ -196,7 +196,7 @@ void FILE_GetDirectoryInodeList(char * DirectoryInodeName, char *** InodeList, i
if (FILE_IsDirectory(DirectoryInodeName))
{
printf("\nReading directory: %s", DirectoryInodeName);
//printf("\nReading directory: %s", DirectoryInodeName);
DIR *TheDirectory;
struct dirent *dir;

View File

@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#ifdef OPENSSL_ENABLED
#warning SSL ENABLED
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
@ -32,11 +31,24 @@
#include <openssl/err.h>
#include "openSsl.h"
#include "fileManagement.h"
BIO *outbio;
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();
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()
@ -44,36 +56,90 @@ void cleanupOpenssl()
EVP_cleanup();
}
SSL_CTX *createContext()
SSL_CTX *createServerContext()
{
const SSL_METHOD *method;
SSL_CTX *ctx;
method = SSLv23_server_method();
method = TLS_server_method();
ctx = SSL_CTX_new(method);
if (!ctx) {
perror("Unable to create SSL context");
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
if (!ctx)
{
perror("Unable to create server SSL context");
ERR_print_errors_fp(stderr);
exit(0);
}
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);
/* 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);
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);
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

View File

@ -22,23 +22,24 @@
* THE SOFTWARE.
*/
#ifdef OPENSSL_ENABLED
#warning SSL ENABLED
#ifndef OPENSSL_H
#define OPENSSL_H
#include <openssl/ssl.h>
#include <openssl/err.h>
#define TLS_NEGOTIATING_TIMEOUT 30
#ifdef __cplusplus
extern "C" {
#endif
void initOpenssl();
void cleanupOpenssl();
SSL_CTX *createContext();
void configureContext(SSL_CTX *ctx);
SSL_CTX *createServerContext();
SSL_CTX *createClientContext();
void configureContext(SSL_CTX *ctx, char *certificatePath, char* privateCertificatePath);
void ShowCerts(SSL* ssl);
#ifdef __cplusplus
}
#endif

View File

@ -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
#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
#START FROM USER 0 TO XXX
USER_0 = username