Beispiel #1
0
// -----------------------------------------------------------------------------
// function_name: encrypt
//
// Encrypts or decrypts the contents of bit vector in place. Type of operation
// depends on the edflag argument
//
// Returns: void
// -----------------------------------------------------------------------------
//
	EXPORT_C void encrypt(char block[], int edflag)
	{
		// encrypt() does not change the setting of errno if successful.
		// However, if errno is non-zero on return, an error has 
		// occurred.
		_encrypt (block, edflag);
	}
int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
  unsigned char *iv, unsigned char *ciphertext)
{
	  EVP_CIPHER_CTX *ctx;

	printf ("encryption: len %d, input %p, output %p\n",plaintext_len,ciphertext, plaintext);
	  int len;

	  int offset = 0;

	  /* Create and initialise the context */
	  if(!(ctx = EVP_CIPHER_CTX_new()))
		 error_handler();

	  if(EVP_EncryptInit_ex(ctx, EVP_aes_256_xts(), NULL, key, iv) != 1)
	  	  error_handler();

	  while (offset < plaintext_len) { 
	  	len = _encrypt(ctx, ciphertext + offset , plaintext + offset, 512);
		printf ("encryption: offset %d, input %p, output %p, len %d\n",offset, ciphertext + offset, plaintext + offset, len);
		offset += len;
	  }
 
	  EVP_CIPHER_CTX_free(ctx);

	  return offset;
}
Beispiel #3
0
void ProtocolManager::parsePacket(NetworkMessage& msg)
{
	if(g_game.getGameState() == GAMESTATE_SHUTDOWN)
	{
		getConnection()->close();
		return;
	}

	uint8_t recvbyte = msg.get<char>();
	OutputMessage_ptr output = getOutputBuffer();
	if(!output)
		return;

	TRACK_MESSAGE(output);
	switch(m_state)
	{
		case NO_LOGGED_IN:
		{
			if((time(NULL) - m_startTime) > 30000)
			{
				//login timeout
				getConnection()->close();
				addLogLine(LOGTYPE_WARNING, "Login timeout");
				return;
			}

			if(m_loginTries > 3)
			{
				output->put<char>(MP_MSG_ERROR);
				output->putString("Too many login attempts");
				getConnection()->send(output);

				getConnection()->close();
				addLogLine(LOGTYPE_WARNING, "Too many login attempts");
				return;
			}

			if(recvbyte != MP_MSG_LOGIN)
			{
				output->put<char>(MP_MSG_ERROR);
				output->putString("You are not logged in");
				getConnection()->send(output);

				getConnection()->close();
				addLogLine(LOGTYPE_WARNING, "Wrong command while not logged in");
				return;
			}
			break;
		}

		case LOGGED_IN:
			break;

		default:
		{
			getConnection()->close();
			addLogLine(LOGTYPE_ERROR, "No valid connection state");
			return;
		}
	}

	m_lastCommand = time(NULL);
	switch(recvbyte)
	{
		case MP_MSG_LOGIN:
		{
			if(m_state == NO_LOGGED_IN)
			{
				std::string pass = msg.getString(), word = g_config.getString(ConfigManager::MANAGER_PASSWORD);
				_encrypt(word, false);
				if(pass == word)
				{
					if(!Manager::getInstance()->loginConnection(this))
					{
						output->put<char>(MP_MSG_FAILURE);
						output->putString("Unknown connection");
						getConnection()->send(output);

						getConnection()->close();
						addLogLine(LOGTYPE_ERROR, "Login failed due to unknown connection");
						return;
					}
					else
					{
						m_state = LOGGED_IN;
						output->put<char>(MP_MSG_USERS);
						addLogLine(LOGTYPE_EVENT, "Logged in, sending users");

						std::map<uint32_t, std::string> users;
						for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
						{
							if(!it->second->isRemoved())
								users[it->first] = it->second->getName();
						}

						output->put<uint16_t>(users.size());
						for(std::map<uint32_t, std::string>::iterator it = users.begin(); it != users.end(); ++it)
						{
							output->put<uint32_t>(it->first);
							output->putString(it->second);
						}
					}
				}
				else
				{
					output->put<char>(MP_MSG_FAILURE);
					output->putString("Wrong password");

					m_loginTries++;
					addLogLine(LOGTYPE_EVENT, "Login failed due to wrong password (" + pass + ")");
				}
			}
			else
			{
				output->put<char>(MP_MSG_FAILURE);
				output->putString("Cannot login right now!");
				addLogLine(LOGTYPE_ERROR, "Wrong state at login");
			}

			break;
		}

		case MP_MSG_LOGOUT:
		{
			output->put<char>(MP_MSG_BYE);
			output->putString("Bye, bye!");
			getConnection()->send(output);

			getConnection()->close();
			addLogLine(LOGTYPE_EVENT, "Logout");
			return;
		}

		case MP_MSG_KEEP_ALIVE:
			break;

		case MP_MSG_PING:
			output->put<char>(MP_MSG_PONG);
			break;

		case MP_MSG_LUA:
		{
			std::string script = msg.getString();
			if(!Manager::getInstance()->execute(script))
			{
				output->put<char>(MP_MSG_FAILURE);
				output->putString("Unable to reserve enviroment for Lua script");
				addLogLine(LOGTYPE_ERROR, "Unable to reserve enviroment for Lua script");
			}
			else
			{
				output->put<char>(MP_MSG_SUCCESS);
				addLogLine(LOGTYPE_EVENT, "Executed Lua script");
			}

			break;
		}

		case MP_MSG_USER_INFO:
		{
			uint32_t playerId = msg.get<uint32_t>();
			if(Player* player = g_game.getPlayerByID(playerId))
			{
				output->put<char>(MP_MSG_USER_DATA);
				output->put<uint32_t>(playerId);

				output->put<uint32_t>(player->getGroupId());
				output->put<uint32_t>(player->getVocationId());

				output->put<uint32_t>(player->getLevel());
				output->put<uint32_t>(player->getMagicLevel());
				// TODO?
			}
			else
			{
				output->put<char>(MP_MSG_FAILURE);
				output->putString("Player not found");
			}
		}

		case MP_MSG_CHAT_REQUEST:
		{
			output->put<char>(MP_MSG_CHAT_LIST);
			ChannelList list = g_chat.getPublicChannels();

			output->put<uint16_t>(list.size());
			for(ChannelList::const_iterator it = list.begin(); it != list.end(); ++it)
			{
				output->put<uint16_t>((*it)->getId());
				output->putString((*it)->getName());

				output->put<uint16_t>((*it)->getFlags());
				output->put<uint16_t>((*it)->getUsers().size());
			}

			break;
		}

		case MP_MSG_CHAT_OPEN:
		{
			ChatChannel* channel = NULL;
			uint16_t channelId = msg.get<uint16_t>();
			if((channel = g_chat.getChannelById(channelId)) && g_chat.isPublicChannel(channelId))
			{
				m_channels |= (uint32_t)channelId;
				output->put<char>(MP_MSG_CHAT_USERS);
				UsersMap users = channel->getUsers();

				output->put<uint16_t>(users.size());
				for(UsersMap::const_iterator it = users.begin(); it != users.end(); ++it)
					output->put<uint32_t>(it->first);
			}
			else
			{
				output->put<char>(MP_MSG_FAILURE);
				output->putString("Invalid channel");
			}

			break;
		}

		case MP_MSG_CHAT_CLOSE:
		{
			uint16_t channelId = msg.get<uint16_t>();
			if(g_chat.getChannelById(channelId) && g_chat.isPublicChannel(channelId))
			{
				m_channels &= ~(uint32_t)channelId;
				output->put<char>(MP_MSG_SUCCESS);
			}
			else
			{
				output->put<char>(MP_MSG_FAILURE);
				output->putString("Invalid channel");
			}

			break;
		}

		case MP_MSG_CHAT_TALK:
		{
			std::string name = msg.getString();
			uint16_t channelId = msg.get<uint16_t>();
			SpeakClasses type = (SpeakClasses)msg.get<char>();
			std::string message = msg.getString();

			ChatChannel* channel = NULL;
			if((channel = g_chat.getChannelById(channelId)) && g_chat.isPublicChannel(channelId))
			{
				if(!channel->talk(name, type, message))
				{
					output->put<char>(MP_MSG_FAILURE);
					output->putString("Could not talk to channel");
				}
				else
					output->put<char>(MP_MSG_SUCCESS);
			}
			else
			{
				output->put<char>(MP_MSG_FAILURE);
				output->putString("Invalid channel");
			}

			break;
		}

		default:
		{
			output->put<char>(MP_MSG_ERROR);
			output->putString("Unknown command");

			addLogLine(LOGTYPE_WARNING, "Unknown command");
			break;
		}
	}
}
Beispiel #4
0
bool encryptTest(std::string plain, std::string& hash)
{
	std::transform(hash.begin(), hash.end(), hash.begin(), upchar);
	_encrypt(plain, true);
	return plain == hash;
}
Beispiel #5
0
int encrypt(char* clave, char* palabra, char* out){
	bool is_present = 0;//falso
	int pos = 0;

	// matrix 3x3
	int result1[3];
	int word_code[6];
	int i;
	int matrix[9] = {0};

	for (i = 0; i < 9; i++) {
		is_present = 0;
		pos  = 0;
		while(!is_present && pos < 41){
			if(alfabeto[pos] == clave[i]){
				matrix[i] = pos;
				is_present = 1;
			}
			pos += 1;
		}
	}

	int size = strlen(palabra);
	out[size] = 0;
	while(size > 2){
		for (i = 0; i < 3; i++) {
			is_present = 0;
			pos  = 0;
			while(!is_present && pos < 41){
				if(alfabeto[pos] == palabra[i]){
					word_code[i] = pos;
					is_present = 1;
				}
				pos += 1;
			}
		}

		_encrypt(matrix, word_code, result1);
		for (i = 0; i < 3; i++)
			*(out++) =  alfabeto[result1[i]];

		palabra += 3;
		size -= 3;
	}

	if(size){
		word_code[0] = 0;
		word_code[1] = 0;
		word_code[2] = 0;
		for (i = 0; i < size; i++) {
			is_present = 0;
			pos  = 0;
			while(!is_present && pos < 41){
				if(alfabeto[pos] == palabra[i]){
					word_code[i] = pos;
					is_present = 1;
				}
				pos += 1;
			}
		}

		_encrypt(matrix, word_code, result1);
		for (i = 0; i < size; i++) {
			*(out++) =  alfabeto[result1[i]];
		}
	}

	return 0;
}
Beispiel #6
0
void ProtocolAdmin::parsePacket(NetworkMessage& msg)
{
	if(g_game.getGameState() == GAMESTATE_SHUTDOWN)
	{
		getConnection()->close();
		return;
	}

	uint8_t recvbyte = msg.get<char>();
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(!output)
		return;

	TRACK_MESSAGE(output);
	switch(m_state)
	{
		case ENCRYPTION_NO_SET:
		{
			if(Admin::getInstance()->isEncypted())
			{
				if((time(NULL) - m_startTime) > 30000)
				{
					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "encryption timeout");
					return;
				}

				if(recvbyte != AP_MSG_ENCRYPTION && recvbyte != AP_MSG_KEY_EXCHANGE)
				{
					output->put<char>(AP_MSG_ERROR);
					output->putString("encryption needed");
					OutputMessagePool::getInstance()->send(output);

					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "wrong command while ENCRYPTION_NO_SET");
					return;
				}
			}
			else
				m_state = NO_LOGGED_IN;

			break;
		}

		case NO_LOGGED_IN:
		{
			if(g_config.getBool(ConfigManager::ADMIN_REQUIRE_LOGIN))
			{
				if((time(NULL) - m_startTime) > 30000)
				{
					//login timeout
					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "login timeout");
					return;
				}

				if(m_loginTries > 3)
				{
					output->put<char>(AP_MSG_ERROR);
					output->putString("too many login tries");
					OutputMessagePool::getInstance()->send(output);

					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "too many login tries");
					return;
				}

				if(recvbyte != AP_MSG_LOGIN)
				{
					output->put<char>(AP_MSG_ERROR);
					output->putString("you are not logged in");
					OutputMessagePool::getInstance()->send(output);

					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "wrong command while NO_LOGGED_IN");
					return;
				}
			}
			else
				m_state = LOGGED_IN;

			break;
		}

		case LOGGED_IN:
			break;

		default:
		{
			getConnection()->close();
			addLogLine(LOGTYPE_EVENT, "no valid connection state!!!");
			return;
		}
	}

	m_lastCommand = time(NULL);
	switch(recvbyte)
	{
		case AP_MSG_LOGIN:
		{
			if(m_state == NO_LOGGED_IN && g_config.getBool(ConfigManager::ADMIN_REQUIRE_LOGIN))
			{
				std::string pass = msg.getString(), word = g_config.getString(ConfigManager::ADMIN_PASSWORD);
				_encrypt(word, false);
				if(pass == word)
				{
					m_state = LOGGED_IN;
					output->put<char>(AP_MSG_LOGIN_OK);
					addLogLine(LOGTYPE_EVENT, "login ok");
				}
				else
				{
					m_loginTries++;
					output->put<char>(AP_MSG_LOGIN_FAILED);
					output->putString("wrong password");
					addLogLine(LOGTYPE_EVENT, "login failed.("+ pass + ")");
				}
			}
			else
			{
				output->put<char>(AP_MSG_LOGIN_FAILED);
				output->putString("cannot login");
				addLogLine(LOGTYPE_EVENT, "wrong state at login");
			}

			break;
		}

		case AP_MSG_ENCRYPTION:
		{
			if(m_state == ENCRYPTION_NO_SET && Admin::getInstance()->isEncypted())
			{
				uint8_t keyType = msg.get<char>();
				switch(keyType)
				{
					case ENCRYPTION_RSA1024XTEA:
					{
						RSA* rsa = Admin::getInstance()->getRSAKey(ENCRYPTION_RSA1024XTEA);
						if(!rsa)
						{
							output->put<char>(AP_MSG_ENCRYPTION_FAILED);
							addLogLine(LOGTYPE_EVENT, "no valid server key type");
							break;
						}

						if(RSA_decrypt(rsa, msg))
						{
							m_state = NO_LOGGED_IN;
							uint32_t k[4]= {msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>()};

							//use for in/out the new key we have
							enableXTEAEncryption();
							setXTEAKey(k);

							output->put<char>(AP_MSG_ENCRYPTION_OK);
							addLogLine(LOGTYPE_EVENT, "encryption ok");
						}
						else
						{
							output->put<char>(AP_MSG_ENCRYPTION_FAILED);
							output->putString("wrong encrypted packet");
							addLogLine(LOGTYPE_EVENT, "wrong encrypted packet");
						}

						break;
					}

					default:
					{
						output->put<char>(AP_MSG_ENCRYPTION_FAILED);
						output->putString("no valid key type");

						addLogLine(LOGTYPE_EVENT, "no valid client key type");
						break;
					}
				}
			}
			else
			{
				output->put<char>(AP_MSG_ENCRYPTION_FAILED);
				output->putString("cannot set encryption");
				addLogLine(LOGTYPE_EVENT, "cannot set encryption");
			}

			break;
		}

		case AP_MSG_KEY_EXCHANGE:
		{
			if(m_state == ENCRYPTION_NO_SET && Admin::getInstance()->isEncypted())
			{
				uint8_t keyType = msg.get<char>();
				switch(keyType)
				{
					case ENCRYPTION_RSA1024XTEA:
					{
						RSA* rsa = Admin::getInstance()->getRSAKey(ENCRYPTION_RSA1024XTEA);
						if(!rsa)
						{
							output->put<char>(AP_MSG_KEY_EXCHANGE_FAILED);
							addLogLine(LOGTYPE_EVENT, "no valid server key type");
							break;
						}

						output->put<char>(AP_MSG_KEY_EXCHANGE_OK);
						output->put<char>(ENCRYPTION_RSA1024XTEA);

						char RSAPublicKey[128];
						rsa->getPublicKey(RSAPublicKey);

						output->put<char>s(RSAPublicKey, 128);
						break;
					}

					default:
					{
						output->put<char>(AP_MSG_KEY_EXCHANGE_FAILED);
						addLogLine(LOGTYPE_EVENT, "no valid client key type");
						break;
					}
				}
			}
			else
			{
				output->put<char>(AP_MSG_KEY_EXCHANGE_FAILED);
				output->putString("cannot get public key");
				addLogLine(LOGTYPE_EVENT, "cannot get public key");
			}

			break;
		}

		case AP_MSG_COMMAND:
		{
			if(m_state != LOGGED_IN)
			{
				addLogLine(LOGTYPE_EVENT, "recvbyte == AP_MSG_COMMAND && m_state != LOGGED_IN !!!");
				break;
			}

			uint8_t command = msg.get<char>();
			switch(command)
			{
				case CMD_SAVE_SERVER:
				case CMD_SHALLOW_SAVE_SERVER:
				{
					uint8_t flags = (uint8_t)SAVE_PLAYERS | (uint8_t)SAVE_MAP | (uint8_t)SAVE_STATE;
					if(command == CMD_SHALLOW_SAVE_SERVER)
						flags |= SAVE_PLAYERS_SHALLOW;

					addLogLine(LOGTYPE_EVENT, "saving server");
					Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::saveGameState, &g_game, flags)));

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				case CMD_CLOSE_SERVER:
				{
					addLogLine(LOGTYPE_EVENT, "closing server");
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&Game::setGameState, &g_game, GAMESTATE_CLOSED)));

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				case CMD_OPEN_SERVER:
				{
					addLogLine(LOGTYPE_EVENT, "opening server");
					g_game.setGameState(GAMESTATE_NORMAL);

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				case CMD_SHUTDOWN_SERVER:
				{
					addLogLine(LOGTYPE_EVENT, "shutting down server");
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&Game::setGameState, &g_game, GAMESTATE_SHUTDOWN)));

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				case CMD_PAY_HOUSES:
				{
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&ProtocolAdmin::adminCommandPayHouses, this)));
					break;
				}

				case CMD_RELOAD_SCRIPTS:
				{
					const int8_t reload = msg.get<char>();
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&ProtocolAdmin::adminCommandReload, this, reload)));
					break;
				}

				case CMD_KICK:
				{
					const std::string param = msg.getString();
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&ProtocolAdmin::adminCommandKickPlayer, this, param)));
					break;
				}

				case CMD_SEND_MAIL:
				{
					const std::string xmlData = msg.getString();
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&ProtocolAdmin::adminCommandSendMail, this, xmlData)));
					break;
				}

				case CMD_BROADCAST:
				{
					const std::string param = msg.getString();
					addLogLine(LOGTYPE_EVENT, "broadcasting: " + param);
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&Game::broadcastMessage, &g_game, param, MSG_STATUS_WARNING)));

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				default:
				{
					output->put<char>(AP_MSG_COMMAND_FAILED);
					output->putString("not known server command");
					addLogLine(LOGTYPE_EVENT, "not known server command");
				}
			}
			break;
		}

		case AP_MSG_PING:
			output->put<char>(AP_MSG_PING_OK);
			break;

		case AP_MSG_KEEP_ALIVE:
			break;

		default:
		{
			output->put<char>(AP_MSG_ERROR);
			output->putString("not known command byte");

			addLogLine(LOGTYPE_EVENT, "not known command byte");
			break;
		}
	}

	if(output->size() > 0)
		OutputMessagePool::getInstance()->send(output);
}