Fix bug #108: share limits can be avoided.

This was due to updates to the share limit not being enforced after a succesful login.
This commit is contained in:
Jan Vidar Krey 2010-02-07 23:08:04 +01:00
parent 78ae9fb3ce
commit 8065903604
7 changed files with 88 additions and 50 deletions

View File

@ -825,63 +825,79 @@ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_me
{
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, 256);
char code[4];
char buf[250];
const char* text = 0;
const char* flag = 0;
char* escaped_text = 0;
int reconnect_time = 0;
if (!cmd) return;
#define STATUS(CODE, MSG, FLAG) case status_ ## MSG : set_status_code(level, CODE, code); text = cfg->MSG; flag = FLAG; break
#define STATUS(CODE, MSG, FLAG, RCONTIME) case status_ ## MSG : set_status_code(level, CODE, code); text = cfg->MSG; flag = FLAG; reconnect_time = RCONTIME; break
switch (msg)
{
STATUS(11, msg_hub_full, 0);
STATUS(12, msg_hub_disabled, 0);
STATUS(26, msg_hub_registered_users_only, 0);
STATUS(43, msg_inf_error_nick_missing, 0);
STATUS(43, msg_inf_error_nick_multiple, 0);
STATUS(21, msg_inf_error_nick_invalid, 0);
STATUS(21, msg_inf_error_nick_long, 0);
STATUS(21, msg_inf_error_nick_short, 0);
STATUS(21, msg_inf_error_nick_spaces, 0);
STATUS(21, msg_inf_error_nick_bad_chars, 0);
STATUS(21, msg_inf_error_nick_not_utf8, 0);
STATUS(22, msg_inf_error_nick_taken, 0);
STATUS(21, msg_inf_error_nick_restricted, 0);
STATUS(43, msg_inf_error_cid_invalid, "FBID");
STATUS(43, msg_inf_error_cid_missing, "FMID");
STATUS(24, msg_inf_error_cid_taken, 0);
STATUS(43, msg_inf_error_pid_missing, "FMPD");
STATUS(27, msg_inf_error_pid_invalid, "FBPD");
STATUS(31, msg_ban_permanently, 0);
STATUS(32, msg_ban_temporarily, "TL600"); /* FIXME: Use a proper timeout */
STATUS(23, msg_auth_invalid_password, 0);
STATUS(20, msg_auth_user_not_found, 0);
STATUS(30, msg_error_no_memory, 0);
STATUS(43, msg_user_share_size_low, "FB" ADC_INF_FLAG_SHARED_SIZE);
STATUS(43, msg_user_share_size_high, "FB" ADC_INF_FLAG_SHARED_SIZE);
STATUS(43, msg_user_slots_low, "FB" ADC_INF_FLAG_UPLOAD_SLOTS);
STATUS(43, msg_user_slots_high, "FB" ADC_INF_FLAG_UPLOAD_SLOTS);
STATUS(43, msg_user_hub_limit_low, 0);
STATUS(43, msg_user_hub_limit_high, 0);
STATUS(11, msg_hub_full, 0, 600); /* FIXME: Proper timeout? */
STATUS(12, msg_hub_disabled, 0, -1);
STATUS(26, msg_hub_registered_users_only, 0, 0);
STATUS(43, msg_inf_error_nick_missing, 0, 0);
STATUS(43, msg_inf_error_nick_multiple, 0, 0);
STATUS(21, msg_inf_error_nick_invalid, 0, 0);
STATUS(21, msg_inf_error_nick_long, 0, 0);
STATUS(21, msg_inf_error_nick_short, 0, 0);
STATUS(21, msg_inf_error_nick_spaces, 0, 0);
STATUS(21, msg_inf_error_nick_bad_chars, 0, 0);
STATUS(21, msg_inf_error_nick_not_utf8, 0, 0);
STATUS(22, msg_inf_error_nick_taken, 0, 0);
STATUS(21, msg_inf_error_nick_restricted, 0, 0);
STATUS(43, msg_inf_error_cid_invalid, "FBID", 0);
STATUS(43, msg_inf_error_cid_missing, "FMID", 0);
STATUS(24, msg_inf_error_cid_taken, 0, 0);
STATUS(43, msg_inf_error_pid_missing, "FMPD", 0);
STATUS(27, msg_inf_error_pid_invalid, "FBPD", 0);
STATUS(31, msg_ban_permanently, 0, 0);
STATUS(32, msg_ban_temporarily, "TL600", 600); /* FIXME: Proper timeout? */
STATUS(23, msg_auth_invalid_password, 0, 0);
STATUS(20, msg_auth_user_not_found, 0, 0);
STATUS(30, msg_error_no_memory, 0, 0);
STATUS(43, msg_user_share_size_low, "FB" ADC_INF_FLAG_SHARED_SIZE, 0);
STATUS(43, msg_user_share_size_high, "FB" ADC_INF_FLAG_SHARED_SIZE, 0);
STATUS(43, msg_user_slots_low, "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0);
STATUS(43, msg_user_slots_high, "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0);
STATUS(43, msg_user_hub_limit_low, 0, 0);
STATUS(43, msg_user_hub_limit_high, 0, 0);
}
#undef STATUS
escaped_text = adc_msg_escape(text);
adc_msg_add_argument(cmd, code);
adc_msg_add_argument(cmd, escaped_text);
hub_free(escaped_text);
if (flag)
{
adc_msg_add_argument(cmd, flag);
}
route_to_user(hub, user, cmd);
if (level >= status_level_fatal)
{
snprintf(buf, 230, "MS%s", escaped_text);
adc_msg_add_argument(cmd, buf);
if (reconnect_time != 0)
{
snprintf(buf, 10, "TL%d", reconnect_time);
adc_msg_add_argument(cmd, buf);
}
route_to_user(hub, user, cmd);
}
hub_free(escaped_text);
adc_msg_free(cmd);
adc_msg_free(qui);
}
const char* hub_get_status_message(struct hub_info* hub, enum status_message msg)

View File

@ -45,7 +45,7 @@ enum status_message
status_msg_auth_invalid_password = -21, /* Password is wrong */
status_msg_auth_user_not_found = -22, /* User not found in password database */
status_msg_error_no_memory = -23, /* Hub is out of memory */
status_msg_user_share_size_low = -40, /* User is not sharing enough. */
status_msg_user_share_size_high = -41, /* User is sharing too much. */
status_msg_user_slots_low = -42, /* User has too few slots open. */

View File

@ -33,6 +33,13 @@ static void log_user_login_error(struct hub_user* u, enum status_message msg)
LOG_USER("LoginError %s/%s %s \"%s\" (%s) \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, message, u->user_agent);
}
static void log_user_update_error(struct hub_user* u, enum status_message msg)
{
const char* addr = user_get_address(u);
const char* message = hub_get_status_message_log(u->hub, msg);
LOG_USER("UpdateError %s/%s %s \"%s\" (%s) \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, message, u->user_agent);
}
static void log_user_logout(struct hub_user* u, const char* message)
{
const char* addr = user_get_address(u);
@ -83,6 +90,13 @@ void on_login_failure(struct hub_info* hub, struct hub_user* u, enum status_mess
hub_disconnect_user(hub, u, quit_logon_error);
}
void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
{
log_user_update_error(u, msg);
hub_send_status(hub, u, msg, status_level_fatal);
hub_disconnect_user(hub, u, quit_update_error);
}
void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick)
{
if (user_is_logged_in(u))

View File

@ -29,6 +29,7 @@ extern void on_login_success(struct hub_info* hub, struct hub_user* u);
* This event is triggered whenever a user failed to log in to the hub.
*/
extern void on_login_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg);
extern void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg);
/**
* This event is triggered whenever a previously logged in user leaves the hub.

View File

@ -187,7 +187,7 @@ static int check_required_login_flags(struct hub_info* hub, struct hub_user* use
* remove any wrong address, and replace it with the correct one
* as seen by the hub.
*/
int check_network(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
static int check_network(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
const char* address = user_get_address(user);
@ -223,7 +223,7 @@ int check_network(struct hub_info* hub, struct hub_user* user, struct adc_messag
return 0;
}
void strip_network(struct hub_user* user, struct adc_message* cmd)
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_IPV6_UDP_PORT);
@ -526,7 +526,6 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_
return 0;
}
/*
* Set the expected credentials, and returns 1 if authentication is needed,
* or 0 if not.
@ -648,7 +647,7 @@ static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct hub_user*
return ret; \
} while(0)
int hub_perform_login_checks(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
static int hub_perform_login_checks(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
/* Make syntax checks. */
INF_CHECK(check_required_login_flags, hub, user, cmd);
@ -666,7 +665,7 @@ int hub_perform_login_checks(struct hub_info* hub, struct hub_user* user, struct
*
* @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)
static int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
int code = 0;
@ -737,7 +736,7 @@ int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct ad
adc_msg_free(cmd);
return 0;
}
ret = hub_handle_info_login(hub, user, cmd);
if (ret < 0)
{
@ -763,7 +762,7 @@ int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct ad
/* 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.
@ -775,9 +774,15 @@ int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct ad
#endif
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_NICK);
}
/* FIXME - What if limits are not met ? */
check_limits(hub, user, cmd);
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);

View File

@ -336,6 +336,7 @@ const char* user_get_quit_reason_string(enum user_quit_reason reason)
case quit_socket_error: return "socket error"; break;
case quit_protocol_error: return "protocol error"; break;
case quit_logon_error: return "login error"; break;
case quit_update_error: return "update error"; break;
case quit_hub_disabled: return "hub disabled"; break;
case quit_ghost_timeout: return "ghost"; break;
}

View File

@ -68,8 +68,9 @@ enum user_quit_reason
quit_socket_error = 7, /** A socket error occured */
quit_protocol_error = 8, /** Fatal protocol error */
quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */
quit_hub_disabled = 10, /** Hub is disabled. No new connections allowed */
quit_ghost_timeout = 11, /** The user is a ghost, and trying to login from another connection */
quit_update_error = 10, /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */
quit_hub_disabled = 11, /** Hub is disabled. No new connections allowed */
quit_ghost_timeout = 12, /** The user is a ghost, and trying to login from another connection */
};
/** Returns an apropriate string for the given quit reason */