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,45 +825,48 @@ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_me
{ {
struct hub_config* cfg = hub->config; struct hub_config* cfg = hub->config;
struct adc_message* cmd = adc_msg_construct(ADC_CMD_ISTA, 6); 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 code[4];
char buf[250];
const char* text = 0; const char* text = 0;
const char* flag = 0; const char* flag = 0;
char* escaped_text = 0; char* escaped_text = 0;
int reconnect_time = 0;
if (!cmd) return; 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) switch (msg)
{ {
STATUS(11, msg_hub_full, 0); STATUS(11, msg_hub_full, 0, 600); /* FIXME: Proper timeout? */
STATUS(12, msg_hub_disabled, 0); STATUS(12, msg_hub_disabled, 0, -1);
STATUS(26, msg_hub_registered_users_only, 0); STATUS(26, msg_hub_registered_users_only, 0, 0);
STATUS(43, msg_inf_error_nick_missing, 0); STATUS(43, msg_inf_error_nick_missing, 0, 0);
STATUS(43, msg_inf_error_nick_multiple, 0); STATUS(43, msg_inf_error_nick_multiple, 0, 0);
STATUS(21, msg_inf_error_nick_invalid, 0); STATUS(21, msg_inf_error_nick_invalid, 0, 0);
STATUS(21, msg_inf_error_nick_long, 0); STATUS(21, msg_inf_error_nick_long, 0, 0);
STATUS(21, msg_inf_error_nick_short, 0); STATUS(21, msg_inf_error_nick_short, 0, 0);
STATUS(21, msg_inf_error_nick_spaces, 0); STATUS(21, msg_inf_error_nick_spaces, 0, 0);
STATUS(21, msg_inf_error_nick_bad_chars, 0); STATUS(21, msg_inf_error_nick_bad_chars, 0, 0);
STATUS(21, msg_inf_error_nick_not_utf8, 0); STATUS(21, msg_inf_error_nick_not_utf8, 0, 0);
STATUS(22, msg_inf_error_nick_taken, 0); STATUS(22, msg_inf_error_nick_taken, 0, 0);
STATUS(21, msg_inf_error_nick_restricted, 0); STATUS(21, msg_inf_error_nick_restricted, 0, 0);
STATUS(43, msg_inf_error_cid_invalid, "FBID"); STATUS(43, msg_inf_error_cid_invalid, "FBID", 0);
STATUS(43, msg_inf_error_cid_missing, "FMID"); STATUS(43, msg_inf_error_cid_missing, "FMID", 0);
STATUS(24, msg_inf_error_cid_taken, 0); STATUS(24, msg_inf_error_cid_taken, 0, 0);
STATUS(43, msg_inf_error_pid_missing, "FMPD"); STATUS(43, msg_inf_error_pid_missing, "FMPD", 0);
STATUS(27, msg_inf_error_pid_invalid, "FBPD"); STATUS(27, msg_inf_error_pid_invalid, "FBPD", 0);
STATUS(31, msg_ban_permanently, 0); STATUS(31, msg_ban_permanently, 0, 0);
STATUS(32, msg_ban_temporarily, "TL600"); /* FIXME: Use a proper timeout */ STATUS(32, msg_ban_temporarily, "TL600", 600); /* FIXME: Proper timeout? */
STATUS(23, msg_auth_invalid_password, 0); STATUS(23, msg_auth_invalid_password, 0, 0);
STATUS(20, msg_auth_user_not_found, 0); STATUS(20, msg_auth_user_not_found, 0, 0);
STATUS(30, msg_error_no_memory, 0); STATUS(30, msg_error_no_memory, 0, 0);
STATUS(43, msg_user_share_size_low, "FB" ADC_INF_FLAG_SHARED_SIZE); 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); 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); 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); STATUS(43, msg_user_slots_high, "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0);
STATUS(43, msg_user_hub_limit_low, 0); STATUS(43, msg_user_hub_limit_low, 0, 0);
STATUS(43, msg_user_hub_limit_high, 0); STATUS(43, msg_user_hub_limit_high, 0, 0);
} }
#undef STATUS #undef STATUS
@ -872,16 +875,29 @@ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_me
adc_msg_add_argument(cmd, code); adc_msg_add_argument(cmd, code);
adc_msg_add_argument(cmd, escaped_text); adc_msg_add_argument(cmd, escaped_text);
hub_free(escaped_text);
if (flag) if (flag)
{ {
adc_msg_add_argument(cmd, flag); adc_msg_add_argument(cmd, flag);
} }
route_to_user(hub, user, cmd); route_to_user(hub, user, cmd);
adc_msg_free(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) const char* hub_get_status_message(struct hub_info* hub, enum status_message msg)

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); 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) static void log_user_logout(struct hub_user* u, const char* message)
{ {
const char* addr = user_get_address(u); 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); 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) void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick)
{ {
if (user_is_logged_in(u)) 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. * 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_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. * 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 * remove any wrong address, and replace it with the correct one
* as seen by the hub. * 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); 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; 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_ADDR);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT); 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; return 0;
} }
/* /*
* Set the expected credentials, and returns 1 if authentication is needed, * Set the expected credentials, and returns 1 if authentication is needed,
* or 0 if not. * or 0 if not.
@ -648,7 +647,7 @@ static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct hub_user*
return ret; \ return ret; \
} while(0) } 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. */ /* Make syntax checks. */
INF_CHECK(check_required_login_flags, hub, user, cmd); 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. * @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; int code = 0;
@ -776,8 +775,14 @@ int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct ad
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_NICK); adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_NICK);
} }
/* FIXME - What if limits are not met ? */ ret = check_limits(hub, user, cmd);
check_limits(hub, user, cmd); if (ret < 0)
{
on_update_failure(hub, user, ret);
adc_msg_free(cmd);
return -1;
}
strip_network(user, cmd); strip_network(user, cmd);
hub_handle_info_low_bandwidth(hub, 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_socket_error: return "socket error"; break;
case quit_protocol_error: return "protocol error"; break; case quit_protocol_error: return "protocol error"; break;
case quit_logon_error: return "login 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_hub_disabled: return "hub disabled"; break;
case quit_ghost_timeout: return "ghost"; 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_socket_error = 7, /** A socket error occured */
quit_protocol_error = 8, /** Fatal protocol error */ quit_protocol_error = 8, /** Fatal protocol error */
quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */ quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */
quit_hub_disabled = 10, /** Hub is disabled. No new connections allowed */ quit_update_error = 10, /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */
quit_ghost_timeout = 11, /** The user is a ghost, and trying to login from another connection */ 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 */ /** Returns an apropriate string for the given quit reason */