Esempio n. 1
0
/** The following comes from InspIRCd to get the full path of the Anope executable
 */
static Anope::string GetFullProgDir(const Anope::string &argv0)
{
	char buffer[PATH_MAX];
#ifdef _WIN32
	/* Windows has specific API calls to get the EXE path that never fail.
	 * For once, Windows has something of use, compared to the POSIX code
	 * for this, this is positively neato.
	 */
	if (GetModuleFileName(NULL, buffer, PATH_MAX))
	{
		Anope::string fullpath = buffer;
		Anope::string::size_type n = fullpath.rfind("\\");
		Anope::ServicesBin = fullpath.substr(n + 1, fullpath.length());
		return fullpath.substr(0, n);
	}
#else
	// Get the current working directory
	if (getcwd(buffer, PATH_MAX))
	{
		Anope::string remainder = argv0;

		Anope::ServicesBin = remainder;
		Anope::string::size_type n = Anope::ServicesBin.rfind("/");
		Anope::string fullpath;
		if (Anope::ServicesBin[0] == '/')
			fullpath = Anope::ServicesBin.substr(0, n);
		else
			fullpath = Anope::string(buffer) + "/" + Anope::ServicesBin.substr(0, n);
		Anope::ServicesBin = Anope::ServicesBin.substr(n + 1, remainder.length());
		return fullpath;
	}
#endif
	return "/";
}
Esempio n. 2
0
void IRC2SQL::OnBotNotice(User *u, BotInfo *bi, Anope::string &message)
{
	Anope::string versionstr;
	if (bi != StatServ)
		return;
	if (message[0] == '\1' && message[message.length() - 1] == '\1')
	{
		if (message.substr(0, 9).equals_ci("\1VERSION "))
		{
			if (u->HasExt("CTCPVERSION"))
				return;
			u->Extend<bool>("CTCPVERSION");

			versionstr = Anope::NormalizeBuffer(message.substr(9, message.length() - 10));
			if (versionstr.empty())
				return;
			query = "UPDATE `" + prefix + "user` "
				"SET version=@version@ "
				"WHERE nick=@nick@";
			query.SetValue("version", versionstr);
			query.SetValue("nick", u->nick);
			this->RunQuery(query);
		}
	}
}
Esempio n. 3
0
/** Checks if a username is valid
 * @param ident The username
 * @return true if the ident is valid
 */
bool IsValidIdent(const Anope::string &ident)
{
	if (ident.empty() || ident.length() > Config->UserLen)
		return false;
	for (unsigned i = 0; i < ident.length(); ++i)
	{
		const char &c = ident[i];
		if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-')
			;
		else
			return false;
	}

	return true;
}
Esempio n. 4
0
/**
 * Checks whether we have a valid, common e-mail address.
 * This is NOT entirely RFC compliant, and won't be so, because I said
 * *common* cases. ;) It is very unlikely that e-mail addresses that
 * are really being used will fail the check.
 *
 * @param email Email to Validate
 * @return bool
 */
bool MailValidate(const Anope::string &email)
{
	bool has_period = false;

	static char specials[] = {'(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' '};

	if (email.empty())
		return false;
	Anope::string copy = email;

	size_t at = copy.find('@');
	if (at == Anope::string::npos)
		return false;
	Anope::string domain = copy.substr(at + 1);
	copy = copy.substr(0, at);

	/* Don't accept empty copy or domain. */
	if (copy.empty() || domain.empty())
		return false;

	/* Check for forbidden characters in the name */
	for (unsigned i = 0, end = copy.length(); i < end; ++i)
	{
		if (copy[i] <= 31 || copy[i] >= 127)
			return false;
		for (unsigned int j = 0; j < 13; ++j)
			if (copy[i] == specials[j])
				return false;
	}

	/* Check for forbidden characters in the domain */
	for (unsigned i = 0, end = domain.length(); i < end; ++i)
	{
		if (domain[i] <= 31 || domain[i] >= 127)
			return false;
		for (unsigned int j = 0; j < 13; ++j)
			if (domain[i] == specials[j])
				return false;
		if (domain[i] == '.')
		{
			if (!i || i == end - 1)
				return false;
			has_period = true;
		}
	}

	return has_period;
}
Esempio n. 5
0
	EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) override
	{
		if (!md5)
			return EVENT_CONTINUE;

		Encryption::Context *context = md5->CreateContext();
		context->Update(reinterpret_cast<const unsigned char *>(src.c_str()), src.length());
		context->Finalize();

		Encryption::Hash hash = context->GetFinalizedHash();

		char digest[32], digest2[16];
		memset(digest, 0, sizeof(digest));
		if (hash.second > sizeof(digest))
			throw CoreException("Hash too large");
		memcpy(digest, hash.first, hash.second);

		for (int i = 0; i < 32; i += 2)
			digest2[i / 2] = XTOI(digest[i]) << 4 | XTOI(digest[i + 1]);

		Anope::string buf = "oldmd5:" + Anope::Hex(digest2, sizeof(digest2));

		Log(LOG_DEBUG_2) << "(enc_old) hashed password from [" << src << "] to [" << buf << "]";
		dest = buf;
		delete context;
		return EVENT_ALLOW;
	}
Esempio n. 6
0
bool IRCDProto::IsIdentValid(const Anope::string &ident)
{
	if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
		return false;

	for (unsigned int i = 0; i < ident.length(); ++i)
	{
		const char &c = ident[i];

		if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-')
			continue;

		return false;
	}

	return true;
}
Esempio n. 7
0
/**
 * Number of tokens in a string
 * @param str String
 * @param dilim Dilimiter
 * @return number of tokens
 */
int myNumToken(const Anope::string &str, char dilim)
{
	if (str.empty())
		return 0;
	int counter = 0;
	for (size_t idx = 0, len = str.length(); idx <= len; ++idx)
		if (str[idx] == dilim || idx == len)
			++counter;
	return counter;
}
Esempio n. 8
0
bool IRCDProto::IsChannelValid(const Anope::string &chan)
{
	if (chan.empty() || chan[0] != '#' || chan.length() > Config->GetBlock("networkinfo")->Get<unsigned>("chanlen"))
		return false;

	if (chan.find_first_of(" ,") != Anope::string::npos)
		return false;

	return true;
}
Esempio n. 9
0
void User::SendMessage(const MessageSource &source, const Anope::string &msg)
{
	const char *translated_message = Language::Translate(this, msg.c_str());

	/* Send privmsg instead of notice if:
	* - UsePrivmsg is enabled
	* - The user is not registered and NSDefMsg is enabled
	* - The user is registered and has set /ns set msg on
	*/
	bool send_privmsg = Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasFieldS("MSG")));
	sepstream sep(translated_message, '\n', true);
	for (Anope::string tok; sep.GetToken(tok);)
	{
		if (tok.empty())
			tok = " ";
		spacesepstream ssep(tok, true);
		Anope::string buf;
		for (Anope::string word; ssep.GetToken(word);)
		{
			Anope::string add = buf.empty() ? word : " " + word;
			if (buf.length() + add.length() > Config->LineWrap)
			{
				if (send_privmsg)
					IRCD->SendPrivmsg(source, this->GetUID(), "%s", buf.c_str());
				else
					IRCD->SendNotice(source, this->GetUID(), "%s", buf.c_str());
				buf.clear();
				add = word;
			}
			buf.append(add);
		}

		if (!buf.empty())
		{
			if (send_privmsg)
				IRCD->SendPrivmsg(source, this->GetUID(), "%s", buf.c_str());
			else
				IRCD->SendNotice(source, this->GetUID(), "%s", buf.c_str());
		}
	}
}
Esempio n. 10
0
void Anope::Unhex(const Anope::string &src, char *dest)
{
	size_t len = src.length(), destpos = 0;
	for (size_t i = 0; i < len; i += 2)
	{
		char h = src[i], l = src[i + 1];
		unsigned char byte = (h >= 'a' ? h - 'a' + 10 : h - '0') << 4;
		byte += (l >= 'a' ? l - 'a' + 10 : l - '0');
		dest[destpos++] = byte;
	}
	dest[destpos] = 0;
}
Esempio n. 11
0
int LDAPBind::run()
{
	berval cred;
	cred.bv_val = strdup(pass.c_str());
	cred.bv_len = pass.length();

	int i = ldap_sasl_bind_s(service->GetConnection(), who.c_str(), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);

	free(cred.bv_val);

	return i;
}
Esempio n. 12
0
/** Checks if a host is valid
 * @param host The host
 * @param true if the host is valid
 */
bool IsValidHost(const Anope::string &host)
{
	if (host.empty() || host.length() > Config->HostLen)
		return false;

	if (Config->VhostDisallowBE.find_first_of(host[0]) != Anope::string::npos)
		return false;
	else if (Config->VhostDisallowBE.find_first_of(host[host.length() - 1]) != Anope::string::npos)
		return false;

	int dots = 0;
	for (unsigned i = 0; i < host.length(); ++i)
	{
		if (host[i] == '.')
			++dots;
		if (Config->VhostChars.find_first_of(host[i]) == Anope::string::npos)
			return false;
	}

	return Config->VhostUndotted || dots > 0;
}
Esempio n. 13
0
void Command::SendSyntax(CommandSource &source)
{
	Anope::string s = Language::Translate(source.GetAccount(), _("Syntax"));
	if (!this->syntax.empty())
	{
		source.Reply("%s: \002%s %s\002", s.c_str(), source.command.c_str(), Language::Translate(source.GetAccount(), this->syntax[0].c_str()));
		Anope::string spaces(s.length(), ' ');
		for (unsigned i = 1, j = this->syntax.size(); i < j; ++i)
			source.Reply("%s  \002%s %s\002", spaces.c_str(), source.command.c_str(), Language::Translate(source.GetAccount(), this->syntax[i].c_str()));
	}
	else
		source.Reply("%s: \002%s\002", s.c_str(), source.command.c_str());
}
Esempio n. 14
0
/** Converts a string from hex
 * @param src The data to be converted
 * @param dest The destination string
 */
void Anope::Unhex(const Anope::string &src, Anope::string &dest)
{
	size_t len = src.length();
	Anope::string rv;
	for (size_t i = 0; i < len; i += 2)
	{
		char h = src[i], l = src[i + 1];
		unsigned char byte = (h >= 'a' ? h - 'a' + 10 : h - '0') << 4;
		byte += (l >= 'a' ? l - 'a' + 10 : l - '0');
		rv += byte;
	}
	dest = rv;
}
Esempio n. 15
0
	bool IsIdentValid(const Anope::string &ident) override
	{
		if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
			return false;

		Anope::string chars = "~}|{ `_^]\\[ .-$";

		for (unsigned i = 0; i < ident.length(); ++i)
		{
			const char &c = ident[i];

			if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
				continue;

			if (chars.find(c) != Anope::string::npos)
				continue;

			return false;
		}

		return true;
	}
Esempio n. 16
0
    void DoChannel(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
    {
        if (request.data.empty())
            return;

        Channel *c = Channel::Find(request.data[0]);

        request.reply("name", iface->Sanitize(c ? c->name : request.data[0]));

        if (c)
        {
            request.reply("bancount", stringify(c->HasMode("BAN")));
            int count = 0;
            std::vector<Anope::string> v = c->GetModeList("BAN");
            for (unsigned int i = 0; i < v.size(); ++i)
                request.reply("ban" + stringify(++count), iface->Sanitize(v[i]));

            request.reply("exceptcount", stringify(c->HasMode("EXCEPT")));
            count = 0;
            v = c->GetModeList("EXCEPT");
            for (unsigned int i = 0; i < v.size(); ++i)
                request.reply("except" + stringify(++count), iface->Sanitize(v[i]));

            request.reply("invitecount", stringify(c->HasMode("INVITEOVERRIDE")));
            count = 0;
            v = c->GetModeList("INVITEOVERRIDE");
            for (unsigned int i = 0; i < v.size(); ++i)
                request.reply("invite" + stringify(++count), iface->Sanitize(v[i]));

            Anope::string users;
            for (Channel::ChanUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it)
            {
                ChanUserContainer *uc = it->second;
                users += uc->status.BuildModePrefixList() + uc->user->nick + " ";
            }
            if (!users.empty())
            {
                users.erase(users.length() - 1);
                request.reply("users", iface->Sanitize(users));
            }

            if (!c->topic.empty())
                request.reply("topic", iface->Sanitize(c->topic));

            if (!c->topic_setter.empty())
                request.reply("topicsetter", iface->Sanitize(c->topic_setter));

            request.reply("topictime", stringify(c->topic_time));
            request.reply("topicts", stringify(c->topic_ts));
        }
    }
Esempio n. 17
0
	void DoChannel(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request)
	{
		if (request->data.empty())
			return;

		Channel *c = findchan(request->data[0]);

		request->reply("name", iface->Sanitize(c ? c->name : request->data[0]));

		if (c)
		{
			request->reply("bancount", stringify(c->HasMode(CMODE_BAN)));
			int count = 0;
			std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = c->GetModeList(CMODE_BAN);
			for (; its.first != its.second; ++its.first)
				request->reply("ban" + stringify(++count), iface->Sanitize(its.first->second));

			request->reply("exceptcount", stringify(c->HasMode(CMODE_EXCEPT)));
			count = 0;
			its = c->GetModeList(CMODE_EXCEPT);
			for (; its.first != its.second; ++its.first)
				request->reply("except" + stringify(++count), iface->Sanitize(its.first->second));

			request->reply("invitecount", stringify(c->HasMode(CMODE_INVITEOVERRIDE)));
			count = 0;
			its = c->GetModeList(CMODE_INVITEOVERRIDE);
			for (; its.first != its.second; ++its.first)
				request->reply("invite" + stringify(++count), iface->Sanitize(its.first->second));

			Anope::string users;
			for (CUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it)
			{
				UserContainer *uc = *it;
				users += uc->Status->BuildModePrefixList() + uc->user->nick + " ";
			}
			if (!users.empty())
			{
				users.erase(users.length() - 1);
				request->reply("users", iface->Sanitize(users));
			}

			if (!c->topic.empty())
				request->reply("topic", iface->Sanitize(c->topic));

			if (!c->topic_setter.empty())
				request->reply("topicsetter", iface->Sanitize(c->topic_setter));

			request->reply("topictime", stringify(c->topic_time));
		}
	}
Esempio n. 18
0
/** Converts a string to hex
 * @param the data to be converted
 * @return a anope::string containing the hex value
 */
Anope::string Anope::Hex(const Anope::string &data)
{
	const char hextable[] = "0123456789abcdef";

	size_t l = data.length();
	Anope::string rv;
	for (size_t i = 0; i < l; ++i)
	{
		unsigned char c = data[i];
		rv += hextable[c >> 4];
		rv += hextable[c & 0xF];
	}
	return rv;
}
Esempio n. 19
0
bool IRCDProto::IsHostValid(const Anope::string &host)
{
	if (host.empty() || host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
		return false;

	const Anope::string &vhostdisablebe = Config->GetBlock("networkinfo")->Get<Anope::string>("disallow_start_or_end"),
		vhostchars = Config->GetBlock("networkinfo")->Get<Anope::string>("vhost_chars");

	if (vhostdisablebe.find_first_of(host[0]) != Anope::string::npos)
		return false;
	else if (vhostdisablebe.find_first_of(host[host.length() - 1]) != Anope::string::npos)
		return false;

	int dots = 0;
	for (unsigned int i = 0; i < host.length(); ++i)
	{
		if (host[i] == '.')
			++dots;
		if (vhostchars.find_first_of(host[i]) == Anope::string::npos)
			return false;
	}

	return dots > 0 || Config->GetBlock("networkinfo")->Get<bool>("allow_undotted_vhosts");
}
Esempio n. 20
0
	void DoDel(CommandSource &source, NickServ::Account *nc, const Anope::string &chans)
	{
		std::vector<AutoJoin *> channels = nc->GetRefs<AutoJoin *>();
		Anope::string delchans;
		Anope::string notfoundchans;
		commasepstream sep(chans);

		for (Anope::string chan; sep.GetToken(chan);)
		{
			unsigned i = 0;
			for (; i < channels.size(); ++i)
				if (channels[i]->GetChannel().equals_ci(chan))
					break;

			if (i == channels.size())
				notfoundchans += chan + ", ";
			else
			{
				delete channels[i];
				delchans += chan + ", ";
			}
		}

		if (!notfoundchans.empty())
		{
			notfoundchans = notfoundchans.substr(0, notfoundchans.length() - 2);
			source.Reply(_("\002{0}\002 was not found on the auto join list of \002{1}\002."), notfoundchans, nc->GetDisplay());
		}

		if (delchans.empty())
			return;

		delchans = delchans.substr(0, delchans.length() - 2);
		Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE channel " << delchans << " from " << nc->GetDisplay();
		source.Reply(_("\002{0}\002 was removed from the auto join list of \002{1}\002."), delchans, nc->GetDisplay());
	}
Esempio n. 21
0
/** Build a list of mode strings to send to the IRCd from the mode stacker
 * @param info The stacker info for a channel or user
 * @return a list of strings
 */
static std::list<Anope::string> BuildModeStrings(StackerInfo *info)
{
	std::list<Anope::string> ret;
	std::list<std::pair<Mode *, Anope::string> >::iterator it, it_end;
	Anope::string buf = "+", parambuf;
	unsigned NModes = 0;

	for (it = info->AddModes.begin(), it_end = info->AddModes.end(); it != it_end; ++it)
	{
		if (++NModes > IRCD->MaxModes || (buf.length() + parambuf.length() > IRCD->MaxLine - 100)) // Leave room for command, channel, etc
		{
			ret.push_back(buf + parambuf);
			buf = "+";
			parambuf.clear();
			NModes = 1;
		}

		buf += it->first->mchar;

		if (!it->second.empty())
			parambuf += " " + it->second;
	}

	if (buf[buf.length() - 1] == '+')
		buf.erase(buf.length() - 1);

	buf += "-";
	for (it = info->DelModes.begin(), it_end = info->DelModes.end(); it != it_end; ++it)
	{
		if (++NModes > IRCD->MaxModes || (buf.length() + parambuf.length() > IRCD->MaxLine - 100)) // Leave room for command, channel, etc
		{
			ret.push_back(buf + parambuf);
			buf = "-";
			parambuf.clear();
			NModes = 1;
		}

		buf += it->first->mchar;

		if (!it->second.empty())
			parambuf += " " + it->second;
	}

	if (buf[buf.length() - 1] == '-')
		buf.erase(buf.length() - 1);

	if (!buf.empty())
		ret.push_back(buf + parambuf);

	return ret;
}
Esempio n. 22
0
	void DoUser(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request)
	{
		if (request->data.empty())
			return;

		User *u = finduser(request->data[0]);

		request->reply("nick", iface->Sanitize(u ? u->nick : request->data[0]));

		if (u)
		{
			request->reply("ident", iface->Sanitize(u->GetIdent()));
			request->reply("vident", iface->Sanitize(u->GetVIdent()));
			request->reply("host", iface->Sanitize(u->host));
			if (!u->vhost.empty())
				request->reply("vhost", iface->Sanitize(u->vhost));
			if (!u->chost.empty())
				request->reply("chost", iface->Sanitize(u->chost));
			if (u->ip())
				request->reply("ip", u->ip.addr());
			request->reply("timestamp", stringify(u->timestamp));
			request->reply("signon", stringify(u->my_signon));
			if (u->Account())
			{
				request->reply("account", iface->Sanitize(u->Account()->display));
				if (u->Account()->o)
					request->reply("opertype", iface->Sanitize(u->Account()->o->ot->GetName()));
			}

			Anope::string channels;
			for (UChannelList::const_iterator it = u->chans.begin(); it != u->chans.end(); ++it)
			{
				ChannelContainer *cc = *it;
				channels += cc->Status->BuildModePrefixList() + cc->chan->name + " ";
			}
			if (!channels.empty())
			{
				channels.erase(channels.length() - 1);
				request->reply("channels", channels);
			}
		}
	}
Esempio n. 23
0
    void DoUser(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
    {
        if (request.data.empty())
            return;

        User *u = User::Find(request.data[0]);

        request.reply("nick", iface->Sanitize(u ? u->nick : request.data[0]));

        if (u)
        {
            request.reply("ident", iface->Sanitize(u->GetIdent()));
            request.reply("vident", iface->Sanitize(u->GetVIdent()));
            request.reply("host", iface->Sanitize(u->host));
            if (!u->vhost.empty())
                request.reply("vhost", iface->Sanitize(u->vhost));
            if (!u->chost.empty())
                request.reply("chost", iface->Sanitize(u->chost));
            request.reply("ip", u->ip.addr());
            request.reply("timestamp", stringify(u->timestamp));
            request.reply("signon", stringify(u->signon));
            if (u->Account())
            {
                request.reply("account", iface->Sanitize(u->Account()->GetDisplay()));
                if (u->Account()->o)
                    request.reply("opertype", iface->Sanitize(u->Account()->o->GetType()->GetName()));
            }

            Anope::string channels;
            for (User::ChanUserList::const_iterator it = u->chans.begin(); it != u->chans.end(); ++it)
            {
                ChanUserContainer *cc = it->second;
                channels += cc->status.BuildModePrefixList() + cc->chan->name + " ";
            }
            if (!channels.empty())
            {
                channels.erase(channels.length() - 1);
                request.reply("channels", channels);
            }
        }
    }
Esempio n. 24
0
bool IRCDProto::IsNickValid(const Anope::string &nick)
{
	/**
	 * RFC: defination of a valid nick
	 * nickname =  ( letter / special ) ( letter / digit / special / "-" )
	 * letter   =  A-Z / a-z
	 * digit    =  0-9
	 * special  =  [, ], \, `, _, ^, {, |, }
	 **/

	 if (nick.empty())
	 	return false;

	Anope::string special = "[]\\`_^{|}";

	for (unsigned int i = 0; i < nick.length(); ++i)
		if (!(nick[i] >= 'A' && nick[i] <= 'Z') && !(nick[i] >= 'a' && nick[i] <= 'z')
		  && special.find(nick[i]) == Anope::string::npos
		  && (Config && Config->NickChars.find(nick[i]) == Anope::string::npos)
		  && (!i || (!(nick[i] >= '0' && nick[i] <= '9') && nick[i] != '-')))
			return false;

	return true;
}
Esempio n. 25
0
	bool IsValid(const Anope::string &value) const
	{
		try
		{
			Anope::string rest;
			if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
				return true;
		}
		catch (const ConvertException &) { }

		return false;
	}
Esempio n. 26
0
void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
	const Anope::string &receiver = params[0];
	Anope::string message = params[1];

	User *u = source.GetUser();

	if (IRCD->IsChannelValid(receiver))
	{
		Channel *c = Channel::Find(receiver);
		if (c)
		{
			EventManager::Get()->Dispatch(&Event::Privmsg::OnPrivmsg, u, c, message);
		}
	}
	else
	{
		/* If a server is specified (nick@server format), make sure it matches
		 * us, and strip it off. */
		Anope::string botname = receiver;
		size_t s = receiver.find('@');
		bool nick_only = false;
		if (s != Anope::string::npos)
		{
			Anope::string servername(receiver.begin() + s + 1, receiver.end());
			botname = botname.substr(0, s);
			nick_only = true;
			if (!servername.equals_ci(Me->GetName()))
				return;
		}
		else if (!IRCD->RequiresID && Config->UseStrictPrivmsg)
		{
			ServiceBot *bi = ServiceBot::Find(receiver);
			if (!bi)
				return;
			Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick;
			u->SendMessage(bi, _("\"/msg %s\" is no longer supported.  Use \"/msg %s@%s\" or \"/%s\" instead."), bi->nick.c_str(), bi->nick.c_str(), Me->GetName().c_str(), bi->nick.c_str());
			return;
		}

		ServiceBot *bi = ServiceBot::Find(botname, nick_only);

		if (bi)
		{
			if (message[0] == '\1' && message[message.length() - 1] == '\1')
			{
				if (message.substr(0, 6).equals_ci("\1PING "))
				{
					Anope::string buf = message;
					buf.erase(buf.begin());
					buf.erase(buf.end() - 1);
					IRCD->SendCTCP(bi, u->nick, "%s", buf.c_str());
				}
				else if (message.substr(0, 9).equals_ci("\1VERSION\1"))
				{
					Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
					IRCD->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
				}
				return;
			}

			EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::BotPrivmsg::OnBotPrivmsg, u, bi, message);
			if (MOD_RESULT == EVENT_STOP)
				return;

			bi->OnMessage(u, message);
		}
	}

	return;
}
Esempio n. 27
0
bool IRCdMessage::OnPrivmsg(const Anope::string &source, const std::vector<Anope::string> &params)
{
	const Anope::string &receiver = params.size() > 0 ? params[0] : "";
	Anope::string message = params.size() > 1 ? params[1] : "";

	/* Messages from servers can happen on some IRCds, check for . */
	if (source.empty() || receiver.empty() || message.empty() || source.find('.') != Anope::string::npos)
		return true;

	User *u = finduser(source);

	if (!u)
	{
		Log() << message << ": user record for " << source << " not found";

		BotInfo *bi = findbot(receiver);
		if (bi)
			ircdproto->SendMessage(bi, source, "%s", "Internal error - unable to process request.");

		return true;
	}

	if (receiver[0] == '#')
	{
		Channel *c = findchan(receiver);
		if (c)
		{
			FOREACH_MOD(I_OnPrivmsg, OnPrivmsg(u, c, message));
		}
	}
	else
	{
		/* If a server is specified (nick@server format), make sure it matches
		 * us, and strip it off. */
		Anope::string botname = receiver;
		size_t s = receiver.find('@');
		if (s != Anope::string::npos)
		{
			Anope::string servername(receiver.begin() + s + 1, receiver.end());
			botname = botname.substr(0, s);
			if (!servername.equals_ci(Config->ServerName))
				return true;
		}
		else if (Config->UseStrictPrivMsg)
		{
			BotInfo *bi = findbot(receiver);
			if (!bi)
				return true;
			Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << source;
			u->SendMessage(bi, _("\"/msg %s\" is no longer supported.  Use \"/msg %s@%s\" or \"/%s\" instead."), receiver.c_str(), receiver.c_str(), Config->ServerName.c_str(), receiver.c_str());
			return true;
		}

		BotInfo *bi = findbot(botname);

		if (bi)
		{
			EventReturn MOD_RESULT;
			FOREACH_RESULT(I_OnBotPrivmsg, OnBotPrivmsg(u, bi, message));
			if (MOD_RESULT == EVENT_STOP)
				return true;

			if (message[0] == '\1' && message[message.length() - 1] == '\1')
			{
				if (message.substr(0, 6).equals_ci("\1PING "))
				{
					Anope::string buf = message;
					buf.erase(buf.begin());
					buf.erase(buf.end() - 1);
					ircdproto->SendCTCP(bi, u->nick, "%s", buf.c_str());
				}
				else if (message.substr(0, 9).equals_ci("\1VERSION\1"))
				{
					Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
					ircdproto->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircd->name, enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str());
				}
				return true;
			}
			
			bi->OnMessage(u, message);
		}
	}

	return true;
}
Esempio n. 28
0
void BufferedSocket::Write(const Anope::string &message)
{
	this->Write(message.c_str(), message.length());
}
Esempio n. 29
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params)
	{
		const Anope::string &subcommand = params[0];

		if (subcommand.equals_ci("ADD") && params.size() > 2)
		{
			const Anope::string &oper = params[1];
			const Anope::string &otype = params[2];

			NickAlias *na = findnick(oper);
			if (na == NULL)
				source.Reply(NICK_X_NOT_REGISTERED, oper.c_str());
			else if (na->nc->o)
				source.Reply(_("Nick \2%s\2 is already an operator."), na->nick.c_str());
			else
			{
				OperType *ot = OperType::Find(otype);
				if (ot == NULL)
					source.Reply(_("Oper type \2%s\2 has not been configured."), otype.c_str());
				else
				{
					na->nc->o = new MyOper(na->nc->display, ot);

					Log(LOG_ADMIN, source.u, this) << "ADD " << na->nick << " as type " << ot->GetName();
					source.Reply("%s (%s) added to the \2%s\2 list.", na->nick.c_str(), na->nc->display.c_str(), ot->GetName().c_str());
				}
			}
		}
		else if (subcommand.equals_ci("DEL") && params.size() > 1)
		{
			const Anope::string &oper = params[1];

			NickAlias *na = findnick(oper);
			if (na == NULL)
				source.Reply(NICK_X_NOT_REGISTERED, oper.c_str());
			else if (!na->nc || !na->nc->o)
				source.Reply(_("Nick \2%s\2 is not a services operator."), oper.c_str());
			else
			{
				delete na->nc->o;
				na->nc->o = NULL;

				Log(LOG_ADMIN, source.u, this) << "DEL " << na->nick;
				source.Reply(_("Oper privileges removed from %s (%s)."), na->nick.c_str(), na->nc->display.c_str());
			}
		}
		else if (subcommand.equals_ci("LIST"))
		{
			source.Reply(_("Name     Type"));
			for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it)
			{
				NickCore *nc = it->second;

				if (!nc->o)
					continue;

				source.Reply(_("%-8s %s"), nc->o->name.c_str(), nc->o->ot->GetName().c_str());
				if (nc->o->config)
					source.Reply(_("   This oper is configured in the configuration file."));
				for (std::list<User *>::iterator uit = nc->Users.begin(); uit != nc->Users.end(); ++uit)
				{
					User *u = *uit;
					source.Reply(_("   %s is online using this oper block."), u->nick.c_str());
				}
			}
		}
		else if (subcommand.equals_ci("INFO") && params.size() > 1)
		{
			Anope::string fulltype = params[1];
			if (params.size() > 2)
				fulltype += " " + params[2];
			OperType *ot = OperType::Find(fulltype);
			if (ot == NULL)	
				source.Reply(_("Oper type \2%s\2 has not been configured."), fulltype.c_str());
			else
			{
				if (ot->GetCommands().empty())
					source.Reply(_("Opertype \2%s\2 has no allowed commands."), ot->GetName().c_str());
				else
				{
					source.Reply(_("Available commands for \2%s\2:"), ot->GetName().c_str());
					Anope::string buf;
					std::list<Anope::string> cmds = ot->GetCommands();
					for (std::list<Anope::string>::const_iterator it = cmds.begin(), it_end = cmds.end(); it != it_end; ++it)
					{
						buf += *it + " ";
						if (buf.length() > 400)
						{
							source.Reply("%s", buf.c_str());
							buf.clear();
						}
					}
					if (!buf.empty())
					{
						source.Reply("%s", buf.c_str());
						buf.clear();
					}
				}
				if (ot->GetPrivs().empty())
					source.Reply(_("Opertype \2%s\2 has no allowed privileges."), ot->GetName().c_str());
				else
				{
					source.Reply(_("Available privileges for \2%s\2:"), ot->GetName().c_str());
					Anope::string buf;
					std::list<Anope::string> privs = ot->GetPrivs();
					for (std::list<Anope::string>::const_iterator it = privs.begin(), it_end = privs.end(); it != it_end; ++it)
					{
						buf += *it + " ";
						if (buf.length() > 400)
						{
							source.Reply("%s", buf.c_str());
							buf.clear();
						}
					}
					if (!buf.empty())
					{
						source.Reply("%s", buf.c_str());
						buf.clear();
					}
				}
				if (!ot->modes.empty())
					source.Reply(_("Opertype \2%s\2 receives modes \2%s\2 once identifying."), ot->GetName().c_str(), ot->modes.c_str());
			}
		}
		else
			this->OnSyntaxError(source, subcommand);

		return;
	}
Esempio n. 30
0
	void Unserialize(const Anope::string &data)
	{
		for (unsigned i = data.length(); i > 0; --i)
			this->flags.insert(data[i - 1]);
	}