Esempio n. 1
0
File: inf.c Progetto: tehnick/uhub
/*
 * It is possible to do user-agent checking here.
 * But this is not something we want to do, and is deprecated in the ADC specification.
 * One should rather look at capabilities/features.
 */
static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	char* ua_name_encoded = 0;
	char* ua_version_encoded = 0;
	char* str = 0;
	size_t offset = 0;

	/* Get client user agent version */
	ua_name_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT);
	ua_version_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION);
	if (ua_name_encoded)
	{
		str = adc_msg_unescape(ua_name_encoded);
		if (str)
		{
			offset = strlen(str);
			memcpy(user->id.user_agent, str, MIN(offset, MAX_UA_LEN));
			hub_free(str);
		}
	}

	if (ua_version_encoded)
	{
		str = adc_msg_unescape(ua_version_encoded);
		if (str)
		{
			memcpy(user->id.user_agent + offset, str, MIN(strlen(str), MAX_UA_LEN - offset));
			hub_free(str);
		}
	}

	hub_free(ua_name_encoded);
	hub_free(ua_version_encoded);
	return 0;
}
Esempio n. 2
0
File: inf.c Progetto: leejb521/uhub
/*
 * FIXME: Only works for tiger hash. If a client doesnt support tiger we cannot let it in!
 */
static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	size_t pos;
	char* cid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
	char* pid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);

	if (!cid || !pid)
	{
		hub_free(cid);
		hub_free(pid);
		return status_msg_error_no_memory;
	}

	if (strlen(cid) != MAX_CID_LEN)
	{
		hub_free(cid);
		hub_free(pid);
		return status_msg_inf_error_cid_invalid;
	}

	if (strlen(pid) != MAX_CID_LEN)
	{
		hub_free(cid);
		hub_free(pid);
		return status_msg_inf_error_pid_invalid;
	}

	for (pos = 0; pos < MAX_CID_LEN; pos++)
	{
		if (!is_valid_base32_char(cid[pos]))
		{
			hub_free(cid);
			hub_free(pid);
			return status_msg_inf_error_cid_invalid;
		}

		if (!is_valid_base32_char(pid[pos]))
		{
			hub_free(cid);
			hub_free(pid);
			return status_msg_inf_error_pid_invalid;
		}
	}

	if (!check_hash_tiger(cid, pid))
	{
		hub_free(cid);
		hub_free(pid);
		return status_msg_inf_error_cid_invalid;
	}

	/* Set the cid in the user object */
	memcpy(user->id.cid, cid, MAX_CID_LEN);
	user->id.cid[MAX_CID_LEN] = 0;

	hub_free(cid);
	hub_free(pid);
	return 0;
}
Esempio n. 3
0
File: inf.c Progetto: leejb521/uhub
static int set_feature_cast_supports(struct hub_user* u, struct adc_message* cmd)
{
	char *it, *tmp;

	if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_SUPPORT))
	{
		tmp = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SUPPORT);
		if (!tmp)
			return -1; // FIXME: OOM

		user_clear_feature_cast_support(u);

		it = tmp;
		while (strlen(it) > 4)
		{
			it[4] = 0; /* FIXME: Not really needed */
			user_set_feature_cast_support(u, it);
			it = &it[5];
		}

		if (*it)
		{
			user_set_feature_cast_support(u, it);
		}
		hub_free(tmp);
	}
	return 0;
}
Esempio n. 4
0
File: inf.c Progetto: leejb521/uhub
/**
 * 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;
}
Esempio n. 5
0
File: inf.c Progetto: leejb521/uhub
static int check_nick(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	char* nick;
	char* tmp;
	enum nick_status status;

	tmp = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_NICK);
	if (!tmp) return 0;
	nick = adc_msg_unescape(tmp);
	free(tmp); tmp = 0;
	if (!nick) return 0;

	status = nick_length_ok(nick);
	if (status != nick_ok)
	{
		hub_free(nick);
		if (status == nick_invalid_short)
			return status_msg_inf_error_nick_short;
		return status_msg_inf_error_nick_long;
	}

	status = nick_bad_characters(nick);
	if (status != nick_ok)
	{
		hub_free(nick);
		if (status == nick_invalid_spaces)
			return status_msg_inf_error_nick_spaces;
		return status_msg_inf_error_nick_bad_chars;
	}

	status = nick_is_utf8(nick);
	if (status != nick_ok)
	{
		hub_free(nick);
		return status_msg_inf_error_nick_not_utf8;
	}

	if (user_is_connecting(user))
	{
		memcpy(user->id.nick, nick, strlen(nick));
		user->id.nick[strlen(nick)] = 0;
	}

	hub_free(nick);
	return 0;
}
Esempio n. 6
0
File: inf.c Progetto: leejb521/uhub
/*
 * It is possible to do user-agent checking here.
 * But this is not something we want to do, and is deprecated in the ADC specification.
 * One should rather look at capabilities/features.
 */
static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	char* ua_encoded = 0;
	char* ua = 0;

	/* Get client user agent version */
	ua_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT);
	if (ua_encoded)
	{
		ua = adc_msg_unescape(ua_encoded);
		if (ua)
		{
			memcpy(user->id.user_agent, ua, MIN(strlen(ua), MAX_UA_LEN));
			hub_free(ua);
		}
	}
	hub_free(ua_encoded);
	return 0;
}
Esempio n. 7
0
File: inf.c Progetto: leejb521/uhub
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;
}