Пример #1
0
/* send_linebuf_remote()
 *
 * inputs	- client to attach to, sender, linebuf
 * outputs	-
 * side effects - client has linebuf attached
 */
static void
send_linebuf_remote(struct Client *to, struct Client *from, buf_head_t *linebuf)
{
	if(to->from)
		to = to->from;

	/* test for fake direction */
	if(!MyClient(from) && IsPerson(to) && (to == from->from))
	{
		if(IsServer(from))
		{
			sendto_realops_flags(UMODE_ALL, L_ALL,
					     "Send message to %s[%s] dropped from %s(Fake Dir)",
					     to->name, to->from->name, from->name);
			return;
		}

		sendto_realops_flags(UMODE_ALL, L_ALL,
				     "Ghosted: %s[%s@%s] from %s[%s@%s] (%s)",
				     to->name, to->username, to->host,
				     from->name, from->username, from->host, to->from->name);
		kill_client_serv_butone(NULL, to, "%s (%s[%s@%s] Ghosted %s)",
					me.name, to->name, to->username,
					to->host, to->from->name);

		to->flags |= FLAGS_KILLED;

		exit_client(NULL, to, &me, "Ghosted client");
		return;
	}

	_send_linebuf(to, linebuf);
	return;
}
Пример #2
0
/* 
 * check_clean_nick()
 * 
 * input	- pointer to source
 *		- nickname
 *		- truncated nickname
 *		- origin of client
 * output	- none
 * side effects - if nickname is erroneous, or a different length to
 *                truncated nickname, return 1
 */
static int
check_clean_nick(struct Client *client_p, struct Client *source_p,
		 char *nick, char *newnick, char *server)
{
	/* the old code did some wacky stuff here, if the nick is invalid, kill it
	 * and dont bother messing at all
	 */

	/*
	 * Zero length nicks are bad too..this shouldn't happen but..
	 */

	if(!clean_nick_name(nick) || strcmp(nick, newnick) || nick[0] == '\0')
	{
		ServerStats->is_kill++;
		sendto_realops_flags(UMODE_DEBUG, L_ALL,
				     "Bad Nick: %s From: %s(via %s)", nick, server, client_p->name);

		sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)", me.name, newnick, me.name);

		/* bad nick change */
		if(source_p != client_p)
		{
			kill_client_serv_butone(client_p, source_p, "%s (Bad Nickname)", me.name);
			source_p->flags |= FLAGS_KILLED;
			exit_client(client_p, source_p, &me, "Bad Nickname");
		}

		return 1;
	}

	return 0;
}
Пример #3
0
static int
ms_signon(struct Client *client_p, struct Client *source_p,
          int parc, const char *parv[])
{
    struct Client *target_p;
    int newts, sameuser;
    char login[NICKLEN+1];

    if(!clean_nick(parv[1])) {
        ServerStats.is_kill++;
        sendto_realops_snomask(SNO_DEBUG, L_ALL,
                               "Bad Nick from SIGNON: %s From: %s(via %s)",
                               parv[1], source_p->servptr->name, client_p->name);
        /* if source_p has an id, kill_client_serv_butone() will
         * send a kill to client_p, otherwise do it here */
        if (!has_id(source_p))
            sendto_one(client_p, ":%s KILL %s :%s (Bad nickname from SIGNON)",
                       get_id(&me, client_p), parv[1], me.name);
        kill_client_serv_butone(client_p, source_p, "%s (Bad nickname from SIGNON)",
                                me.name);
        source_p->flags |= FLAGS_KILLED;
        exit_client(NULL, source_p, &me, "Bad nickname from SIGNON");
        return 0;
    }

    if(!clean_username(parv[2]) || !clean_host(parv[3])) {
        ServerStats.is_kill++;
        sendto_realops_snomask(SNO_DEBUG, L_ALL,
                               "Bad user@host from SIGNON: %s@%s From: %s(via %s)",
                               parv[2], parv[3], source_p->servptr->name, client_p->name);
        /* if source_p has an id, kill_client_serv_butone() will
         * send a kill to client_p, otherwise do it here */
        if (!has_id(source_p))
            sendto_one(client_p, ":%s KILL %s :%s (Bad user@host from SIGNON)",
                       get_id(&me, client_p), parv[1], me.name);
        kill_client_serv_butone(client_p, source_p, "%s (Bad user@host from SIGNON)",
                                me.name);
        source_p->flags |= FLAGS_KILLED;
        exit_client(NULL, source_p, &me, "Bad user@host from SIGNON");
        return 0;
    }

    newts = atol(parv[4]);

    if(!strcmp(parv[5], "0"))
        login[0] = '\0';
    else if(*parv[5] != '*') {
        if (clean_nick(parv[5]))
            rb_strlcpy(login, parv[5], NICKLEN + 1);
        else
            return 0;
    }

    target_p = find_named_client(parv[1]);
    if(target_p != NULL && target_p != source_p) {
        /* In case of collision, follow NICK rules. */
        /* XXX this is duplicated code and does not do SAVE */
        if(IsUnknown(target_p))
            exit_client(NULL, target_p, &me, "Overridden");
        else {
            if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo) || !source_p->user) {
                sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                       "Nick change collision from SIGNON from %s to %s(%s <- %s)(both killed)",
                                       source_p->name, target_p->name, target_p->from->name,
                                       client_p->name);

                ServerStats.is_kill++;
                sendto_one_numeric(target_p, ERR_NICKCOLLISION,
                                   form_str(ERR_NICKCOLLISION), target_p->name);

                kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)", me.name);

                ServerStats.is_kill++;

                kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)", me.name);

                target_p->flags |= FLAGS_KILLED;
                exit_client(NULL, target_p, &me, "Nick collision(new)");
                source_p->flags |= FLAGS_KILLED;
                exit_client(client_p, source_p, &me, "Nick collision(old)");
                return 0;
            } else {
                sameuser = !irccmp(target_p->username, source_p->username) &&
                           !irccmp(target_p->host, source_p->host);

                if((sameuser && newts < target_p->tsinfo) ||
                   (!sameuser && newts > target_p->tsinfo)) {
                    if(sameuser)
                        sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                               "Nick change collision from SIGNON from %s to %s(%s <- %s)(older killed)",
                                               source_p->name, target_p->name,
                                               target_p->from->name, client_p->name);
                    else
                        sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                               "Nick change collision from SIGNON from %s to %s(%s <- %s)(newer killed)",
                                               source_p->name, target_p->name,
                                               target_p->from->name, client_p->name);

                    ServerStats.is_kill++;

                    sendto_one_numeric(target_p, ERR_NICKCOLLISION,
                                       form_str(ERR_NICKCOLLISION), target_p->name);

                    /* kill the client issuing the nickchange */
                    kill_client_serv_butone(client_p, source_p,
                                            "%s (Nick change collision)", me.name);

                    source_p->flags |= FLAGS_KILLED;

                    if(sameuser)
                        exit_client(client_p, source_p, &me, "Nick collision(old)");
                    else
                        exit_client(client_p, source_p, &me, "Nick collision(new)");
                    return 0;
                } else {
                    if(sameuser)
                        sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                               "Nick collision from SIGNON on %s(%s <- %s)(older killed)",
                                               target_p->name, target_p->from->name,
                                               client_p->name);
                    else
                        sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                               "Nick collision from SIGNON on %s(%s <- %s)(newer killed)",
                                               target_p->name, target_p->from->name,
                                               client_p->name);

                    sendto_one_numeric(target_p, ERR_NICKCOLLISION,
                                       form_str(ERR_NICKCOLLISION), target_p->name);

                    /* kill the client who existed before hand */
                    kill_client_serv_butone(client_p, target_p,
                                            "%s (Nick collision)", me.name);

                    ServerStats.is_kill++;

                    target_p->flags |= FLAGS_KILLED;
                    (void) exit_client(client_p, target_p, &me, "Nick collision");
                }
            }

        }
    }

    send_signon(client_p, source_p, parv[1], parv[2], parv[3], newts, login);
    return 0;
}
Пример #4
0
static int
me_svslogin(struct Client *client_p, struct Client *source_p,
            int parc, const char *parv[])
{
    struct Client *target_p, *exist_p;
    char nick[NICKLEN+1], login[NICKLEN+1];
    char user[USERLEN+1], host[HOSTLEN+1];
    int valid = 0;

    if(!(source_p->flags & FLAGS_SERVICE))
        return 0;

    if((target_p = find_client(parv[1])) == NULL)
        return 0;

    if(!MyClient(target_p) && !IsUnknown(target_p))
        return 0;

    if(clean_nick(parv[2])) {
        rb_strlcpy(nick, parv[2], NICKLEN + 1);
        valid |= NICK_VALID;
    } else if(*target_p->name)
        rb_strlcpy(nick, target_p->name, NICKLEN + 1);
    else
        strcpy(nick, "*");

    if(clean_username(parv[3])) {
        rb_strlcpy(user, parv[3], USERLEN + 1);
        valid |= USER_VALID;
    } else
        rb_strlcpy(user, target_p->username, USERLEN + 1);

    if(clean_host(parv[4])) {
        rb_strlcpy(host, parv[4], HOSTLEN + 1);
        valid |= HOST_VALID;
    } else
        rb_strlcpy(host, target_p->host, HOSTLEN + 1);

    if(*parv[5] == '*') {
        if(target_p->user)
            rb_strlcpy(login, target_p->user->suser, NICKLEN + 1);
        else
            login[0] = '\0';
    } else if(!strcmp(parv[5], "0"))
        login[0] = '\0';
    else
        rb_strlcpy(login, parv[5], NICKLEN + 1);

    /* Login (mostly) follows nick rules. */
    if(*login && !clean_nick(login))
        return 0;

    if((exist_p = find_person(nick)) && target_p != exist_p) {
        char buf[BUFSIZE];

        if(MyClient(exist_p))
            sendto_one(exist_p, ":%s KILL %s :(Nickname regained by services)",
                       me.name, exist_p->name);

        exist_p->flags |= FLAGS_KILLED;
        kill_client_serv_butone(NULL, exist_p, "%s (Nickname regained by services)",
                                me.name);

        rb_snprintf(buf, sizeof(buf), "Killed (%s (Nickname regained by services))",
                    me.name);
        exit_client(NULL, exist_p, &me, buf);
    } else if((exist_p = find_client(nick)) && IsUnknown(exist_p) && exist_p != target_p) {
        exit_client(NULL, exist_p, &me, "Overridden");
    }

    if(*login) {
        /* Strip leading digits, unless it's purely numeric. */
        const char *p = login;
        while(IsDigit(*p))
            p++;
        if(!*p)
            p = login;

        sendto_one(target_p, form_str(RPL_LOGGEDIN), me.name, EmptyString(target_p->name) ? "*" : target_p->name,
                   nick, user, host, p, p);
    } else
        sendto_one(target_p, form_str(RPL_LOGGEDOUT), me.name, EmptyString(target_p->name) ? "*" : target_p->name,
                   nick, user, host);

    if(IsUnknown(target_p)) {
        struct User *user_p = make_user(target_p);

        if(valid & NICK_VALID)
            strcpy(target_p->preClient->spoofnick, nick);

        if(valid & USER_VALID)
            strcpy(target_p->preClient->spoofuser, user);

        if(valid & HOST_VALID)
            strcpy(target_p->preClient->spoofhost, host);

        rb_strlcpy(user_p->suser, login, NICKLEN + 1);
    } else {
        char note[NICKLEN + 10];

        send_signon(NULL, target_p, nick, user, host, rb_current_time(), login);

        rb_snprintf(note, NICKLEN + 10, "Nick: %s", target_p->name);
        rb_note(target_p->localClient->F, note);
    }

    return 0;
}
Пример #5
0
static int
perform_nick_collides(struct Client *source_p, struct Client *client_p,
		      struct Client *target_p, int parc, char *parv[], time_t newts, char *nick)
{
	int sameuser;

	/* server introducing new nick */
	if(IsServer(source_p))
	{
		/* if we dont have a ts, or their TS's are the same, kill both */
		if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
		{
			sendto_realops_flags(UMODE_ALL, L_ALL,
					     "Nick collision on %s(%s <- %s)(both killed)",
					     target_p->name, target_p->from->name, client_p->name);

			kill_client_serv_butone(NULL, target_p,
						"%s (Nick collision (new))", me.name);
			ServerStats->is_kill++;
			sendto_one(target_p, form_str(ERR_NICKCOLLISION),
				   me.name, target_p->name, target_p->name);

			target_p->flags |= FLAGS_KILLED;
			exit_client(client_p, target_p, &me, "Nick collision (new)");
			return 0;
		}
		/* the timestamps are different */
		else
		{
			sameuser = (target_p->user) && !irccmp(target_p->username, parv[5])
				&& !irccmp(target_p->host, parv[6]);

			/* if the users are the same (loaded a client on a different server)
			 * and the new users ts is older, or the users are different and the
			 * new users ts is newer, ignore the new client and let it do the kill
			 */
			if((sameuser && newts < target_p->tsinfo) ||
			   (!sameuser && newts > target_p->tsinfo))
			{
				return 0;
			}
			else
			{
				if(sameuser)
					sendto_realops_flags(UMODE_ALL, L_ALL,
							     "Nick collision on %s(%s <- %s)(older killed)",
							     target_p->name, target_p->from->name,
							     client_p->name);
				else
					sendto_realops_flags(UMODE_ALL, L_ALL,
							     "Nick collision on %s(%s <- %s)(newer killed)",
							     target_p->name, target_p->from->name,
							     client_p->name);

				ServerStats->is_kill++;
				sendto_one(target_p, form_str(ERR_NICKCOLLISION),
					   me.name, target_p->name, target_p->name);

				/* if it came from a LL server, itd have been source_p,
				 * so we dont need to mark target_p as known
				 */
				kill_client_serv_butone(source_p, target_p,
							"%s (Nick collision (new))", me.name);

				target_p->flags |= FLAGS_KILLED;
				(void) exit_client(client_p, target_p, &me, "Nick collision");

				nick_from_server(client_p, source_p, parc, parv, newts, nick);
				return 0;
			}
		}
	}

	/* its a client changing nick and causing a collide */
	if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo) || !source_p->user)
	{
		sendto_realops_flags(UMODE_ALL, L_ALL,
				     "Nick change collision from %s to %s(%s <- %s)(both killed)",
				     source_p->name, target_p->name, target_p->from->name,
				     client_p->name);

		ServerStats->is_kill++;
		sendto_one(target_p, form_str(ERR_NICKCOLLISION),
			   me.name, target_p->name, target_p->name);

		/* if we got the message from a LL, it knows about source_p */
		kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)", me.name);

		ServerStats->is_kill++;

		kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)", me.name);

		target_p->flags |= FLAGS_KILLED;
		exit_client(NULL, target_p, &me, "Nick collision(new)");
		source_p->flags |= FLAGS_KILLED;
		exit_client(client_p, source_p, &me, "Nick collision(old)");
		return 0;
	}
	else
	{
		sameuser = !irccmp(target_p->username, source_p->username) &&
			!irccmp(target_p->host, source_p->host);

		if((sameuser && newts < target_p->tsinfo) ||
		   (!sameuser && newts > target_p->tsinfo))
		{
			if(sameuser)
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "Nick change collision from %s to %s(%s <- %s)(older killed)",
						     source_p->name, target_p->name,
						     target_p->from->name, client_p->name);
			else
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "Nick change collision from %s to %s(%s <- %s)(newer killed)",
						     source_p->name, target_p->name,
						     target_p->from->name, client_p->name);

			ServerStats->is_kill++;

			/* this won't go back to the incoming link, so LL doesnt matter */
			kill_client_serv_butone(client_p, source_p,
						"%s (Nick change collision)", me.name);

			source_p->flags |= FLAGS_KILLED;

			if(sameuser)
				exit_client(client_p, source_p, &me, "Nick collision(old)");
			else
				exit_client(client_p, source_p, &me, "Nick collision(new)");
			return 0;
		}
		else
		{
			if(sameuser)
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "Nick collision on %s(%s <- %s)(older killed)",
						     target_p->name, target_p->from->name,
						     client_p->name);
			else
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "Nick collision on %s(%s <- %s)(newer killed)",
						     target_p->name, target_p->from->name,
						     client_p->name);

			kill_client_serv_butone(source_p, target_p, "%s (Nick collision)", me.name);

			ServerStats->is_kill++;
			sendto_one(target_p, form_str(ERR_NICKCOLLISION),
				   me.name, target_p->name, target_p->name);

			target_p->flags |= FLAGS_KILLED;
			(void) exit_client(client_p, target_p, &me, "Nick collision");
		}
	}

	/* we should only ever call nick_from_server() here, as
	 * this is a client changing nick, not a new client
	 */
	nick_from_server(client_p, source_p, parc, parv, newts, nick);

	return 0;
}