Example #1
0
File: route.c Project: junaidk/uhub
int route_message(struct hub_info* hub, struct hub_user* u, struct adc_message* msg)
{
	struct hub_user* target = NULL;

	switch (msg->cache[0])
	{
		case 'B': /* Broadcast to all logged in clients */
			route_to_all(hub, msg);
			break;
			
		case 'D':
			target = uman_get_user_by_sid(hub->users, msg->target);
			if (target)
			{
				route_to_user(hub, target, msg);
			}
			break;
			
		case 'E':
			target = uman_get_user_by_sid(hub->users, msg->target);
			if (target)
			{
				route_to_user(hub, target, msg);
				route_to_user(hub, u, msg);
			}
			break;
			
		case 'F':
			route_to_subscribers(hub, msg);
			break;	
		
		default:
			/* Ignore the message */
			break;
	}
	return 0;
}
Example #2
0
File: hub.c Project: imobilis/uhub
int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* line, size_t length)
{
	int ret = 0;
	struct adc_message* cmd = 0;

	LOG_PROTO("recv %s: %s", sid_to_string(u->id.sid), line);

	if (user_is_disconnecting(u))
		return -1;

	cmd = adc_msg_parse_verify(u, line, length);
	if (cmd)
	{
		switch (cmd->cmd)
		{
			case ADC_CMD_HSUP:
				CHECK_FLOOD(extras, 0);
				ret = hub_handle_support(hub, u, cmd);
				break;

			case ADC_CMD_HPAS:
				CHECK_FLOOD(extras, 0);
				ret = hub_handle_password(hub, u, cmd);
				break;

			case ADC_CMD_BINF:
				CHECK_FLOOD(update, 1);
				ret = hub_handle_info(hub, u, cmd);
				break;

			case ADC_CMD_DINF:
			case ADC_CMD_EINF:
			case ADC_CMD_FINF:
			case ADC_CMD_BQUI:
			case ADC_CMD_DQUI:
			case ADC_CMD_EQUI:
			case ADC_CMD_FQUI:
				/* these must never be allowed for security reasons, so we ignore them. */
				CHECK_FLOOD(extras, 1);
				break;

			case ADC_CMD_EMSG:
			case ADC_CMD_DMSG:
			case ADC_CMD_BMSG:
			case ADC_CMD_FMSG:
				CHECK_FLOOD(chat, 1);
				ret = hub_handle_chat_message(hub, u, cmd);
				break;

			case ADC_CMD_BSCH:
			case ADC_CMD_DSCH:
			case ADC_CMD_ESCH:
			case ADC_CMD_FSCH:
				cmd->priority = -1;
				if (plugin_handle_search(hub, u, cmd->cache) == st_deny)
					break;
				CHECK_FLOOD(search, 1);
				ROUTE_MSG;

			case ADC_CMD_FRES: // spam
			case ADC_CMD_BRES: // spam
			case ADC_CMD_ERES: // pointless.
				CHECK_FLOOD(extras, 1);
				break;

			case ADC_CMD_DRES:
				cmd->priority = -1;
				if (plugin_handle_search_result(hub, u, uman_get_user_by_sid(hub->users, cmd->target), cmd->cache) == st_deny)
					break;
				/* CHECK_FLOOD(search, 0); */
				ROUTE_MSG;

			case ADC_CMD_DRCM:
				cmd->priority = -1;
				if (plugin_handle_revconnect(hub, u, uman_get_user_by_sid(hub->users, cmd->target)) == st_deny)
					break;
				CHECK_FLOOD(connect, 1);
				ROUTE_MSG;

			case ADC_CMD_DCTM:
				cmd->priority = -1;
				if (plugin_handle_connect(hub, u, uman_get_user_by_sid(hub->users, cmd->target)) == st_deny)
					break;
				CHECK_FLOOD(connect, 1);
				ROUTE_MSG;

			case ADC_CMD_BCMD:
			case ADC_CMD_DCMD:
			case ADC_CMD_ECMD:
			case ADC_CMD_FCMD:
			case ADC_CMD_HCMD:
				CHECK_FLOOD(extras, 1);
				break;

			default:
				CHECK_FLOOD(extras, 1);
				ROUTE_MSG;
		}
		adc_msg_free(cmd);
	}
	else
	{
		if (!user_is_logged_in(u))
		{
			ret = -1;
		}
	}

	return ret;
}
Example #3
0
File: hub.c Project: imobilis/uhub
int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd)
{
	char* message = adc_msg_get_argument(cmd, 0);
	char* message_decoded = NULL;
	int ret = 0;
	int relay = 1;
	int broadcast;
	int private_msg;
	int command;
	int offset;

	if (!message)
		return 0;

	message_decoded = adc_msg_unescape(message);
	if (!message_decoded)
	{
		hub_free(message);
		return 0;
	}

	if (!user_is_logged_in(u))
	{
		hub_free(message);
		return 0;
	}

	broadcast = (cmd->cache[0] == 'B');
	private_msg = (cmd->cache[0] == 'D' || cmd->cache[0] == 'E');
	command = (message[0] == '!' || message[0] == '+');

	if (broadcast && command)
	{
		/*
		 * A message such as "++message" is handled as "+message", by removing the first character.
		 * The first character is removed by memmoving the string one byte to the left.
		 */
		if (message[1] == message[0])
		{
			relay = 1;
			offset = adc_msg_get_arg_offset(cmd);
			memmove(cmd->cache+offset+1, cmd->cache+offset+2, cmd->length - offset);
			cmd->length--;
		}
		else
		{
			relay = command_invoke(hub->commands, u, message_decoded);
		}
	}

	/* FIXME: Plugin should do this! */
	if (relay && (((hub->config->chat_is_privileged && !user_is_protected(u)) || (user_flag_get(u, flag_muted))) && broadcast))
	{
		relay = 0;
	}

	if (relay)
	{
		plugin_st status = st_default;
		if (broadcast)
		{
			status = plugin_handle_chat_message(hub, u, message_decoded, 0);
		}
		else if (private_msg)
		{
			struct hub_user* target = uman_get_user_by_sid(hub->users, cmd->target);
			if (target)
				status = plugin_handle_private_message(hub, u, target, message_decoded, 0);
			else
				relay = 0;
		}

		if (status == st_deny)
			relay = 0;
	}

	if (relay)
	{
		/* adc_msg_remove_named_argument(cmd, "PM"); */
		if (broadcast)
		{
			plugin_log_chat_message(hub, u, message_decoded, 0);
		}
		ret = route_message(hub, u, cmd);
	}
	hub_free(message);
	hub_free(message_decoded);
	return ret;
}