void nick(t_client *cli, t_packet *pack) { char buff[4096]; memset(buff, 0, 4096); if (!pack->arg[0]) { send_msg(cli->fd, "461 NICK :Needs more params"); return ; } if (check_nick(pack->arg[0], cli->fd) == 1) return ; strcpy(cli->login, pack->arg[0]); if (strcmp(cli->rname, "") && strcmp(cli->login, "") && !cli->registered) { send_msg(cli->fd, CO(CO(buff, "NICK "), cli->login)); send_msg(cli->fd, CO(CP(buff, "USER "), cli->login)); cli->registered = 1; } }
/* * 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; }
int main(int argc, char **argv) { int x; umask(0077); /* initialize stuff */ memset(&me, 0, sizeof(me)); me.argc = argc; me.argv = argv; me.start = time(NULL); me.settime = time(NULL) + (60*60*4); /* setup signals */ signal(SIGHUP, do_signal); signal(SIGINT, do_signal); signal(SIGQUIT, do_signal); signal(SIGILL, do_signal); signal(SIGTRAP, do_signal); signal(SIGBUS, do_signal); signal(SIGSEGV, do_signal); signal(SIGSYS, do_signal); signal(SIGALRM, SIG_IGN); signal(SIGTERM, do_signal); signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); while ((x = getopt(me.argc, me.argv, "qd")) != -1) { switch (x) { case 'd': me.debug = 1; break; } } if (me.debug == 0) printf("%s by %s\n", VER_STR, MYEMAIL); if (read_conf()) err(1, "ERROR! Unable to read configuration file"); if (!me.servname || !me.servdesc) errx(1, "ERROR! Your M: line is invalid, incomplete, or missing!"); for (x = 0; x < ALL; x++) if (!me.sclients[x].nick || check_nick(NULL, me.sclients[x].nick) || !me.sclients[x].username || check_um(NULL, me.sclients[x].username) || !me.sclients[x].realname || check_rm(NULL, me.sclients[x].realname)) errx(1, "ERROR! Your N: line for %d is invalid, incomplete, or missing!", x); if (!me.chans[0]) errx(1, "ERROR! You need at least one R: line in %s", CONF); if (!(me.logfd = fopen(PIDFILE, "w"))) err(1, "ERROR! Unable to open pidfile"); fprintf(me.logfd, "%d\n", getpid()); fclose(me.logfd); if (!(me.logfd = fopen(LOGFILE, "a"))) err(1, "ERROR! Unable to open logfile"); if ((x = read_db(0)) > 0) err(1, "ERROR! Unable to read %s", databases[x]); if (me.ip.s_addr == NULL) { if (!self_lookup()) err(1, "ERROR! self-lookup failed!"); else printf("WARNING: no vhost defined in conf, using default of %s\n", inet_ntoa(me.ip)); } if (me.debug == 0) switch (me.pid = fork()) { case -1: err(1, "ERROR! Unable to fork"); case 0: for (x = 0; x < 12; x++) if (x != fileno(me.logfd)) close(x); break; default: printf("forked into the background: pid = %d\n", me.pid); return 0; } listen_sock(7272); try_next_hub(); add_event(1, SERVTIMEOUT / 2, &ping_hub); add_event(1, CONNTIMEOUT / 3, &cleanup_dcc); io_loop(); /* NOTREACHED */ exit(0); }