Beispiel #1
0
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);
}