void hub_set_variables(struct hub_info* hub, struct acl_handle* acl) { char* tmp; char* server = adc_msg_escape(PRODUCT_STRING); /* FIXME: OOM */ hub->acl = acl; hub->command_info = adc_msg_construct(ADC_CMD_IINF, 15); if (hub->command_info) { adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_CLIENT_TYPE, ADC_CLIENT_TYPE_HUB); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_PRODUCT, PRODUCT); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_VERSION, GIT_VERSION); tmp = adc_msg_escape(hub->config->hub_name); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_NICK, tmp); hub_free(tmp); tmp = adc_msg_escape(hub->config->hub_description); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_DESCRIPTION, tmp); hub_free(tmp); } hub->command_support = adc_msg_construct(ADC_CMD_ISUP, 6 + strlen(ADC_PROTO_SUPPORT)); if (hub->command_support) { adc_msg_add_argument(hub->command_support, ADC_PROTO_SUPPORT); } hub->command_banner = adc_msg_construct(ADC_CMD_ISTA, 100 + strlen(server)); if (hub->command_banner) { if (hub->config->show_banner_sys_info) tmp = adc_msg_escape("Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO); else tmp = adc_msg_escape("Powered by " PRODUCT_STRING); adc_msg_add_argument(hub->command_banner, "000"); adc_msg_add_argument(hub->command_banner, tmp); hub_free(tmp); } if (hub_plugins_load(hub) < 0) { LOG_FATAL("Unable to load plugins."); hub->status = hub_status_shutdown; } else hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled); hub_free(server); }
void hub_send_password_challenge(struct hub_info* hub, struct hub_user* u) { struct adc_message* igpa; igpa = adc_msg_construct(ADC_CMD_IGPA, 38); adc_msg_add_argument(igpa, acl_password_generate_challenge(hub, u)); user_set_state(u, state_verify); route_to_user(hub, u, igpa); adc_msg_free(igpa); }
void hub_send_ping(struct hub_info* hub, struct hub_user* user) { /* This will just send a newline, despite appearing to do more below. */ struct adc_message* ping = adc_msg_construct(0, 0); ping->cache[0] = '\n'; ping->cache[1] = 0; ping->length = 1; ping->priority = 1; route_to_user(hub, user, ping); adc_msg_free(ping); }
void uman_send_quit_message(struct hub_info* hub, struct hub_user* leaving) { struct adc_message* command = adc_msg_construct(ADC_CMD_IQUI, 6); adc_msg_add_argument(command, (const char*) sid_to_string(leaving->id.sid)); if (leaving->quit_reason == quit_banned || leaving->quit_reason == quit_kicked) { adc_msg_add_argument(command, ADC_QUI_FLAG_DISCONNECT); } route_to_all(hub, command); adc_msg_free(command); }
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); } }
void hub_send_flood_warning(struct hub_info* hub, struct hub_user* u, const char* message) { struct adc_message* msg; char* tmp; if (user_flag_get(u, flag_flood)) return; msg = adc_msg_construct(ADC_CMD_ISTA, 128); if (msg) { tmp = adc_msg_escape(message); adc_msg_add_argument(msg, "110"); adc_msg_add_argument(msg, tmp); hub_free(tmp); route_to_user(hub, u, msg); user_flag_set(u, flag_flood); adc_msg_free(msg); } }
/** * @param hub The hub instance this message is sent from. * @param user The user this message is sent to. * @param msg See enum status_message * @param level See enum status_level */ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_message msg, enum msg_status_level level) { 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, 512); char code[4]; char buf[256]; const char* text = 0; const char* flag = 0; char* escaped_text = 0; int reconnect_time = 0; int redirect = 0; if (!cmd || !qui) { adc_msg_free(cmd); adc_msg_free(qui); return; } #define STATUS(CODE, MSG, FLAG, RCONTIME, REDIRECT) case status_ ## MSG : set_status_code(level, CODE, code); text = cfg->MSG; flag = FLAG; reconnect_time = RCONTIME; redirect = REDIRECT; break switch (msg) { STATUS(11, msg_hub_full, 0, 600, 1); /* FIXME: Proper timeout? */ STATUS(12, msg_hub_disabled, 0, -1, 1); STATUS(26, msg_hub_registered_users_only, 0, 0, 1); STATUS(43, msg_inf_error_nick_missing, 0, 0, 0); STATUS(43, msg_inf_error_nick_multiple, 0, 0, 0); STATUS(21, msg_inf_error_nick_invalid, 0, 0, 0); STATUS(21, msg_inf_error_nick_long, 0, 0, 0); STATUS(21, msg_inf_error_nick_short, 0, 0, 0); STATUS(21, msg_inf_error_nick_spaces, 0, 0, 0); STATUS(21, msg_inf_error_nick_bad_chars, 0, 0, 0); STATUS(21, msg_inf_error_nick_not_utf8, 0, 0, 0); STATUS(22, msg_inf_error_nick_taken, 0, 0, 0); STATUS(21, msg_inf_error_nick_restricted, 0, 0, 0); STATUS(43, msg_inf_error_cid_invalid, "FBID", 0, 0); STATUS(43, msg_inf_error_cid_missing, "FMID", 0, 0); STATUS(24, msg_inf_error_cid_taken, 0, 0, 0); STATUS(43, msg_inf_error_pid_missing, "FMPD", 0, 0); STATUS(27, msg_inf_error_pid_invalid, "FBPD", 0, 0); STATUS(31, msg_ban_permanently, 0, 0, 0); STATUS(32, msg_ban_temporarily, "TL600", 600, 0); /* FIXME: Proper timeout? */ STATUS(23, msg_auth_invalid_password, 0, 0, 0); STATUS(20, msg_auth_user_not_found, 0, 0, 0); STATUS(30, msg_error_no_memory, 0, 0, 0); STATUS(43, msg_user_share_size_low, "FB" ADC_INF_FLAG_SHARED_SIZE, 0, 1); STATUS(43, msg_user_share_size_high, "FB" ADC_INF_FLAG_SHARED_SIZE, 0, 1); STATUS(43, msg_user_slots_low, "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0, 1); STATUS(43, msg_user_slots_high, "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0, 1); STATUS(43, msg_user_hub_limit_low, 0, 0, 1); STATUS(43, msg_user_hub_limit_high, 0, 0, 1); STATUS(47, msg_proto_no_common_hash, 0, -1, 1); STATUS(40, msg_proto_obsolete_adc0, 0, -1, 1); } #undef STATUS escaped_text = adc_msg_escape(text); adc_msg_add_argument(cmd, code); adc_msg_add_argument(cmd, escaped_text); if (flag) { adc_msg_add_argument(cmd, flag); } route_to_user(hub, user, cmd); if (level >= status_level_fatal) { adc_msg_add_argument(qui, sid_to_string(user->id.sid)); snprintf(buf, 230, "MS%s", escaped_text); adc_msg_add_argument(qui, buf); if (reconnect_time != 0) { snprintf(buf, 10, "TL%d", reconnect_time); adc_msg_add_argument(qui, buf); } if (redirect && *hub->config->redirect_addr) { snprintf(buf, 255, "RD%s", hub->config->redirect_addr); adc_msg_add_argument(qui, buf); } route_to_user(hub, user, qui); } hub_free(escaped_text); adc_msg_free(cmd); adc_msg_free(qui); }
int hub_handle_support(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd) { int ret = 0; int index = 0; int ok = 1; char* arg = adc_msg_get_argument(cmd, index); if (hub->status == hub_status_disabled && u->state == state_protocol) { on_login_failure(hub, u, status_msg_hub_disabled); hub_free(arg); return -1; } while (arg) { if (strlen(arg) == 6) { fourcc_t fourcc = FOURCC(arg[2], arg[3], arg[4], arg[5]); if (strncmp(arg, ADC_SUP_FLAG_ADD, 2) == 0) { user_support_add(u, fourcc); } else if (strncmp(arg, ADC_SUP_FLAG_REMOVE, 2) == 0) { user_support_remove(u, fourcc); } else { ok = 0; } } else { ok = 0; } index++; hub_free(arg); arg = adc_msg_get_argument(cmd, index); } if (u->state == state_protocol) { if (index == 0) ok = 0; /* Need to support *SOMETHING*, at least BASE */ if (!ok) { /* disconnect user. Do not send crap during initial handshake! */ hub_disconnect_user(hub, u, quit_logon_error); return -1; } if (user_flag_get(u, feature_base)) { /* User supports ADC/1.0 and a hash we know */ if (user_flag_get(u, feature_tiger)) { hub_send_handshake(hub, u); /* TODO: timeouts for mux users */ if (u->connection) net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE); } else { // no common hash algorithm. hub_send_status(hub, u, status_msg_proto_no_common_hash, status_level_fatal); hub_disconnect_user(hub, u, quit_protocol_error); } } else if (user_flag_get(u, feature_bas0)) { if (hub->config->obsolete_clients) { hub_send_handshake(hub, u); /* TODO: timeouts for mux users */ if (u->connection) net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE); } else { /* disconnect user for using an obsolete client. */ char* tmp = adc_msg_escape(hub->config->msg_proto_obsolete_adc0); struct adc_message* message = adc_msg_construct(ADC_CMD_IMSG, 6 + strlen(tmp)); adc_msg_add_argument(message, tmp); hub_free(tmp); route_to_user(hub, u, message); adc_msg_free(message); hub_disconnect_user(hub, u, quit_protocol_error); } } else { /* Not speaking a compatible protocol - just disconnect. */ hub_disconnect_user(hub, u, quit_logon_error); } } return ret; }
void hub_set_variables(struct hub_info* hub, struct acl_handle* acl) { int fd, ret; char buf[MAX_RECV_BUF]; char* tmp; char* server = adc_msg_escape(PRODUCT_STRING); /* FIXME: OOM */ hub->acl = acl; hub->command_info = adc_msg_construct(ADC_CMD_IINF, 15); if (hub->command_info) { adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_CLIENT_TYPE, ADC_CLIENT_TYPE_HUB); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT, server); tmp = adc_msg_escape(hub->config->hub_name); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_NICK, tmp); hub_free(tmp); tmp = adc_msg_escape(hub->config->hub_description); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_DESCRIPTION, tmp); hub_free(tmp); } /* (Re-)read the message of the day */ hub->command_motd = 0; fd = (hub->config->file_motd && *hub->config->file_motd) ? open(hub->config->file_motd, 0) : -1; if (fd != -1) { ret = read(fd, buf, MAX_RECV_BUF); if (ret > 0) { buf[ret] = 0; tmp = adc_msg_escape(buf); hub->command_motd = adc_msg_construct(ADC_CMD_IMSG, 6 + strlen(tmp)); adc_msg_add_argument(hub->command_motd, tmp); hub_free(tmp); } close(fd); } hub->command_rules = 0; fd = (hub->config->file_rules && *hub->config->file_rules) ? open(hub->config->file_rules, 0) : -1; if (fd != -1) { ret = read(fd, buf, MAX_RECV_BUF); if (ret > 0) { buf[ret] = 0; tmp = adc_msg_escape(buf); hub->command_rules = adc_msg_construct(ADC_CMD_IMSG, 6 + strlen(tmp)); adc_msg_add_argument(hub->command_rules, tmp); hub_free(tmp); } close(fd); } hub->command_support = adc_msg_construct(ADC_CMD_ISUP, 6 + strlen(ADC_PROTO_SUPPORT)); if (hub->command_support) { adc_msg_add_argument(hub->command_support, ADC_PROTO_SUPPORT); } hub->command_banner = adc_msg_construct(ADC_CMD_ISTA, 100 + strlen(server)); if (hub->command_banner) { if (hub->config->show_banner_sys_info) tmp = adc_msg_escape("Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO); else tmp = adc_msg_escape("Powered by " PRODUCT_STRING); adc_msg_add_argument(hub->command_banner, "000"); adc_msg_add_argument(hub->command_banner, tmp); hub_free(tmp); } #ifdef PLUGIN_SUPPORT hub_plugins_load(hub); #endif hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled); hub_free(server); }