예제 #1
0
파일: route.c 프로젝트: junaidk/uhub
int route_info_message(struct hub_info* hub, struct hub_user* u)
{
	if (!user_is_nat_override(u))
	{
		return route_to_all(hub, u->info);
	}
	else
	{
		struct adc_message* cmd = adc_msg_copy(u->info);
		const char* address = user_get_address(u);
		struct hub_user* user = 0;
		
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
		adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
	
		user = (struct hub_user*) list_get_first(hub->users->list);
		while (user)
		{
			if (user_is_nat_override(user))
				route_to_user(hub, user, cmd);
			else
				route_to_user(hub, user, u->info);
			
			user = (struct hub_user*) list_get_next(hub->users->list);
		}
		adc_msg_free(cmd);
	}
	return 0;
}
예제 #2
0
파일: hub.c 프로젝트: imobilis/uhub
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);
	}
}
예제 #3
0
파일: route.c 프로젝트: CoiLock/uhub
int route_to_all(struct hub_info* hub, struct adc_message* command) /* iterate users */
{
	struct hub_user* user;
	LIST_FOREACH(struct hub_user*, user, hub->users->list,
	{
		route_to_user(hub, user, command);
	});
예제 #4
0
파일: usermanager.c 프로젝트: Nyogtha/uhub
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;
}
예제 #5
0
파일: hub.c 프로젝트: imobilis/uhub
void hub_send_password_challenge(struct hub_info* hub, struct hub_user* u)
{
	struct adc_message* igpa;
	igpa = adc_msg_construct(ADC_CMD_IGPA, 38);
	adc_msg_add_argument(igpa, acl_password_generate_challenge(hub, u));
	user_set_state(u, state_verify);
	route_to_user(hub, u, igpa);
	adc_msg_free(igpa);
}
예제 #6
0
파일: hub.c 프로젝트: q3k/uhub
int hub_send_rules(struct hub_info* hub, struct hub_user* u)
{
	if (hub->command_rules)
	{
		route_to_user(hub, u, hub->command_rules);
		return 1;
	}
	return 0;
}
예제 #7
0
파일: route.c 프로젝트: junaidk/uhub
int route_to_all(struct hub_info* hub, struct adc_message* command) /* iterate users */
{
	struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list);
	while (user)
	{
		route_to_user(hub, user, command);
		user = (struct hub_user*) list_get_next(hub->users->list);
	}

	return 0;
}
예제 #8
0
파일: hub.c 프로젝트: imobilis/uhub
void hub_send_ping(struct hub_info* hub, struct hub_user* user)
{
	/* This will just send a newline, despite appearing to do more below. */
	struct adc_message* ping = adc_msg_construct(0, 0);
	ping->cache[0]     = '\n';
	ping->cache[1]     = 0;
	ping->length       = 1;
	ping->priority     = 1;
	route_to_user(hub, user, ping);
	adc_msg_free(ping);
}
예제 #9
0
파일: hub.c 프로젝트: q3k/uhub
void hub_send_sid(struct hub_info* hub, struct hub_user* u)
{
	sid_t sid;
	struct adc_message* command;
	if (user_is_connecting(u))
	{
		command = adc_msg_construct(ADC_CMD_ISID, 10);
		sid = uman_get_free_sid(hub, u);
		adc_msg_add_argument(command, (const char*) sid_to_string(sid));
		route_to_user(hub, u, command);
		adc_msg_free(command);
	}
}
예제 #10
0
파일: route.c 프로젝트: 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;
}
예제 #11
0
파일: route.c 프로젝트: junaidk/uhub
int route_to_subscribers(struct hub_info* hub, struct adc_message* command) /* iterate users */
{
	int do_send;
	char* tmp;
	
	struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list);
	while (user)
	{
		if (user->feature_cast)
		{
			do_send = 1;
			
			tmp = list_get_first(command->feature_cast_include);
			while (tmp)
			{
				if (!user_have_feature_cast_support(user, tmp))
				{
					do_send = 0;
					break;
				}
				tmp = list_get_next(command->feature_cast_include);;
			}
			
			if (!do_send) {
				user = (struct hub_user*) list_get_next(hub->users->list);
				continue;
			}
			
			tmp = list_get_first(command->feature_cast_exclude);
			while (tmp)
			{
				if (user_have_feature_cast_support(user, tmp))
				{
					do_send = 0;
					break;
				}
				tmp = list_get_next(command->feature_cast_exclude);
			}
			
			if (do_send)
			{
				route_to_user(hub, user, command);
			}
		}
		user = (struct hub_user*) list_get_next(hub->users->list);
	}
	
	return 0;
}
예제 #12
0
파일: hub.c 프로젝트: imobilis/uhub
void hub_send_flood_warning(struct hub_info* hub, struct hub_user* u, const char* message)
{
	struct adc_message* msg;
	char* tmp;

	if (user_flag_get(u, flag_flood))
		return;

	msg = adc_msg_construct(ADC_CMD_ISTA, 128);
	if (msg)
	{
		tmp = adc_msg_escape(message);
		adc_msg_add_argument(msg, "110");
		adc_msg_add_argument(msg, tmp);
		hub_free(tmp);

		route_to_user(hub, u, msg);
		user_flag_set(u, flag_flood);
		adc_msg_free(msg);
	}
}
예제 #13
0
파일: hub.c 프로젝트: imobilis/uhub
/**
 * @param hub The hub instance this message is sent from.
 * @param user The user this message is sent to.
 * @param msg See enum status_message
 * @param level See enum status_level
 */
void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_message msg, enum msg_status_level level)
{
	struct hub_config* cfg = hub->config;
	struct adc_message* cmd = adc_msg_construct(ADC_CMD_ISTA, 6);
	struct adc_message* qui = adc_msg_construct(ADC_CMD_IQUI, 512);
	char code[4];
	char buf[256];
	const char* text = 0;
	const char* flag = 0;
	char* escaped_text = 0;
	int reconnect_time = 0;
	int redirect = 0;

	if (!cmd || !qui)
	{
		adc_msg_free(cmd);
		adc_msg_free(qui);
		return;
	}

#define STATUS(CODE, MSG, FLAG, RCONTIME, REDIRECT) case status_ ## MSG : set_status_code(level, CODE, code); text = cfg->MSG; flag = FLAG; reconnect_time = RCONTIME; redirect = REDIRECT; break
	switch (msg)
	{
		STATUS(11, msg_hub_full, 0, 600, 1); /* FIXME: Proper timeout? */
		STATUS(12, msg_hub_disabled, 0, -1, 1);
		STATUS(26, msg_hub_registered_users_only, 0, 0, 1);
		STATUS(43, msg_inf_error_nick_missing, 0, 0, 0);
		STATUS(43, msg_inf_error_nick_multiple, 0, 0, 0);
		STATUS(21, msg_inf_error_nick_invalid, 0, 0, 0);
		STATUS(21, msg_inf_error_nick_long, 0, 0, 0);
		STATUS(21, msg_inf_error_nick_short, 0, 0, 0);
		STATUS(21, msg_inf_error_nick_spaces, 0, 0, 0);
		STATUS(21, msg_inf_error_nick_bad_chars, 0, 0, 0);
		STATUS(21, msg_inf_error_nick_not_utf8, 0, 0, 0);
		STATUS(22, msg_inf_error_nick_taken, 0, 0, 0);
		STATUS(21, msg_inf_error_nick_restricted, 0, 0, 0);
		STATUS(43, msg_inf_error_cid_invalid, "FBID", 0, 0);
		STATUS(43, msg_inf_error_cid_missing, "FMID", 0, 0);
		STATUS(24, msg_inf_error_cid_taken, 0, 0, 0);
		STATUS(43, msg_inf_error_pid_missing, "FMPD", 0, 0);
		STATUS(27, msg_inf_error_pid_invalid, "FBPD", 0, 0);
		STATUS(31, msg_ban_permanently, 0, 0, 0);
		STATUS(32, msg_ban_temporarily, "TL600", 600, 0); /* FIXME: Proper timeout? */
		STATUS(23, msg_auth_invalid_password, 0, 0, 0);
		STATUS(20, msg_auth_user_not_found, 0, 0, 0);
		STATUS(30, msg_error_no_memory, 0, 0, 0);
		STATUS(43, msg_user_share_size_low,   "FB" ADC_INF_FLAG_SHARED_SIZE, 0, 1);
		STATUS(43, msg_user_share_size_high,  "FB" ADC_INF_FLAG_SHARED_SIZE, 0, 1);
		STATUS(43, msg_user_slots_low,        "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0, 1);
		STATUS(43, msg_user_slots_high,       "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0, 1);
		STATUS(43, msg_user_hub_limit_low, 0, 0, 1);
		STATUS(43, msg_user_hub_limit_high, 0, 0, 1);
		STATUS(47, msg_proto_no_common_hash, 0, -1, 1);
		STATUS(40, msg_proto_obsolete_adc0, 0, -1, 1);
	}
#undef STATUS

	escaped_text = adc_msg_escape(text);

	adc_msg_add_argument(cmd, code);
	adc_msg_add_argument(cmd, escaped_text);

	if (flag)
	{
		adc_msg_add_argument(cmd, flag);
	}

	route_to_user(hub, user, cmd);

	if (level >= status_level_fatal)
	{
		adc_msg_add_argument(qui, sid_to_string(user->id.sid));

		snprintf(buf, 230, "MS%s", escaped_text);
		adc_msg_add_argument(qui, buf);

		if (reconnect_time != 0)
		{
			snprintf(buf, 10, "TL%d", reconnect_time);
			adc_msg_add_argument(qui, buf);
		}

		if (redirect && *hub->config->redirect_addr)
		{
			snprintf(buf, 255, "RD%s", hub->config->redirect_addr);
			adc_msg_add_argument(qui, buf);
		}
		route_to_user(hub, user, qui);
	}

	hub_free(escaped_text);
	adc_msg_free(cmd);
	adc_msg_free(qui);
}
예제 #14
0
파일: hub.c 프로젝트: imobilis/uhub
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);
	}
}
예제 #15
0
파일: hub.c 프로젝트: imobilis/uhub
int hub_handle_support(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd)
{
	int ret = 0;
	int index = 0;
	int ok = 1;
	char* arg = adc_msg_get_argument(cmd, index);

	if (hub->status == hub_status_disabled && u->state == state_protocol)
	{
		on_login_failure(hub, u, status_msg_hub_disabled);
		hub_free(arg);
		return -1;
	}

	while (arg)
	{
		if (strlen(arg) == 6)
		{
			fourcc_t fourcc = FOURCC(arg[2], arg[3], arg[4], arg[5]);
			if (strncmp(arg, ADC_SUP_FLAG_ADD, 2) == 0)
			{
				user_support_add(u, fourcc);
			}
			else if (strncmp(arg, ADC_SUP_FLAG_REMOVE, 2) == 0)
			{
				user_support_remove(u, fourcc);
			}
			else
			{
				ok = 0;
			}
		}
		else
		{
			ok = 0;
		}

		index++;
		hub_free(arg);
		arg = adc_msg_get_argument(cmd, index);
	}

	if (u->state == state_protocol)
	{
		if (index == 0) ok = 0; /* Need to support *SOMETHING*, at least BASE */
		if (!ok)
		{
			/* disconnect user. Do not send crap during initial handshake! */
			hub_disconnect_user(hub, u, quit_logon_error);
			return -1;
		}

		if (user_flag_get(u, feature_base))
		{
			/* User supports ADC/1.0 and a hash we know */
			if (user_flag_get(u, feature_tiger))
			{
				hub_send_handshake(hub, u);
				/* TODO: timeouts for mux users */
				if (u->connection)
					net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE);
			}
			else
			{
				// no common hash algorithm.
				hub_send_status(hub, u, status_msg_proto_no_common_hash, status_level_fatal);
				hub_disconnect_user(hub, u, quit_protocol_error);
			}
		}
		else if (user_flag_get(u, feature_bas0))
		{
			if (hub->config->obsolete_clients)
			{
				hub_send_handshake(hub, u);
				/* TODO: timeouts for mux users */
				if (u->connection)
					net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE);
			}
			else
			{
				/* disconnect user for using an obsolete client. */
				char* tmp = adc_msg_escape(hub->config->msg_proto_obsolete_adc0);
				struct adc_message* message = adc_msg_construct(ADC_CMD_IMSG, 6 + strlen(tmp));
				adc_msg_add_argument(message, tmp);
				hub_free(tmp);
				route_to_user(hub, u, message);
				adc_msg_free(message);
				hub_disconnect_user(hub, u, quit_protocol_error);
			}
		}
		else
		{
			/* Not speaking a compatible protocol - just disconnect. */
			hub_disconnect_user(hub, u, quit_logon_error);
		}
	}

	return ret;
}