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); } }
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); } }
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; }
void net_event(struct net_connection* con, int event, void *arg) { struct hub_user* user = (struct hub_user*) arg; int flag_close = 0; #ifdef DEBUG_SENDQ LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg); #endif if (event == NET_EVENT_TIMEOUT) { if (user_is_connecting(user)) { hub_disconnect_user(g_hub, user, quit_timeout); } return; } if (event & NET_EVENT_READ) { flag_close = handle_net_read(user); if (flag_close) { hub_disconnect_user(g_hub, user, flag_close); return; } } if (event & NET_EVENT_WRITE) { flag_close = handle_net_write(user); if (flag_close) { hub_disconnect_user(g_hub, user, flag_close); return; } } }
/* * 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; }
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); } }