Example #1
0
/*
 * m_svinfo - SVINFO message handler
 *      parv[0] = sender prefix
 *      parv[1] = TS_CURRENT for the server
 *      parv[2] = TS_MIN for the server
 *      parv[3] = server is standalone or connected to non-TS only
 *      parv[4] = server's idea of UTC time
 */
int m_svinfo(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  time_t deltat;
  time_t theirtime;

  if (MyConnect(sptr) && IsUnknown(sptr))
    return exit_client(sptr, sptr, sptr, "Need SERVER before SVINFO");

  if (!IsServer(sptr) || !MyConnect(sptr) || parc < 5)
    return 0;

  if (TS_CURRENT < atoi(parv[2]) || atoi(parv[1]) < TS_MIN)
    {
      /*
       * a server with the wrong TS version connected; since we're
       * TS_ONLY we can't fall back to the non-TS protocol so
       * we drop the link  -orabidoo
       */
#ifdef HIDE_SERVERS_IPS
      sendto_realops("Link %s dropped, wrong TS protocol version (%s,%s)",
      		 get_client_name(sptr, MASK_IP), parv[1], parv[2]);
#else		 
      sendto_realops("Link %s dropped, wrong TS protocol version (%s,%s)",
                 get_client_name(sptr, TRUE), parv[1], parv[2]);
#endif		 
      return exit_client(sptr, sptr, sptr, "Incompatible TS version");
    }

  sptr->serv->tsversion = atoi(parv[1]);
  
  /*
   * since we're here, might as well set CurrentTime while we're at it
   */
  CurrentTime = time(0);
  theirtime = atol(parv[4]);
  deltat = abs(theirtime - CurrentTime);

  if (deltat > TS_MAX_DELTA)
    {
#ifdef HIDE_SERVERS_IPS
      sendto_realops(
       "Link %s dropped, excessive TS delta (my TS=%d, their TS=%d, delta=%d)",
       		 get_client_name(sptr, MASK_IP), CurrentTime, theirtime,deltat);
#else		 
      sendto_realops(
       "Link %s dropped, excessive TS delta (my TS=%d, their TS=%d, delta=%d)",
                 get_client_name(sptr, TRUE), CurrentTime, theirtime,deltat);
#endif		 
      return exit_client(sptr, sptr, sptr, "Excessive TS delta");
    }

  if (deltat > TS_WARN_DELTA)
    { 
#ifdef HIDE_SERVERS_IPS
      sendto_realops(
      		 "Link %s notable TS delta (my TS=%d, their TS=%d, delta=%d)",
		 get_client_name(sptr, MASK_IP), CurrentTime, theirtime, deltat);
#else		 
      sendto_realops(
                 "Link %s notable TS delta (my TS=%d, their TS=%d, delta=%d)",
                 get_client_name(sptr, TRUE), CurrentTime, theirtime, deltat);
#endif		 
    }

  return 0;
}
Example #2
0
SequenceDataPtr TransposeTransformer::TypedTranspose<TElementTo>::Apply(ImageSequenceData* inputSequence)
{
    auto shape = m_parent->m_inputStream.m_sampleLayout;
    if (shape.IsUnknown()) // Taking the shape from the sequence.
    {
        shape = inputSequence->m_sampleShape;
    }

    if (shape.IsUnknown())
        RuntimeError("Unknown shape of the sample in stream '%ls'.", m_parent->m_inputStream.m_name.c_str());

    assert(inputSequence->m_numberOfSamples == 1);

    size_t count = shape.TotalSize();

    ImageDimensions dimensions(TensorShape(shape.Dimensions()), ImageLayoutKind::HWC);
    size_t rowCount = dimensions.m_height * dimensions.m_width;
    size_t channelCount = dimensions.m_numChannels;

    auto dims = dimensions.AsTensorShape(CHW).GetDims();
    NDShape resultShape(std::vector<size_t>(dims.begin(), dims.end()));
    auto result = std::make_shared<DenseSequenceWithBuffer<TElementTo>>(m_memBuffers, count, resultShape);
    result->m_key = inputSequence->m_key;

    auto dst = result->GetBuffer();

    if (channelCount == 3) // Unrolling for BGR, the most common case.
    {
        size_t nRows = inputSequence->m_image.rows;
        size_t nCols = inputSequence->m_image.cols;

        TElementTo* b = dst;
        TElementTo* g = dst + rowCount;
        TElementTo* r = dst + 2 * rowCount;

        for (size_t i = 0; i < nRows; ++i)
        {
            auto* x = inputSequence->m_image.ptr<TElementFrom>((int)i);
            for (size_t j = 0; j < nCols; ++j)
            {
                auto row = j * 3;
                *b++ = static_cast<TElementTo>(x[row]);
                *g++ = static_cast<TElementTo>(x[row + 1]);
                *r++ = static_cast<TElementTo>(x[row + 2]);
            }
        }
    }
    else
    {
        auto src = reinterpret_cast<const TElementFrom*>(inputSequence->GetDataBuffer());
        for (size_t irow = 0; irow < rowCount; irow++)
        {
            for (size_t icol = 0; icol < channelCount; icol++)
            {
                dst[icol * rowCount + irow] = static_cast<TElementTo>(src[irow * channelCount + icol]);
            }
        }
    }

    
    result->m_numberOfSamples = inputSequence->m_numberOfSamples;
    return result;
}
Example #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;
}
Example #4
0
static	time_t	check_pings(time_t currenttime)
{		
  register	aClient	*cptr;		/* current local cptr being examined */
  aConfItem 	*aconf = (aConfItem *)NULL;
  int		ping = 0;		/* ping time value from client */
  int		i;			/* used to index through fd/cptr's */
  time_t	oldest = 0;		/* next ping time */
  time_t	timeout;		/* found necessary ping time */
  char *reason;				/* pointer to reason string */
  int die_index=0;			/* index into list */
  char ping_time_out_buffer[64];	/* blech that should be a define */

					/* of dying clients */
  dying_clients[0] = (aClient *)NULL;	/* mark first one empty */

  /*
   * I re-wrote the way klines are handled. Instead of rescanning
   * the local[] array and calling exit_client() right away, I
   * mark the client thats dying by placing a pointer to its aClient
   * into dying_clients[]. When I have examined all in local[],
   * I then examine the dying_clients[] for aClient's to exit.
   * This saves the rescan on k-lines, also greatly simplifies the code,
   *
   * Jan 28, 1998
   * -Dianora
   */

   for (i = 0; i <= highest_fd; i++)
    {
      if (!(cptr = local[i]) || IsMe(cptr) || IsLog(cptr))
	continue;		/* and go examine next fd/cptr */
      /*
      ** Note: No need to notify opers here. It's
      ** already done when "FLAGS_DEADSOCKET" is set.
      */
      if (cptr->flags & FLAGS_DEADSOCKET)
	{
	  /* N.B. EVERY single time dying_clients[] is set
	   * it must be followed by an immediate continue,
	   * to prevent this cptr from being marked again for exit.
	   * If you don't, you could cause exit_client() to be called twice
	   * for the same cptr. i.e. bad news
	   * -Dianora
	   */

	  dying_clients[die_index] = cptr;
	  dying_clients_reason[die_index++] =
	    ((cptr->flags & FLAGS_SENDQEX) ?
	     "SendQ exceeded" : "Dead socket");
	  dying_clients[die_index] = (aClient *)NULL;
	  continue;		/* and go examine next fd/cptr */
	}

      if (rehashed)
	{
	  if(dline_in_progress)
	    {
	      if(IsPerson(cptr))
		{
		  if( (aconf = find_dkill(cptr)) ) /* if there is a returned 
						      aConfItem then kill it */
		    {
		      sendto_ops("D-line active for %s",
				 get_client_name(cptr, FALSE));

		      dying_clients[die_index] = cptr;
#ifdef KLINE_WITH_REASON
		      reason = aconf->passwd ? aconf->passwd : "D-lined";
		      dying_clients_reason[die_index++] = reason;
#else
		      dying_clients_reason[die_index++] = "D-lined";
#endif
		      dying_clients[die_index] = (aClient *)NULL;
		      sendto_one(cptr, err_str(ERR_YOUREBANNEDCREEP),
				 me.name, cptr->name, reason);
		      continue;		/* and go examine next fd/cptr */
		    }
		}
	    }
	  else
	    {
	      if(IsPerson(cptr))
		{
#ifdef GLINES
		  if( (aconf = find_gkill(cptr)) )
		    {
		      sendto_ops("G-line active for %s",
				 get_client_name(cptr, FALSE));

		      dying_clients[die_index] = cptr;
#ifdef KLINE_WITH_REASON
		      reason = aconf->passwd ? aconf->passwd : "G-lined";
		      dying_clients_reason[die_index++] = reason;
#else
		      dying_clients_reason[die_index++] = "G-lined";
#endif
		      dying_clients[die_index] = (aClient *)NULL;
		      sendto_one(cptr, err_str(ERR_YOUREBANNEDCREEP),
				 me.name, cptr->name, reason);
		      continue;		/* and go examine next fd/cptr */
		    }
		  else
#endif
		  if((aconf = find_kill(cptr)))	/* if there is a returned
						   aConfItem.. then kill it */
		    {
		      sendto_ops("K-line active for %s",
				 get_client_name(cptr, FALSE));
		      dying_clients[die_index] = cptr;

#ifdef KLINE_WITH_REASON
#ifdef K_COMMENT_ONLY
		      reason = aconf->passwd ? aconf->passwd : "K-lined";
#else
		      reason = (BadPtr(aconf->passwd) || 
				!is_comment(aconf->passwd)) ?
			"K-lined" : aconf->passwd;
#endif
		      dying_clients_reason[die_index++] = reason;
#else
		      dying_clients_reason[die_index++] = "K-lined";
#endif
		      dying_clients[die_index] = (aClient *)NULL;
		      sendto_one(cptr, err_str(ERR_YOUREBANNEDCREEP),
				 me.name, cptr->name, reason);
		      continue;		/* and go examine next fd/cptr */
		    }
		}
	    }
	}

#ifdef IDLE_CHECK
      if (IsPerson(cptr))
	{
	  if( !IsElined(cptr) && ((timeofday - cptr->user->last) > idle_time))
	    {
	      aConfItem *aconf;

	      dying_clients[die_index] = cptr;
	      dying_clients_reason[die_index++] = "idle exceeder";
	      dying_clients[die_index] = (aClient *)NULL;

	      aconf = make_conf();
	      aconf->status = CONF_KILL;
	      DupString(aconf->host, cptr->user->host);
	      DupString(aconf->passwd, "idle exceeder" );
	      DupString(aconf->name, cptr->user->username);
	      aconf->port = 0;
	      aconf->hold = timeofday + 60;
	      add_temp_kline(aconf);
	      sendto_ops("Idle exceeder %s temp k-lining",
			 get_client_name(cptr,FALSE));
	      continue;		/* and go examine next fd/cptr */
	    }
	}
#endif

#ifdef REJECT_HOLD
      if (IsRejectHeld(cptr))
	{
	  if( timeofday > (cptr->firsttime + REJECT_HOLD_TIME) )
	    {
	      dying_clients[die_index] = cptr;
	      dying_clients_reason[die_index++] = "reject held client";
	      dying_clients[die_index] = (aClient *)NULL;
	      continue;		/* and go examine next fd/cptr */
	    }
	}
#endif

#if defined(R_LINES) && defined(R_LINES_OFTEN)
      /*
       * this is used for KILL lines with time restrictions
       * on them - send a message to the user being killed
       * first.
       * *** Moved up above  -taner ***
       *
       * Moved here, no more rflag -Dianora 
       */
      if (IsPerson(cptr) && find_restrict(cptr))
	{
	  sendto_ops("Restricting %s, closing link.",
		     get_client_name(cptr,FALSE));

	  dying_clients[die_index] = cptr;
	  dying_clients_reason[die_index++] = "you have been R-lined";
	  dying_clients[die_index] = (aClient *)NULL;
	  continue;			/* and go examine next fd/cptr */
	}
#endif

      if (!IsRegistered(cptr))
	ping = CONNECTTIMEOUT;
      else
	ping = get_client_ping(cptr);

      /*
       * Ok, so goto's are ugly and can be avoided here but this code
       * is already indented enough so I think its justified. -avalon
       */
       /*  if (!rflag &&
	       (ping >= currenttime - cptr->lasttime))
	      goto ping_timeout; */

      /*
       * *sigh* I think not -Dianora
       */

      if (ping < (currenttime - cptr->lasttime))
	{

	  /*
	   * If the server hasnt talked to us in 2*ping seconds
	   * and it has a ping time, then close its connection.
	   * If the client is a user and a KILL line was found
	   * to be active, close this connection too.
	   */
	  if (((currenttime - cptr->lasttime) >= (2 * ping) &&
	       (cptr->flags & FLAGS_PINGSENT)) ||
	      ((!IsRegistered(cptr) && (currenttime - cptr->since) >= ping)))
	    {
	      if (!IsRegistered(cptr) &&
		  (DoingDNS(cptr) || DoingAuth(cptr)))
		{
		  if (cptr->authfd >= 0)
		    {
		      (void)close(cptr->authfd);
		      cptr->authfd = -1;
		      cptr->count = 0;
		      *cptr->buffer = '\0';
		    }
#ifdef SHOW_HEADERS
		  if (DoingDNS(cptr))
		    send(cptr->fd, REPORT_FAIL_DNS, R_fail_dns, 0);
		  else
		    send(cptr->fd, REPORT_FAIL_ID, R_fail_id, 0);
#endif
		  Debug((DEBUG_NOTICE,"DNS/AUTH timeout %s",
			 get_client_name(cptr,TRUE)));
		  del_queries((char *)cptr);
		  ClearAuth(cptr);
		  ClearDNS(cptr);
		  SetAccess(cptr);
		  cptr->since = currenttime;
		  continue;
		}
	      if (IsServer(cptr) || IsConnecting(cptr) ||
		  IsHandshake(cptr))
		{
		  sendto_ops("No response from %s, closing link",
			     get_client_name(cptr, FALSE));
		}
	      /*
	       * this is used for KILL lines with time restrictions
	       * on them - send a messgae to the user being killed
	       * first.
	       * *** Moved up above  -taner ***
	       */
	      cptr->flags2 |= FLAGS2_PING_TIMEOUT;
	      dying_clients[die_index++] = cptr;
	      /* the reason is taken care of at exit time */
      /*      dying_clients_reason[die_index++] = "Ping timeout"; */
	      dying_clients[die_index] = (aClient *)NULL;
	      
	      /*
	       * need to start loop over because the close can
	       * affect the ordering of the local[] array.- avalon
	       *
	       ** Not if you do it right - Dianora
	       */

	      continue;
	    }
	  else if ((cptr->flags & FLAGS_PINGSENT) == 0)
	    {
	      /*
	       * if we havent PINGed the connection and we havent
	       * heard from it in a while, PING it to make sure
	       * it is still alive.
	       */
	      cptr->flags |= FLAGS_PINGSENT;
	      /* not nice but does the job */
	      cptr->lasttime = currenttime - ping;
	      sendto_one(cptr, "PING :%s", me.name);
	    }
	}
      /* ping_timeout: */
      timeout = cptr->lasttime + ping;
      while (timeout <= currenttime)
	timeout += ping;
      if (timeout < oldest || !oldest)
	oldest = timeout;

      /*
       * Check UNKNOWN connections - if they have been in this state
       * for > 100s, close them.
       */

      if (IsUnknown(cptr))
	{
	  if (cptr->firsttime ? ((timeofday - cptr->firsttime) > 100) : 0)
	    {
	      dying_clients[die_index] = cptr;
	      dying_clients_reason[die_index++] = "Connection Timed Out";
	      dying_clients[die_index] = (aClient *)NULL;
	      continue;
	    }
	}
    }

  /* Now exit clients marked for exit above.
   * it doesn't matter if local[] gets re-arranged now
   *
   * -Dianora
   */

  for(die_index = 0; (cptr = dying_clients[die_index]); die_index++)
    {
      if(cptr->flags2 & FLAGS2_PING_TIMEOUT)
	{
	  (void)ircsprintf(ping_time_out_buffer,
			    "Ping timeout: %d seconds",
			    currenttime - cptr->lasttime);
	  (void)exit_client(cptr, cptr, &me, ping_time_out_buffer );
	}
      else
	(void)exit_client(cptr, cptr, &me, dying_clients_reason[die_index]);
    }

  rehashed = 0;
  dline_in_progress = 0;

  if (!oldest || oldest < currenttime)
    oldest = currenttime + PINGFREQUENCY;
  Debug((DEBUG_NOTICE,"Next check_ping() call at: %s, %d %d %d",
	 myctime(oldest), ping, oldest, currenttime));
  
  return (oldest);
}
Example #5
0
/*
** m_user
**	parv[0] = sender prefix
**	parv[1] = username (login name, account)
**	parv[2] = client host name (used only from other servers)
**	parv[3] = server host name (used only from other servers)
**	parv[4] = users real name info
**
** NOTE: Be advised that multiple USER messages are possible,
**       hence, always check if a certain struct is already allocated... -- Syzop
*/
DLLFUNC CMD_FUNC(m_user)
{
#define	UFLAGS	(UMODE_INVISIBLE|UMODE_WALLOP|UMODE_SERVNOTICE)
	char *username, *host, *server, *realname, *umodex = NULL, *virthost =
	    NULL, *ip = NULL;
	char *account = NULL;
	anUser *user;
	aClient *acptr;

	if (IsServer(cptr) && !IsUnknown(sptr))
		return 0;

	if (MyConnect(sptr) && (sptr->listener->umodes & LISTENER_SERVERSONLY))
	{
		return exit_client(cptr, sptr, sptr,
		    "This port is for servers only");
	}

	if (parc > 2 && (username = (char *)index(parv[1], '@')))
		*username = '******';
	if (parc < 5 || *parv[1] == '\0' || *parv[2] == '\0' ||
	    *parv[3] == '\0' || *parv[4] == '\0')
	{
		sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
		    me.name, parv[0], "USER");
		if (IsServer(cptr))
			sendto_ops("bad USER param count for %s from %s",
			    parv[0], get_client_name(cptr, FALSE));
		else
			return 0;
	}


	/* Copy parameters into better documenting variables */

	username = (parc < 2 || BadPtr(parv[1])) ? "<bad-boy>" : parv[1];
	host = (parc < 3 || BadPtr(parv[2])) ? "<nohost>" : parv[2];
	server = (parc < 4 || BadPtr(parv[3])) ? "<noserver>" : parv[3];

	/* This we can remove as soon as all servers have upgraded. */

	if (parc == 6 && IsServer(cptr))
	{
		account = parv[4];
		realname = (BadPtr(parv[5])) ? "<bad-realname>" : parv[5];
		umodex = NULL;
	}
	else if (parc == 8 && IsServer(cptr))
	{
		account = parv[4];
		realname = (BadPtr(parv[7])) ? "<bad-realname>" : parv[7];
		umodex = parv[5];
		virthost = parv[6];
	}
	else if (parc == 9 && IsServer(cptr))
	{
		account = parv[4];
		realname = (BadPtr(parv[8])) ? "<bad-realname>" : parv[8];
		umodex = parv[5];
		virthost = parv[6];
		ip = parv[7];
	}
	else
	{
		realname = (BadPtr(parv[4])) ? "<bad-realname>" : parv[4];
	}
	user = make_user(sptr);

	if (!MyConnect(sptr))
	{
		if (sptr->srvptr == NULL)
			sendto_ops("WARNING, User %s introduced as being "
			    "on non-existant server %s.", sptr->name, server);
		if (SupportNS(cptr))
		{
			acptr = (aClient *)find_server_b64_or_real(server);
			if (acptr)
				user->server = find_or_add(acptr->name);
			else
				user->server = find_or_add(server);
		}
		else
			user->server = find_or_add(server);
		strlcpy(user->realhost, host, sizeof(user->realhost));
		goto user_finish;
	}

	if (!IsUnknown(sptr))
	{
		sendto_one(sptr, err_str(ERR_ALREADYREGISTRED),
		    me.name, parv[0]);
		return 0;
	}

	if (!IsServer(cptr))
	{
		sptr->umodes |= CONN_MODES;
		if (CONNECT_SNOMASK)
		{
			sptr->umodes |= UMODE_SERVNOTICE;
			create_snomask(sptr, user, CONNECT_SNOMASK);
		}
	}

	/* Set it temporarely to at least something trusted,
	 * this was copying user supplied data directly into user->realhost
	 * which seemed bad. Not to say this is much better ;p. -- Syzop
	 */
	strncpyzt(user->realhost, Inet_ia2p(&sptr->ip), sizeof(user->realhost));
	if (!user->ip_str)
		user->ip_str = strdup(Inet_ia2p(&sptr->ip));
	user->server = me_hash;
      user_finish:
	if (account)
		strlcpy(user->account, account, sizeof(user->account));
	strlcpy(sptr->info, realname, sizeof(sptr->info));
	if (sptr->name[0] && (IsServer(cptr) ? 1 : IsNotSpoof(sptr)))
		/* NICK and no-spoof already received, now we have USER... */
	{
		if (USE_BAN_VERSION && MyConnect(sptr))
			sendto_one(sptr, ":IRC!IRC@%s PRIVMSG %s :\1VERSION\1",
				me.name, sptr->name);

		return(
		    register_user(cptr, sptr, sptr->name, username, umodex,
		    virthost,ip));
	}
	else
		strncpyzt(sptr->user->username, username, USERLEN + 1);

	return 0;
}
Example #6
0
static      time_t
check_pings(time_t currenttime)
{
aClient 	*cptr;
aConfItem 	*aconf = (aConfItem *) NULL;
int     	 killflag, zkillflag, ping = 0, i;
time_t      	 oldest = 0; /* timeout removed, see EXPLANATION below */
char       	*reason, *ktype, fbuf[512];
char 		*errtxt = "No response from %s, closing link";


   for (i = 0; i <= highest_fd; i++) 
   {
      if (!(cptr = local[i]) || IsMe(cptr) || IsLog(cptr))
	 continue;

       /* Note: No need to notify opers here. It's 
	* already done when "FLAGS_DEADSOCKET" is set.
        */

      if (cptr->flags & FLAGS_DEADSOCKET) 
      {
	 (void) exit_client(cptr, cptr, &me, (cptr->flags & FLAGS_SENDQEX) ?
			    "SendQ exceeded" : "Dead socket");
	 i--;
	 continue;
      }

      killflag = NO;
      zkillflag = NO;

      if (rehashed) 
      {
	 if (zline_in_progress) 
	 {
	    if (IsPerson(cptr)) 
	    {
	       if ((aconf = find_zkill(cptr)))	
		  zkillflag = YES;
	    }
	 }
	 else 
	 {
	    if(IsPerson(cptr)) 
	    {
	       if((aconf = find_kill(cptr)))	
		  killflag = YES;	
	    }
	 }
      }

      /* Added a bit of code here to differentiate 
       * between K and Z-lines. -ThemBones
       */

      if (zkillflag || killflag)
      {
         ktype = zkillflag ? "Z-lined" : 
            ((aconf->status == CONF_KILL) ? "K-lined" : "Autokilled");

	 if (killflag) 
         {
	    sendto_ops("%s active for %s",
                       (aconf->status == CONF_KILL) ? "K-line" : "Autokill",
		       get_client_name(cptr, FALSE));
	    reason = aconf->passwd ? aconf->passwd : ktype;
	 }
	 else 
         {			/* its a Z line */
	    sendto_ops("Z-line active for %s",
		       get_client_name(cptr, FALSE));
	    reason = aconf->passwd ? aconf->passwd : "Z-lined";
	 }

	 sendto_one(cptr, err_str(ERR_YOUREBANNEDCREEP),
		    me.name, cptr->name, ktype);

         ircsprintf(fbuf, "%s: %s", ktype, reason);
	 (void) exit_client(cptr, cptr, &me, fbuf);
	 i--;			/* subtract out this fd so we check it again.. */			
	 continue;
      }

      if (IsRegistered(cptr))
	 ping = cptr->pingval;
      else
	 ping = CONNECTTIMEOUT;

      /*
       * Ok, so goto's are ugly and can be avoided here but this code
       * is already indented enough so I think its justified. -avalon
       *
       * justified by what? laziness? <g>
       * If the client pingtime is fine (ie, not larger than the client ping) 
       * skip over all the checks below. - lucas
       */

      if (ping < (currenttime - cptr->lasttime))
      {
         /*
          * If the server hasnt talked to us in 2*ping seconds and it has
          * a ping time, then close its connection. If the client is a
          * user and a KILL line was found to be active, close this
          * connection too.
          */
         if (((cptr->flags & FLAGS_PINGSENT) && ((currenttime - cptr->lasttime) >= (2 * ping))) ||
             ((!IsRegistered(cptr) && (currenttime - cptr->since) >= ping))) 
         {
	    if (!IsRegistered(cptr) && (DoingDNS(cptr) || DoingAuth(cptr))) 
            {
	       if (cptr->authfd >= 0) 
	       {
	          (void) close(cptr->authfd);
	          cptr->authfd = -1;
	          cptr->count = 0;
	          *cptr->buffer = '\0';
	       }
#ifdef SHOW_HEADERS
	       if (DoingDNS(cptr))
	          ssl_send(cptr, REPORT_FAIL_DNS, R_fail_dns, 0);
	       if (DoingAuth(cptr))
	          ssl_send(cptr, REPORT_FAIL_ID, R_fail_id, 0);
#endif
	       Debug((DEBUG_NOTICE, "DNS/AUTH timeout %s",
	 	      get_client_name(cptr, TRUE)));
	       del_queries((char *) cptr);
	       ClearAuth(cptr);
	       ClearDNS(cptr);
	       SetAccess(cptr);
	       cptr->since = currenttime;
	       continue;
	    }

	    if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr)) 
	    {
	       ircsprintf(fbuf, "from %s: %s", me.name, errtxt);
	       sendto_gnotice(fbuf, get_client_name(cptr, HIDEME));
	       ircsprintf(fbuf, ":%s GNOTICE :%s", me.name, errtxt);                                
	       sendto_serv_butone(cptr, fbuf, get_client_name(cptr, HIDEME));
	    }

	    (void) exit_client(cptr, cptr, &me, "Ping timeout");
	    i--;			/* subtract out this fd so we check it again.. */			
	    continue;
         } /* don't send pings during a burst, as we send them already. */

         else if (!(cptr->flags & (FLAGS_PINGSENT|FLAGS_BURST))) {
	    /*
	     * if we havent PINGed the connection and we havent heard from
	     * it in a while, PING it to make sure it is still alive.
	     */
	    cptr->flags |= FLAGS_PINGSENT;
	    /*
	     * not nice but does the job 
	     */
	    cptr->lasttime = currenttime - ping;
	    sendto_one(cptr, "PING :%s", me.name);
         }
      }

      /* see EXPLANATION below
       *
       * timeout = cptr->lasttime + ping;
       * while (timeout <= currenttime)
       *  timeout += ping;
       * if (timeout < oldest || !oldest)
       *   oldest = timeout;
       */

      /*
       * Check UNKNOWN connections - if they have been in this state
       * for > 100s, close them.
       */
      if (IsUnknown(cptr))
	 if (cptr->firsttime ? ((timeofday - cptr->firsttime) > 100) : 0) 
	    (void) exit_client(cptr, cptr, &me, "Connection Timed Out");
   }

   rehashed = 0;
   zline_in_progress = 0;

   /* EXPLANATION
    * on a server with a large volume of clients, at any given point
    * there may be a client which needs to be pinged the next second,
    * or even right away (a second may have passed while running
    * check_pings). Preserving CPU time is more important than
    * pinging clients out at exact times, IMO. Therefore, I am going to make
    * check_pings always return currenttime + 9. This means that it may take
    * a user up to 9 seconds more than pingfreq to timeout. Oh well.
    * Plus, the number is 9 to 'stagger' our check_pings calls out over
    * time, to avoid doing it and the other tasks ircd does at the same time
    * all the time (which are usually done on intervals of 5 seconds or so). 
    * - lucas
    *
    *  if (!oldest || oldest < currenttime)
    *     oldest = currenttime + PINGFREQUENCY;
    */

   oldest = currenttime + 9;

   Debug((DEBUG_NOTICE, "Next check_ping() call at: %s, %d %d %d",
	  myctime(oldest), ping, oldest, currenttime));

   return oldest;
}
Example #7
0
/*
 * ms_nick()
 *      
 * server -> server nick change
 *    parv[0] = sender prefix
 *    parv[1] = nickname
 *    parv[2] = TS when nick change
 *
 * server introducing new nick
 *    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] = server
 *    parv[8] = ircname
 */
static void
ms_nick(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct Client *target_p;
	char nick[NICKLEN];
	time_t newts = 0;

	if(parc < 2 || BadPtr(parv[1]))
	{
		sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]);
		return;
	}

	/* parc == 3 on nickchange, parc == 9 on new nick */
	if((IsClient(source_p) && (parc != 3)) || (IsServer(source_p) && ((parc != 9) && (parc != 10))))
	{
		char tbuf[BUFSIZE] = { 0 };
		int j;

		for (j = 0; j < parc; j++)
		{
			strcat(tbuf, parv[j]);
			strcat(tbuf, " ");
		}

		sendto_realops_flags(UMODE_ALL, L_ALL,
				     "Dropping server %s due to (invalid) command 'NICK' "
				     "with only %d arguments.  (Buf: '%s')",
				     client_p->name, parc, tbuf);
		ilog(L_CRIT, "Insufficient parameters (%d) for command 'NICK' from %s.  Buf: %s",
		     parc, client_p->name, tbuf);
		exit_client(client_p, client_p, client_p,
			    "Not enough arguments to server command.");
		return;
	}

	/* fix the length of the nick */
	strlcpy(nick, parv[1], sizeof(nick));

    if ((parc == 9) || (parc == 10))
	{
		if (check_clean_nick(client_p, source_p, nick, parv[1], parv[7]))
			return;
	}
	else
	{
		if (check_clean_nick(client_p, source_p, nick, parv[1], (char *)source_p->user->server))
			return;
	}

	if(parc == 9 || parc == 10)
	{
		if(check_clean_user(client_p, nick, parv[5], parv[7]) ||
		   check_clean_host(client_p, nick, parv[6], parv[7]))
			return;

		/* check the length of the clients gecos */
		if(strlen(parv[(parc > 9)? 9 : 8]) > REALLEN)
		{
			sendto_realops_flags(UMODE_ALL, L_ALL,
					     "Long realname from server %s for %s", parv[7],
					     parv[1]);
			parv[(parc > 9)? 9 : 8][REALLEN] = '\0';
		}

		if(IsServer(source_p))
			newts = atol(parv[3]);
	}
	else
	{
		if(!IsServer(source_p))
			newts = atol(parv[2]);
	}

	/* if the nick doesnt exist, allow it and process like normal */
	if(!(target_p = find_client(nick)))
	{
		nick_from_server(client_p, source_p, parc, parv, newts, nick);
		return;
	}

	/* we're not living in the past anymore, an unknown client is local only. */
	if(IsUnknown(target_p))
	{
		exit_client(NULL, target_p, &me, "Overridden");
		nick_from_server(client_p, source_p, parc, parv, newts, nick);
		return;
	}

	if(target_p == source_p)
	{
		if(strcmp(target_p->name, nick))
		{
			/* client changing case of nick */
			nick_from_server(client_p, source_p, parc, parv, newts, nick);
			return;
		}
		else
			/* client not changing nicks at all */
			return;
	}

	perform_nick_collides(source_p, client_p, target_p, parc, parv, newts, nick);


}
Example #8
0
/*
 * m_nick - message handler for local clients
 * parv[0] = sender prefix
 * parv[1] = nickname
 */
int m_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client* acptr;
  char           nick[NICKLEN + 2];
  char*          arg;
  char*          s;
  const char*    client_name;

  assert(0 != cptr);
  assert(cptr == sptr);

  if (IsServerPort(cptr))
    return exit_client(cptr, cptr, &me, "Use a different port");

  /*
   * parv[0] will be empty for clients connecting for the first time
   */
  client_name = (*(cli_name(sptr))) ? cli_name(sptr) : "*";

  if (parc < 2) {
    send_reply(sptr, ERR_NONICKNAMEGIVEN);
    return 0;
  }

  /*
   * Don't let them send make us send back a really long string of
   * garbage
   */
  arg = parv[1];
  if (strlen(arg) > IRCD_MIN(NICKLEN, feature_int(FEAT_NICKLEN)))
    arg[IRCD_MIN(NICKLEN, feature_int(FEAT_NICKLEN))] = '\0';

  if ((s = strchr(arg, '~')))
    *s = '\0';

  strcpy(nick, arg);

  /*
   * If do_nick_name() returns a null name then reject it.
   */
  if (0 == do_nick_name(nick)) {
    send_reply(sptr, ERR_ERRONEUSNICKNAME, arg);
    return 0;
  }

  /* 
   * Check if this is a LOCAL user trying to use a reserved (Juped)
   * nick, if so tell him that it's a nick in use...
   */
  if (isNickJuped(nick)) {
    send_reply(sptr, ERR_NICKNAMEINUSE, nick);
    return 0;                        /* NICK message ignored */
  }

  if (!(acptr = FindClient(nick))) {
    /*
     * No collisions, all clear...
     */
    return set_nick_name(cptr, sptr, nick, parc, parv);
  }
  if (IsServer(acptr)) {
    send_reply(sptr, ERR_NICKNAMEINUSE, nick);
    return 0;                        /* NICK message ignored */
  }
  /*
   * If acptr == sptr, then we have a client doing a nick
   * change between *equivalent* nicknames as far as server
   * is concerned (user is changing the case of his/her
   * nickname or somesuch)
   */
  if (acptr == sptr) {
    /*
     * If acptr == sptr, then we have a client doing a nick
     * change between *equivalent* nicknames as far as server
     * is concerned (user is changing the case of his/her
     * nickname or somesuch)
     */
    if (0 != strcmp(cli_name(acptr), nick)) {
      /*
       * Allows change of case in his/her nick
       */
      return set_nick_name(cptr, sptr, nick, parc, parv);
    }
    /*
     * This is just ':old NICK old' type thing.
     * Just forget the whole thing here. There is
     * no point forwarding it to anywhere,
     * especially since servers prior to this
     * version would treat it as nick collision.
     */
    return 0;
  }
  /*
   * Note: From this point forward it can be assumed that
   * acptr != sptr (point to different client structures).
   */
  assert(acptr != sptr);
  /*
   * If the older one is "non-person", the new entry is just
   * allowed to overwrite it. Just silently drop non-person,
   * and proceed with the nick. This should take care of the
   * "dormant nick" way of generating collisions...
   *
   * XXX - hmmm can this happen after one is registered?
   *
   * Yes, client 1 connects to IRC and registers, client 2 connects and
   * sends "NICK foo" but doesn't send anything more.  client 1 now does
   * /nick foo, they should succeed and client 2 gets disconnected with
   * the message below.
   */
  if (IsUnknown(acptr) && MyConnect(acptr)) {
    ServerStats->is_ref++;
    IPcheck_connect_fail(acptr);
    exit_client(cptr, acptr, &me, "Overridden by other sign on");
    return set_nick_name(cptr, sptr, nick, parc, parv);
  }
  /*
   * NICK is coming from local client connection. Just
   * send error reply and ignore the command.
   */
  send_reply(sptr, ERR_NICKNAMEINUSE, nick);
  return 0;                        /* NICK message ignored */
}
Example #9
0
/*
 * ms_svsnick()
 *
 *     parv[0] = sender prefix
 *     parv[1] = oldnick
 *     parv[2] = newnick
 */
static void ms_svsnick(struct Client *client_p, struct Client *source_p,
                       int parc, char *parv[])
{
	char     oldnick[NICKLEN];
	char     newnick[NICKLEN];
	struct   Client *oldnickname;
	struct   Client *newnickname;

	if (!IsServer(source_p))
		return;

	/* XXX BadPtr is needed */
	if(parc < 3 || BadPtr(parv[1]) || BadPtr(parv[2]))
	{
		sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
		           me.name, parv[0]);
		return;
	}

	/* terminate nick to NICKLEN */
	strlcpy(oldnick, parv[1], NICKLEN);
	strlcpy(newnick, parv[2], NICKLEN);

	if(!clean_nick_name(oldnick))
	{
		sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
		           me.name, parv[0], oldnick);
		return;
	}

	/* check the nickname is ok */
	if(!clean_nick_name(newnick))
	{
		sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
		           me.name, parv[0], newnick);
		return;
	}

	if(find_nick_resv(newnick) &&
	        !(IsOper(source_p) && ConfigChannel.oper_pass_resv))
	{
		sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
		           me.name, parv[0], newnick);
		return;
	}
	if(!(oldnickname = find_client(oldnick)))
	{
		sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, oldnick);
		return;
	}
	if(newnickname = find_client(newnick))
	{
		sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name,
		           parv[0], newnick);
		return;
	}
	if(MyConnect(oldnickname))
	{
		if(!IsFloodDone(oldnickname))
			flood_endgrace(oldnickname);
		if (newnickname = find_client(oldnick))
		{
			if(newnickname == oldnickname)
			{
				/* check the nick isnt exactly the same */
				if(strcmp(oldnickname->name, newnick))
				{
					change_local_nick(oldnickname->servptr, oldnickname, newnick);
					return;
				}
				else
				{
					/* client is doing :old NICK old
					* ignore it..
					*/
					return;
				}
			}
			/* if the client that has the nick isnt registered yet (nick but no
			 * user) then drop the unregged client
			 */
			if(IsUnknown(newnickname))
			{
				/* the old code had an if(MyConnect(target_p)) here.. but I cant see
				 * how that can happen, m_nick() is local only --fl_
				 */

				exit_client(NULL, newnickname, &me, "Overridden");
				change_local_nick(oldnickname->servptr, oldnickname, newnick);
				return;
			}
			else
			{
				sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name,
				           parv[0], newnick);
				return;
			}
		}
		else
		{
			if(!ServerInfo.hub && uplink && IsCapable(uplink, CAP_LL))
			{
				/* The uplink might know someone by this name already. */
				sendto_one(uplink, ":%s NBURST %s %s %s", me.name, newnick,
				           newnick, oldnickname->name);
				return;
			}
			else
			{
				change_local_nick(oldnickname->servptr, oldnickname, newnick);
				return;
			}
		}
	}
	else
	{
		sendto_server(client_p, source_p, NULL, CAP_SVNICK, NOCAPS, NOFLAGS,
		              ":%s SVSNICK %s %s", me.name, oldnick, newnick);
		return;
	}
}
Example #10
0
/*
 * m_nick()
 *
 *     parv[0] = sender prefix
 *     parv[1] = nickname
 */
static void
m_nick(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	char nick[NICKLEN];
	struct Client *target_p;

	if(parc < 2 || BadPtr(parv[1]))
	{
		sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]);
		return;
	}

	/* mark end of grace period, to prevent nickflooding */
	if(!IsFloodDone(source_p))
		flood_endgrace(source_p);

	/* terminate nick to NICKLEN */
	strlcpy(nick, parv[1], sizeof(nick));

	/* check the nickname is ok */
	if(!clean_nick_name(nick))
	{
		sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], nick);
		return;
	}

	if(find_nick_resv(nick))
	{
		sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
			   me.name, parv[0], nick);
		return;
	}

	if((target_p = find_client(nick)))
	{
		/* If(target_p == source_p) the client is changing nicks between
		 * equivalent nicknames ie: [nick] -> {nick}
		 */

		if(target_p == source_p)
		{
			/* check the nick isnt exactly the same */
			if(strcmp(target_p->name, nick))
			{
				change_local_nick(client_p, source_p, nick);
				return;
			}
			else
			{
				/* client is doing :old NICK old
				 * ignore it..
				 */
				return;
			}
		}

		/* if the client that has the nick isnt registered yet (nick but no
		 * user) then drop the unregged client
		 */
		if(IsUnknown(target_p))
		{
			/* the old code had an if(MyConnect(target_p)) here.. but I cant see
			 * how that can happen, m_nick() is local only --fl_
			 */

			exit_client(NULL, target_p, &me, "Overridden");
			change_local_nick(client_p, source_p, nick);
			return;
		}
		else
		{
			sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, parv[0], nick);
			return;
		}

	}
	else
	{
		change_local_nick(client_p, source_p, nick);
		return;
	}
}
Example #11
0
/*
 *  exit_client 
 * This is old "m_bye". Name  changed, because this is not a
 * protocol function, but a general server utility function.
 * 
 *      This function exits a client of *any* type (user, server, etc) 
 * from this server. Also, this generates all necessary prototol 
 * messages that this exit may cause. 
 * 
 *   1) If the client is a local client, then this implicitly exits
 * all other clients depending on this connection (e.g. remote
 * clients having 'from'-field that points to this. 
 * 
 *   2) If the client is a remote client, then only this is exited. 
 * 
 * For convenience, this function returns a suitable value for 
 * m_function return value: 
 * 
 *      FLUSH_BUFFER    if (cptr == sptr) 
 *      0 if (cptr != sptr)
 */
int 
exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment)
{
#ifdef  FNAME_USERLOG
    time_t on_for;
#endif
    
    if (MyConnect(sptr)) 
    {
        call_hooks(CHOOK_SIGNOFF, sptr);

        if (IsUnknown(sptr))
            Count.unknown--;
        if (IsAnOper(sptr)) 
            remove_from_list(&oper_list, sptr, NULL);
        if (sptr->flags & FLAGS_HAVERECVQ)
        {
            /* mark invalid, will be deleted in do_recvqs() */
            DLink *lp = find_dlink(recvq_clients, sptr);
            if (lp)
                lp->flags = -1;
        }
        if (IsClient(sptr))
            Count.local--;
        if (IsNegoServer(sptr))
            sendto_realops("Lost server %s during negotiation: %s", 
                           sptr->name, comment);
        
        if (IsServer(sptr)) 
        {
            Count.myserver--;
            if (IsULine(sptr))
                Count.myulined--;
            remove_from_list(&server_list, sptr, NULL);
            if (server_list == NULL) 
                server_was_split = YES;
        }
        sptr->flags |= FLAGS_CLOSING;
        if (IsPerson(sptr)) 
        {
            Link *lp, *next;
            LOpts *lopt = sptr->user->lopt;
            /* poof goes their watchlist! */
            hash_del_watch_list(sptr);
            /* if they have listopts, axe those, too */
            if(lopt != NULL) 
            {
                remove_from_list(&listing_clients, sptr, NULL);
                for (lp = lopt->yeslist; lp; lp = next) 
                {
                    next = lp->next;
                    MyFree(lp->value.cp);
                    free_link(lp);
                }
                for (lp = lopt->nolist; lp; lp = next) 
                {
                    next = lp->next;
                    MyFree(lp->value.cp);
                    free_link(lp);
                }
                                
                MyFree(sptr->user->lopt);
                sptr->user->lopt = NULL;
            }
            sendto_realops_lev(CCONN_LEV,
                               "Client exiting: %s (%s@%s) [%s] [%s]",
                               sptr->name, sptr->user->username,
                               sptr->user->host,
                               (sptr->flags & FLAGS_NORMALEX) ?
                               "Client Quit" : comment,
                               sptr->hostip);
        }
#ifdef FNAME_USERLOG
        on_for = timeofday - sptr->firsttime;
#endif
#if defined(USE_SYSLOG) && defined(SYSLOG_USERS)
        if (IsPerson(sptr))
            syslog(LOG_NOTICE, "%s (%3d:%02d:%02d): %s!%s@%s %d/%d\n",
                   myctime(sptr->firsttime),
                   on_for / 3600, (on_for % 3600) / 60,
                   on_for % 60, sptr->name,
                   sptr->user->username, sptr->user->host,
                   sptr->sendK, sptr->receiveK);
#endif
#if defined(FNAME_USERLOG)
        {
            char        linebuf[300];
            static int  logfile = -1;
            static long lasttime;
            
            /*
             * This conditional makes the logfile active only after it's
             * been created - thus logging can be turned off by removing
             * the file.
             * 
             * stop NFS hangs...most systems should be able to open a file in
             * 3 seconds. -avalon (curtesy of wumpus)
             * 
             * Keep the logfile open, syncing it every 10 seconds -Taner
             */
            if (IsPerson(sptr)) 
            {
                if (logfile == -1) 
                {
                    alarm(3);
                    logfile = open(FNAME_USERLOG, O_WRONLY | O_APPEND);
                    alarm(0);
                }
                ircsprintf(linebuf, "%s (%3d:%02d:%02d): %s!%s@%s %d/%d\n",
                           myctime(sptr->firsttime), on_for / 3600,
                           (on_for % 3600) / 60, on_for % 60,
                           sptr->name, sptr->user->username,
                           sptr->user->host, sptr->sendK, sptr->receiveK);
                alarm(3);
                write(logfile, linebuf, strlen(linebuf));
                alarm(0);
                /* Resync the file evey 10 seconds*/
                if (timeofday - lasttime > 10) 
                {
                    alarm(3);
                    close(logfile);
                    alarm(0);
                    logfile = -1;
                    lasttime = timeofday;
                }
            }
        }
#endif
        if (sptr->fd >= 0) 
        {
            if (cptr != NULL && sptr != cptr)
                sendto_one(sptr, "ERROR :Closing Link: %s %s (%s)",
                           IsPerson(sptr) ? sptr->sockhost : "0.0.0.0", 
                           sptr->name, comment);
            else
                sendto_one(sptr, "ERROR :Closing Link: %s (%s)",
                           IsPerson(sptr) ? sptr->sockhost : "0.0.0.0", 
                           comment);
        }
        /*
         * * Currently only server connections can have * depending
         * remote clients here, but it does no * harm to check for all
         * local clients. In * future some other clients than servers
         * might * have remotes too... *
         * 
         * Close the Client connection first and mark it * so that no
         * messages are attempted to send to it. *, The following *must*
         * make MyConnect(sptr) == FALSE!). * It also makes sptr->from ==
         * NULL, thus it's unnecessary * to test whether "sptr != acptr"
         * in the following loops.
         */
        if (IsServer(sptr)) 
        {
            sendto_ops("%s was connected for %lu seconds.  %lu/%lu "
                       "sendK/recvK.", sptr->name,
		       (long)(timeofday - sptr->firsttime),
                       sptr->sendK, sptr->receiveK);
#ifdef USE_SYSLOG
            syslog(LOG_NOTICE, "%s was connected for %lu seconds.  %lu/%lu "
                   "sendK/recvK.", sptr->name, 
                        (u_long) timeofday - sptr->firsttime,
                   sptr->sendK, sptr->receiveK);
#endif
            close_connection(sptr);
            sptr->sockerr = 0;
            sptr->flags |= FLAGS_DEADSOCKET;
        }
        else
        {
            close_connection(sptr);
            sptr->sockerr = 0;
            sptr->flags |= FLAGS_DEADSOCKET;
        }
                
    }
    exit_one_client(cptr, sptr, from, comment);
    return cptr == sptr ? FLUSH_BUFFER : 0;
}
Example #12
0
/** Check access for a server given its name (passed in cptr struct).
 * Must check for all C/N lines which have a name which matches the
 * name given and a host which matches. A host alias which is the
 * same as the server name is also acceptable in the host field of a
 * C/N line.
 * @param cptr Peer server to check.
 * @return 0 if accepted, -1 if access denied.
 */
int conf_check_server(struct Client *cptr)
{
  struct ConfItem* c_conf = NULL;
  struct SLink*    lp;

  Debug((DEBUG_DNS, "sv_cl: check access for %s[%s]", 
        cli_name(cptr), cli_sockhost(cptr)));

  if (IsUnknown(cptr) && !attach_confs_byname(cptr, cli_name(cptr), CONF_SERVER)) {
    Debug((DEBUG_DNS, "No C/N lines for %s", cli_sockhost(cptr)));
    return -1;
  }
  lp = cli_confs(cptr);
  /*
   * We initiated this connection so the client should have a C and N
   * line already attached after passing through the connect_server()
   * function earlier.
   */
  if (IsConnecting(cptr) || IsHandshake(cptr)) {
    c_conf = find_conf_byname(lp, cli_name(cptr), CONF_SERVER);
    if (!c_conf) {
      sendto_opmask_butone(0, SNO_OLDSNO,
                           "Connect Error: lost Connect block for %s",
                           cli_name(cptr));
      det_confs_butmask(cptr, 0);
      return -1;
    }
  }

  /* Try finding the Connect block by DNS name and IP next. */
  if (!c_conf && !(c_conf = find_conf_byhost(lp, cli_sockhost(cptr), CONF_SERVER)))
        c_conf = find_conf_byip(lp, &cli_ip(cptr), CONF_SERVER);

  /*
   * Attach by IP# only if all other checks have failed.
   * It is quite possible to get here with the strange things that can
   * happen when using DNS in the way the irc server does. -avalon
   */
  if (!c_conf)
    c_conf = find_conf_byip(lp, &cli_ip(cptr), CONF_SERVER);
  /*
   * detach all conf lines that got attached by attach_confs()
   */
  det_confs_butmask(cptr, 0);
  /*
   * if no Connect block, then deny access
   */
  if (!c_conf) {
    Debug((DEBUG_DNS, "sv_cl: access denied: %s[%s@%s]",
          cli_name(cptr), cli_username(cptr), cli_sockhost(cptr)));
    return -1;
  }
  /*
   * attach the Connect block to the client structure for later use.
   */
  attach_conf(cptr, c_conf);

  if (!irc_in_addr_valid(&c_conf->address.addr))
    memcpy(&c_conf->address.addr, &cli_ip(cptr), sizeof(c_conf->address.addr));

  Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]",
         cli_name(cptr), cli_sockhost(cptr)));
  return 0;
}
Example #13
0
/** Reload the configuration file.
 * @param cptr Client that requested rehash (if a signal, &me).
 * @param sig Type of rehash (0 = oper-requested, 1 = signal, 2 =
 *   oper-requested but do not restart resolver)
 * @return CPTR_KILLED if any client was K/G-lined because of the
 * rehash; otherwise 0.
 */
int rehash(struct Client *cptr, int sig)
{
  struct ConfItem** tmp = &GlobalConfList;
  struct ConfItem*  tmp2;
  struct Client*    acptr;
  int               i;
  int               ret = 0;
  int               found_g = 0;

  if (1 == sig)
    sendto_opmask_butone(0, SNO_OLDSNO,
                         "Got signal SIGHUP, reloading ircd conf. file");

  while ((tmp2 = *tmp)) {
    if (tmp2->clients) {
      /*
       * Configuration entry is still in use by some
       * local clients, cannot delete it--mark it so
       * that it will be deleted when the last client
       * exits...
       */
      if (CONF_CLIENT == (tmp2->status & CONF_CLIENT))
        tmp = &tmp2->next;
      else {
        *tmp = tmp2->next;
        tmp2->next = 0;
      }
      tmp2->status |= CONF_ILLEGAL;
    }
    else {
      *tmp = tmp2->next;
      free_conf(tmp2);
    }
  }
  conf_erase_crule_list();
  conf_erase_deny_list();
  conf_erase_webirc_list();
  conf_erase_shost_list();
  conf_erase_except_list();
  motd_clear();

  /*
   * delete the juped nicks list
   */
  clearNickJupes();

  clear_quarantines();

  class_mark_delete();
  mark_listeners_closing();
  auth_mark_closing();
  close_mappings();

  read_configuration_file();

  if (sig != 2)
    restart_resolver();

  log_reopen(); /* reopen log files */

  auth_close_unused();
  close_listeners();
  class_delete_marked();         /* unless it fails */

  /*
   * Flush out deleted I and P lines although still in use.
   */
  for (tmp = &GlobalConfList; (tmp2 = *tmp);) {
    if (CONF_ILLEGAL == (tmp2->status & CONF_ILLEGAL)) {
      *tmp = tmp2->next;
      tmp2->next = NULL;
      if (!tmp2->clients)
        free_conf(tmp2);
    }
    else
      tmp = &tmp2->next;
  }

  for (i = 0; i <= HighestFd; i++) {
    if ((acptr = LocalClientArray[i])) {
      assert(!IsMe(acptr));
      if (IsServer(acptr))
        det_confs_butmask(acptr, ~(CONF_UWORLD | CONF_ILLEGAL));
      /* Because admin's are getting so uppity about people managing to
       * get past K/G's etc, we'll "fix" the bug by actually explaining
       * whats going on.
       */
      if ((found_g = find_kill(acptr))) {
        sendto_opmask_butone(0, found_g > -1 ? SNO_GLINE : SNO_OPERKILL,
                             found_g == -2 ? "G-line active for %s%s" :
                             (found_g == -3 ? "Z-line active for %s%s" :
                             "K-line active for %s%s"),
                             IsUnknown(acptr) ? "Unregistered Client ":"",
                             get_client_name(acptr, SHOW_IP));
        if (exit_client(cptr, acptr, &me, found_g == -2 ? "G-lined" :
            (found_g == -3 ? "Z-lined" : "K-lined")) == CPTR_KILLED)
          ret = CPTR_KILLED;
      }
    }
  }

  attach_conf_uworld(&me);

  geoip_init();

  auth_send_event("rehash", NULL);

  return ret;
}
void Connection::SearchResponse(const char *pIP, unsigned short port)
{
    if (IsUnknown()) {
        return;
    }
    
    int length = COMMUNICATION_HEADER_LENGTH;
    
    if (IsClient()) {
        length += 1;
        
        char data[length];
        
        data[0] = 0x00;
        data[1] = CommunicationType_SearchResponse;
        data[2] = 0x01;
        data[3] = 0x00;
        data[4] = 0x01;
        
        m_pSocketUDP->CreateSender(pIP, port);
        m_pSocketUDP->SendData(data, length);
        return;
    }
    
    // クライアント配列に登録してクライアント番号を決めておく
    unsigned short clientNo = UNKNOWN_CLIENT_NO;
    for (int i = 0; i < MAX_MULTI_PLAYER; i++) {
        if (0 == m_pClients[i]) {
            char *pClientIp = new char[strlen(pIP)];
            memcpy(pClientIp, pIP, strlen(pIP));
            m_pClients[i] = new ConnectionClient(pClientIp, port);
            clientNo = i;
            break;
        }
    }
    
    const char *pSelfIP = CSocket::GetIP();
    unsigned short selfPort = m_port;
    
    int clientNoLength = 2;
    int portLength     = 2;
    int ipLength       = (int)(strlen(pSelfIP) + 1);
    int dataLength     = clientNoLength + portLength + ipLength;
    length            += dataLength;
    
    ToLittleEndian((char *)&dataLength, sizeof(int));
    ToLittleEndian((char *)&clientNo, sizeof(unsigned short));
    ToLittleEndian((char *)&selfPort, sizeof(unsigned short));
    
    char data[length];
    
    data[0] = 0x00;
    data[1] = CommunicationType_SearchResponse;
    data[2] = ((char *)&dataLength)[0];
    data[3] = ((char *)&dataLength)[1];
    data[4] = ((char *)&clientNo)[0];
    data[5] = ((char *)&clientNo)[1];
    data[6] = ((char *)&selfPort)[0];
    data[7] = ((char *)&selfPort)[1];
    
    for (int i = 0; i < ipLength; i++) {
        data[8 + i] = pSelfIP[i];
    }
    
    m_pSocketUDP->CreateSender(pIP, port);
    m_pSocketUDP->SendData(data, length);
}
Example #15
0
/** Handle a connection that has sent a valid PASS and SERVER.
 * @param cptr New peer server.
 * @param aconf Connect block for \a cptr.
 * @return Zero.
 */
int server_estab(struct Client *cptr, struct ConfItem *aconf)
{
  struct Client* acptr = 0;
  const char*    inpath;
  int            i;

  assert(0 != cptr);
  assert(0 != cli_local(cptr));

  inpath = cli_name(cptr);

  if (IsUnknown(cptr)) {
    if (aconf->passwd[0])
      sendrawto_one(cptr, MSG_PASS " :%s", aconf->passwd);
    /*
     *  Pass my info to the new server
     */
    sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6 :%s",
		  cli_name(&me), cli_serv(&me)->timestamp,
		  cli_serv(cptr)->timestamp, MAJOR_PROTOCOL, NumServCap(&me),
		  feature_bool(FEAT_HUB) ? "h" : "",
		  *(cli_info(&me)) ? cli_info(&me) : "IRCers United");
  }

  det_confs_butmask(cptr, CONF_SERVER | CONF_UWORLD);

  if (!IsHandshake(cptr))
    hAddClient(cptr);
  SetServer(cptr);
  cli_handler(cptr) = SERVER_HANDLER;
  Count_unknownbecomesserver(UserStats);
  SetBurst(cptr);

/*    nextping = CurrentTime; */

  /*
   * NOTE: check for acptr->user == cptr->serv->user is necessary to insure
   * that we got the same one... bleah
   */
  if (cli_serv(cptr)->user && *(cli_serv(cptr))->by &&
      (acptr = findNUser(cli_serv(cptr)->by))) {
    if (cli_user(acptr) == cli_serv(cptr)->user) {
      sendcmdto_one(&me, CMD_NOTICE, acptr, "%C :Link with %s established.",
                    acptr, inpath);
    }
    else {
      /*
       * if not the same client, set by to empty string
       */
      acptr = 0;
      *(cli_serv(cptr))->by = '\0';
    }
  }

  sendto_opmask_butone(acptr, SNO_OLDSNO, "Link with %s established.", inpath);
  cli_serv(cptr)->up = &me;
  cli_serv(cptr)->updown = add_dlink(&(cli_serv(&me))->down, cptr);
  sendto_opmask_butone(0, SNO_NETWORK, "Net junction: %s %s", cli_name(&me),
                       cli_name(cptr));
  SetJunction(cptr);
  /*
   * Old sendto_serv_but_one() call removed because we now
   * need to send different names to different servers
   * (domain name matching) Send new server to other servers.
   */
  for (i = 0; i <= HighestFd; i++)
  {
    if (!(acptr = LocalClientArray[i]) || !IsServer(acptr) ||
        acptr == cptr || IsMe(acptr))
      continue;
    if (!match(cli_name(&me), cli_name(cptr)))
      continue;
    sendcmdto_one(&me, CMD_SERVER, acptr,
		  "%s 2 0 %Tu J%02u %s%s +%s%s%s :%s", cli_name(cptr),
		  cli_serv(cptr)->timestamp, Protocol(cptr), NumServCap(cptr),
		  IsHub(cptr) ? "h" : "", IsService(cptr) ? "s" : "",
		  IsIPv6(cptr) ? "6" : "", cli_info(cptr));
  }

  /* Send these as early as possible so that glined users/juped servers can
   * be removed from the network while the remote server is still chewing
   * our burst.
   */
  gline_burst(cptr);
  jupe_burst(cptr);

  /*
   * Pass on my client information to the new server
   *
   * First, pass only servers (idea is that if the link gets
   * canceled because the server was already there,
   * there are no NICK's to be canceled...). Of course,
   * if cancellation occurs, all this info is sent anyway,
   * and I guess the link dies when a read is attempted...? --msa
   *
   * Note: Link cancellation to occur at this point means
   * that at least two servers from my fragment are building
   * up connection this other fragment at the same time, it's
   * a race condition, not the normal way of operation...
   */

  for (acptr = &me; acptr; acptr = cli_prev(acptr)) {
    /* acptr->from == acptr for acptr == cptr */
    if (cli_from(acptr) == cptr)
      continue;
    if (IsServer(acptr)) {
      const char* protocol_str;

      if (Protocol(acptr) > 9)
        protocol_str = IsBurst(acptr) ? "J" : "P";
      else
        protocol_str = IsBurst(acptr) ? "J0" : "P0";

      if (0 == match(cli_name(&me), cli_name(acptr)))
        continue;
      sendcmdto_one(cli_serv(acptr)->up, CMD_SERVER, cptr,
		    "%s %d 0 %Tu %s%u %s%s +%s%s%s :%s", cli_name(acptr),
		    cli_hopcount(acptr) + 1, cli_serv(acptr)->timestamp,
		    protocol_str, Protocol(acptr), NumServCap(acptr),
		    IsHub(acptr) ? "h" : "", IsService(acptr) ? "s" : "",
		    IsIPv6(acptr) ? "6" : "", cli_info(acptr));
    }
  }

  for (acptr = &me; acptr; acptr = cli_prev(acptr))
  {
    /* acptr->from == acptr for acptr == cptr */
    if (cli_from(acptr) == cptr)
      continue;
    if (IsUser(acptr))
    {
      char xxx_buf[25];
      char *s = umode_str(acptr);
      sendcmdto_one(cli_user(acptr)->server, CMD_NICK, cptr,
		    "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
		    cli_name(acptr), cli_hopcount(acptr) + 1, cli_lastnick(acptr),
		    cli_user(acptr)->username, cli_user(acptr)->realhost,
		    *s ? "+" : "", s, *s ? " " : "",
		    iptobase64(xxx_buf, &cli_ip(acptr), sizeof(xxx_buf), IsIPv6(cptr)),
		    NumNick(acptr), cli_info(acptr));
    }
  }
  /*
   * Last, send the BURST.
   * (Or for 2.9 servers: pass all channels plus statuses)
   */
  {
    struct Channel *chptr;
    for (chptr = GlobalChannelList; chptr; chptr = chptr->next)
      send_channel_modes(cptr, chptr);
  }
  sendcmdto_one(&me, CMD_END_OF_BURST, cptr, "");
  return 0;
}
/* Rewritten by Run - 24 sept 94 */
static void exit_one_client(struct Client* bcptr, const char* comment)
{
  struct SLink *lp;
  struct Ban *bp;

  if (cli_serv(bcptr) && cli_serv(bcptr)->client_list)  /* Was SetServerYXX called ? */
    ClearServerYXX(bcptr);      /* Removes server from server_list[] */
  if (IsUser(bcptr)) {
    /*
     * clear out uping requests
     */
    if (IsUPing(bcptr))
      uping_cancel(bcptr, 0);
    /*
     * Stop a running /LIST clean
     */
    if (MyUser(bcptr) && cli_listing(bcptr)) {
      MyFree(cli_listing(bcptr));
      cli_listing(bcptr) = NULL;
    }
    /*
     * If a person is on a channel, send a QUIT notice
     * to every client (person) on the same channel (so
     * that the client can show the "**signoff" message).
     * (Note: The notice is to the local clients *only*)
     */
    sendcmdto_common_channels_butone(bcptr, CMD_QUIT, NULL, ":%s", comment);

    remove_user_from_all_channels(bcptr);

    /* Clean up invitefield */
    while ((lp = cli_user(bcptr)->invited))
      del_invite(bcptr, lp->value.chptr);

    /* Clean up silencefield */
    while ((bp = cli_user(bcptr)->silence)) {
      cli_user(bcptr)->silence = bp->next;
      free_ban(bp);
    }

    /* Clean up snotice lists */
    if (MyUser(bcptr))
      set_snomask(bcptr, ~0, SNO_DEL);

    if (IsInvisible(bcptr)) {
      assert(UserStats.inv_clients > 0);
      --UserStats.inv_clients;
    }
    if (IsOper(bcptr)) {
      assert(UserStats.opers > 0);
      --UserStats.opers;
    }
    if (MyConnect(bcptr))
      Count_clientdisconnects(bcptr, UserStats);
    else
      Count_remoteclientquits(UserStats, bcptr);
  }
  else if (IsServer(bcptr))
  {
    /* Remove downlink list node of uplink */
    remove_dlink(&(cli_serv(cli_serv(bcptr)->up))->down, cli_serv(bcptr)->updown);
    cli_serv(bcptr)->updown = 0;

    if (MyConnect(bcptr))
      Count_serverdisconnects(UserStats);
    else
      Count_remoteserverquits(UserStats);
  }
  else if (IsMe(bcptr))
  {
    sendto_opmask_butone(0, SNO_OLDSNO, "ERROR: tried to exit me! : %s",
			 comment);
    return;                     /* ...must *never* exit self! */
  }
  else if (IsUnknown(bcptr) || IsConnecting(bcptr) || IsHandshake(bcptr))
    Count_unknowndisconnects(UserStats);

  /*
   * Update IPregistry
   */
  if (IsIPChecked(bcptr))
    IPcheck_disconnect(bcptr);

  /* 
   * Remove from serv->client_list
   * NOTE: user is *always* NULL if this is a server
   */
  if (cli_user(bcptr)) {
    assert(!IsServer(bcptr));
    /* bcptr->user->server->serv->client_list[IndexYXX(bcptr)] = NULL; */
    RemoveYXXClient(cli_user(bcptr)->server, cli_yxx(bcptr));
  }

  /* Remove bcptr from the client list */
#ifdef DEBUGMODE
  if (hRemClient(bcptr) != 0)
    Debug((DEBUG_ERROR, "%p !in tab %s[%s] %p %p %p %d %d %p",
          bcptr, cli_name(bcptr), cli_from(bcptr) ? cli_sockhost(cli_from(bcptr)) : "??host",
          cli_from(bcptr), cli_next(bcptr), cli_prev(bcptr), cli_fd(bcptr),
          cli_status(bcptr), cli_user(bcptr)));
#else
  hRemClient(bcptr);
#endif
  remove_client_from_list(bcptr);
}
Example #17
0
/*
 * m_webirc
 * parv[0] = sender prefix
 * parv[1] = password that authenticates the WEBIRC command from this client
 * parv[2] = username or client requesting spoof (cgiirc defaults to cgiirc)
 * parv[3] = hostname of user
 * parv[4] = IP address of user
 */
int m_webirc(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    char oldusername[USERLEN + 1];
    struct userBan *ban;
    int i;

    if (parc < 5 || *parv[1] == '\0' || *parv[2] == '\0' ||
	*parv[3] == '\0' || *parv[4] == '\0')
    {
	sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "WEBIRC");
	return 0;
    }
    if (!MyConnect(sptr) || !IsUnknown(cptr) || cptr->receiveM != 1)
    {
	sendto_one(sptr, err_str(ERR_ALREADYREGISTRED), me.name, parv[0]);
	return 0;
    }

    strncpyzt(oldusername, cptr->username, USERLEN + 1);
    make_user(cptr);
    if (!(cptr->flags & FLAGS_GOTID))
	strcpy(cptr->username, "webirc");
    i = attach_Iline(cptr, cptr->hostp, cptr->sockhost);
    if (i == 0)
    {
	aAllow *pwaconf = sptr->user->allow;

	if (BadPtr(pwaconf->passwd) ||
	    strncmp(pwaconf->passwd, "webirc.", strlen("webirc.")) != 0)
	{
	    sendto_one(sptr, "NOTICE * :Not a CGI:IRC auth block");
	    i = -1;
	}
	else if (!StrEq(parv[1], pwaconf->passwd + strlen("webirc.")))
	{
	    sendto_one(sptr, "NOTICE * :CGI:IRC password incorrect");
	    i = -1;
	}
	else if (pwaconf->flags & CONF_FLAGS_NOTHROTTLE)
	    throttle_remove(cptr->sockhost);
    }
    clear_conflinks(cptr);
    free_user(cptr->user, cptr);
    cptr->user = NULL;
    cptr->flags &= ~FLAGS_DOID;
    strncpyzt(cptr->username, oldusername, USERLEN + 1);
    if (i != 0)
	return 0;

    if (inet_pton(AF_INET, parv[4], &cptr->ip.ip4))
	cptr->ip_family = AF_INET;
    else if (inet_pton(AF_INET6, parv[4], &cptr->ip.ip6))
	cptr->ip_family = AF_INET6;
    else
    {
	sendto_one(sptr, "NOTICE * :Invalid IP");
	return 0;
    }

    if (cptr->flags & FLAGS_GOTID)
    {
	cptr->webirc_username = MyMalloc(strlen(cptr->username) + 1);
	strcpy(cptr->webirc_username, cptr->username);
    }
    else
    {
	cptr->webirc_username = MyMalloc(strlen(parv[2]) + 1);
	strcpy(cptr->webirc_username, parv[2]);
    }
    cptr->webirc_ip = MyMalloc(strlen(cptr->sockhost) + 1);
    strcpy(cptr->webirc_ip, cptr->sockhost);

    get_sockhost(cptr, parv[3]);
    cptr->hostp = NULL;

    /*
     * Acknowledge that WEBIRC was accepted, and flush the client's send queue
     * to make debugging easier.
     */
    sendto_one(sptr, ":%s NOTICE AUTH :*** CGI:IRC host/IP set to %s %s",
	       me.name, cptr->sockhost, parv[4]);
    dump_connections(cptr->fd);

    /* if they are throttled, drop them silently. */
    if (throttle_check(parv[4], cptr->fd, NOW) == 0)
    {
	cptr->flags |= FLAGS_DEADSOCKET;

	ircstp->is_ref++;
	ircstp->is_throt++;
	return exit_client(cptr, sptr, &me, "Client throttled");
    }

    ban = check_userbanned(cptr, UBAN_IP|UBAN_CIDR4|UBAN_WILDUSER, 0);
    if(ban)
    {
	int loc = (ban->flags & UBAN_LOCAL) ? 1 : 0;

	ircstp->is_ref++;
	ircstp->is_ref_2++;
	return exit_banned_client(cptr, loc, loc ? 'K' : 'A', ban->reason, 0);
    }
    return 0;
}
Example #18
0
/*
 * ms_nick - server message handler for nicks
 * parv[0] = sender prefix
 * parv[1] = nickname
 *
 * If from server, source is client:
 *   parv[2] = timestamp
 *
 * Source is server:
 *   parv[2] = hopcount
 *   parv[3] = timestamp
 *   parv[4] = username
 *   parv[5] = hostname
 *   parv[6] = umode (optional)
 *   parv[parc-3] = IP#                 <- Only Protocol >= 10
 *   parv[parc-2] = YXX, numeric nick   <- Only Protocol >= 10
 *   parv[parc-1] = info
 *   parv[0] = server
 */
int ms_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client *acptr;
  char nick[NICKLEN + 2];
  time_t lastnick = 0;
  int differ = 1;
  const char *type;

  assert(0 != cptr);
  assert(0 != sptr);
  assert(IsServer(cptr));

  if ((IsServer(sptr) && parc < 8) || parc < 3)
  {
    sendto_opmask_butone(0, SNO_OLDSNO, "bad NICK param count for %s from %C",
			 parv[1], cptr);
    return need_more_params(sptr, "NICK");
  }

  ircd_strncpy(nick, parv[1], NICKLEN);
  nick[NICKLEN] = '\0';

  if (IsServer(sptr))
  {
    lastnick = atoi(parv[3]);
    if (lastnick > OLDEST_TS && !IsBurstOrBurstAck(sptr)) 
      cli_serv(sptr)->lag = TStime() - lastnick;
  }
  else
  {
    lastnick = atoi(parv[2]); 
    if (lastnick > OLDEST_TS && !IsBurstOrBurstAck(sptr))
      cli_serv(cli_user(sptr)->server)->lag = TStime() - lastnick;
  }
  /*
   * If do_nick_name() returns a null name OR if the server sent a nick
   * name and do_nick_name() changed it in some way (due to rules of nick
   * creation) then reject it. If from a server and we reject it,
   * and KILL it. -avalon 4/4/92
   */
  if (!do_nick_name(nick) || strcmp(nick, parv[1]))
  {
    send_reply(sptr, ERR_ERRONEUSNICKNAME, parv[1]);
    
    ++ServerStats->is_kill;
    sendto_opmask_butone(0, SNO_OLDSNO, "Bad Nick: %s From: %s %C", parv[1],
			 parv[0], cptr);
    sendcmdto_one(&me, CMD_KILL, cptr, "%s :%s (%s <- %s[%s])",
		  IsServer(sptr) ? parv[parc - 2] : parv[0], cli_name(&me), parv[1],
		  nick, cli_name(cptr));
    if (!IsServer(sptr))
    {
      /*
       * bad nick _change_
       */
      sendcmdto_serv_butone(&me, CMD_KILL, 0, "%s :%s (%s <- %s!%s@%s)",
			    parv[0], cli_name(&me), cli_name(cptr), parv[0],
			    cli_user(sptr) ? cli_username(sptr) : "",
			    cli_user(sptr) ? cli_name(cli_user(sptr)->server) :
			    cli_name(cptr));
    }
    return 0;
  }
  /* Check against nick name collisions. */
  if ((acptr = FindClient(nick)) == NULL)
    /* No collisions, all clear... */
    return set_nick_name(cptr, sptr, nick, parc, parv);

  /*
   * If acptr == sptr, then we have a client doing a nick
   * change between *equivalent* nicknames as far as server
   * is concerned (user is changing the case of his/her
   * nickname or somesuch)
   */
  if (acptr == sptr)
  {
    if (strcmp(cli_name(acptr), nick) != 0)
      /* Allows change of case in his/her nick */
      return set_nick_name(cptr, sptr, nick, parc, parv);
    else
      /* Setting their nick to what it already is? Ignore it. */
      return 0;
  }
  /* now we know we have a real collision. */
  /*
   * Note: From this point forward it can be assumed that
   * acptr != sptr (point to different client structures).
   */
  assert(acptr != sptr);
  /*
   * If the older one is "non-person", the new entry is just
   * allowed to overwrite it. Just silently drop non-person,
   * and proceed with the nick. This should take care of the
   * "dormant nick" way of generating collisions...
   */
  if (IsUnknown(acptr) && MyConnect(acptr))
  {
    ServerStats->is_ref++;
    IPcheck_connect_fail(acptr);
    exit_client(cptr, acptr, &me, "Overridden by other sign on");
    return set_nick_name(cptr, sptr, nick, parc, parv);
  }
  /*
   * Decide, we really have a nick collision and deal with it
   */
  /*
   * NICK was coming from a server connection.
   * This means we have a race condition (two users signing on
   * at the same time), or two net fragments reconnecting with the same nick.
   * The latter can happen because two different users connected
   * or because one and the same user switched server during a net break.
   * If the TimeStamps are equal, we kill both (or only 'new'
   * if it was a ":server NICK new ...").
   * Otherwise we kill the youngest when user@host differ,
   * or the oldest when they are the same.
   * We treat user and ~user as different, because if it wasn't
   * a faked ~user the AUTH wouldn't have added the '~'.
   * --Run
   *
   */
  if (IsServer(sptr))
  {
    struct irc_in_addr ip;
    /*
     * A new NICK being introduced by a neighbouring
     * server (e.g. message type ":server NICK new ..." received)
     *
     * compare IP address and username
     */
    base64toip(parv[parc - 3], &ip);
    differ =  (0 != memcmp(&cli_ip(acptr), &ip, sizeof(cli_ip(acptr)))) ||
              (0 != ircd_strcmp(cli_user(acptr)->username, parv[4]));
    sendto_opmask_butone(0, SNO_OLDSNO, "Nick collision on %C (%C %Tu <- "
			 "%C %Tu (%s user@host))", acptr, cli_from(acptr),
			 cli_lastnick(acptr), cptr, lastnick,
			 differ ? "Different" : "Same");
  }
  else
  {
    /*
     * A NICK change has collided (e.g. message type ":old NICK new").
     *
     * compare IP address and username
     */
    differ =  (0 != memcmp(&cli_ip(acptr), &cli_ip(sptr), sizeof(cli_ip(acptr)))) ||
              (0 != ircd_strcmp(cli_user(acptr)->username, cli_user(sptr)->username));
    sendto_opmask_butone(0, SNO_OLDSNO, "Nick change collision from %C to "
			 "%C (%C %Tu <- %C %Tu)", sptr, acptr, cli_from(acptr),
			 cli_lastnick(acptr), cptr, lastnick);
  }
  type = differ ? "overruled by older nick" : "nick collision from same user@host";
  /*
   * Now remove (kill) the nick on our side if it is the youngest.
   * If no timestamp was received, we ignore the incoming nick
   * (and expect a KILL for our legit nick soon ):
   * When the timestamps are equal we kill both nicks. --Run
   * acptr->from != cptr should *always* be true (?).
   *
   * This exits the client sending the NICK message
   */
  if ((differ && lastnick >= cli_lastnick(acptr)) ||
      (!differ && lastnick <= cli_lastnick(acptr)))
  {
    ServerStats->is_kill++;
    if (!IsServer(sptr))
    {
      /* If this was a nick change and not a nick introduction, we
       * need to ensure that we remove our record of the client, and
       * send a KILL to the whole network.
       */
      assert(!MyConnect(sptr));
      /* Inform the rest of the net... */
      sendcmdto_serv_butone(&me, CMD_KILL, 0, "%C :%s (%s)",
                            sptr, cli_name(&me), type);
      /* Don't go sending off a QUIT message... */
      SetFlag(sptr, FLAG_KILLED);
      /* Remove them locally. */
      exit_client_msg(cptr, sptr, &me,
                      "Killed (%s (%s))",
                      feature_str(FEAT_HIS_SERVERNAME), type);
    }
    else
    {
      /* If the origin is a server, this was a new client, so we only
       * send the KILL in the direction it came from.  We have no
       * client record that we would have to clean up.
       */
      sendcmdto_one(&me, CMD_KILL, cptr, "%s :%s (%s)",
                    parv[parc - 2], cli_name(&me), type);
    }
    /* If the timestamps differ and we just killed sptr, we don't need to kill
     * acptr as well.
     */
    if (lastnick != cli_lastnick(acptr))
      return 0;
  }
  /* Tell acptr why we are killing it. */
  send_reply(acptr, ERR_NICKCOLLISION, nick);

  ServerStats->is_kill++;
  SetFlag(acptr, FLAG_KILLED);
  /*
   * This exits the client we had before getting the NICK message
   */
  sendcmdto_serv_butone(&me, CMD_KILL, NULL, "%C :%s (%s)",
                        acptr, feature_str(FEAT_HIS_SERVERNAME),
                        type);
  exit_client_msg(cptr, acptr, &me, "Killed (%s (%s))",
                  feature_str(FEAT_HIS_SERVERNAME), type);
  if (lastnick == cli_lastnick(acptr))
    return 0;
  if (sptr == NULL)
    return 0;
  return set_nick_name(cptr, sptr, nick, parc, parv);
}
Example #19
0
/*
 * m_notice - generic message handler
 */
int m_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char*           name;
  char*           server;
  int             ret = 0;
  int             i;
  int             j;
  int             fd = 0;
  int             count;
  char            *clean;
  char*           vector[MAXTARGETS];
  char*           temp; /* added by Vadtec 02/25/2008 */
  char*           parv_temp; /* added by Vadtec 02/26/2008 */
  int             found_g = 0; /* added by Vadtec 02/26/2008 */
  int             sent = 0; /* added by Vadtec 03/13/2008 */
  struct Client*  acptr; /* added by Vadtec 02/26/2008 */
  struct Channel* chptr; /* added by Vadtec 02/27/2008 */
  int             isdcc = 0;

  assert(0 != cptr);
  assert(cptr == sptr);

  ClrFlag(sptr, FLAG_TS8);

  if (parc < 2 || EmptyString(parv[1]))
    return send_reply(sptr, ERR_NORECIPIENT, MSG_NOTICE);

  if (parc < 3 || EmptyString(parv[parc - 1]))
    return send_reply(sptr, ERR_NOTEXTTOSEND);

  if (parv[1][0] == '@' && IsChannelPrefix(parv[1][1])) {
    parv[1]++;                        /* Get rid of '@' */
    return m_wallchops(cptr, sptr, parc, parv);
  }

  count = unique_name_vector(parv[1], ',', vector, MAXTARGETS);

  /* Check here to make sure that the client is ours so we dont respond to NOTICES from other server's users. - Vadtec 02/25/2008 */
  /* Also, check to make sure that the notice is actually destined for the *server* and not another user. That way we don't process
     some user saying "what version do you use" to another user via notice. - Vadtec 03/13/2008 */
  if (feature_bool(FEAT_CTCP_VERSIONING) && MyConnect(sptr) && !strcmp(parv[1], cli_name(&me))) {
    /*
     Added by Vadtec 02/25/2008.
     This is so that we can do version checking (and banning) of connecting clients.
     Rules: Only one really. CTCP VERSION is not part of the RFC and therefore clients are not required to respond to
     a request for their version.
     NOTE: If we are lucky enough to have _GNU_SOURCE, we will use it over the standard strstr because its case insensetive.
           This should help against clients that like to send lower case CTCPs from slipping through as easily with only one
           function call.
    */
    for (fd = HighestFd; fd >= 0 && !sent; --fd) { /* Added the "sent" check here so that if we have already sent the notice
                                                      we don't needlessly loop through *all* the users - Vadtec 03/13/2008 */
      if ((acptr = LocalClientArray[fd])) {
        if (!cli_user(acptr))
          continue;

        #ifdef _GNU_SOURCE
        if ((temp = strcasestr(parv[2], "\x01VERSION"))) { /* added \x01 to the string so that it will *only* respond to CTCP version
                                                              replies. Seems redundant, but we dont want the users doing
                                                              /notice <server> version (and getting away with it) - Vadtec 03/13/2008 */
          temp = strchrnul(parv[2], ' '); /* Moved this here to take advantage of strchrnul - added by Vadtec 03/13/2008 */
        #else
        if ((temp = strstr(parv[2], "\x01VERSION")) || (temp = strstr(parv[2], "\x01version"))) { /* See above comment about \x01 - Vadtec */
          temp = strchr(parv[2], ' '); /* Moved this here to take advantage of strchrnul - added by Vadtec 03/13/2008 */
          if (temp == 0)
            temp = parv[2] + strlen(parv[2]); /* This does the same thing as strchrnul - Vadtec */
        #endif
          parv_temp = parv[2];
          j = 0;
          while (j <= (temp - parv[2])) { parv_temp++; j++; }

          clean = normalizeBuffer(parv_temp);
          doCleanBuffer((char *) clean);

          ircd_strncpy(cli_version(sptr), normalizeBuffer(clean), VERSIONLEN);
          sendcmdto_serv_butone(&me, CMD_MARK, cptr, "%s %s :%s", cli_name(sptr), MARK_CVERSION, cli_version(sptr));

          /* Moved here to solve duplicate MARK's if any of the CTCP_* conditions were false 05/13/2009 */
          sent = 1;

          if (feature_bool(FEAT_CTCP_VERSIONING_CHAN)) {
            sprintf(temp, "%s has version \002%s\002", cli_name(sptr), cli_version(sptr));
            /* Announce to channel. */
            if ((chptr = FindChannel(feature_str(FEAT_CTCP_VERSIONING_CHANNAME)))) {
              if (feature_bool(FEAT_CTCP_VERSIONING_USEMSG))
                sendcmdto_channel_butone(&me, CMD_PRIVATE, chptr, cptr, SKIP_DEAF | SKIP_BURST, '\0', "%H :%s", chptr, temp);
              else
                sendcmdto_channel_butone(&me, CMD_NOTICE, chptr, cptr, SKIP_DEAF | SKIP_BURST, '\0', "%H :%s", chptr, temp);
              /* Removed sent=1 from here because it caused the MARK above to be sent
                 more then once if any of the conditions leading here are false 05/13/2009 */
            }
          }

          if (feature_bool(FEAT_CTCP_VERSIONING_KILL)) {
            if ((found_g = find_kill(acptr))) {
              sendto_opmask_butone(0, found_g == -2 ? SNO_GLINE : SNO_OPERKILL,
                                   found_g == -2 ? "G-line active for %s%s" :
                                   "K-line active for %s%s",
                                   IsUnknown(sptr) ? "Unregistered Client ":"",
                                   get_client_name(sptr, SHOW_IP));
              return exit_client_msg(cptr, acptr, &me, "Banned Client: %s", cli_version(acptr));
            }
          }
          else
            return 0;
        }
      }
    }
  }

  for (i = 0; i < count; ++i) {
    name = vector[i];
    if (IsChannelPrefix(*name)) {
      ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_CHANNOTICE, name);
      if (ret != 0) {
        if (ret == 2)
          return CPTR_KILLED;
        else
          return 0;
      }
    } else {
      #ifdef _GNU_SOURCE
      if ((temp = strcasestr(parv[2], "\001DCC"))) {
        temp = strchrnul(parv[2], ' ');
      #else
      if ((temp = strstr(parv[2], "\001DCC")) || (temp = strstr(parv[2], "\001dcc"))) {
        temp = strchr(parv[2], ' ');
      #endif
        isdcc = 1;
        ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_DCC, name);
        if (ret != 0) {
          if (ret == 2)
            return CPTR_KILLED;
          else
            return 0;
        }
      }

      if (!isdcc) {
        ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_NOTICE, name);
        if (ret != 0) {
          if (ret == 2)
            return CPTR_KILLED;
          else
            return 0;
        }
      }
    }
  }
  i = 0;

  for (i = 0; i < count; ++i) {
    name = vector[i];
    /*
     * channel msg?
     */
    if (IsChannelPrefix(*name)) {
      relay_channel_notice(sptr, name, parv[parc - 1], count);
    }
    /*
     * we have to check for the '@' at least once no matter what we do
     * handle it first so we don't have to do it twice
     */
    else if ((server = strchr(name, '@')))
      relay_directed_notice(sptr, name, server, parv[parc - 1]);
    else 
      relay_private_notice(sptr, name, parv[parc - 1]);
  }
  return 0;
}

/*
 * ms_notice - server message handler
 */
int ms_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char* name;
  char* server;

  ClrFlag(sptr, FLAG_TS8);

  if (parc < 3) {
    /*
     * we can't deliver it, sending an error back is pointless
     */
    return protocol_violation(sptr,"Not enough params for NOTICE");
  }
  name = parv[1];
  /*
   * channel msg?
   */
  if (IsChannelPrefix(*name)) {
    server_relay_channel_notice(sptr, name, parv[parc - 1]);
  }
  /*
   * coming from another server, we have to check this here
   */
  else if ('$' == *name && IsOper(sptr)) {
    server_relay_masked_notice(sptr, name, parv[parc - 1]);
  }
  else if ((server = strchr(name, '@'))) {
    /*
     * XXX - can't get away with not doing everything
     * relay_directed_notice has to do
     */
    relay_directed_notice(sptr, name, server, parv[parc - 1]);
  }
  else {
    server_relay_private_notice(sptr, name, parv[parc - 1]);
  }
  return 0;
}

/*
 * mo_notice - oper message handler
 */
int mo_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char*           name;
  char*           server;
  int             i;
  int             count;
  char*           vector[MAXTARGETS];
  assert(0 != cptr);
  assert(cptr == sptr);

  ClrFlag(sptr, FLAG_TS8);

  if (parc < 2 || EmptyString(parv[1]))
    return send_reply(sptr, ERR_NORECIPIENT, MSG_NOTICE);

  if (parc < 3 || EmptyString(parv[parc - 1]))
    return send_reply(sptr, ERR_NOTEXTTOSEND);

  if (parv[1][0] == '@' && IsChannelPrefix(parv[1][1])) {
    parv[1]++;                        /* Get rid of '@' */
    return m_wallchops(cptr, sptr, parc, parv);
  }

  count = unique_name_vector(parv[1], ',', vector, MAXTARGETS);

  for (i = 0; i < count; ++i) {
    name = vector[i];
    /*
     * channel msg?
     */
    if (IsChannelPrefix(*name))
      relay_channel_notice(sptr, name, parv[parc - 1], count);

    else if (*name == '$')
      relay_masked_notice(sptr, name, parv[parc - 1]);

    else if ((server = strchr(name, '@')))
      relay_directed_notice(sptr, name, server, parv[parc - 1]);

    else 
      relay_private_notice(sptr, name, parv[parc - 1]);
  }
  return 0;
}
Example #20
0
void	tstats(aClient *cptr, char *name)
{
	Reg	aClient	*acptr;
	Reg	int	i;
	Reg	struct stats	*sp;
	struct	stats	tmp;

	sp = &tmp;
	bcopy((char *)ircstp, (char *)sp, sizeof(*sp));
	for (i = 0; i < MAXCONNECTIONS; i++)
	    {
		if (!(acptr = local[i]))
			continue;
		if (IsServer(acptr))
		    {
			sp->is_sbs += acptr->sendB;
			sp->is_sbr += acptr->receiveB;
			sp->is_sti += timeofday - acptr->firsttime;
			sp->is_sv++;
		    }
		else if (IsClient(acptr))
		    {
			sp->is_cbs += acptr->sendB;
			sp->is_cbr += acptr->receiveB;
			sp->is_cti += timeofday - acptr->firsttime;
			sp->is_cl++;
		    }
		else if (IsUnknown(acptr))
			sp->is_ni++;
	    }

	sendto_one(cptr, ":%s %d %s :accepts %lu refused %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_ac, sp->is_ref);
	sendto_one(cptr, ":%s %d %s :unknown: commands %lu prefixes %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_unco, sp->is_unpf);
	sendto_one(cptr, ":%s %d %s :nick collisions %lu saves %lu, unknown closes %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_kill, sp->is_save, sp->is_ni);
	sendto_one(cptr, ":%s %d %s :wrong direction %lu empty %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_wrdi, sp->is_empt);
	sendto_one(cptr, ":%s %d %s :users without servers %lu ghosts N/A",
		   ME, RPL_STATSDEBUG, name, sp->is_nosrv);
	sendto_one(cptr, ":%s %d %s :numerics seen %lu mode fakes %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_num, sp->is_fake);
	sendto_one(cptr, ":%s %d %s :auth: successes %lu fails %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_asuc, sp->is_abad);
	sendto_one(cptr,":%s %d %s :local connections %lu udp packets %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_loc, sp->is_udpok);
	sendto_one(cptr,":%s %d %s :udp errors %lu udp dropped %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_udperr, sp->is_udpdrop);
	sendto_one(cptr,
   ":%s %d %s :link checks %lu passed %lu 15s/%lu 30s dropped %luSq/%luYg/%luFl",
		   ME, RPL_STATSDEBUG, name, sp->is_ckl, sp->is_cklq,
		   sp->is_cklok, sp->is_cklQ, sp->is_ckly, sp->is_cklno);
	if (sp->is_wwcnt)
		sendto_one(cptr, ":%s %d %s :whowas turnover %lu/%lu/%lu [%lu]",
			   ME, RPL_STATSDEBUG, name, sp->is_wwmt,
			   (u_int) (sp->is_wwt / sp->is_wwcnt), sp->is_wwMt,
			   KILLCHASETIMELIMIT);
	if (sp->is_lkcnt)
		sendto_one(cptr, ":%s %d %s :ndelay turnover %lu/%lu/%lu [%lu]",
			   ME, RPL_STATSDEBUG, name, sp->is_lkmt,
			   (u_int) (sp->is_lkt / sp->is_lkcnt), sp->is_lkMt,
			   DELAYCHASETIMELIMIT);
	sendto_one(cptr, ":%s %d %s :abuse protections %u strict %u", ME,
		   RPL_STATSDEBUG, name, (bootopt & BOOT_PROT) ? 1 : 0,
		   (bootopt & BOOT_STRICTPROT) ? 1 : 0);
#ifdef DELAY_CLOSE
	sendto_one(cptr, ":%s %d %s :delay close %lu total %lu",
		ME, RPL_STATSDEBUG, name, istat.is_delayclosewait,
		istat.is_delayclose);
#endif
	sendto_one(cptr, ":%s %d %s :local channels reops %d remote %d",
		ME, RPL_STATSDEBUG, name, sp->is_reop, sp->is_rreop);
	sendto_one(cptr, ":%s %d %s :Client - Server",
		   ME, RPL_STATSDEBUG, name);
	sendto_one(cptr, ":%s %d %s :connected %lu %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_cl, sp->is_sv);
	sendto_one(cptr, ":%s %d %s :bytes sent %llu %llu",
		   ME, RPL_STATSDEBUG, name,
		   sp->is_cbs, sp->is_sbs);
	sendto_one(cptr, ":%s %d %s :bytes recv %llu %llu",
		   ME, RPL_STATSDEBUG, name,
		   sp->is_cbr, sp->is_sbr);
	sendto_one(cptr, ":%s %d %s :time connected %lu %lu",
		   ME, RPL_STATSDEBUG, name, sp->is_cti, sp->is_sti);
#if defined(USE_IAUTH)
	report_iauth_stats(cptr, name);
#endif
}
Example #21
0
/*! \brief SVSNICK command handler
 *
 * \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] = command
 *      - parv[1] = old nickname
 *      - parv[2] = new nickname
 *      - parv[3] = timestamp
 */
static int
ms_svsnick(struct Client *source_p, int parc, char *parv[])
{
  struct Client *target_p = NULL, *exists_p = NULL;

  if (!HasFlag(source_p, FLAGS_SERVICE) || !valid_nickname(parv[2], 1))
    return 0;

  if ((target_p = find_person(source_p, parv[1])) == NULL)
    return 0;

  if (!MyConnect(target_p))
  {
    if (target_p->from == source_p->from)
    {
      sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
                           "Received wrong-direction SVSNICK "
                           "for %s (behind %s) from %s",
                           target_p->name, source_p->from->name,
                           get_client_name(source_p, HIDE_IP));
      return 0;
    }

    sendto_one(target_p, ":%s SVSNICK %s %s %s", source_p->id,
               target_p->id, parv[2], parv[3]);
    return 0;
  }

  if ((exists_p = hash_find_client(parv[2])))
  {
    if (target_p == exists_p)
    {
      if (!strcmp(target_p->name, parv[2]))
        return 0;
    }
    else if (IsUnknown(exists_p))
      exit_client(exists_p, "SVSNICK Override");
    else
    {
      exit_client(target_p, "SVSNICK Collide");
      return 0;
    }
  }

  target_p->tsinfo = strtoimax(parv[3], NULL, 10);
  clear_ban_cache_client(target_p);
  watch_check_hash(target_p, RPL_LOGOFF);

  if (HasUMode(target_p, UMODE_REGISTERED))
  {
    const unsigned int oldmodes = target_p->umodes;
    char modebuf[IRCD_BUFSIZE] = "";

    DelUMode(target_p, UMODE_REGISTERED);
    send_umode(target_p, target_p, oldmodes, modebuf);
  }

  sendto_common_channels_local(target_p, 1, 0, 0, ":%s!%s@%s NICK :%s",
                               target_p->name, target_p->username,
                               target_p->host, parv[2]);

  whowas_add_history(target_p, 1);

  sendto_server(NULL, 0, 0, ":%s NICK %s :%ju",
                target_p->id, parv[2], target_p->tsinfo);
  hash_del_client(target_p);
  strlcpy(target_p->name, parv[2], sizeof(target_p->name));
  hash_add_client(target_p);

  watch_check_hash(target_p, RPL_LOGON);

  fd_note(&target_p->connection->fd, "Nick: %s", target_p->name);
  return 0;
}
Example #22
0
BOOL ShellCache::IsPathAllowed(LPCTSTR path)
{
    ValidatePathFilter();
    Locker lock(m_critSec);
    svn_tristate_t allowed = pathFilter.IsPathAllowed (path);
    if (allowed != svn_tristate_unknown)
        return allowed == svn_tristate_true ? TRUE : FALSE;

    UINT drivetype = 0;
    int drivenumber = PathGetDriveNumber(path);
    if ((drivenumber >=0)&&(drivenumber < 25))
    {
        drivetype = drivetypecache[drivenumber];
        if ((drivetype == -1)||((GetTickCount64() - drivetypeticker)>DRIVETYPETIMEOUT))
        {
            if ((DWORD(drivefloppy) == 0)&&((drivenumber == 0)||(drivenumber == 1)))
                drivetypecache[drivenumber] = DRIVE_REMOVABLE;
            else
            {
                drivetypeticker = GetTickCount64();
                TCHAR pathbuf[MAX_PATH + 4] = { 0 };      // MAX_PATH ok here. PathStripToRoot works with partial paths too.
                wcsncpy_s(pathbuf, path, _countof(pathbuf) - 1);
                PathStripToRoot(pathbuf);
                PathAddBackslash(pathbuf);
                CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": GetDriveType for %s, Drive %d\n", pathbuf, drivenumber);
                drivetype = GetDriveType(pathbuf);
                drivetypecache[drivenumber] = drivetype;
            }
        }
    }
    else
    {
        TCHAR pathbuf[MAX_PATH + 4] = { 0 };      // MAX_PATH ok here. PathIsUNCServer works with partial paths too.
        wcsncpy_s(pathbuf, path, _countof(pathbuf) - 1);
        if (PathIsUNCServer(pathbuf))
            drivetype = DRIVE_REMOTE;
        else
        {
            PathStripToRoot(pathbuf);
            PathAddBackslash(pathbuf);
            if (wcsncmp(pathbuf, drivetypepathcache, MAX_PATH-1)==0)       // MAX_PATH ok.
                drivetype = drivetypecache[26];
            else
            {
                CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L"GetDriveType for %s\n", pathbuf);
                drivetype = GetDriveType(pathbuf);
                drivetypecache[26] = drivetype;
                wcsncpy_s(drivetypepathcache, pathbuf, MAX_PATH - 1);      // MAX_PATH ok.
            }
        }
    }
    if ((drivetype == DRIVE_REMOVABLE)&&(!IsRemovable()))
        return FALSE;
    if ((drivetype == DRIVE_FIXED)&&(!IsFixed()))
        return FALSE;
    if (((drivetype == DRIVE_REMOTE)||(drivetype == DRIVE_NO_ROOT_DIR))&&(!IsRemote()))
        return FALSE;
    if ((drivetype == DRIVE_CDROM)&&(!IsCDRom()))
        return FALSE;
    if ((drivetype == DRIVE_RAMDISK)&&(!IsRAM()))
        return FALSE;
    if ((drivetype == DRIVE_UNKNOWN)&&(IsUnknown()))
        return FALSE;

    return TRUE;
}
Example #23
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);
		sendto_realops_snomask(SNO_SKILL, L_ALL,
				"Nick collision due to SVSLOGIN on %s",
				nick);

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