예제 #1
0
/*
** m_ping
**	parv[0] = sender prefix
**	parv[1] = origin
**	parv[2] = destination
*/
DLLFUNC int  m_ping(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient *acptr;
	char *origin, *destination;

	if (parc < 2 || *parv[1] == '\0')
	{
		sendto_one(sptr, err_str(ERR_NOORIGIN), me.name, parv[0]);
		return 0;
	}
	origin = parv[1];
	destination = parv[2];	/* Will get NULL or pointer (parc >= 2!!) */

	if (!MyClient(sptr))
	{
		/* I've no idea who invented this or what it is supposed to do.. */
		acptr = find_client(origin, NULL);
		if (!acptr)
			acptr = find_server_quick(origin);
		if (acptr && acptr != sptr)
			origin = cptr->name;
	}

	if (!BadPtr(destination) && mycmp(destination, me.name) != 0)
	{
		if (MyClient(sptr))
			origin = sptr->name; /* Make sure origin is not spoofed */
		if ((acptr = find_server_quick(destination)) && (acptr != &me))
			sendto_one(acptr, ":%s PING %s :%s", parv[0], origin, destination);
		else
		{
			sendto_one(sptr, err_str(ERR_NOSUCHSERVER),
			    me.name, parv[0], destination);
			return 0;
		}
	}
	else
		sendto_one(sptr, ":%s %s %s :%s", me.name,
		    IsToken(cptr) ? TOK_PONG : MSG_PONG,
		    (destination) ? destination : me.name, origin);
	return 0;
}
예제 #2
0
/*
** m_pong
**	parv[0] = sender prefix
**	parv[1] = origin
**	parv[2] = destination
*/
DLLFUNC int m_pong(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient *acptr;
	char *origin, *destination;

#ifdef NOSPOOF
	if (!IsRegistered(cptr))
		return m_nospoof(cptr, sptr, parc, parv);
#endif

	if (parc < 2 || *parv[1] == '\0')
	{
		sendto_one(sptr, err_str(ERR_NOORIGIN), me.name, parv[0]);
		return 0;
	}

	origin = parv[1];
	destination = parv[2];
	cptr->flags &= ~FLAGS_PINGSENT;
	sptr->flags &= ~FLAGS_PINGSENT;

	/* Remote pongs for clients? uhh... */
	if (MyClient(sptr) || !IsRegistered(sptr))
		destination = NULL;

	if (!BadPtr(destination) && mycmp(destination, me.name) != 0)
	{
		if ((acptr = find_client(destination, NULL)) ||
		    (acptr = find_server_quick(destination)))
		{
			if (!IsServer(cptr) && !IsServer(acptr))
			{
				sendto_one(sptr, err_str(ERR_NOSUCHSERVER),
				    me.name, parv[0], destination);
				return 0;
			}
			else
				sendto_one(acptr, ":%s PONG %s %s",
				    parv[0], origin, destination);
		}
		else
		{
			sendto_one(sptr, err_str(ERR_NOSUCHSERVER),
			    me.name, parv[0], destination);
			return 0;
		}
	}
#ifdef	DEBUGMODE
	else
		Debug((DEBUG_NOTICE, "PONG: %s %s", origin,
		    destination ? destination : "*"));
#endif
	return 0;
}
예제 #3
0
/*
** m_whois
**	parv[0] = sender prefix
**	parv[1] = nickname masklist
*/
DLLFUNC int  m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	Membership *lp;
	anUser *user;
	aClient *acptr, *a2cptr;
	aChannel *chptr;
	char *nick, *tmp, *name;
	char *p = NULL;
	int  found, len, mlen, cnt = 0;
	char querybuf[BUFSIZE];

	if (IsServer(sptr))	
		return 0;

	if (parc < 2)
	{
		sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
		    me.name, parv[0]);
		return 0;
	}

	if (parc > 2)
	{
		if (hunt_server(cptr, sptr, ":%s WHOIS %s :%s", 1, parc, parv) != HUNTED_ISME)
			return 0;
		parv[1] = parv[2];
	}

	strcpy(querybuf, parv[1]);

	for (tmp = canonize(parv[1]); (nick = strtok_r(tmp, ",", &p)); tmp = NULL)
	{
		unsigned char invis, showchannel, member, wilds, hideoper; /* <- these are all boolean-alike */

		if (++cnt > MAXTARGETS)
			break;

		found = 0;
		/* We do not support "WHOIS *" */
		wilds = (index(nick, '?') || index(nick, '*'));
		if (wilds)
			continue;

		if ((acptr = find_client(nick, NULL)))
		{
			if (IsServer(acptr))
				continue;
			/*
			 * I'm always last :-) and acptr->next == NULL!!
			 */
			if (IsMe(acptr))
				break;
			/*
			 * 'Rules' established for sending a WHOIS reply:
			 * - only send replies about common or public channels
			 *   the target user(s) are on;
			 */

			if (!IsPerson(acptr))
				continue;

			user = acptr->user;
			name = (!*acptr->name) ? "?" : acptr->name;

			invis = acptr != sptr && IsInvisible(acptr);
			member = (user->channel) ? 1 : 0;

			a2cptr = find_server_quick(user->server);

			hideoper = 0;
			if (IsHideOper(acptr) && (acptr != sptr) && !IsAnOper(sptr))
				hideoper = 1;

			if (IsWhois(acptr) && (sptr != acptr))
			{
				sendnotice(acptr,
				    "*** %s (%s@%s) did a /whois on you.",
				    sptr->name,
				    sptr->user->username, sptr->user->realhost);
			}
			sendto_one(sptr, rpl_str(RPL_WHOISUSER), me.name,
			    parv[0], name,
			    user->username,
			    IsHidden(acptr) ? user->virthost : user->realhost,
			    acptr->info);

			if (IsOper(sptr) || acptr == sptr)
			{
				char sno[512];
				strcpy(sno, get_sno_str(acptr));
				
				/* send the target user's modes */
				sendto_one(sptr, rpl_str(RPL_WHOISMODES),
				    me.name, parv[0], name,
				    get_mode_str(acptr), sno[1] == 0 ? "" : sno);
			}
			if ((acptr == sptr) || IsAnOper(sptr))
			{
				sendto_one(sptr, rpl_str(RPL_WHOISHOST),
				    me.name, parv[0], acptr->name,
					(MyConnect(acptr) && strcmp(acptr->username, "unknown")) ? acptr->username : "******",
					user->realhost, user->ip_str ? user->ip_str : "");
			}

			if (IsARegNick(acptr))
				sendto_one(sptr, rpl_str(RPL_WHOISREGNICK), me.name, parv[0], name);
			
			found = 1;
			mlen = strlen(me.name) + strlen(parv[0]) + 10 + strlen(name);
			for (len = 0, *buf = '\0', lp = user->channel; lp; lp = lp->next)
			{
				chptr = lp->chptr;
				showchannel = 0;
				if (ShowChannel(sptr, chptr))
					showchannel = 1;
				if (OPCanSeeSecret(sptr))
					showchannel = 1;
				if ((acptr->umodes & UMODE_HIDEWHOIS) && !IsMember(sptr, chptr) && !IsAnOper(sptr))
					showchannel = 0;
				if (IsServices(acptr) && !IsNetAdmin(sptr) && !IsSAdmin(sptr))
					showchannel = 0;
				if (acptr == sptr)
					showchannel = 1;
				/* Hey, if you are editting here... don't forget to change the webtv w_whois ;p. */

				if (showchannel)
				{
					long access;
					if (len + strlen(chptr->chname) > (size_t)BUFSIZE - 4 - mlen)
					{
						sendto_one(sptr,
						    ":%s %d %s %s :%s",
						    me.name,
						    RPL_WHOISCHANNELS,
						    parv[0], name, buf);
						*buf = '\0';
						len = 0;
					}
#ifdef SHOW_SECRET
					if (IsAnOper(sptr)
#else
					if (IsNetAdmin(sptr)
#endif
					    && SecretChannel(chptr) && !IsMember(sptr, chptr))
						*(buf + len++) = '?';
					if (acptr->umodes & UMODE_HIDEWHOIS && !IsMember(sptr, chptr)
						&& IsAnOper(sptr))
						*(buf + len++) = '!';
					access = get_access(acptr, chptr);
					if (!SupportNAMESX(sptr))
					{
#ifdef PREFIX_AQ
						if (access & CHFL_CHANOWNER)
							*(buf + len++) = '~';
						else if (access & CHFL_CHANPROT)
							*(buf + len++) = '&';
						else
#endif
						if (access & CHFL_CHANOP)
							*(buf + len++) = '@';
						else if (access & CHFL_HALFOP)
							*(buf + len++) = '%';
						else if (access & CHFL_VOICE)
							*(buf + len++) = '+';
					}
					else
					{
#ifdef PREFIX_AQ
						if (access & CHFL_CHANOWNER)
							*(buf + len++) = '~';
						if (access & CHFL_CHANPROT)
							*(buf + len++) = '&';
#endif
						if (access & CHFL_CHANOP)
							*(buf + len++) = '@';
						if (access & CHFL_HALFOP)
							*(buf + len++) = '%';
						if (access & CHFL_VOICE)
							*(buf + len++) = '+';
					}
					if (len)
						*(buf + len) = '\0';
					(void)strcpy(buf + len, chptr->chname);
					len += strlen(chptr->chname);
					(void)strcat(buf + len, " ");
					len++;
				}
			}

			if (buf[0] != '\0')
				sendto_one(sptr, rpl_str(RPL_WHOISCHANNELS), me.name, parv[0], name, buf); 

                        if (!(IsULine(acptr) && !IsOper(sptr) && HIDE_ULINES))
				sendto_one(sptr, rpl_str(RPL_WHOISSERVER),
				    me.name, parv[0], name, user->server,
				    a2cptr ? a2cptr->info : "*Not On This Net*");

			if (user->away)
				sendto_one(sptr, rpl_str(RPL_AWAY), me.name,
				    parv[0], name, user->away);
			/* makesure they aren't +H (we'll also check
			   before we display a helpop or IRCD Coder msg)
			   -- codemastr */

			if ((IsAnOper(acptr) || IsServices(acptr)) && !hideoper)
			{
				buf[0] = '\0';
				if (IsNetAdmin(acptr))
					strlcat(buf, "a Network Administrator", sizeof buf);
				else if (IsSAdmin(acptr))
					strlcat(buf, "a Services Administrator", sizeof buf);
				else if (IsAdmin(acptr) && !IsCoAdmin(acptr))
					strlcat(buf, "a Server Administrator", sizeof buf);
				else if (IsCoAdmin(acptr))
					strlcat(buf, "a Co Administrator", sizeof buf);
				else if (IsServices(acptr))
					strlcat(buf, "a Network Service", sizeof buf);
				else if (IsOper(acptr))
					strlcat(buf, "an IRC Operator", sizeof buf);

				else
					strlcat(buf, "a Local IRC Operator", sizeof buf);
				if (buf[0])
				{
					if (IsOper(sptr) && MyClient(acptr))
						sendto_one(sptr,
						    ":%s 313 %s %s :is %s (%s)", me.name,
						    parv[0], name, buf, acptr->user->operlogin);
					else
						sendto_one(sptr,
						    rpl_str(RPL_WHOISOPERATOR), me.name,
						    parv[0], name, buf);
				}
			}

			if (IsHelpOp(acptr) && !hideoper && !user->away)
				sendto_one(sptr, rpl_str(RPL_WHOISHELPOP), me.name, parv[0], name);

			if (acptr->umodes & UMODE_BOT)
				sendto_one(sptr, rpl_str(RPL_WHOISBOT), me.name, parv[0], name, ircnetwork);

			if (acptr->umodes & UMODE_SECURE)
				sendto_one(sptr, rpl_str(RPL_WHOISSECURE), me.name, parv[0], name,
					"is using a Secure Connection");

			if (!BadPtr(user->swhois) && !hideoper)
					sendto_one(sptr, ":%s %d %s %s :%s",
					    me.name, RPL_WHOISSPECIAL, parv[0],
					    name, acptr->user->swhois);

			/*
			 * display services account name if it's actually a services account name and
			 * not a legacy timestamp.  --nenolod
			 */
			if (!isdigit(*user->svid))
				sendto_one(sptr, rpl_str(RPL_WHOISLOGGEDIN), me.name, parv[0], name, user->svid);

			/*
			 * Umode +I hides an oper's idle time from regular users.
			 * -Nath.
			 */
			if (MyConnect(acptr) && (IsAnOper(sptr) || !(acptr->umodes & UMODE_HIDLE)))
			{
				sendto_one(sptr, rpl_str(RPL_WHOISIDLE),
				    me.name, parv[0], name,
				    TStime() - acptr->last, acptr->firsttime);
			}
		}
		if (!found)
			sendto_one(sptr, err_str(ERR_NOSUCHNICK),
			    me.name, parv[0], nick);
	}
	sendto_one(sptr, rpl_str(RPL_ENDOFWHOIS), me.name, parv[0], querybuf);

	return 0;
}
예제 #4
0
/*
** DoNumeric (replacement for the old do_numeric)
**
**	parc	number of arguments ('sender' counted as one!)
**	parv[0]	pointer to 'sender' (may point to empty string) (not used)
**	parv[1]..parv[parc-1]
**		pointers to additional parameters, this is a NULL
**		terminated list (parv[parc] == NULL).
**
** *WARNING*
**	Numerics are mostly error reports. If there is something
**	wrong with the message, just *DROP* it! Don't even think of
**	sending back a neat error message -- big danger of creating
**	a ping pong error message...
*/
int  do_numeric(int numeric, aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient *acptr;
	aChannel *chptr;
	char *nick, *p;
	int  i;

	/* Is this an outgoing connect, and we get a numeric 451 (not registered) back for the
	 * magic command __PANGPANG__ and we did not send a SERVER message yet?
	 * Then this means we are dealing with an Unreal server <3.2.9 and we should send the
	 * SERVER command right now.
	 */
	if (!IsServer(sptr) && !IsPerson(sptr) && (numeric == 451) && (parc > 2) && strstr(parv[1], "__PANGPANG__") &&
	    IsHandshake(cptr) && sptr->serv && !IsServerSent(sptr))
	{
		send_server_message(sptr);
		return 0;
	}

	if (parc < 1 || !IsServer(sptr))
		return 0;
	/* Remap low number numerics. */
	if (numeric < 100)
		numeric += 100;

	/*
	   ** Prepare the parameter portion of the message into 'buffer'.
	   ** (Because the buffer is twice as large as the message buffer
	   ** for the socket, no overflow can occur here... ...on current
	   ** assumptions--bets are off, if these are changed --msa)
	   ** Note: if buffer is non-empty, it will begin with SPACE.
	 */
	buffer[0] = '\0';
	if (parc > 2)
	{
		/*
		 * For strlcat nazis, please read above
		*/
		for (i = 2; i < (parc - 1); i++)
		{
			(void)strcat(buffer, " ");
			(void)strcat(buffer, parv[i]);
		}
		(void)strcat(buffer, " :");
		(void)strcat(buffer, parv[parc - 1]);
	}
	else
		sendto_realops("do_numeric( %i, %s, %s, %i, { %s, %s } )!",
		    numeric, cptr->name, sptr->name, parc,
		    parv[0], parv[1] ? parv[1] : "<null>");
	for (; (nick = strtoken(&p, parv[1], ",")); parv[1] = NULL)
	{
		if ((acptr = find_client(nick, (aClient *)NULL)))
		{
			/*
			   ** Drop to bit bucket if for me...
			   ** ...one might consider sendto_ops
			   ** here... --msa
			   ** And so it was done. -avalon
			   ** And regretted. Dont do it that way. Make sure
			   ** it goes only to non-servers. -avalon
			   ** Check added to make sure servers don't try to loop
			   ** with numerics which can happen with nick collisions.
			   ** - Avalon
			 */
			if (!IsMe(acptr) && IsPerson(acptr))
			{
				/* Added for .U3.2. drop remote 'You are not on
				   ** that channel', we should be synced anyway,
				   ** and this is an annoying message with TSpre7
				   ** still on the net; would result in numeric 442 for
				   ** every KICK... Can be removed when TSpre7 is gone.
				   ** --Run
				   if (numeric==ERR_NOTONCHANNEL) return 0;
				 */

				sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
				    parv[0], numeric, nick, buffer);
			}
			else if (IsServer(acptr) && acptr->from != cptr)
				sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
				    parv[0], numeric, nick, buffer);
		}
		else if ((acptr = find_server_quick(nick)))
		{
			if (!IsMe(acptr) && acptr->from != cptr)
				sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
				    parv[0], numeric, nick, buffer);
		}
		else if ((chptr = find_channel(nick, (aChannel *)NULL)))
			sendto_channel_butone(cptr, sptr, chptr, ":%s %d %s%s",
			    parv[0], numeric, chptr->chname, buffer);
	}
	return 0;
}
예제 #5
0
/***********************************************************************
 * m_connect() - Added by Jto 11 Feb 1989
 ***********************************************************************//*
   ** m_connect
   **  parv[0] = sender prefix
   **  parv[1] = servername
   **  parv[2] = port number
   **  parv[3] = remote server
 */
DLLFUNC CMD_FUNC(m_connect)
{
	int  port, tmpport, retval;
	ConfigItem_link	*aconf;
	ConfigItem_deny_link *deny;
	aClient *acptr;


	if (!IsPrivileged(sptr))
	{
		sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
		return -1;
	}

	if (MyClient(sptr) && !OPCanGRoute(sptr) && parc > 3)
	{			/* Only allow LocOps to make */
		/* local CONNECTS --SRB      */
		sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
		return 0;
	}
	if (MyClient(sptr) && !OPCanLRoute(sptr) && parc <= 3)
	{
		sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
		return 0;
	}
	if (hunt_server_token(cptr, sptr, MSG_CONNECT, TOK_CONNECT, "%s %s :%s",
	    3, parc, parv) != HUNTED_ISME)
		return 0;

	if (parc < 2 || *parv[1] == '\0')
	{
		sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
		    me.name, parv[0], "CONNECT");
		return -1;
	}

	if ((acptr = find_server_quick(parv[1])))
	{
		sendto_one(sptr, ":%s %s %s :*** Connect: Server %s %s %s.",
		    me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], parv[1], "already exists from",
		    acptr->from->name);
		return 0;
	}

	for (aconf = conf_link; aconf; aconf = (ConfigItem_link *) aconf->next)
		if (!match(parv[1], aconf->servername))
			break;

	/* Checked first servernames, then try hostnames. */

	if (!aconf)
	{
		sendto_one(sptr,
		    ":%s %s %s :*** Connect: Server %s is not configured for linking", me.name,
		    IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], parv[1]);
		return 0;
	}
	/*
	   ** Get port number from user, if given. If not specified,
	   ** use the default form configuration structure. If missing
	   ** from there, then use the precompiled default.
	 */
	tmpport = port = aconf->port;
	if (parc > 2 && !BadPtr(parv[2]))
	{
		if ((port = atoi(parv[2])) <= 0)
		{
			sendto_one(sptr,
			    ":%s %s %s :*** Connect: Illegal port number", me.name,
			    IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]);
			return 0;
		}
	}
	else if (port <= 0 && (port = PORTNUM) <= 0)
	{
		sendto_one(sptr, ":%s %s %s :*** Connect: missing port number",
		    me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]);
		return 0;
	}



/* Evaluate deny link */
	for (deny = conf_deny_link; deny; deny = (ConfigItem_deny_link *) deny->next) {
		if (deny->flag.type == CRULE_ALL && !match(deny->mask, aconf->servername)
			&& crule_eval(deny->rule)) {
			sendto_one(sptr,
				":%s %s %s :*** Connect: Disallowed by connection rule",
				me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]);
			return 0;
		}
	}
	if (strchr(aconf->hostname, '*') != NULL || strchr(aconf->hostname, '?') != NULL)
	{
		sendto_one(sptr,
			":%s %s %s :*** Connect: You cannot connect to a server with wildcards (* and ?) in the hostname",
			me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]);
		return 0;
	}	
	/*
	   ** Notify all operators about remote connect requests
	 */
	if (!IsAnOper(cptr))
	{
		sendto_serv_butone(&me,
		    ":%s GLOBOPS :Remote CONNECT %s %s from %s",
		    me.name, parv[1], parv[2] ? parv[2] : "",
		    get_client_name(sptr, FALSE));
	}
	/* Interesting */
	aconf->port = port;
	switch (retval = connect_server(aconf, sptr, NULL))
	{
	  case 0:
		  sendto_one(sptr,
		      ":%s %s %s :*** Connecting to %s[%s].",
		      me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], aconf->servername, aconf->hostname);
		  break;
	  case -1:
		  sendto_one(sptr, ":%s %s %s :*** Couldn't connect to %s.",
		      me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], aconf->servername);
		  break;
	  case -2:
		  sendto_one(sptr, ":%s %s %s :*** Resolving hostname '%s'...",
		      me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], aconf->hostname);
		  break;
	  default:
		  sendto_one(sptr,
		      ":%s %s %s :*** Connection to %s failed: %s",
		      me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], aconf->servername, STRERROR(retval));
	}
	aconf->port = tmpport;
	return 0;
}