void add_history(struct Client *client_p, int online) { struct Whowas *who = &WHOWAS[whowas_next]; s_assert(NULL != client_p); if(client_p == NULL) return; if(who->hashv != -1) { if(who->online) del_whowas_from_clist(&(who->online->whowas), who); del_whowas_from_list(&WHOWASHASH[who->hashv], who); } who->hashv = hash_whowas_name(client_p->name); who->logoff = rb_current_time(); /* * NOTE: strcpy ok here, the sizes in the client struct MUST * match the sizes in the whowas struct */ rb_strlcpy(who->name, client_p->name, sizeof(who->name)); strcpy(who->username, client_p->username); strcpy(who->hostname, client_p->host); strcpy(who->realname, client_p->info); strcpy(who->suser, client_p->user->suser); strcpy(who->sockhost, client_p->sockhost); who->flags = (IsIPSpoof(client_p) ? WHOWAS_IP_SPOOFING : 0) | (IsDynSpoof(client_p) ? WHOWAS_DYNSPOOF : 0); who->servername = scache_get_name(client_p->servptr->serv->nameinfo); if(online) { who->online = client_p; add_whowas_to_clist(&(client_p->whowas), who); } else who->online = NULL; add_whowas_to_list(&WHOWASHASH[who->hashv], who); whowas_next++; if(whowas_next == NICKNAMEHISTORYLENGTH) whowas_next = 0; }
static void check_umode_change(void *vdata) { hook_data_umode_changed *data = (hook_data_umode_changed *)vdata; struct Client *source_p = data->client; if (!MyClient(source_p)) return; /* didn't change +h umode, we don't need to do anything */ if (!((data->oldumodes ^ source_p->umodes) & user_modes['h'])) return; if (source_p->umodes & user_modes['h']) { if (IsIPSpoof(source_p) || source_p->localClient->mangledhost == NULL || (IsDynSpoof(source_p) && strcmp(source_p->host, source_p->localClient->mangledhost))) { source_p->umodes &= ~user_modes['h']; return; } if (strcmp(source_p->host, source_p->localClient->mangledhost)) { strlcpy(source_p->host, source_p->localClient->mangledhost, HOSTLEN); distribute_hostchange(source_p); } else /* not really nice, but we need to send this numeric here */ sendto_one_numeric(source_p, RPL_HOSTHIDDEN, "%s :is now your hidden host", source_p->host); } else if (!(source_p->umodes & user_modes['h'])) { if (source_p->localClient->mangledhost != NULL && !strcmp(source_p->host, source_p->localClient->mangledhost)) { strlcpy(source_p->host, source_p->orighost, HOSTLEN); distribute_hostchange(source_p); } } }
static void check_new_user(void *vdata) { struct Client *source_p = (void *)vdata; if (IsIPSpoof(source_p)) { source_p->umodes &= ~user_modes['h']; return; } source_p->localClient->mangledhost = MyMalloc(HOSTLEN); if (!irccmp(source_p->orighost, source_p->sockhost)) do_host_cloak(source_p->orighost, source_p->localClient->mangledhost, 1); else do_host_cloak(source_p->orighost, source_p->localClient->mangledhost, 0); if (IsDynSpoof(source_p)) source_p->umodes &= ~user_modes['h']; if (source_p->umodes & user_modes['h']) { strlcpy(source_p->host, source_p->localClient->mangledhost, sizeof(source_p->host)); if (irccmp(source_p->host, source_p->orighost)) SetDynSpoof(source_p); } }
static void check_new_user(void *vdata) { struct Client *source_p = (void *)vdata; if (!IsIPSpoof(source_p)) return; if (EmptyString(source_p->user->suser)) return; char *accountpart = strstr(source_p->orighost, "account"); if (!accountpart) return; char buf[HOSTLEN]; memset(buf, 0, sizeof(buf)); char *dst = buf; strncpy(buf, source_p->orighost, accountpart - source_p->orighost); dst += accountpart - source_p->orighost; int needhash = 0; for (char *src = source_p->user->suser; *src ; src++ ) { if (dst > buf + sizeof(buf)) { /* Doesn't fit. Warn opers and bail. */ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Couldn't fit account name part %s in hostname for %s!%s@%s", source_p->user->suser, source_p->name, source_p->username, source_p->orighost); return; } char c = ToLower(*src); if (IsHostChar(c)) *dst++ = c; else needhash = 1; } if (needhash) { if (dst > buf + sizeof(buf) - 12) /* '/x-' plus eight digit hash plus null terminator */ { /* Doesn't fit. Warn opers and bail. */ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Couldn't fit account name part %s in hostname for %s!%s@%s", source_p->user->suser, source_p->name, source_p->username, source_p->orighost); return; } *dst++ = '/'; *dst++ = 'x'; *dst++ = '-'; unsigned int hashval = fnv_hash_string(source_p->user->suser); hashval %= 100000000; // eight digits only please. snprintf(dst, 9, "%08ud", hashval); } /* just in case */ buf[HOSTLEN-1] = '\0'; /* If hostname has been changed already (probably by services cloak on SASL login), then * leave it intact. If not, change it. In either case, update the original hostname. */ if (0 == irccmp(source_p->host, source_p->orighost)) change_nick_user_host(source_p, source_p->name, source_p->username, buf, 0, "Changing host"); strncpy(source_p->orighost, buf, HOSTLEN); }