mirror of
https://github.com/glest/glest-source.git
synced 2025-08-13 20:03:58 +02:00
- 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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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:
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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()
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user