- 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__);
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; 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) {
FTPServerThread::addClientToServerIPAddress(clientIp,ServerIp);
}

View File

@ -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:

View File

@ -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);

View File

@ -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
}

View File

@ -16,6 +16,7 @@
#include <vector>
#include <string>
#include "types.h"
#include "socket.h"
#include "leak_dumper.h"
@ -34,16 +35,18 @@ protected:
std::pair<string,string> tilesetsPath;
int portNumber;
int maxPlayers;
static FTPClientValidationInterface *ftpValidationIntf;
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();
virtual void execute();
virtual void signalQuit();
virtual bool shutdownAndWait();
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;
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

View File

@ -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()

View File

@ -15,8 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WIN32
#ifndef WIN32
#include <stdio.h>
#include <string.h>
@ -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

View File

@ -15,8 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef WIN32
#ifdef WIN32
#include <windows.h>
#include <stdio.h>
@ -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

View File

@ -27,6 +27,7 @@ using namespace Shared::PlatformCommon;
namespace Shared { namespace PlatformCommon {
static std::map<uint32,uint32> 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<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->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;
}