utility_retcode_t init_rtsp_client(struct rtsp_client *client) { utility_retcode_t ret; FUNC_ENTER; syscalls_memset(client, 0, sizeof(*client)); get_client_name(client->name, sizeof(client->name)); get_client_host(client->host, sizeof(client->host)); get_client_version(client->version, sizeof(client->version)); get_user_agent(client->user_agent, sizeof(client->user_agent)); ret = get_random_bytes(client->challenge, sizeof(client->challenge)); if (UTILITY_SUCCESS != ret) { goto out; } ret = get_client_instance(client->instance, sizeof(client->instance)); out: FUNC_RETURN; return ret; }
int _register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char *umode, char *virthost, char *ip) { ConfigItem_ban *bconf; char *parv[3], *tmpstr; #ifdef HOSTILENAME char stripuser[USERLEN + 1], *u1 = stripuser, *u2, olduser[USERLEN + 1], userbad[USERLEN * 2 + 1], *ubad = userbad, noident = 0; #endif int xx; anUser *user = sptr->user; aClient *nsptr; int i; char mo[256]; char *tkllayer[9] = { me.name, /*0 server.name */ "+", /*1 +|- */ "z", /*2 G */ "*", /*3 user */ NULL, /*4 host */ NULL, NULL, /*6 expire_at */ NULL, /*7 set_at */ NULL /*8 reason */ }; aTKline *savetkl = NULL; ConfigItem_tld *tlds; cptr->last = TStime(); parv[0] = sptr->name; parv[1] = parv[2] = NULL; nick = sptr->name; /* <- The data is always the same, but the pointer is sometimes not, * I need this for one of my modules, so do not remove! ;) -- Syzop */ if (MyConnect(sptr)) { if ((i = check_client(sptr, username))) { /* This had return i; before -McSkaf */ if (i == -5) return FLUSH_BUFFER; sendto_snomask(SNO_CLIENT, "*** Notice -- %s from %s.", i == -3 ? "Too many connections" : "Unauthorized connection", get_client_host(sptr)); ircstp->is_ref++; ircsprintf(mo, "This server is full."); return exit_client(cptr, sptr, &me, i == -3 ? mo : "You are not authorized to connect to this server"); } if (sptr->hostp) { /* reject ascci < 32 and ascii >= 127 (note: upper resolver might be even more strict) */ for (tmpstr = sptr->sockhost; *tmpstr > ' ' && *tmpstr < 127; tmpstr++); /* if host contained invalid ASCII _OR_ the DNS reply is an IP-like reply * (like: 1.2.3.4), then reject it and use IP instead. */ if (*tmpstr || !*user->realhost || (isdigit(*sptr->sockhost) && isdigit(*tmpstr - 1))) strncpyzt(sptr->sockhost, (char *)Inet_ia2p((struct IN_ADDR*)&sptr->ip), sizeof(sptr->sockhost)); } strncpyzt(user->realhost, sptr->sockhost, sizeof(sptr->sockhost)); /* SET HOSTNAME */ /* * I do not consider *, ~ or ! 'hostile' in usernames, * as it is easy to differentiate them (Use \*, \? and \\) * with the possible? * exception of !. With mIRC etc. ident is easy to fake * to contain @ though, so if that is found use non-ident * username. -Donwulff * * I do, We only allow a-z A-Z 0-9 _ - and . now so the * !strchr(sptr->username, '@') check is out of date. -Cabal95 * * Moved the noident stuff here. -OnyxDragon */ if (!(sptr->flags & FLAGS_DOID)) strncpyzt(user->username, username, USERLEN + 1); else if (sptr->flags & FLAGS_GOTID) strncpyzt(user->username, sptr->username, USERLEN + 1); else { /* because username may point to user->username */ char temp[USERLEN + 1]; strncpyzt(temp, username, USERLEN + 1); if (IDENT_CHECK == 0) { strncpyzt(user->username, temp, USERLEN + 1); } else { *user->username = '******'; strncpyzt((user->username + 1), temp, USERLEN); #ifdef HOSTILENAME noident = 1; #endif } } #ifdef HOSTILENAME /* * Limit usernames to just 0-9 a-z A-Z _ - and . * It strips the "bad" chars out, and if nothing is left * changes the username to the first 8 characters of their * nickname. After the MOTD is displayed it sends numeric * 455 to the user telling them what(if anything) happened. * -Cabal95 * * Moved the noident thing to the right place - see above * -OnyxDragon * * No longer use nickname if the entire ident is invalid, * if thats the case, it is likely the user is trying to cause * problems so just ban them. (Using the nick could introduce * hostile chars) -- codemastr */ for (u2 = user->username + noident; *u2; u2++) { if (isallowed(*u2)) *u1++ = *u2; else if (*u2 < 32) { /* * Make sure they can read what control * characters were in their username. */ *ubad++ = '^'; *ubad++ = *u2 + '@'; } else *ubad++ = *u2; } *u1 = '\0'; *ubad = '\0'; if (strlen(stripuser) != strlen(user->username + noident)) { if (stripuser[0] == '\0') { return exit_client(cptr, cptr, cptr, "Hostile username. Please use only 0-9 a-z A-Z _ - and . in your username."); } strcpy(olduser, user->username + noident); strncpy(user->username + 1, stripuser, USERLEN - 1); user->username[0] = '~'; user->username[USERLEN] = '\0'; } else u1 = NULL; #endif /* * following block for the benefit of time-dependent K:-lines */ if ((bconf = Find_ban(sptr, make_user_host(user->username, user->realhost), CONF_BAN_USER))) { ircstp->is_ref++; sendto_one(cptr, ":%s %d %s :*** You are not welcome on this server (%s)" " Email %s for more information.", me.name, ERR_YOUREBANNEDCREEP, cptr->name, bconf->reason ? bconf->reason : "", KLINE_ADDRESS); return exit_client(cptr, cptr, cptr, "You are banned"); } if ((bconf = Find_ban(NULL, sptr->info, CONF_BAN_REALNAME))) { ircstp->is_ref++; sendto_one(cptr, ":%s %d %s :*** Your GECOS (real name) is not allowed on this server (%s)" " Please change it and reconnect", me.name, ERR_YOUREBANNEDCREEP, cptr->name, bconf->reason ? bconf->reason : ""); return exit_client(cptr, sptr, &me, "Your GECOS (real name) is banned from this server"); } tkl_check_expire(NULL); /* Check G/Z lines before shuns -- kill before quite -- codemastr */ if ((xx = find_tkline_match(sptr, 0)) < 0) { ircstp->is_ref++; return xx; } find_shun(sptr); /* Technical note regarding next few lines of code: * If the spamfilter matches, depending on the action: * If it's block/dccblock/whatever the retval is -1 ===> we return, client stays "locked forever". * If it's kill/tklline the retval is -2 ==> we return with -2 (aka: FLUSH_BUFFER) * If it's action is viruschan the retval is -5 ==> we continue, and at the end of this return * take special actions. We cannot do that directly here since the user is not fully registered * yet (at all). * -- Syzop */ spamfilter_build_user_string(spamfilter_user, sptr->name, sptr); xx = dospamfilter(sptr, spamfilter_user, SPAMF_USER, NULL, 0, &savetkl); if ((xx < 0) && (xx != -5)) return xx; RunHookReturnInt(HOOKTYPE_PRE_LOCAL_CONNECT, sptr, !=0); } else {
/* * read_iauth * * read and process data from the authentication slave process. */ void read_iauth(void) { static char obuf[READBUF_SIZE+1], last = '?'; static int olen = 0, ia_dbg = 0; char buf[READBUF_SIZE+1], *start, *end, tbuf[BUFSIZ]; aClient *cptr; int i; if (adfd == -1) { olen = 0; return; } while (1) { if (olen) bcopy(obuf, buf, olen); if ((i = recv(adfd, buf+olen, READBUF_SIZE-olen, 0)) <= 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { sendto_flag(SCH_AUTH, "Aiiie! lost slave authentication process (errno = %d)", errno); close(adfd); adfd = -1; olen = 0; start_iauth(0); } break; } olen += i; buf[olen] = '\0'; start = buf; while ((end = index(start, '\n'))) { *end++ = '\0'; last = *start; if (*start == '>') { sendto_flag(SCH_AUTH, "%s", start+1); start = end; continue; } if (*start == 'G') { ia_dbg = atoi(start+2); if (ia_dbg) sendto_flag(SCH_AUTH,"ia_dbg = %d",ia_dbg); start = end; continue; } if (*start == 'O') /* options */ { iauth_options = 0; if (strchr(start+2, 'A')) iauth_options |= XOPT_EARLYPARSE; if (strchr(start+2, 'R')) iauth_options |= XOPT_REQUIRED; if (strchr(start+2, 'T')) iauth_options |= XOPT_NOTIMEOUT; if (strchr(start+2, 'W')) iauth_options |= XOPT_EXTWAIT; if (iauth_options) sendto_flag(SCH_AUTH, "iauth options: %x", iauth_options); start = end; continue; } if (*start == 'V') /* version */ { if (iauth_version) MyFree(iauth_version); iauth_version = mystrdup(start+2); sendto_flag(SCH_AUTH, "iauth version %s running.", iauth_version); start = end; sendto_iauth("0 M %s", me.name); continue; } if (*start == 'a') { aExtCf *ectmp; while ((ectmp = iauth_conf)) { iauth_conf = iauth_conf->next; MyFree(ectmp->line); MyFree(ectmp); } /* little lie.. ;) */ sendto_flag(SCH_AUTH, "New iauth configuration."); start = end; continue; } if (*start == 'A') { aExtCf **ectmp = &iauth_conf; while (*ectmp) ectmp = &((*ectmp)->next); *ectmp = (aExtCf *) MyMalloc(sizeof(aExtCf)); (*ectmp)->line = mystrdup(start+2); (*ectmp)->next = NULL; start = end; continue; } if (*start == 's') { aExtData *ectmp; while ((ectmp = iauth_stats)) { iauth_stats = iauth_stats->next; MyFree(ectmp->line); MyFree(ectmp); } iauth_stats = (aExtData *) MyMalloc(sizeof(aExtData)); iauth_stats->line = MyMalloc(60); sprintf(iauth_stats->line, "iauth modules statistics (%s)", myctime(timeofday)); iauth_stats->next = (aExtData *) MyMalloc(sizeof(aExtData)); iauth_stats->next->line = MyMalloc(60); sprintf(iauth_stats->next->line, "spawned: %d, current options: %X (%.11s)", iauth_spawn, iauth_options, (iauth_version) ? iauth_version : "???"); iauth_stats->next->next = NULL; start = end; continue; } if (*start == 'S') { aExtData **ectmp = &iauth_stats; while (*ectmp) ectmp = &((*ectmp)->next); *ectmp = (aExtData *) MyMalloc(sizeof(aExtData)); (*ectmp)->line = mystrdup(start+2); (*ectmp)->next = NULL; start = end; continue; } if (*start != 'U' && *start != 'u' && *start != 'o' && *start != 'K' && *start != 'k' && *start != 'D') { sendto_flag(SCH_AUTH, "Garbage from iauth [%s]", start); sendto_iauth("-1 E Garbage [%s]", start); /* ** The above should never happen, but i've seen it ** occasionnally, so let's try to get more info ** about it! -kalt */ sendto_flag(SCH_AUTH, "last=%u start=%x end=%x buf=%x olen=%d i=%d", last, start, end, buf, olen, i); sendto_iauth( "-1 E last=%u start=%x end=%x buf=%x olen=%d i=%d", last, start, end, buf, olen, i); start = end; continue; } if ((cptr = local[i = atoi(start+2)]) == NULL) { /* this is fairly common and can be ignored */ if (ia_dbg) { sendto_flag(SCH_AUTH, "Client %d is gone.", i); sendto_iauth("%d E Gone [%s]", i, start); } start = end; continue; } #ifndef INET6 sprintf(tbuf, "%c %d %s %u ", start[0], i, inetntoa((char *)&cptr->ip), cptr->port); #else sprintf(tbuf, "%c %d %s %u ", start[0], i, inetntop(AF_INET6, (char *)&cptr->ip, ipv6string, sizeof(ipv6string)), cptr->port); #endif if (strncmp(tbuf, start, strlen(tbuf))) { /* this is fairly common and can be ignored */ if (ia_dbg) { sendto_flag(SCH_AUTH, "Client mismatch: %d [%s] != [%s]", i, start, tbuf); sendto_iauth("%d E Mismatch [%s] != [%s]", i, start, tbuf); } start = end; continue; } if (start[0] == 'U') { if (*(start+strlen(tbuf)) == '\0') { sendto_flag(SCH_AUTH, "Null U message! %d [%s]", i, start); sendto_iauth("%d E Null U [%s]", i, start); start = end; continue; } if (cptr->auth != cptr->username) { istat.is_authmem -= strlen(cptr->auth) + 1; istat.is_auth -= 1; MyFree(cptr->auth); } cptr->auth = mystrdup(start+strlen(tbuf)); set_clean_username(cptr); cptr->flags |= FLAGS_GOTID; } else if (start[0] == 'u') { if (*(start+strlen(tbuf)) == '\0') { sendto_flag(SCH_AUTH, "Null u message! %d [%s]", i, start); sendto_iauth("%d E Null u [%s]", i, start); start = end; continue; } if (cptr->auth != cptr->username) { istat.is_authmem -= strlen(cptr->auth) + 1; istat.is_auth -= 1; MyFree(cptr->auth); } cptr->auth = MyMalloc(strlen(start+strlen(tbuf)) + 2); *cptr->auth = '-'; strcpy(cptr->auth+1, start+strlen(tbuf)); set_clean_username(cptr); cptr->flags |= FLAGS_GOTID; } else if (start[0] == 'o') { if (!WaitingXAuth(cptr)) { sendto_flag(SCH_AUTH, "Early o message discarded!"); sendto_iauth("%d E Early o [%s]", i,start); start = end; continue; } if (cptr->user == NULL) { /* just to be safe */ sendto_flag(SCH_AUTH, "Ack! cptr->user is NULL"); start = end; continue; } strncpyzt(cptr->user->username, tbuf, USERLEN+1); } else if (start[0] == 'D') { /*authentication finished*/ ClearXAuth(cptr); SetDoneXAuth(cptr); if (WaitingXAuth(cptr)) { ClearWXAuth(cptr); register_user(cptr, cptr, cptr->name, cptr->user->username); } else ClearWXAuth(cptr); } else { char *reason; /* Copy kill reason received from iauth */ reason = strstr(start, " :"); if (reason && (reason + 2 != '\0')) { if (cptr->reason) { MyFree(cptr->reason); } cptr->reason = mystrdup(reason + 2); } /* ** mark for kill, because it cannot be killed ** yet: we don't even know if this is a server ** or a user connection! */ if (start[0] == 'K') cptr->exitc = EXITC_AREF; else cptr->exitc = EXITC_AREFQ; /* should also check to make sure it's still an unregistered client.. */ /* Finally, working after registration. --B. */ if (IsRegisteredUser(cptr)) { if (cptr->exitc == EXITC_AREF) { sendto_flag(SCH_LOCAL, "Denied after connection " "from %s.", get_client_host(cptr)); } (void) exit_client(cptr, cptr, &me, cptr->reason ? cptr->reason : "Denied access"); } } start = end; } olen -= start - buf; if (olen) memcpy(obuf, start, olen); } }