Beispiel #1
0
void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick)
{
	if (user_is_logged_in(u))
	{
		plugin_log_user_nick_change(hub, u, nick);
	}
}
Beispiel #2
0
void hub_send_support(struct hub_info* hub, struct hub_user* u)
{
	if (user_is_connecting(u) || user_is_logged_in(u))
	{
		route_to_user(hub, u, hub->command_support);
	}
}
Beispiel #3
0
Datei: hub.c Projekt: q3k/uhub
void hub_disconnect_user(struct hub_info* hub, struct hub_user* user, int reason)
{
	struct event_data post;
	int need_notify = 0;

	/* is user already being disconnected ? */
	if (user_is_disconnecting(user))
	{
		return;
	}

	/* stop reading from user */
	net_shutdown_r(net_con_get_sd(user->connection));
	net_con_close(user->connection);
	user->connection = 0;

	LOG_TRACE("hub_disconnect_user(), user=%p, reason=%d, state=%d", user, reason, user->state);

	need_notify = user_is_logged_in(user) && hub->status == hub_status_running;
	user->quit_reason = reason;
	user_set_state(user, state_cleanup);

	if (need_notify)
	{
		memset(&post, 0, sizeof(post));
		post.id     = UHUB_EVENT_USER_QUIT;
		post.ptr    = user;
		event_queue_post(hub->queue, &post);
	}
	else
	{
		hub_schedule_destroy_user(hub, user);
	}
}
Beispiel #4
0
int uman_send_user_list(struct hub_info* hub, struct hub_user* target)
{
	int ret = 1;
	struct hub_user* user;
	user_flag_set(target, flag_user_list);
	user = (struct hub_user*) list_get_first(hub->users->list); /* iterate users - only on INF or PAS msg */
	while (user)
	{
		if (user_is_logged_in(user))
		{
			ret = route_to_user(hub, target, user->info);
			if (!ret)
				break;
		}
		user = (struct hub_user*) list_get_next(hub->users->list);
	}

#if 0
	FIXME: FIXME FIXME handle send queue excess
	if (!target->send_queue_size)
	{
	    user_flag_unset(target, flag_user_list);
	}
#endif
	return ret;
}
Beispiel #5
0
/* Notify plugins, etc */
void on_login_success(struct hub_info* hub, struct hub_user* u)
{
	/* Send user list of all existing users */
	if (!uman_send_user_list(hub, hub->users, u))
		return;

	/* Mark as being in the normal state, and add user to the user list */
	user_set_state(u, state_normal);
	uman_add(hub->users, u);

	/* Announce new user to all connected users */
	if (user_is_logged_in(u))
		route_info_message(hub, u);

	plugin_log_user_login_success(hub, u);

	/* reset timeout */
	net_con_clear_timeout(u->connection);
}
Beispiel #6
0
/* Notify plugins, etc */
void on_login_success(struct hub_info* hub, struct hub_user* u)
{
	/* Send user list of all existing users */
	if (!uman_send_user_list(hub, hub->users, u))
		return;

	/* Mark as being in the normal state, and add user to the user list */
	user_set_state(u, state_normal);
	uman_add(hub->users, u);

	// Make operators receive hub notifications by default.
	if (user_is_protected(u))
		user_flag_set(u, flag_opnotify);

	/* Announce new user to all connected users */
	if (user_is_logged_in(u))
		route_info_message(hub, u);

	plugin_log_user_login_success(hub, u);

	/* reset timeout */
	net_con_clear_timeout(u->connection);
}
Beispiel #7
0
static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	char* arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_SIZE);
	if (arg)
	{
		int64_t shared_size = atoll(arg);
		if (shared_size < 0)
			shared_size = 0;

		if (user_is_logged_in(user))
		{
			hub->users->shared_size  -= user->limits.shared_size;
			hub->users->shared_size  += shared_size;
		}
		user->limits.shared_size = shared_size;
		hub_free(arg);
		arg = 0;
	}

	arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
	if (arg)
	{
		int shared_files = atoi(arg);
		if (shared_files < 0)
			shared_files = 0;

		if (user_is_logged_in(user))
		{
			hub->users->shared_files -= user->limits.shared_files;
			hub->users->shared_files += shared_files;
		}
		user->limits.shared_files = shared_files;
		hub_free(arg);
		arg = 0;
	}

	arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
	if (arg)
	{
		int num = atoi(arg);
		if (num < 0) num = 0;
		user->limits.hub_count_user = num;
		hub_free(arg);
		arg = 0;
	}

	arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
	if (arg)
	{
		int num = atoi(arg);
		if (num < 0) num = 0;
		user->limits.hub_count_registered = num;
		hub_free(arg);
		arg = 0;
	}

	arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR);
	if (arg)
	{
		int num = atoi(arg);
		if (num < 0) num = 0;
		user->limits.hub_count_operator = num;
		hub_free(arg);
		arg = 0;
	}

	arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SLOTS);
	if (arg)
	{
		int num = atoi(arg);
		if (num < 0) num = 0;
		user->limits.upload_slots = num;
		hub_free(arg);
		arg = 0;
	}

	/* summarize total slots */
	user->limits.hub_count_total = user->limits.hub_count_user + user->limits.hub_count_registered + user->limits.hub_count_operator;

	if (!user_is_protected(user))
	{
		if (user->limits.shared_size < hub_get_min_share(hub) && hub_get_min_share(hub))
		{
			return status_msg_user_share_size_low;
		}

		if (user->limits.shared_size > hub_get_max_share(hub) && hub_get_max_share(hub))
		{
			return status_msg_user_share_size_high;
		}

		if ((user->limits.hub_count_user           > hub_get_max_hubs_user(hub)  && hub_get_max_hubs_user(hub)) ||
			(user->limits.hub_count_registered > hub_get_max_hubs_reg(hub)   && hub_get_max_hubs_reg(hub))  ||
			(user->limits.hub_count_operator   > hub_get_max_hubs_op(hub)    && hub_get_max_hubs_op(hub))   ||
			(user->limits.hub_count_total      > hub_get_max_hubs_total(hub) && hub_get_max_hubs_total(hub)))
		{
			return status_msg_user_hub_limit_high;
		}

		if ((user->limits.hub_count_user           < hub_get_min_hubs_user(hub)  && hub_get_min_hubs_user(hub)) ||
			(user->limits.hub_count_registered < hub_get_min_hubs_reg(hub)   && hub_get_min_hubs_reg(hub))  ||
			(user->limits.hub_count_operator   < hub_get_min_hubs_op(hub)    && hub_get_min_hubs_op(hub)))
		{
			return status_msg_user_hub_limit_low;
		}

		if (user->limits.upload_slots < hub_get_min_slots(hub) && hub_get_min_slots(hub))
		{
			return status_msg_user_slots_low;
		}

		if (user->limits.upload_slots > hub_get_max_slots(hub) && hub_get_max_slots(hub))
		{
			return status_msg_user_slots_high;
		}
	}
	return 0;
}
Beispiel #8
0
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;
}
Beispiel #9
0
void hub_send_hubinfo(struct hub_info* hub, struct hub_user* u)
{
	struct adc_message* info = adc_msg_copy(hub->command_info);
	int value = 0;
	uint64_t size = 0;

	if (user_flag_get(u, feature_ping))
	{
/*
		FIXME: These are missing:
		HH - Hub Host address ( DNS or IP )
		WS - Hub Website
		NE - Hub Network
		OW - Hub Owner name
*/
		adc_msg_add_named_argument(info, "UC", uhub_itoa(hub_get_user_count(hub)));
		adc_msg_add_named_argument(info, "MC", uhub_itoa(hub_get_max_user_count(hub)));
		adc_msg_add_named_argument(info, "SS", uhub_ulltoa(hub_get_shared_size(hub)));
		adc_msg_add_named_argument(info, "SF", uhub_ulltoa(hub_get_shared_files(hub)));

		/* Maximum/minimum share size */
		size = hub_get_max_share(hub);
		if (size) adc_msg_add_named_argument(info, "XS", uhub_ulltoa(size));
		size = hub_get_min_share(hub);
		if (size) adc_msg_add_named_argument(info, "MS", uhub_ulltoa(size));

		/* Maximum/minimum upload slots allowed per user */
		value = hub_get_max_slots(hub);
		if (value) adc_msg_add_named_argument(info, "XL", uhub_itoa(value));
		value = hub_get_min_slots(hub);
		if (value) adc_msg_add_named_argument(info, "ML", uhub_itoa(value));

		/* guest users must be on min/max hubs */
		value = hub_get_max_hubs_user(hub);
		if (value) adc_msg_add_named_argument(info, "XU", uhub_itoa(value));
		value = hub_get_min_hubs_user(hub);
		if (value) adc_msg_add_named_argument(info, "MU", uhub_itoa(value));

		/* registered users must be on min/max hubs */
		value = hub_get_max_hubs_reg(hub);
		if (value) adc_msg_add_named_argument(info, "XR", uhub_itoa(value));
		value = hub_get_min_hubs_reg(hub);
		if (value) adc_msg_add_named_argument(info, "MR", uhub_itoa(value));

		/* operators must be on min/max hubs */
		value = hub_get_max_hubs_op(hub);
		if (value) adc_msg_add_named_argument(info, "XO", uhub_itoa(value));
		value = hub_get_min_hubs_op(hub);
		if (value) adc_msg_add_named_argument(info, "MO", uhub_itoa(value));

		/* uptime in seconds */
		adc_msg_add_named_argument(info, "UP", uhub_itoa((int) difftime(time(0), hub->tm_started)));
	}

	if (user_is_connecting(u) || user_is_logged_in(u))
	{
		route_to_user(hub, u, info);
	}
	adc_msg_free(info);

	/* Only send banner when connecting */
	if (hub->config->show_banner && user_is_connecting(u))
	{
		route_to_user(hub, u, hub->command_banner);
	}
}
Beispiel #10
0
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;
}
Beispiel #11
0
Datei: hub.c Projekt: q3k/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:
				/* these must never be allowed for security reasons, so we ignore them. */
				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;
				CHECK_CHAT_ONLY;
				CHECK_FLOOD(search, 1);
				ROUTE_MSG;

			case ADC_CMD_DRES:
				cmd->priority = -1;
				CHECK_CHAT_ONLY;
				/* CHECK_FLOOD(search, 0); */
				ROUTE_MSG;

			case ADC_CMD_DRCM:
			case ADC_CMD_DCTM:
				cmd->priority = -1;
				CHECK_CHAT_ONLY;
				CHECK_FLOOD(connect, 1);
				ROUTE_MSG;

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

	return ret;
}