| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "SecurityFunctionsTest.h"
- /*
- Description:
- Tests:
- virtual void RakPeerInterface::AddToSecurityExceptionList ( const char * ip )
- virtual void RakPeerInterface::AddToBanList ( const char * IP, TimeMS milliseconds = 0 )
- virtual void RakPeerInterface::GetIncomingPassword ( char * passwordData, int * passwordDataLength )
- virtual void RakPeerInterface::InitializeSecurity ( const char * pubKeyE, const char * pubKeyN, const char * privKeyP, const char * privKeyQ )
- virtual bool RakPeerInterface::IsBanned ( const char * IP )
- virtual bool RakPeerInterface::IsInSecurityExceptionList ( const char * ip )
- virtual void RakPeerInterface::RemoveFromSecurityExceptionList ( const char * ip )
- virtual void RakPeerInterface::RemoveFromBanList ( const char * IP )
- virtual void RakPeerInterface::SetIncomingPassword ( const char * passwordData, int passwordDataLength )
- virtual void ClearBanList (void)=0
- Success conditions:
- All functions pass tests.
- Failure conditions:
- Any function fails test.
- Client connects with no password
- Client connects with wrong password
- Client failed to connect with correct password
- Client was banned but connected anyways
- GetIncomingPassword returned wrong password
- IsBanned does not show localhost as banned
- Localhost was not unbanned
- Client failed to connect after banlist removal
- Client failed to connect after banlist removal with clear function
- Client did not connect encrypted
- Client connected encrypted but shouldn't have
- IsInSecurityExceptionList does not register localhost addition
- RakPeerInterface Functions used, tested indirectly by its use:
- Startup
- SetMaximumIncomingConnections
- Receive
- DeallocatePacket
- Send
- IsConnected
- GetStatistics
- RakPeerInterface Functions Explicitly Tested:
- SetIncomingPassword
- GetIncomingPassword
- AddToBanList
- IsBanned
- RemoveFromBanList
- ClearBanList
- InitializeSecurity //Disabled because of RakNetStatistics changes
- AddToSecurityExceptionList //Disabled because of RakNetStatistics changes
- IsInSecurityExceptionList //Disabled because of RakNetStatistics changes
- RemoveFromSecurityExceptionList //Disabled because of RakNetStatistics changes
- */
- int SecurityFunctionsTest::RunTest(DataStructures::List<RakString> params,bool isVerbose,bool noPauses)
- {
- char thePassword[]="password";
- server=RakPeerInterface::GetInstance();
- client=RakPeerInterface::GetInstance();
- client->Startup(1,&SocketDescriptor(),1);
- server->Startup(1,&SocketDescriptor(60000,0),1);
- server->SetMaximumIncomingConnections(1);
- server->SetIncomingPassword(thePassword,(int)strlen(thePassword));
- char returnedPass[22];
- int returnedLen=22;
- server->GetIncomingPassword(returnedPass,&returnedLen);
- returnedPass[returnedLen]=0;//Password is a data block convert to null terminated string to make the test easier
- if (strcmp(returnedPass,thePassword)!=0)
- {
- if (isVerbose)
- {
- printf("%s was returned but %s is the password\n",returnedPass,thePassword);
- DebugTools::ShowError("GetIncomingPassword returned wrong password\n",!noPauses && isVerbose,__LINE__,__FILE__);
- }
- return 5;
- }
- SystemAddress serverAddress;
- serverAddress.SetBinaryAddress("127.0.0.1");
- serverAddress.port=60000;
- TimeMS entryTime=GetTimeMS();
- if (isVerbose)
- printf("Testing if no password is rejected\n");
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,0,0);
- }
- RakSleep(100);
- }
- if (CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
- {
- if (isVerbose)
- DebugTools::ShowError("Client connected with no password\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 1;
- }
- if (isVerbose)
- printf("Testing if incorrect password is rejected\n");
- char badPass[]="badpass";
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,badPass,(int)strlen(badPass));
- }
- RakSleep(100);
- }
- if (CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
- {
- if (isVerbose)
- DebugTools::ShowError("Client connected with wrong password\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 2;
- }
- if (isVerbose)
- printf("Testing if correct password is accepted\n");
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
- }
- RakSleep(100);
- }
- if (!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
- {
- if (isVerbose)
- DebugTools::ShowError("Client failed to connect with correct password\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 3;
- }
- while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
- {
- client->CloseConnection (serverAddress,true,0,LOW_PRIORITY);
- }
- if (isVerbose)
- printf("Testing if connection is rejected after adding to ban list\n");
- server->AddToBanList("127.0.0.1",0);
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
- }
- RakSleep(100);
- }
- if(!server->IsBanned("127.0.0.1"))
- {
- if (isVerbose)
- DebugTools::ShowError("IsBanned does not show localhost as banned\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 6;
- }
- if (CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
- {
- if (isVerbose)
- DebugTools::ShowError("Client was banned but connected anyways\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 4;
- }
- if (isVerbose)
- printf("Testing if connection is accepted after ban removal by RemoveFromBanList\n");
- server->RemoveFromBanList("127.0.0.1");
- if(server->IsBanned("127.0.0.1"))
- {
- if (isVerbose)
- DebugTools::ShowError("Localhost was not unbanned\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 7;
- }
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
- }
- RakSleep(100);
- }
- if (!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
- {
- if (isVerbose)
- DebugTools::ShowError("Client failed to connect after banlist removal\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 8;
- }
- while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
- {
- client->CloseConnection (serverAddress,true,0,LOW_PRIORITY);
- }
- if (isVerbose)
- printf("Testing if connection is rejected after adding to ban list\n");
- server->AddToBanList("127.0.0.1",0);
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
- }
- RakSleep(100);
- }
- if(!server->IsBanned("127.0.0.1"))
- {
- if (isVerbose)
- DebugTools::ShowError("IsBanned does not show localhost as banned\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 6;
- }
- if (CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
- {
- if (isVerbose)
- DebugTools::ShowError("Client was banned but connected anyways\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 4;
- }
- if (isVerbose)
- printf("Testing if connection is accepted after ban removal by ClearBanList\n");
- server->ClearBanList();
- if(server->IsBanned("127.0.0.1"))
- {
- if (isVerbose)
- DebugTools::ShowError("Localhost was not unbanned\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 7;
- }
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,thePassword,(int)strlen(thePassword));
- }
- RakSleep(100);
- }
- if (!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true))
- {
- if (isVerbose)
- DebugTools::ShowError("Client failed to connect after banlist removal with clear function\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 9;
- }
- while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
- {
- client->CloseConnection (serverAddress,true,0,LOW_PRIORITY);
- }
- /*//Disabled because of statistics changes
- if (isVerbose)
- printf("Testing InitializeSecurity on server\n");
- //-----------------------------
- // RSACrypt is a using namespace RakNet;
- class that handles RSA encryption/decryption internally
- RSACrypt rsacrypt;
- uint32_t e;
- uint32_t modulus[RAKNET_RSA_FACTOR_LIMBS];
- uint32_t p[RAKNET_RSA_FACTOR_LIMBS/2],q[RAKNET_RSA_FACTOR_LIMBS/2];
- printf("Generating %i bit key. This will take a while...\n", RAKNET_RSA_FACTOR_LIMBS*32);
- rsacrypt.generatePrivateKey(RAKNET_RSA_FACTOR_LIMBS);
- e=rsacrypt.getPublicExponent();
- rsacrypt.getPublicModulus(modulus);
- rsacrypt.getPrivateP(p);
- rsacrypt.getPrivateQ(q);
- RakPeerInterface::DestroyInstance(server);
- server=RakPeerInterface::GetInstance();
- server->InitializeSecurity(0,0,(char*)p, (char*)q);
- server->Startup(1,30,&SocketDescriptor(60000,0),1);
- server->SetMaximumIncomingConnections(1);
- server->SetIncomingPassword(thePassword,strlen(thePassword));
- if (isVerbose)
- printf("Testing if client connects encrypted\n");
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,thePassword,strlen(thePassword));
- }
- RakSleep(100);
- }
- char str2[]="AAAAAAAAAA";
- str2[0]=(char)(ID_USER_PACKET_ENUM+1);
- client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
- client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
- Packet *packet;
- entryTime=GetTimeMS();
- while(GetTimeMS()-entryTime<1000)
- {
- for (packet=server->Receive(); packet;server->DeallocatePacket(packet), packet=server->Receive())
- {
- }
- }
- RakNetStatistics *rss;
- rss=client->GetStatistics(serverAddress);
- if (rss->encryptionBitsSent<=0)//If we did connect encrypted we should see encryptionBitsSent
- {
- if (isVerbose)
- DebugTools::ShowError("Client did not connect encrypted\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 10;
- }
- while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
- {
- client->CloseConnection (serverAddress,true,0,LOW_PRIORITY);
- }
- //Destroy to clear statistics
- RakPeerInterface::DestroyInstance(client);
- client=RakPeerInterface::GetInstance();
- client->Startup(1,30,&SocketDescriptor(),1);
- if (isVerbose)
- printf("Testing AddToSecurityExceptionList client should connect without encryption\n");
- server->AddToSecurityExceptionList("127.0.0.1");
- if (!server->IsInSecurityExceptionList("127.0.0.1"))
- {
- if (isVerbose)
- DebugTools::ShowError("IsInSecurityExceptionList does not register localhost addition\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 12;
- }
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,thePassword,strlen(thePassword));
- }
- RakSleep(100);
- }
- str2[0]=(char)(ID_USER_PACKET_ENUM+1);
- client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
- client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
- // Packet *packet;
- entryTime=GetTimeMS();
- while(GetTimeMS()-entryTime<1000)
- {
- for (packet=server->Receive(); packet;server->DeallocatePacket(packet), packet=server->Receive())
- {
- }
- }
- rss=client->GetStatistics(serverAddress);
- if (rss->encryptionBitsSent>0)//If we did connect encrypted we should see encryptionBitsSent
- {
- if (isVerbose)
- DebugTools::ShowError("Client connected encrypted but shouldn't have\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 11;
- }
- if (isVerbose)
- printf("Testing RemoveFromSecurityExceptionList\n");
- while(CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))//disconnect client
- {
- client->CloseConnection (serverAddress,true,0,LOW_PRIORITY);
- }
- server->RemoveFromSecurityExceptionList("127.0.0.1");
- if (isVerbose)
- printf("Testing if client connects encrypted\n");
- entryTime=GetTimeMS();
- while(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true)&&GetTimeMS()-entryTime<5000)
- {
- if(!CommonFunctions::ConnectionStateMatchesOptions (client,serverAddress,true,true,true,true))
- {
- client->Connect("127.0.0.1",serverAddress.port,thePassword,strlen(thePassword));
- }
- RakSleep(100);
- }
- str2[0]=(char)(ID_USER_PACKET_ENUM+1);
- client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
- client->Send(str2,(int) strlen(str2)+1, HIGH_PRIORITY, RELIABLE_ORDERED ,0, UNASSIGNED_SYSTEM_ADDRESS, true);
- entryTime=GetTimeMS();
- while(GetTimeMS()-entryTime<1000)
- {
- for (packet=server->Receive(); packet;server->DeallocatePacket(packet), packet=server->Receive())
- {
- }
- }
- rss=client->GetStatistics(serverAddress);
- if (rss->encryptionBitsSent<=0)//If we did connect encrypted we should see encryptionBitsSent
- {
- if (isVerbose)
- DebugTools::ShowError("Client did not connect encrypted\n",!noPauses && isVerbose,__LINE__,__FILE__);
- return 10;
- }
- */
- return 0;
- }
- RakString SecurityFunctionsTest::GetTestName()
- {
- return "SecurityFunctionsTest";
- }
- RakString SecurityFunctionsTest::ErrorCodeToString(int errorCode)
- {
- switch (errorCode)
- {
- case 0:
- return "No error";
- break;
- case 1:
- return "Client connected with no password";
- break;
- case 2:
- return "Client connected with wrong password";
- break;
- case 3:
- return "Client failed to connect with correct password";
- break;
- case 4:
- return "Client was banned but connected anyways";
- break;
- case 5:
- return "GetIncomingPassword returned wrong password";
- break;
- case 6:
- return "IsBanned does not show localhost as banned";
- break;
- case 7:
- return "Localhost was not unbanned";
- break;
- case 8:
- return "Client failed to connect after banlist removal";
- break;
- case 9:
- return "Client failed to connect after banlist removal with clear function";
- break;
- case 10:
- return "Client did not connect encrypted";
- break;
- case 11:
- return "Client connected encrypted but shouldn't have";
- break;
- case 12:
- return "IsInSecurityExceptionList does not register localhost addition";
- break;
- default:
- return "Undefined Error";
- }
- }
- SecurityFunctionsTest::SecurityFunctionsTest(void)
- {
- }
- SecurityFunctionsTest::~SecurityFunctionsTest(void)
- {
- }
- void SecurityFunctionsTest::DestroyPeers()
- {
- RakPeerInterface::DestroyInstance(client);
- RakPeerInterface::DestroyInstance(server);
- }
|