diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index b1b236fad..661e91f4d 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -112,7 +112,7 @@ ServerInterface::ServerInterface() : GameNetworkInterface() { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); int portNumber = Config::getInstance().getInt("FTPServerPort",intToStr(ServerSocket::getFTPServerPort()).c_str()); ServerSocket::setFTPServerPort(portNumber); - ftpServer = new FTPServerThread(mapsPath,tilesetsPath,portNumber,GameConstants::maxPlayers); + ftpServer = new FTPServerThread(mapsPath,tilesetsPath,portNumber,GameConstants::maxPlayers,this); ftpServer->start(); } SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -158,6 +158,24 @@ ServerInterface::~ServerInterface() { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } +int ServerInterface::isValidClientType(uint32 clientIp) { + int result = 0; + + for(int i= 0; igetSocket(); + uint32 slotIp = socket->getConnectedIPAddress(socket->getIpAddress()); + if(slotIp == clientIp) { + result = 1; + break; + } + } + } + return result; +} + void ServerInterface::addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp) { FTPServerThread::addClientToServerIPAddress(clientIp,ServerIp); } diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 2df11c744..b7880bcf8 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -33,7 +33,7 @@ namespace Glest{ namespace Game{ // class ServerInterface // ===================================================== -class ServerInterface: public GameNetworkInterface, public ConnectionSlotCallbackInterface, public SimpleTaskCallbackInterface { +class ServerInterface: public GameNetworkInterface, public ConnectionSlotCallbackInterface, public SimpleTaskCallbackInterface, public FTPClientValidationInterface { private: ConnectionSlot* slots[GameConstants::maxPlayers]; @@ -123,6 +123,7 @@ public: virtual void simpleTask(BaseThread *callingThread); void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp); + virtual int isValidClientType(uint32 clientIp); private: diff --git a/source/shared_lib/include/feathery_ftp/ftpIfc.h b/source/shared_lib/include/feathery_ftp/ftpIfc.h index 7371b2d1e..ad3e778f0 100644 --- a/source/shared_lib/include/feathery_ftp/ftpIfc.h +++ b/source/shared_lib/include/feathery_ftp/ftpIfc.h @@ -38,7 +38,7 @@ extern "C" { #endif -void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3); +void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4); int ftpCreateAccount(const char* name, const char* passw, const char* root, int accRights); int ftpStart(int portNumber); int ftpShutdown(void); diff --git a/source/shared_lib/include/feathery_ftp/ftpTypes.h b/source/shared_lib/include/feathery_ftp/ftpTypes.h index ea3a10088..f02d15ef0 100755 --- a/source/shared_lib/include/feathery_ftp/ftpTypes.h +++ b/source/shared_lib/include/feathery_ftp/ftpTypes.h @@ -68,11 +68,13 @@ int VERBOSE_MODE_ENABLED; typedef ip_t (*ftpFindExternalFTPServerIpType)(ip_t clientIp); typedef void (*ftpAddUPNPPortForwardType)(int internalPort, int externalPort); -typedef void (*ftpRemoveUPNPPortForwardType)(int internalPort, int externalPort); +typedef void (*ftpRemoveUPNPPortForwardType)(int internalPort, int externalPort); +typedef int (*ftpIsValidClientType)(ip_t clientIp); ftpFindExternalFTPServerIpType ftpFindExternalFTPServerIp; ftpAddUPNPPortForwardType ftpAddUPNPPortForward; -ftpRemoveUPNPPortForwardType ftpRemoveUPNPPortForward; +ftpRemoveUPNPPortForwardType ftpRemoveUPNPPortForward; +ftpIsValidClientType ftpIsValidClient; #ifdef __cplusplus } diff --git a/source/shared_lib/include/platform/posix/miniftpserver.h b/source/shared_lib/include/platform/posix/miniftpserver.h index 1dab63abc..807eebb2d 100644 --- a/source/shared_lib/include/platform/posix/miniftpserver.h +++ b/source/shared_lib/include/platform/posix/miniftpserver.h @@ -16,6 +16,7 @@ #include #include #include "types.h" +#include "socket.h" #include "leak_dumper.h" @@ -34,16 +35,18 @@ protected: std::pair tilesetsPath; int portNumber; int maxPlayers; + static FTPClientValidationInterface *ftpValidationIntf; public: - FTPServerThread(std::pair mapsPath, std::pair tilesetsPath, int portNumber,int maxPlayers); + FTPServerThread(std::pair mapsPath, std::pair tilesetsPath, int portNumber,int maxPlayers, FTPClientValidationInterface *ftpValidationIntf); ~FTPServerThread(); virtual void execute(); virtual void signalQuit(); virtual bool shutdownAndWait(); static void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp); + static FTPClientValidationInterface * getFtpValidationIntf() { return ftpValidationIntf; } }; diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index f2de00eaa..ae870e0da 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -48,7 +48,13 @@ using std::string; using namespace Shared::PlatformCommon; -namespace Shared{ namespace Platform { +namespace Shared { namespace Platform { + +// The callback Interface used by the UPNP discovery process +class FTPClientValidationInterface { +public: + virtual int isValidClientType(uint32 clientIp) = 0; +}; // The callback Interface used by the UPNP discovery process diff --git a/source/shared_lib/sources/feathery_ftp/ftpRuntime.c b/source/shared_lib/sources/feathery_ftp/ftpRuntime.c index 1387fb371..c97157403 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpRuntime.c +++ b/source/shared_lib/sources/feathery_ftp/ftpRuntime.c @@ -39,10 +39,11 @@ LOCAL int serverListenPort; LOCAL int serverPassiveListenPort; //LOCAL socket_t serverPassivePort; -void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3) { +void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4) { ftpFindExternalFTPServerIp = cb1; ftpAddUPNPPortForward = cb2; - ftpRemoveUPNPPortForward = cb3; + ftpRemoveUPNPPortForward = cb3; + ftpIsValidClient = cb4; } int ftpGetListenPort() diff --git a/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c b/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c index 27154ceeb..055ea2f26 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c +++ b/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c @@ -15,8 +15,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -#ifndef WIN32 + +#ifndef WIN32 #include #include @@ -35,7 +35,7 @@ #include "ftpTypes.h" #include "ftpConfig.h" -#include "ftp.h" +#include "ftp.h" ip_t ownIp; @@ -46,7 +46,7 @@ LOCAL int maxSockNr; void ftpArchInit() { - ownIp = 0; + ownIp = 0; maxSockNr = 0; FD_ZERO(&watchedSockets); FD_ZERO(&signaledSockets); @@ -178,7 +178,7 @@ int ftpRemoveDir(const char* path) } int ftpCloseSocket(socket_t s) -{ +{ if(VERBOSE_MODE_ENABLED) printf("\nClosing socket: %d\n",s); return close(s); } @@ -244,27 +244,26 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses } } else - { - int passivePort = ftpGetPassivePort() + sessionId; - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d\n",sessionId,passivePort); - + { + int passivePort = ftpGetPassivePort() + sessionId; + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d\n",sessionId,passivePort); + myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = INADDR_ANY; - myAddr.sin_port = htons(passivePort); - //myAddr.sin_port = htons(ftpGetPassivePort() + sessionId); - - int val = 1; - setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + myAddr.sin_port = htons(passivePort); + //myAddr.sin_port = htons(ftpGetPassivePort() + sessionId); + + setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) { - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d FAILED: %d\n",sessionId,passivePort,dataSocket); - - close(dataSocket); + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d FAILED: %d\n",sessionId,passivePort,dataSocket); + + close(dataSocket); return -1; - } - - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok\n",sessionId,passivePort); + } + + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok\n",sessionId,passivePort); len = sizeof(myAddr); if(getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln @@ -274,18 +273,18 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses } *port = ntohs(myAddr.sin_port); - *ip = ownIp; - - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d about to listen on port: %d using listener socket: %d\n",sessionId,passivePort,*port,dataSocket); + *ip = ownIp; + + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d about to listen on port: %d using listener socket: %d\n",sessionId,passivePort,*port,dataSocket); if(listen(dataSocket, 1)) - { - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d FAILED #2: %d\n",sessionId,passivePort,dataSocket); + { + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d FAILED #2: %d\n",sessionId,passivePort,dataSocket); close(dataSocket); return -1; - } - + } + //*port = ftpGetPassivePort(); //*ip = ownIp; //dataSocket = ftpGetServerPassivePortListenSocket(); @@ -303,9 +302,21 @@ socket_t ftpAcceptDataConnection(socket_t listner) dataSocket = accept(listner, (struct sockaddr *)&clientinfo, &len); if(dataSocket < 0) + { dataSocket = -1; + } close(listner); // Server-Socket wird nicht mehr gebrauch deshalb schließen + + ip_t remoteIP = ntohl(clientinfo.sin_addr.s_addr); + if(ftpIsValidClient && ftpIsValidClient(remoteIP) == 0) + { +if(VERBOSE_MODE_ENABLED) printf("Connection with %s is NOT a valid trusted client, dropping connection.\n", inet_ntoa(clientinfo.sin_addr)); + + close(dataSocket); + dataSocket = -1; + } + return dataSocket; } @@ -313,7 +324,7 @@ socket_t ftpCreateServerSocket(int portNumber) { int theServer; struct sockaddr_in serverinfo; - unsigned len; + unsigned len; int val = 1; theServer = socket(AF_INET, SOCK_STREAM, 0); @@ -324,8 +335,8 @@ socket_t ftpCreateServerSocket(int portNumber) serverinfo.sin_addr.s_addr = INADDR_ANY; serverinfo.sin_port = htons(portNumber); len = sizeof(serverinfo); - - setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + + setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); if(bind(theServer, (struct sockaddr *)&serverinfo, len)) { @@ -362,11 +373,19 @@ socket_t ftpAcceptServerConnection(socket_t server, ip_t *remoteIP, port_t *remo if(VERBOSE_MODE_ENABLED) printf("getsockname error\n"); } - ownIp = ntohl(sockinfo.sin_addr.s_addr); // eigene IP-Adresse abspeichern (wird dir PASV benätigt) + ownIp = ntohl(sockinfo.sin_addr.s_addr); // eigene IP-Adresse abspeichern (wird dir PASV benätigt) } if(VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d accepted.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); + if(ftpIsValidClient && ftpIsValidClient(*remoteIP) == 0) + { +if(VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d is NOT a valid trusted client, dropping connection.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); + + close(clientSocket); + clientSocket = -1; + } + return clientSocket; } @@ -403,4 +422,4 @@ int ftpSelect(int poll) return select(maxSockNr+1, &signaledSockets, NULL, NULL, NULL); } -#endif +#endif diff --git a/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c b/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c index d804fbbfb..f4ccb87bb 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c +++ b/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c @@ -15,8 +15,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -#ifdef WIN32 + +#ifdef WIN32 #include #include @@ -32,7 +32,7 @@ #pragma comment(lib, "ws2_32") #pragma comment(lib, "MSWSOCK") -ip_t ownIp; +ip_t ownIp; LOCAL fd_set watchedSockets; LOCAL fd_set signaledSockets; @@ -41,7 +41,7 @@ LOCAL int maxSockNr; void ftpArchInit() { WSADATA wsaData; - ownIp = 0; + ownIp = 0; maxSockNr = 0; FD_ZERO(&watchedSockets); WSAStartup(MAKEWORD(2, 0),&wsaData); @@ -209,7 +209,8 @@ int ftpRemoveDir(const char* path) int ftpCloseSocket(socket_t s) { - return closesocket((SOCKET)s); + if(VERBOSE_MODE_ENABLED) printf("\nClosing socket: %d\n",s); + return closesocket((SOCKET)s); } int ftpSend(socket_t s, const void *data, int len) @@ -257,8 +258,8 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses } myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = INADDR_ANY; - myAddr.sin_port = htons(20); - + myAddr.sin_port = htons(20); + if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) { closesocket(dataSocket); @@ -274,19 +275,26 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses } } else - { + { + int passivePort = ftpGetPassivePort() + sessionId; + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d\n",sessionId,passivePort); myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = INADDR_ANY; - //myAddr.sin_port = htons(0); - myAddr.sin_port = htons(ftpGetPassivePort() + sessionId); - - setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); + myAddr.sin_port = htons(passivePort); + //myAddr.sin_port = htons(ftpGetPassivePort() + sessionId); + + setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) { + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d FAILED: %d\n",sessionId,passivePort,dataSocket); + closesocket(dataSocket); return -1; } + + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok\n",sessionId,passivePort); + len = sizeof(myAddr); if(getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln { @@ -297,12 +305,16 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses *port = ntohs(myAddr.sin_port); *ip = ownIp; + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d about to listen on port: %d using listener socket: %d\n",sessionId,passivePort,*port,dataSocket); + if(listen(dataSocket, 1)) { + if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d FAILED #2: %d\n",sessionId,passivePort,dataSocket); + closesocket(dataSocket); return -1; - } - + } + //*port = ftpGetPassivePort(); //*ip = ownIp; //dataSocket = ftpGetServerPassivePortListenSocket(); @@ -320,9 +332,21 @@ socket_t ftpAcceptDataConnection(socket_t listner) dataSocket = accept(listner, (struct sockaddr *)&clientinfo, &len); if(dataSocket < 0) + { dataSocket = -1; + } closesocket(listner); // Server-Socket wird nicht mehr gebrauch deshalb schließen + + ip_t remoteIP = ntohl(clientinfo.sin_addr.s_addr); + if(ftpIsValidClient && ftpIsValidClient(remoteIP) == 0) + { +if(VERBOSE_MODE_ENABLED) printf("Connection with %s is NOT a valid trusted client, dropping connection.\n", inet_ntoa(clientinfo.sin_addr)); + + close(dataSocket); + dataSocket = -1; + } + return (socket_t)dataSocket; } @@ -341,8 +365,8 @@ socket_t ftpCreateServerSocket(int portNumber) serverinfo.sin_addr.s_addr = INADDR_ANY; serverinfo.sin_port = htons(portNumber); len = sizeof(serverinfo); - - setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); + + setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); if(bind(theServer, (struct sockaddr *)&serverinfo, len)) { @@ -384,6 +408,14 @@ if(VERBOSE_MODE_ENABLED) printf("getsockname error\n"); if(VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d accepted.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); + if(ftpIsValidClient && ftpIsValidClient(*remoteIP) == 0) + { +if(VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d is NOT a valid trusted client, dropping connection.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); + + close(clientSocket); + clientSocket = -1; + } + return clientSocket; } @@ -420,4 +452,4 @@ int ftpSelect(int poll) return select(maxSockNr+1, &signaledSockets, NULL, NULL, NULL); } -#endif +#endif diff --git a/source/shared_lib/sources/platform/posix/miniftpserver.cpp b/source/shared_lib/sources/platform/posix/miniftpserver.cpp index 6d99d3e87..d67fcdaac 100644 --- a/source/shared_lib/sources/platform/posix/miniftpserver.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpserver.cpp @@ -27,6 +27,7 @@ using namespace Shared::PlatformCommon; namespace Shared { namespace PlatformCommon { static std::map clientToFTPServerList; +FTPClientValidationInterface * FTPServerThread::ftpValidationIntf = NULL; ip_t FindExternalFTPServerIp(ip_t clientIp) { ip_t result = clientToFTPServerList[clientIp]; @@ -36,13 +37,22 @@ ip_t FindExternalFTPServerIp(ip_t clientIp) { return result; } -FTPServerThread::FTPServerThread(std::pair mapsPath,std::pair tilesetsPath, int portNumber, int maxPlayers) : BaseThread() { +int isValidClientType(ip_t clientIp) { + int result = 0; + if(FTPServerThread::getFtpValidationIntf() != NULL) { + result = FTPServerThread::getFtpValidationIntf()->isValidClientType(clientIp); + } + return result; +} + +FTPServerThread::FTPServerThread(std::pair mapsPath,std::pair tilesetsPath, int portNumber, int maxPlayers,FTPClientValidationInterface *ftpValidationIntf) : BaseThread() { this->mapsPath = mapsPath; this->tilesetsPath = tilesetsPath; this->portNumber = portNumber; this->maxPlayers = maxPlayers; + this->ftpValidationIntf = ftpValidationIntf; - ftpInit(&FindExternalFTPServerIp,&UPNP_Tools::AddUPNPPortForward,&UPNP_Tools::RemoveUPNPPortForward); + ftpInit(&FindExternalFTPServerIp,&UPNP_Tools::AddUPNPPortForward,&UPNP_Tools::RemoveUPNPPortForward, &isValidClientType); VERBOSE_MODE_ENABLED = SystemFlags::VERBOSE_MODE_ENABLED; }