Beispiel #1
0
/* check_clean_nick()
 *
 * input	- pointer to source
 *		- 
 *		- nickname
 *		- truncated nickname
 *		- origin of client
 *		- pointer to server nick is coming from
 * 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, struct Client *server_p)
{
  /* the old code did some wacky stuff here, if the nick is invalid, kill it
   * and dont bother messing at all
   */
  if (!clean_nick_name(nick, 0))
  {
    ++ServerStats.is_kill;
    sendto_realops_flags(UMODE_DEBUG, L_ALL,
                         "Bad/long Nick: %s From: %s(via %s)",
                         nick, server_p->name, client_p->name);

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

    /* bad nick change */
    if (source_p != client_p)
    {
      kill_client_ll_serv_butone(client_p, source_p,
                                 "%s (Bad Nickname)",
				 me.name);
      SetKilled(source_p);
      exit_client(source_p, &me, "Bad Nickname");
    }

    return 1;
  }

  return 0;
}
Beispiel #2
0
/* send_message_remote()
 *
 * inputs	- pointer to client from message is being sent
 * 		- pointer to client to send to
 *		- pointer to preformatted buffer
 *		- length of input buffer
 * output	- none
 * side effects	- Despite the function name, this only sends to directly
 *		  connected clients.
 * 
 */
static void
send_message_remote(struct Client *to, struct Client *from,
                    char *buf, int len)
{
  if (!MyConnect(to))
  {
    sendto_realops_flags(UMODE_ALL, L_ALL,
			 "server send message to %s [%s] dropped from %s(Not local server)",
			 to->name, to->from->name, from->name);
    return;
  }

  /* Optimize by checking if (from && to) before everything */
  /* we set to->from up there.. */

  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);

    sendto_server(NULL, CAP_TS6, NOCAPS,
                  ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
                  me.id, to->name, me.name, to->name,
                  to->username, to->host, to->from->name);
    sendto_server(NULL, NOCAPS, CAP_TS6,
                  ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
                  me.name, to->name, me.name, to->name,
                  to->username, to->host, to->from->name);

    SetKilled(to);

    if (IsPerson(from))
      sendto_one(from, form_str(ERR_GHOSTEDCLIENT),
                 me.name, from->name, to->name, to->username,
                 to->host, to->from);

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

    return;
  } 

  send_message(to, buf, len);
}
Beispiel #3
0
/*! \brief UID command handler (called by servers)
 *
 * \param client_p Pointer to allocated Client struct with physical connection
 *                 to this server, i.e. with an open socket connected.
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *
 *  - parv[0] = sender prefix
 *  - parv[1] = nickname
 *  - parv[2] = hop count
 *  - parv[3] = TS
 *  - parv[4] = umode
 *  - parv[5] = username
 *  - parv[6] = hostname
 *  - parv[7] = ip
 *  - parv[8] = uid
 *  - parv[9] = ircname (gecos)
 */
static void
ms_uid(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  struct Client *target_p = NULL;
  time_t newts = 0;

  if (parc != 10 || EmptyString(parv[9]))
    return;

  if (check_clean_nick(client_p, source_p, parv[1], source_p) ||
      check_clean_user(client_p,  parv[1], parv[5], source_p) ||
      check_clean_host(client_p,  parv[1], parv[6], source_p))
    return;

  newts = atol(parv[3]);

  /*
   * if there is an ID collision, kill our client, and kill theirs.
   * this may generate 401's, but it ensures that both clients always
   * go, even if the other server refuses to do the right thing.
   */
  if ((target_p = hash_find_id(parv[8])) != NULL)
  {
    sendto_realops_flags(UMODE_ALL, L_ALL,
		         "ID collision on %s(%s <- %s)(both killed)",
			 target_p->name, target_p->from->name,
			 client_p->name);
    kill_client_ll_serv_butone(NULL, target_p, "%s (ID collision)",
		               me.name);

    ++ServerStats.is_kill;
    SetKilled(target_p);
    exit_client(target_p, &me, "ID Collision");
    return;
  }
    
  if ((target_p = find_client(parv[1])) == NULL)
    uid_from_server(client_p, source_p, parc, parv, newts, parv[1], parv[9]);
  else if (IsUnknown(target_p))
  {
    exit_client(target_p, &me, "Overridden");
    uid_from_server(client_p, source_p, parc, parv, newts, parv[1], parv[9]);
  }
  else
    perform_nick_collides(source_p, client_p, target_p,
                          parc, parv, newts, parv[1], parv[9], parv[8]);
}			  
Beispiel #4
0
static void
perform_nick_collides(struct Client *source_p, struct Client *client_p, 
                      struct Client *target_p, int parc, char *parv[], 
                      time_t newts, char *nick, char *gecos, char *uid)
{
  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);
      
      /* if we have a UID, issue a kill for it */
      if (uid)
        sendto_one(client_p, ":%s KILL %s :%s (Nick collision (new))",
                   me.id, uid, me.name);

      kill_client_ll_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);

      SetKilled(target_p);
      exit_client(target_p, &me, "Nick collision (new)");
      return;
    }
    /* the timestamps are different */
    else
    {
      sameuser = !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))
      {
        if (uid)
          sendto_one(client_p, ":%s KILL %s :%s (Nick collision (new))",
                     me.id, uid, me.name);
	return;
      }
      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_ll_serv_butone(source_p, target_p,
	                           "%s (Nick collision (new))",
				   me.name);

        SetKilled(target_p);
	exit_client(target_p, &me, "Nick collision");
	
	if (parc == 9)
	  nick_from_server(client_p, source_p, parc, parv, newts, nick, gecos);
	else if (parc == 10)
	  uid_from_server(client_p, source_p, parc, parv, newts, nick, gecos);
	  
	return;
      }
    }
  }

  /* its a client changing nick and causing a collide */
  if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
  {
      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);
    
      sendto_one(target_p, form_str(ERR_NICKCOLLISION), me.name,
                 target_p->name, target_p->name);

      ++ServerStats.is_kill;
      kill_client_ll_serv_butone(NULL, source_p, "%s (Nick change collision)",
                                 me.name);

      ++ServerStats.is_kill;
      kill_client_ll_serv_butone(NULL, target_p, "%s (Nick change collision)",
                                 me.name);

      SetKilled(target_p);
      exit_client(target_p, &me, "Nick collision (new)");

      SetKilled(source_p);
      exit_client(source_p, &me, "Nick collision (old)");
      return;
    }
    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;
        kill_client_ll_serv_butone(client_p, source_p,
	                           "%s (Nick change collision)",
				   me.name);

        SetKilled(source_p);
	
	if (sameuser)
	  exit_client(source_p, &me, "Nick collision (old)");
	else
	  exit_client(source_p, &me, "Nick collision (new)");
	return;
     }
     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_ll_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);

       SetKilled(target_p);
       exit_client(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, gecos);
}