- to appease the security freaks, ONLY clients that are ALREADY connected in the lobby are able to connect to the built in FTP server now

This commit is contained in:
Mark Vejvoda
2011-01-07 06:21:23 +00:00
parent 02b7787b35
commit b30fe62528
10 changed files with 152 additions and 60 deletions

View File

@@ -112,7 +112,7 @@ ServerInterface::ServerInterface() : GameNetworkInterface() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
int portNumber = Config::getInstance().getInt("FTPServerPort",intToStr(ServerSocket::getFTPServerPort()).c_str()); int portNumber = Config::getInstance().getInt("FTPServerPort",intToStr(ServerSocket::getFTPServerPort()).c_str());
ServerSocket::setFTPServerPort(portNumber); ServerSocket::setFTPServerPort(portNumber);
ftpServer = new FTPServerThread(mapsPath,tilesetsPath,portNumber,GameConstants::maxPlayers); ftpServer = new FTPServerThread(mapsPath,tilesetsPath,portNumber,GameConstants::maxPlayers,this);
ftpServer->start(); ftpServer->start();
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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__); 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; i<GameConstants::maxPlayers; ++i) {
if(slots[i] != NULL) {
MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i) + "_" + intToStr(i));
Socket *socket = slots[i]->getSocket();
uint32 slotIp = socket->getConnectedIPAddress(socket->getIpAddress());
if(slotIp == clientIp) {
result = 1;
break;
}
}
}
return result;
}
void ServerInterface::addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp) { void ServerInterface::addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp) {
FTPServerThread::addClientToServerIPAddress(clientIp,ServerIp); FTPServerThread::addClientToServerIPAddress(clientIp,ServerIp);
} }

View File

@@ -33,7 +33,7 @@ namespace Glest{ namespace Game{
// class ServerInterface // class ServerInterface
// ===================================================== // =====================================================
class ServerInterface: public GameNetworkInterface, public ConnectionSlotCallbackInterface, public SimpleTaskCallbackInterface { class ServerInterface: public GameNetworkInterface, public ConnectionSlotCallbackInterface, public SimpleTaskCallbackInterface, public FTPClientValidationInterface {
private: private:
ConnectionSlot* slots[GameConstants::maxPlayers]; ConnectionSlot* slots[GameConstants::maxPlayers];
@@ -123,6 +123,7 @@ public:
virtual void simpleTask(BaseThread *callingThread); virtual void simpleTask(BaseThread *callingThread);
void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp); void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp);
virtual int isValidClientType(uint32 clientIp);
private: private:

View File

@@ -38,7 +38,7 @@
extern "C" { extern "C" {
#endif #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 ftpCreateAccount(const char* name, const char* passw, const char* root, int accRights);
int ftpStart(int portNumber); int ftpStart(int portNumber);
int ftpShutdown(void); int ftpShutdown(void);

View File

@@ -69,10 +69,12 @@ int VERBOSE_MODE_ENABLED;
typedef ip_t (*ftpFindExternalFTPServerIpType)(ip_t clientIp); typedef ip_t (*ftpFindExternalFTPServerIpType)(ip_t clientIp);
typedef void (*ftpAddUPNPPortForwardType)(int internalPort, int externalPort); 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; ftpFindExternalFTPServerIpType ftpFindExternalFTPServerIp;
ftpAddUPNPPortForwardType ftpAddUPNPPortForward; ftpAddUPNPPortForwardType ftpAddUPNPPortForward;
ftpRemoveUPNPPortForwardType ftpRemoveUPNPPortForward; ftpRemoveUPNPPortForwardType ftpRemoveUPNPPortForward;
ftpIsValidClientType ftpIsValidClient;
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -16,6 +16,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "types.h" #include "types.h"
#include "socket.h"
#include "leak_dumper.h" #include "leak_dumper.h"
@@ -34,16 +35,18 @@ protected:
std::pair<string,string> tilesetsPath; std::pair<string,string> tilesetsPath;
int portNumber; int portNumber;
int maxPlayers; int maxPlayers;
static FTPClientValidationInterface *ftpValidationIntf;
public: public:
FTPServerThread(std::pair<string,string> mapsPath, std::pair<string,string> tilesetsPath, int portNumber,int maxPlayers); FTPServerThread(std::pair<string,string> mapsPath, std::pair<string,string> tilesetsPath, int portNumber,int maxPlayers, FTPClientValidationInterface *ftpValidationIntf);
~FTPServerThread(); ~FTPServerThread();
virtual void execute(); virtual void execute();
virtual void signalQuit(); virtual void signalQuit();
virtual bool shutdownAndWait(); virtual bool shutdownAndWait();
static void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp); static void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp);
static FTPClientValidationInterface * getFtpValidationIntf() { return ftpValidationIntf; }
}; };

View File

@@ -48,7 +48,13 @@ using std::string;
using namespace Shared::PlatformCommon; 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 // The callback Interface used by the UPNP discovery process

View File

@@ -39,10 +39,11 @@ LOCAL int serverListenPort;
LOCAL int serverPassiveListenPort; LOCAL int serverPassiveListenPort;
//LOCAL socket_t serverPassivePort; //LOCAL socket_t serverPassivePort;
void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3) { void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4) {
ftpFindExternalFTPServerIp = cb1; ftpFindExternalFTPServerIp = cb1;
ftpAddUPNPPortForward = cb2; ftpAddUPNPPortForward = cb2;
ftpRemoveUPNPPortForward = cb3; ftpRemoveUPNPPortForward = cb3;
ftpIsValidClient = cb4;
} }
int ftpGetListenPort() int ftpGetListenPort()

View File

@@ -253,8 +253,7 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses
myAddr.sin_port = htons(passivePort); myAddr.sin_port = htons(passivePort);
//myAddr.sin_port = htons(ftpGetPassivePort() + sessionId); //myAddr.sin_port = htons(ftpGetPassivePort() + sessionId);
int val = 1; setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr)))
{ {
@@ -303,9 +302,21 @@ socket_t ftpAcceptDataConnection(socket_t listner)
dataSocket = accept(listner, (struct sockaddr *)&clientinfo, &len); dataSocket = accept(listner, (struct sockaddr *)&clientinfo, &len);
if(dataSocket < 0) if(dataSocket < 0)
{
dataSocket = -1; dataSocket = -1;
}
close(listner); // Server-Socket wird nicht mehr gebrauch deshalb schließen 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; return dataSocket;
} }
@@ -367,6 +378,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(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; return clientSocket;
} }

View File

@@ -209,7 +209,8 @@ int ftpRemoveDir(const char* path)
int ftpCloseSocket(socket_t s) 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) int ftpSend(socket_t s, const void *data, int len)
@@ -275,18 +276,25 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses
} }
else 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_family = AF_INET;
myAddr.sin_addr.s_addr = INADDR_ANY; myAddr.sin_addr.s_addr = INADDR_ANY;
//myAddr.sin_port = htons(0); myAddr.sin_port = htons(passivePort);
myAddr.sin_port = htons(ftpGetPassivePort() + sessionId); //myAddr.sin_port = htons(ftpGetPassivePort() + sessionId);
setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) 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); closesocket(dataSocket);
return -1; return -1;
} }
if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok\n",sessionId,passivePort);
len = sizeof(myAddr); len = sizeof(myAddr);
if(getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln if(getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln
{ {
@@ -297,8 +305,12 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses
*port = ntohs(myAddr.sin_port); *port = ntohs(myAddr.sin_port);
*ip = ownIp; *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(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); closesocket(dataSocket);
return -1; return -1;
} }
@@ -320,9 +332,21 @@ socket_t ftpAcceptDataConnection(socket_t listner)
dataSocket = accept(listner, (struct sockaddr *)&clientinfo, &len); dataSocket = accept(listner, (struct sockaddr *)&clientinfo, &len);
if(dataSocket < 0) if(dataSocket < 0)
{
dataSocket = -1; dataSocket = -1;
}
closesocket(listner); // Server-Socket wird nicht mehr gebrauch deshalb schließen 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; return (socket_t)dataSocket;
} }
@@ -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(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; return clientSocket;
} }

View File

@@ -27,6 +27,7 @@ using namespace Shared::PlatformCommon;
namespace Shared { namespace PlatformCommon { namespace Shared { namespace PlatformCommon {
static std::map<uint32,uint32> clientToFTPServerList; static std::map<uint32,uint32> clientToFTPServerList;
FTPClientValidationInterface * FTPServerThread::ftpValidationIntf = NULL;
ip_t FindExternalFTPServerIp(ip_t clientIp) { ip_t FindExternalFTPServerIp(ip_t clientIp) {
ip_t result = clientToFTPServerList[clientIp]; ip_t result = clientToFTPServerList[clientIp];
@@ -36,13 +37,22 @@ ip_t FindExternalFTPServerIp(ip_t clientIp) {
return result; return result;
} }
FTPServerThread::FTPServerThread(std::pair<string,string> mapsPath,std::pair<string,string> 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<string,string> mapsPath,std::pair<string,string> tilesetsPath, int portNumber, int maxPlayers,FTPClientValidationInterface *ftpValidationIntf) : BaseThread() {
this->mapsPath = mapsPath; this->mapsPath = mapsPath;
this->tilesetsPath = tilesetsPath; this->tilesetsPath = tilesetsPath;
this->portNumber = portNumber; this->portNumber = portNumber;
this->maxPlayers = maxPlayers; 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; VERBOSE_MODE_ENABLED = SystemFlags::VERBOSE_MODE_ENABLED;
} }