Exemple #1
0
/**
 * This will check the ip address of the user, and
 * remove any wrong address, and replace it with the correct one
 * as seen by the hub.
 */
static int check_network(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	const char* address = user_get_address(user);

	/* Check for NAT override address */
	if (acl_is_ip_nat_override(hub->acl, address))
	{
		char* client_given_ip = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
		if (client_given_ip && strcmp(client_given_ip, "0.0.0.0") != 0)
		{
			user_set_nat_override(user);
			adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
			adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
			hub_free(client_given_ip);
			return 0;
		}
		hub_free(client_given_ip);
	}

	if (strchr(address, '.'))
	{
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
		adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
	}
	else if (strchr(address, ':'))
	{
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_UDP_PORT);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
		adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR, address);
	}
	return 0;
}
Exemple #2
0
/**
 * Perform additional INF checks used at time of login.
 *
 * @return 0 if success, <0 if error, >0 if authentication needed.
 */
int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	int code = 0;

	INF_CHECK(hub_perform_login_checks, hub, user, cmd);

	/* Private ID must never be broadcasted - drop it! */
	adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);

	code = set_credentials(hub, user, cmd);

	/* Note: this must be done *after* set_credentials. */
	if (check_is_hub_full(hub, user))
	{
		return status_msg_hub_full;
	}

	if (check_registered_users_only(hub, user))
	{
		return status_msg_hub_registered_users_only;
	}

	INF_CHECK(check_limits, hub, user, cmd);

	/* strip off stuff if low_bandwidth_mode is enabled */
	hub_handle_info_low_bandwidth(hub, user, cmd);

	/* Set initial user info */
	user_set_info(user, cmd);

	return code;
}
Exemple #3
0
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;
}
Exemple #4
0
/*
 * These flags can only be set by the hub.
 * Make sure we don't allow clients to specify these themselves.
 *
 * NOTE: Some of them are legacy ADC flags and no longer used, these
 * should be removed at some point in the future when functionality no
 * longer depend on them.
 */
static void remove_server_restricted_flags(struct adc_message* cmd)
{
	adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE); /* Client type flag (CT, obsoletes BO, RG, OP, HU) */
	adc_msg_remove_named_argument(cmd, "BO"); /* Obsolete: bot flag (CT) */
	adc_msg_remove_named_argument(cmd, "RG"); /* Obsolete: registered user flag (CT) */
	adc_msg_remove_named_argument(cmd, "OP"); /* Obsolete: operator flag (CT) */
	adc_msg_remove_named_argument(cmd, "HU"); /* Obsolete: hub flag (CT) */
	adc_msg_remove_named_argument(cmd, "HI"); /* Obsolete: hidden user flag */
	adc_msg_remove_named_argument(cmd, "TO"); /* Client to client token - should not be seen here */
	adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_REFERER);
}
Exemple #5
0
/*
 * If user is in the connecting state, we need to do fairly
 * strict checking of all arguments.
 * This means we disconnect users when they provide invalid data
 * during the login sequence.
 * When users are merely updating their data after successful login
 * we can just ignore any invalid data and not broadcast it.
 *
 * The data we need to check is:
 * - nick name (valid, not taken, etc)
 * - CID/PID (valid, not taken, etc).
 * - IP addresses (IPv4 and IPv6)
 */
int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct adc_message* cmd_unmodified)
{
	int ret;
	struct adc_message* cmd = adc_msg_copy(cmd_unmodified);
	if (!cmd) return -1; /* OOM */

	cmd->priority = 1;

	hub_handle_info_common(user, cmd);

	/* If user is logging in, perform more checks,
	   otherwise only a few things need to be checked.
	 */
	if (user_is_connecting(user))
	{
		/*
		 * Don't allow the user to send multiple INF messages in this stage!
		 * Since that can have serious side-effects.
		 */
		if (user->info)
		{
			adc_msg_free(cmd);
			return 0;
		}

		ret = hub_handle_info_login(hub, user, cmd);
		if (ret < 0)
		{
			on_login_failure(hub, user, ret);
			adc_msg_free(cmd);
			return -1;
		}
		else
		{
			/* Post a message, the user has joined */
			struct event_data post;
			memset(&post, 0, sizeof(post));
			post.id    = UHUB_EVENT_USER_JOIN;
			post.ptr   = user;
			post.flags = ret; /* 0 - all OK, 1 - need authentication */
			event_queue_post(hub->queue, &post);
			adc_msg_free(cmd);
			return 0;
		}
	}
	else
	{
		/* These must not be allowed updated, let's remove them! */
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);

		/*
		 * If the nick is not accepted, do not relay it.
		 * Otherwise, the nickname will be updated.
		 */
		if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_NICK))
		{
#ifdef ALLOW_CHANGE_NICK
			if (!check_nick(hub, user, cmd))
#endif
				adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_NICK);
		}

		ret = check_limits(hub, user, cmd);
		if (ret < 0)
		{
			on_update_failure(hub, user, ret);
			adc_msg_free(cmd);
			return -1;
		}

		strip_network(user, cmd);
		hub_handle_info_low_bandwidth(hub, user, cmd);

		user_update_info(user, cmd);

		if (!adc_msg_is_empty(cmd))
		{
			route_message(hub, user, cmd);
		}

		adc_msg_free(cmd);
	}

	return 0;
}
Exemple #6
0
static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	if (hub->config->low_bandwidth_mode)
	{
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SPEED);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_DOWNLOAD_SPEED);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AUTO_SLOTS);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AUTO_SLOTS_MAX);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AWAY);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_DESCRIPTION);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_EMAIL);
	}

	return 0;
}
Exemple #7
0
static void strip_network(struct hub_user* user, struct adc_message* cmd)
{
	adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
	adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
}