mirror of
https://github.com/anope/anope.git
synced 2026-07-08 23:43:13 +02:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0574de2d22 | |||
| c9c53dbe61 | |||
| a084245822 | |||
| 77e3f062da | |||
| 8bb3067e42 | |||
| 0c469abe4a | |||
| d63e32a579 | |||
| f13c450b93 | |||
| e95c07291a | |||
| 2963fc0a1d | |||
| 5d309d46e1 | |||
| 2e7fcd3098 | |||
| 884759aed4 | |||
| 2ec65023a6 | |||
| 0093f3fa44 | |||
| 2ad76278dd | |||
| 23e59d9f2c | |||
| 3cb9e0b97c | |||
| 0b7b6d9d6d | |||
| 56e6efbe8f | |||
| feed624cdc | |||
| 1a6f42b994 | |||
| 04f49225c9 | |||
| b18d1a69b6 | |||
| 0ace685597 | |||
| bfcfd0b727 | |||
| 087f1cb359 | |||
| 010d20198e | |||
| 953e804231 | |||
| c656fe0694 | |||
| fb3ec7a897 | |||
| 274658f955 | |||
| 7621306f4b | |||
| b804867105 | |||
| f8f1550c31 | |||
| 0fcc66711b | |||
| 8d9574e306 | |||
| 6cb17c734c | |||
| 3545e8e383 | |||
| 3c18e02b0b | |||
| b831cd8a36 | |||
| 516ab164f6 | |||
| b2d028533d | |||
| a88d9cb1f0 | |||
| b57ef5d2c7 | |||
| 1a96390826 | |||
| 60339edf40 | |||
| 6990c692d6 | |||
| 98e62b4032 | |||
| a1d7d42d6a | |||
| 3f7c0829ef | |||
| 46d8af781d | |||
| 67b7c8bd7d | |||
| 21486e2c81 | |||
| 29ac40b584 | |||
| dde444ed0e | |||
| 9b6c209c80 | |||
| 3c7d67c8cd | |||
| c730291762 | |||
| c593661f40 | |||
| 3b62c8f3e2 |
@@ -0,0 +1,46 @@
|
|||||||
|
## About
|
||||||
|
|
||||||
|
Anope is an open source set of IRC Services. It is highly modular, with a vast number of configurable parameters, and is the most used IRC services package. There are also many modules on the [modsite](https://modules.anope.org) to add additional features. It runs on Linux, BSD, and Windows, and supports many modern IRCds, including InspIRCd, UnrealIRCd, and ircd-hybrid. For more details, credits, command line options, and contact information see [docs/README](https://github.com/anope/anope/blob/2.0/docs/README).
|
||||||
|
|
||||||
|
* [Website](https://anope.org)
|
||||||
|
* [GitHub](https://github.com/anope)
|
||||||
|
* IRC \#anope on irc.anope.org
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Linux/BSD
|
||||||
|
Download the latest release off of the [releases page](https://github.com/anope/anope/releases).
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./Config
|
||||||
|
$ cd build
|
||||||
|
$ make
|
||||||
|
$ make install
|
||||||
|
```
|
||||||
|
|
||||||
|
Now change to the directory where you installed Anope to, e.g. `$ cd ~/services/`
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
Download the latest release off of the [releases page](https://github.com/anope/anope/releases) and run the installer.
|
||||||
|
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Copy conf/example.conf to conf/services.conf
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cp conf/example.conf conf/services.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit services.conf, configuring the uplink, serverinfo, and protocol module configurations. Example link blocks for popular IRCds are included in the the example.conf documentation. The [Anope wiki](https://wiki.anope.org) is also a good source of information. Our support channel is located at #anope on [irc.anope.org](irc://irc.anope.org/#anope).
|
||||||
|
|
||||||
|
Note that the example configuration file includes other example configuration files. If you want to modify the other example configuration files, copy them (e.g. `modules.example.conf` to `modules.conf`) and modify the `include` directive in `services.conf` to include the new file.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
Run `$ ./bin/services` to start Anope. If asked to provide logs for support, use the `--support` flag, e.g.: `$ ./bin/services --support`
|
||||||
|
|
||||||
|
## Installing extra modules
|
||||||
|
|
||||||
|
Extra modules, which are usually modules which require extra libraries to use, such as m\_mysql, can be enabled with the `./extras` command from the source directory. Then re-run `Config`, `make` and `make install` again. Third party modules can be installed by placing them into the `modules/third` directory.
|
||||||
+8
-13
@@ -532,7 +532,7 @@ options
|
|||||||
*
|
*
|
||||||
* Note for this to work the regex module providing the regex engine must be loaded.
|
* Note for this to work the regex module providing the regex engine must be loaded.
|
||||||
*/
|
*/
|
||||||
regexengine = "regex/pcre"
|
#regexengine = "regex/pcre"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A list of languages to load on startup that will be available in /nickserv set language.
|
* A list of languages to load on startup that will be available in /nickserv set language.
|
||||||
@@ -1201,23 +1201,14 @@ module
|
|||||||
* encrypted by this module. Old passwords stored in another encryption method are
|
* encrypted by this module. Old passwords stored in another encryption method are
|
||||||
* automatically re-encrypted by the primary encryption module on next identify.
|
* automatically re-encrypted by the primary encryption module on next identify.
|
||||||
*
|
*
|
||||||
* NOTE: enc_old is Anope's previous (broken) MD5 implementation which is present in
|
* enc_md5, enc_sha1, and enc_old are deprecated, and are provided for users
|
||||||
* versions prior to Anope 1.7.17. If your databases were made using that module,
|
* to upgrade to a newer encryption module. Do not use them as the primary
|
||||||
* use this and not enc_md5.
|
* encryption module. They will be removed in a future release.
|
||||||
*
|
|
||||||
* NOTE: enc_sha1 relies on how the OS stores 2+ byte data internally, and is
|
|
||||||
* potentially broken when moving between 2 different OSes, such as moving from
|
|
||||||
* Linux to Windows. It is recommended that you use enc_sha256 instead if you want
|
|
||||||
* to use an SHA-based encryption. If you choose to do so, it is also recommended
|
|
||||||
* that you first try to get everyone's passwords converted to enc_sha256 before
|
|
||||||
* switching OSes by placing enc_sha256 at the beginning of the list.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#module { name = "enc_bcrypt" }
|
#module { name = "enc_bcrypt" }
|
||||||
module { name = "enc_sha256" }
|
module { name = "enc_sha256" }
|
||||||
#module { name = "enc_md5" }
|
|
||||||
#module { name = "enc_sha1" }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When using enc_none, passwords will be stored without encryption. This isn't secure
|
* When using enc_none, passwords will be stored without encryption. This isn't secure
|
||||||
@@ -1225,6 +1216,10 @@ module { name = "enc_sha256" }
|
|||||||
*/
|
*/
|
||||||
#module { name = "enc_none" }
|
#module { name = "enc_none" }
|
||||||
|
|
||||||
|
/* Deprecated encryption modules */
|
||||||
|
#module { name = "enc_md5" }
|
||||||
|
#module { name = "enc_sha1" }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* enc_old is Anope's previous (broken) MD5 implementation used from 1.4.x to 1.7.16.
|
* enc_old is Anope's previous (broken) MD5 implementation used from 1.4.x to 1.7.16.
|
||||||
* If your databases were made using that module, load it here to allow conversion to the primary
|
* If your databases were made using that module, load it here to allow conversion to the primary
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ module { name = "help" }
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Exempt localhost from DNSBL checks */
|
/* Exempt localhost from DNSBL checks */
|
||||||
exempt { ip = "127.0.0.1" }
|
exempt { ip = "127.0.0.0/8" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -540,7 +540,7 @@ module { name = "help" }
|
|||||||
* authenticating users through this mechanism. Supported mechanisms are:
|
* authenticating users through this mechanism. Supported mechanisms are:
|
||||||
* PLAIN, EXTERNAL.
|
* PLAIN, EXTERNAL.
|
||||||
*/
|
*/
|
||||||
#module { name = "m_sasl" }
|
module { name = "m_sasl" }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* m_ssl_gnutls [EXTRA]
|
* m_ssl_gnutls [EXTRA]
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ module
|
|||||||
* - autoop: User will be automatically opped in channels they enter and have access to
|
* - autoop: User will be automatically opped in channels they enter and have access to
|
||||||
* - msg: Services messages will be sent as PRIVMSGs instead of NOTICEs, requires
|
* - msg: Services messages will be sent as PRIVMSGs instead of NOTICEs, requires
|
||||||
* options:useprivmsg to be enabled as well
|
* options:useprivmsg to be enabled as well
|
||||||
* - ns_keepmodes: Enables keepmodes, which retains user modes across sessions
|
* - ns_keep_modes: Enables keepmodes, which retains user modes across sessions
|
||||||
* - ns_no_expire: Enables no expire. Unconfirmed expire overrules this.
|
* - ns_no_expire: Enables no expire. Unconfirmed expire overrules this.
|
||||||
*
|
*
|
||||||
* This directive is optional, if left blank, the options will default to ns_secure, memo_signon, and
|
* This directive is optional, if left blank, the options will default to ns_secure, memo_signon, and
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
Anope Version 2.0.6
|
||||||
|
-------------------
|
||||||
|
Log client IP for web clients running commands via webcpanel
|
||||||
|
Fix log file path for the config file could not be opened log message
|
||||||
|
Allow nickserv/group to be used via XMLRPC
|
||||||
|
Fix logsearch without wildcards
|
||||||
|
Support cidr exempts in m_dnsbl
|
||||||
|
Add support for IPv6 dnsbls
|
||||||
|
Add +u and +L channel modes for ircd-hybrid
|
||||||
|
Set +x after hostserv/off on InspIRCd and UnrealIRCd
|
||||||
|
Fix chanserv/mode not being able to set extbans
|
||||||
|
Send CHGIDENT/CHGHOST on SVSLOGIN on InspIRCd
|
||||||
|
Fix escaping replies from commands in webcpanel
|
||||||
|
Enable require_oper for all opers added via operserv/oper
|
||||||
|
Advertise SASL mechanisms to UnrealIRCd servers
|
||||||
|
|
||||||
Anope Version 2.0.5
|
Anope Version 2.0.5
|
||||||
-------------------
|
-------------------
|
||||||
Fix negative levels to not match users with negative access
|
Fix negative levels to not match users with negative access
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
Anope Version 2.0.6
|
||||||
|
-------------------
|
||||||
|
Mark enc_md5 and enc_sha1 as deprecated. Their use has been discouraged for years, and they will be removed in a future release.
|
||||||
|
Exempt all of 127.0.0.0/8 from m_dnsbl by default
|
||||||
|
Load m_sasl by default
|
||||||
|
Fix documentation for nickserv default option ns_keep_modes
|
||||||
|
|
||||||
Anope Version 2.0.5
|
Anope Version 2.0.5
|
||||||
-------------------
|
-------------------
|
||||||
No significant changes.
|
No significant changes.
|
||||||
|
|||||||
+2
-4
@@ -9,8 +9,6 @@ This program is free but copyrighted software; see the file COPYING for
|
|||||||
details.
|
details.
|
||||||
|
|
||||||
Information about Anope may be found at http://www.anope.org/
|
Information about Anope may be found at http://www.anope.org/
|
||||||
Information about Epona may be found at http://www.epona.org/
|
|
||||||
Information about Services may be found at http://www.ircservices.esper.net/
|
|
||||||
|
|
||||||
Table of Contents
|
Table of Contents
|
||||||
-----------------
|
-----------------
|
||||||
@@ -19,7 +17,7 @@ Table of Contents
|
|||||||
3) Installation
|
3) Installation
|
||||||
4) Command Line Options
|
4) Command Line Options
|
||||||
5) Messages Translation
|
5) Messages Translation
|
||||||
6) Contact and Mailing List
|
6) Contact
|
||||||
|
|
||||||
1) Credits
|
1) Credits
|
||||||
|
|
||||||
@@ -170,7 +168,7 @@ Table of Contents
|
|||||||
|
|
||||||
* Bahamut 1.4.27 or later (including 1.8)
|
* Bahamut 1.4.27 or later (including 1.8)
|
||||||
* Charybdis 3.4 or later
|
* Charybdis 3.4 or later
|
||||||
* Hybrid 8.1 or later
|
* Hybrid 8.2 or later
|
||||||
* InspIRCd 1.2 or 2.0
|
* InspIRCd 1.2 or 2.0
|
||||||
* ngIRCd 19.2 or later
|
* ngIRCd 19.2 or later
|
||||||
* Plexus 3 or later
|
* Plexus 3 or later
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ class CoreExport IdentifyRequest
|
|||||||
virtual void OnSuccess() = 0;
|
virtual void OnSuccess() = 0;
|
||||||
virtual void OnFail() = 0;
|
virtual void OnFail() = 0;
|
||||||
|
|
||||||
|
Module *GetOwner() const { return owner; }
|
||||||
const Anope::string &GetAccount() const { return account; }
|
const Anope::string &GetAccount() const { return account; }
|
||||||
const Anope::string &GetPassword() const { return password; }
|
const Anope::string &GetPassword() const { return password; }
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ class CoreExport CommandSource
|
|||||||
public:
|
public:
|
||||||
/* The account executing the command */
|
/* The account executing the command */
|
||||||
Reference<NickCore> nc;
|
Reference<NickCore> nc;
|
||||||
|
/* for web clients */
|
||||||
|
Anope::string ip;
|
||||||
/* Where the reply should go */
|
/* Where the reply should go */
|
||||||
CommandReply *reply;
|
CommandReply *reply;
|
||||||
/* Channel the command was executed on (fantasy) */
|
/* Channel the command was executed on (fantasy) */
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ namespace Configuration
|
|||||||
File(const Anope::string &, bool);
|
File(const Anope::string &, bool);
|
||||||
~File();
|
~File();
|
||||||
const Anope::string &GetName() const;
|
const Anope::string &GetName() const;
|
||||||
|
Anope::string GetPath() const;
|
||||||
|
|
||||||
bool IsOpen() const;
|
bool IsOpen() const;
|
||||||
bool Open();
|
bool Open();
|
||||||
|
|||||||
@@ -301,6 +301,11 @@ class CoreExport Module : public Extensible
|
|||||||
* before they will be called.
|
* before they will be called.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** Called on startup after database load, but before
|
||||||
|
* connecting to the uplink.
|
||||||
|
*/
|
||||||
|
virtual void OnPostInit() { throw NotImplementedException(); }
|
||||||
|
|
||||||
/** Called before a user has been kicked from a channel.
|
/** Called before a user has been kicked from a channel.
|
||||||
* @param source The kicker
|
* @param source The kicker
|
||||||
* @param cu The user, channel, and status of the user being kicked
|
* @param cu The user, channel, and status of the user being kicked
|
||||||
@@ -1099,6 +1104,7 @@ class CoreExport Module : public Extensible
|
|||||||
|
|
||||||
enum Implementation
|
enum Implementation
|
||||||
{
|
{
|
||||||
|
I_OnPostInit,
|
||||||
I_OnPreUserKicked, I_OnUserKicked, I_OnReload, I_OnPreBotAssign, I_OnBotAssign, I_OnBotUnAssign, I_OnUserConnect,
|
I_OnPreUserKicked, I_OnUserKicked, I_OnReload, I_OnPreBotAssign, I_OnBotAssign, I_OnBotUnAssign, I_OnUserConnect,
|
||||||
I_OnNewServer, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp, I_OnPreCommand, I_OnPostCommand, I_OnSaveDatabase,
|
I_OnNewServer, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp, I_OnPreCommand, I_OnPostCommand, I_OnSaveDatabase,
|
||||||
I_OnLoadDatabase, I_OnEncrypt, I_OnDecrypt, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd,
|
I_OnLoadDatabase, I_OnEncrypt, I_OnDecrypt, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd,
|
||||||
|
|||||||
@@ -228,6 +228,9 @@ namespace HTTPUtils
|
|||||||
case '"':
|
case '"':
|
||||||
dst += """;
|
dst += """;
|
||||||
break;
|
break;
|
||||||
|
case '&':
|
||||||
|
dst += "&";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dst += src[i];
|
dst += src[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ class ForbidService : public Service
|
|||||||
|
|
||||||
virtual ForbidData *FindForbid(const Anope::string &mask, ForbidType type) = 0;
|
virtual ForbidData *FindForbid(const Anope::string &mask, ForbidType type) = 0;
|
||||||
|
|
||||||
|
virtual ForbidData *FindForbidExact(const Anope::string &mask, ForbidType type) = 0;
|
||||||
|
|
||||||
virtual std::vector<ForbidData *> GetForbids() = 0;
|
virtual std::vector<ForbidData *> GetForbids() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ namespace Redis
|
|||||||
public:
|
public:
|
||||||
Provider(Module *c, const Anope::string &n) : Service(c, "Redis::Provider", n) { }
|
Provider(Module *c, const Anope::string &n) : Service(c, "Redis::Provider", n) { }
|
||||||
|
|
||||||
|
virtual bool IsSocketDead() = 0;
|
||||||
|
|
||||||
virtual void SendCommand(Interface *i, const std::vector<Anope::string> &cmds) = 0;
|
virtual void SendCommand(Interface *i, const std::vector<Anope::string> &cmds) = 0;
|
||||||
virtual void SendCommand(Interface *i, const Anope::string &str) = 0;
|
virtual void SendCommand(Interface *i, const Anope::string &str) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace SASL
|
|||||||
if (!hostname.empty() && !ip.empty())
|
if (!hostname.empty() && !ip.empty())
|
||||||
user = hostname + " (" + ip + ")";
|
user = hostname + " (" + ip + ")";
|
||||||
|
|
||||||
Log(Config->GetClient("NickServ"), "sasl") << user << " identified to account " << this->GetAccount() << " using SASL";
|
Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << user << " identified to account " << this->GetAccount() << " using SASL";
|
||||||
sasl->Succeed(s, na->nc);
|
sasl->Succeed(s, na->nc);
|
||||||
delete s;
|
delete s;
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ namespace SASL
|
|||||||
if (!hostname.empty() && !ip.empty())
|
if (!hostname.empty() && !ip.empty())
|
||||||
user = hostname + " (" + ip + ")";
|
user = hostname + " (" + ip + ")";
|
||||||
|
|
||||||
Log(Config->GetClient("NickServ"), "sasl") << user << " failed to identify for " << accountstatus << "account " << this->GetAccount() << " using SASL";
|
Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << user << " failed to identify for " << accountstatus << "account " << this->GetAccount() << " using SASL";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ union CoreExport sockaddrs
|
|||||||
*/
|
*/
|
||||||
Anope::string addr() const;
|
Anope::string addr() const;
|
||||||
|
|
||||||
|
/** Get the reverse address represented by this addr
|
||||||
|
* @return The reverse address
|
||||||
|
*/
|
||||||
|
Anope::string reverse() const;
|
||||||
|
|
||||||
/* Is this address ipv6? */
|
/* Is this address ipv6? */
|
||||||
bool ipv6() const;
|
bool ipv6() const;
|
||||||
|
|
||||||
|
|||||||
+275
-409
File diff suppressed because it is too large
Load Diff
+503
-602
File diff suppressed because it is too large
Load Diff
@@ -393,7 +393,7 @@ class CommandBSBadwords : public Command
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!source.AccessFor(ci).HasPriv("BADWORDS") && (!need_args || !source.HasPriv("botserv/administration")))
|
if (!source.AccessFor(ci).HasPriv("BADWORDS") && !source.HasPriv("botserv/administration"))
|
||||||
{
|
{
|
||||||
source.Reply(ACCESS_DENIED);
|
source.Reply(ACCESS_DENIED);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -13,6 +13,31 @@
|
|||||||
|
|
||||||
class CommandCSAKick : public Command
|
class CommandCSAKick : public Command
|
||||||
{
|
{
|
||||||
|
void Enforce(CommandSource &source, ChannelInfo *ci)
|
||||||
|
{
|
||||||
|
Channel *c = ci->c;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
|
||||||
|
{
|
||||||
|
ChanUserContainer *uc = it->second;
|
||||||
|
++it;
|
||||||
|
|
||||||
|
if (c->CheckKick(uc->user))
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool override = !source.AccessFor(ci).HasPriv("AKICK");
|
||||||
|
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ENFORCE, affects " << count << " users";
|
||||||
|
|
||||||
|
source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
|
||||||
|
}
|
||||||
|
|
||||||
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||||
{
|
{
|
||||||
Anope::string mask = params[2];
|
Anope::string mask = params[2];
|
||||||
@@ -164,7 +189,7 @@ class CommandCSAKick : public Command
|
|||||||
|
|
||||||
source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
|
source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
|
||||||
|
|
||||||
this->DoEnforce(source, ci);
|
this->Enforce(source, ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||||
@@ -384,7 +409,6 @@ class CommandCSAKick : public Command
|
|||||||
void DoEnforce(CommandSource &source, ChannelInfo *ci)
|
void DoEnforce(CommandSource &source, ChannelInfo *ci)
|
||||||
{
|
{
|
||||||
Channel *c = ci->c;
|
Channel *c = ci->c;
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
if (!c)
|
if (!c)
|
||||||
{
|
{
|
||||||
@@ -392,19 +416,7 @@ class CommandCSAKick : public Command
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
|
this->Enforce(source, ci);
|
||||||
{
|
|
||||||
ChanUserContainer *uc = it->second;
|
|
||||||
++it;
|
|
||||||
|
|
||||||
if (c->CheckKick(uc->user))
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool override = !source.AccessFor(ci).HasPriv("AKICK");
|
|
||||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ENFORCE, affects " << count << " users";
|
|
||||||
|
|
||||||
source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoClear(CommandSource &source, ChannelInfo *ci)
|
void DoClear(CommandSource &source, ChannelInfo *ci)
|
||||||
|
|||||||
@@ -654,6 +654,10 @@ class CommandCSMode : public Command
|
|||||||
break;
|
break;
|
||||||
if (!sep.GetToken(param))
|
if (!sep.GetToken(param))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Change to internal name, eg giving -b ~q:*
|
||||||
|
cm = cm->Unwrap(param);
|
||||||
|
|
||||||
if (adding)
|
if (adding)
|
||||||
{
|
{
|
||||||
if (IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) < IRCD->GetMaxListFor(ci->c))
|
if (IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) < IRCD->GetMaxListFor(ci->c))
|
||||||
@@ -667,10 +671,10 @@ class CommandCSMode : public Command
|
|||||||
ci->c->RemoveMode(NULL, cm, v[j]);
|
ci->c->RemoveMode(NULL, cm, v[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // switch
|
||||||
|
|
||||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << params[2] << (params.size() > 3 ? " " + params[3] : "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << modes << (params.size() > 3 ? " " + params[3] : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoClear(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
void DoClear(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||||
@@ -709,6 +713,12 @@ class CommandCSMode : public Command
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cm->mchar)
|
||||||
|
{
|
||||||
|
source.Reply(_("Mode %s is a virtual mode and can't be cleared."), cm->name.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Anope::string> new_params;
|
std::vector<Anope::string> new_params;
|
||||||
new_params.push_back(params[0]);
|
new_params.push_back(params[0]);
|
||||||
new_params.push_back("SET");
|
new_params.push_back("SET");
|
||||||
|
|||||||
@@ -504,20 +504,6 @@ class CommandCSSetPersist : public Command
|
|||||||
{
|
{
|
||||||
ci->Extend<bool>("PERSIST");
|
ci->Extend<bool>("PERSIST");
|
||||||
|
|
||||||
/* Channel doesn't exist, create it */
|
|
||||||
if (!ci->c)
|
|
||||||
{
|
|
||||||
bool created;
|
|
||||||
Channel *c = Channel::FindOrCreate(ci->name, created);
|
|
||||||
if (ci->bi)
|
|
||||||
{
|
|
||||||
ChannelStatus status(BotModes());
|
|
||||||
ci->bi->Join(c, &status);
|
|
||||||
}
|
|
||||||
if (created)
|
|
||||||
c->Sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the perm mode */
|
/* Set the perm mode */
|
||||||
if (cm)
|
if (cm)
|
||||||
{
|
{
|
||||||
@@ -541,7 +527,7 @@ class CommandCSSetPersist : public Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
ChanServ->Assign(NULL, ci);
|
ChanServ->Assign(NULL, ci);
|
||||||
if (!ci->c->FindUser(ChanServ))
|
if (ci->c && !ci->c->FindUser(ChanServ))
|
||||||
{
|
{
|
||||||
ChannelStatus status(BotModes());
|
ChannelStatus status(BotModes());
|
||||||
ChanServ->Join(ci->c, &status);
|
ChanServ->Join(ci->c, &status);
|
||||||
@@ -1099,7 +1085,8 @@ class CommandCSSetNoexpire : public Command
|
|||||||
class CSSet : public Module
|
class CSSet : public Module
|
||||||
{
|
{
|
||||||
SerializableExtensibleItem<bool> noautoop, peace, securefounder,
|
SerializableExtensibleItem<bool> noautoop, peace, securefounder,
|
||||||
restricted, secure, secureops, signkick, signkick_level, noexpire;
|
restricted, secure, secureops, signkick, signkick_level, noexpire,
|
||||||
|
persist;
|
||||||
|
|
||||||
struct KeepModes : SerializableExtensibleItem<bool>
|
struct KeepModes : SerializableExtensibleItem<bool>
|
||||||
{
|
{
|
||||||
@@ -1147,51 +1134,6 @@ class CSSet : public Module
|
|||||||
}
|
}
|
||||||
} keep_modes;
|
} keep_modes;
|
||||||
|
|
||||||
struct Persist : SerializableExtensibleItem<bool>
|
|
||||||
{
|
|
||||||
Persist(Module *m, const Anope::string &n) : SerializableExtensibleItem<bool>(m, n) { }
|
|
||||||
|
|
||||||
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
|
|
||||||
{
|
|
||||||
SerializableExtensibleItem<bool>::ExtensibleUnserialize(e, s, data);
|
|
||||||
|
|
||||||
if (s->GetSerializableType()->GetName() != "ChannelInfo" || !this->HasExt(e))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(s);
|
|
||||||
if (ci->c)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool created;
|
|
||||||
Channel *c = Channel::FindOrCreate(ci->name, created);
|
|
||||||
|
|
||||||
ChannelMode *cm = ModeManager::FindChannelModeByName("PERM");
|
|
||||||
if (cm)
|
|
||||||
{
|
|
||||||
c->SetMode(NULL, cm);
|
|
||||||
}
|
|
||||||
/* on startup we might not know mode availibity here */
|
|
||||||
else if (Me && Me->IsSynced())
|
|
||||||
{
|
|
||||||
if (!ci->bi)
|
|
||||||
{
|
|
||||||
BotInfo *ChanServ = Config->GetClient("ChanServ");
|
|
||||||
if (ChanServ)
|
|
||||||
ChanServ->Assign(NULL, ci);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ci->bi && !c->FindUser(ci->bi))
|
|
||||||
{
|
|
||||||
ChannelStatus status(BotModes());
|
|
||||||
ci->bi->Join(c, &status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (created)
|
|
||||||
c->Sync();
|
|
||||||
}
|
|
||||||
} persist;
|
|
||||||
|
|
||||||
CommandCSSet commandcsset;
|
CommandCSSet commandcsset;
|
||||||
CommandCSSetAutoOp commandcssetautoop;
|
CommandCSSetAutoOp commandcssetautoop;
|
||||||
CommandCSSetBanType commandcssetbantype;
|
CommandCSSetBanType commandcssetbantype;
|
||||||
@@ -1218,7 +1160,8 @@ class CSSet : public Module
|
|||||||
securefounder(this, "SECUREFOUNDER"), restricted(this, "RESTRICTED"),
|
securefounder(this, "SECUREFOUNDER"), restricted(this, "RESTRICTED"),
|
||||||
secure(this, "CS_SECURE"), secureops(this, "SECUREOPS"), signkick(this, "SIGNKICK"),
|
secure(this, "CS_SECURE"), secureops(this, "SECUREOPS"), signkick(this, "SIGNKICK"),
|
||||||
signkick_level(this, "SIGNKICK_LEVEL"), noexpire(this, "CS_NO_EXPIRE"),
|
signkick_level(this, "SIGNKICK_LEVEL"), noexpire(this, "CS_NO_EXPIRE"),
|
||||||
keep_modes(this, "CS_KEEP_MODES"), persist(this, "PERSIST"),
|
persist(this, "PERSIST"),
|
||||||
|
keep_modes(this, "CS_KEEP_MODES"),
|
||||||
|
|
||||||
commandcsset(this), commandcssetautoop(this), commandcssetbantype(this),
|
commandcsset(this), commandcssetautoop(this), commandcssetbantype(this),
|
||||||
commandcssetdescription(this), commandcssetfounder(this), commandcssetkeepmodes(this),
|
commandcssetdescription(this), commandcssetfounder(this), commandcssetkeepmodes(this),
|
||||||
@@ -1299,7 +1242,7 @@ class CSSet : public Module
|
|||||||
|
|
||||||
void OnJoinChannel(User *u, Channel *c) anope_override
|
void OnJoinChannel(User *u, Channel *c) anope_override
|
||||||
{
|
{
|
||||||
if (persist_lower_ts && c->ci && persist.HasExt(c->ci) && c->creation_time > c->ci->time_registered)
|
if (u->server != Me && persist_lower_ts && c->ci && persist.HasExt(c->ci) && c->creation_time > c->ci->time_registered)
|
||||||
{
|
{
|
||||||
Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->time_registered;
|
Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->time_registered;
|
||||||
c->creation_time = c->ci->time_registered;
|
c->creation_time = c->ci->time_registered;
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ class CommandCSSetMisc : public Command
|
|||||||
{
|
{
|
||||||
if (descriptions.count(source.command))
|
if (descriptions.count(source.command))
|
||||||
{
|
{
|
||||||
|
this->SendSyntax(source);
|
||||||
source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
|
source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ class CommandCSXOP : public Command
|
|||||||
BotInfo *access_bi, *flags_bi;
|
BotInfo *access_bi, *flags_bi;
|
||||||
Anope::string access_cmd, flags_cmd;
|
Anope::string access_cmd, flags_cmd;
|
||||||
Command::FindCommandFromService("chanserv/access", access_bi, access_cmd);
|
Command::FindCommandFromService("chanserv/access", access_bi, access_cmd);
|
||||||
Command::FindCommandFromService("chanserv/flags", flags_bi, access_cmd);
|
Command::FindCommandFromService("chanserv/flags", flags_bi, flags_cmd);
|
||||||
if (!access_cmd.empty() || !flags_cmd.empty())
|
if (!access_cmd.empty() || !flags_cmd.empty())
|
||||||
{
|
{
|
||||||
source.Reply(_("Alternative methods of modifying channel access lists are\n"
|
source.Reply(_("Alternative methods of modifying channel access lists are\n"
|
||||||
|
|||||||
@@ -24,45 +24,58 @@ class NSGroupRequest : public IdentifyRequest
|
|||||||
|
|
||||||
void OnSuccess() anope_override
|
void OnSuccess() anope_override
|
||||||
{
|
{
|
||||||
if (!source.GetUser() || source.GetUser()->nick != nick || !target || !target->nc)
|
User *u = source.GetUser();
|
||||||
|
|
||||||
|
/* user changed nick? */
|
||||||
|
if (u != NULL && u->nick != nick)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!target || !target->nc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
User *u = source.GetUser();
|
|
||||||
NickAlias *na = NickAlias::Find(nick);
|
NickAlias *na = NickAlias::Find(nick);
|
||||||
/* If the nick is already registered, drop it. */
|
/* If the nick is already registered, drop it. */
|
||||||
if (na)
|
if (na)
|
||||||
{
|
{
|
||||||
FOREACH_MOD(OnChangeCoreDisplay, (na->nc, u->nick));
|
|
||||||
delete na;
|
delete na;
|
||||||
}
|
}
|
||||||
|
|
||||||
na = new NickAlias(nick, target->nc);
|
na = new NickAlias(nick, target->nc);
|
||||||
|
|
||||||
Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
|
|
||||||
na->last_usermask = last_usermask;
|
|
||||||
na->last_realname = u->realname;
|
|
||||||
na->time_registered = na->last_seen = Anope::CurTime;
|
na->time_registered = na->last_seen = Anope::CurTime;
|
||||||
|
|
||||||
u->Login(target->nc);
|
if (u != NULL)
|
||||||
FOREACH_MOD(OnNickGroup, (u, target));
|
{
|
||||||
|
na->last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
|
||||||
|
na->last_realname = u->realname;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
na->last_realname = source.GetNick();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u != NULL)
|
||||||
|
{
|
||||||
|
u->Login(target->nc);
|
||||||
|
FOREACH_MOD(OnNickGroup, (u, target));
|
||||||
|
}
|
||||||
|
|
||||||
Log(LOG_COMMAND, source, cmd) << "to make " << nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")";
|
Log(LOG_COMMAND, source, cmd) << "to make " << nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")";
|
||||||
source.Reply(_("You are now in the group of \002%s\002."), target->nick.c_str());
|
source.Reply(_("You are now in the group of \002%s\002."), target->nick.c_str());
|
||||||
|
|
||||||
u->lastnickreg = Anope::CurTime;
|
if (u)
|
||||||
|
u->lastnickreg = Anope::CurTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnFail() anope_override
|
void OnFail() anope_override
|
||||||
{
|
{
|
||||||
if (!source.GetUser())
|
User *u = source.GetUser();
|
||||||
return;
|
|
||||||
|
|
||||||
Log(LOG_COMMAND, source, cmd) << "and failed to group to " << target->nick;
|
Log(LOG_COMMAND, source, cmd) << "and failed to group to " << target->nick;
|
||||||
if (NickAlias::Find(GetAccount()) != NULL)
|
if (NickAlias::Find(GetAccount()) != NULL)
|
||||||
{
|
{
|
||||||
source.Reply(PASSWORD_INCORRECT);
|
source.Reply(PASSWORD_INCORRECT);
|
||||||
source.GetUser()->BadPassword();
|
if (u)
|
||||||
|
u->BadPassword();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
|
source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ class CommandNSSetMisc : public Command
|
|||||||
{
|
{
|
||||||
if (descriptions.count(source.command))
|
if (descriptions.count(source.command))
|
||||||
{
|
{
|
||||||
|
this->SendSyntax(source);
|
||||||
source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
|
source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,18 @@ class MyForbidService : public ForbidService
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ForbidData *FindForbidExact(const Anope::string &mask, ForbidType ftype) anope_override
|
||||||
|
{
|
||||||
|
for (unsigned i = this->forbids(ftype).size(); i > 0; --i)
|
||||||
|
{
|
||||||
|
ForbidData *d = this->forbids(ftype)[i - 1];
|
||||||
|
|
||||||
|
if (d->mask.equals_ci(mask))
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<ForbidData *> GetForbids() anope_override
|
std::vector<ForbidData *> GetForbids() anope_override
|
||||||
{
|
{
|
||||||
std::vector<ForbidData *> f;
|
std::vector<ForbidData *> f;
|
||||||
@@ -203,7 +215,7 @@ class CommandOSForbid : public Command
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ForbidData *d = this->fs->FindForbid(entry, ftype);
|
ForbidData *d = this->fs->FindForbidExact(entry, ftype);
|
||||||
bool created = false;
|
bool created = false;
|
||||||
if (d == NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
@@ -322,7 +334,7 @@ class CommandOSForbid : public Command
|
|||||||
{
|
{
|
||||||
const Anope::string &entry = params[2];
|
const Anope::string &entry = params[2];
|
||||||
|
|
||||||
ForbidData *d = this->fs->FindForbid(entry, ftype);
|
ForbidData *d = this->fs->FindForbidExact(entry, ftype);
|
||||||
if (d != NULL)
|
if (d != NULL)
|
||||||
{
|
{
|
||||||
if (Anope::ReadOnly)
|
if (Anope::ReadOnly)
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class CommandOSLogSearch : public Command
|
|||||||
else if (wildcard)
|
else if (wildcard)
|
||||||
match = Anope::Match(buf, "*" + search_string + "*");
|
match = Anope::Match(buf, "*" + search_string + "*");
|
||||||
else
|
else
|
||||||
match = buf.find_first_of_ci(search_string) != Anope::string::npos;
|
match = buf.find_ci(search_string) != Anope::string::npos;
|
||||||
|
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ class CommandOSOper : public Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
na->nc->o = new MyOper(na->nc->display, ot);
|
na->nc->o = new MyOper(na->nc->display, ot);
|
||||||
na->nc->o->require_oper = true;
|
|
||||||
|
|
||||||
if (Anope::ReadOnly)
|
if (Anope::ReadOnly)
|
||||||
source.Reply(READ_ONLY_MODE);
|
source.Reply(READ_ONLY_MODE);
|
||||||
|
|||||||
@@ -179,6 +179,12 @@ class DatabaseRedis : public Module, public Pipe
|
|||||||
|
|
||||||
EventReturn OnLoadDatabase() anope_override
|
EventReturn OnLoadDatabase() anope_override
|
||||||
{
|
{
|
||||||
|
if (!redis)
|
||||||
|
{
|
||||||
|
Log(this) << "Unable to load database - unable to find redis provider";
|
||||||
|
return EVENT_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<Anope::string> type_order = Serialize::Type::GetTypeOrder();
|
const std::vector<Anope::string> type_order = Serialize::Type::GetTypeOrder();
|
||||||
for (unsigned i = 0; i < type_order.size(); ++i)
|
for (unsigned i = 0; i < type_order.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -186,7 +192,13 @@ class DatabaseRedis : public Module, public Pipe
|
|||||||
this->OnSerializeTypeCreate(sb);
|
this->OnSerializeTypeCreate(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (redis->BlockAndProcess());
|
while (!redis->IsSocketDead() && redis->BlockAndProcess());
|
||||||
|
|
||||||
|
if (redis->IsSocketDead())
|
||||||
|
{
|
||||||
|
Log(this) << "I/O error while loading redis database - is it online?";
|
||||||
|
return EVENT_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
redis->Subscribe(&this->sl, "__keyspace@*__:hash:*");
|
redis->Subscribe(&this->sl, "__keyspace@*__:hash:*");
|
||||||
|
|
||||||
@@ -215,6 +227,18 @@ class DatabaseRedis : public Module, public Pipe
|
|||||||
{
|
{
|
||||||
Serialize::Type *t = obj->GetSerializableType();
|
Serialize::Type *t = obj->GetSerializableType();
|
||||||
|
|
||||||
|
if (t == NULL)
|
||||||
|
{
|
||||||
|
/* This is probably the module providing the type unloading.
|
||||||
|
*
|
||||||
|
* The types get registered after the extensible container is
|
||||||
|
* registered so that unserialization on module load can insert
|
||||||
|
* into the extensible container. So, the type destructs prior to
|
||||||
|
* the extensible container, which then triggers this
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Anope::string> args;
|
std::vector<Anope::string> args;
|
||||||
args.push_back("HGETALL");
|
args.push_back("HGETALL");
|
||||||
args.push_back("hash:" + t->GetName() + ":" + stringify(obj->id));
|
args.push_back("hash:" + t->GetName() + ":" + stringify(obj->id));
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class POSIXRegex : public Regex
|
|||||||
public:
|
public:
|
||||||
POSIXRegex(const Anope::string &expr) : Regex(expr)
|
POSIXRegex(const Anope::string &expr) : Regex(expr)
|
||||||
{
|
{
|
||||||
int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB);
|
int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB | REG_ICASE);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
|
|||||||
+9
-25
@@ -296,32 +296,16 @@ class Packet : public Query
|
|||||||
if (!ip.valid())
|
if (!ip.valid())
|
||||||
throw SocketException("Invalid IP");
|
throw SocketException("Invalid IP");
|
||||||
|
|
||||||
if (q.name.find(':') != Anope::string::npos)
|
switch (ip.family())
|
||||||
{
|
{
|
||||||
const char *const hex = "0123456789abcdef";
|
case AF_INET6:
|
||||||
char reverse_ip[128];
|
q.name = ip.reverse() + ".ip6.arpa";
|
||||||
unsigned reverse_ip_count = 0;
|
break;
|
||||||
for (int j = 15; j >= 0; --j)
|
case AF_INET:
|
||||||
{
|
q.name = ip.reverse() + ".in-addr.arpa";
|
||||||
reverse_ip[reverse_ip_count++] = hex[ip.sa6.sin6_addr.s6_addr[j] & 0xF];
|
break;
|
||||||
reverse_ip[reverse_ip_count++] = '.';
|
default:
|
||||||
reverse_ip[reverse_ip_count++] = hex[ip.sa6.sin6_addr.s6_addr[j] >> 4];
|
throw SocketException("Unsupported IP Family");
|
||||||
reverse_ip[reverse_ip_count++] = '.';
|
|
||||||
}
|
|
||||||
reverse_ip[reverse_ip_count++] = 0;
|
|
||||||
|
|
||||||
q.name = reverse_ip;
|
|
||||||
q.name += "ip6.arpa";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned long forward = ip.sa4.sin_addr.s_addr;
|
|
||||||
in_addr reverse;
|
|
||||||
reverse.s_addr = forward << 24 | (forward & 0xFF00) << 8 | (forward & 0xFF0000) >> 8 | forward >> 24;
|
|
||||||
|
|
||||||
ip.ntop(AF_INET, &reverse);
|
|
||||||
|
|
||||||
q.name = ip.addr() + ".in-addr.arpa";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-11
@@ -99,7 +99,7 @@ class DNSBLResolver : public Request
|
|||||||
class ModuleDNSBL : public Module
|
class ModuleDNSBL : public Module
|
||||||
{
|
{
|
||||||
std::vector<Blacklist> blacklists;
|
std::vector<Blacklist> blacklists;
|
||||||
std::set<Anope::string> exempts;
|
std::set<cidr> exempts;
|
||||||
bool check_on_connect;
|
bool check_on_connect;
|
||||||
bool check_on_netburst;
|
bool check_on_netburst;
|
||||||
bool add_to_akill;
|
bool add_to_akill;
|
||||||
@@ -146,7 +146,10 @@ class ModuleDNSBL : public Module
|
|||||||
|
|
||||||
this->exempts.clear();
|
this->exempts.clear();
|
||||||
for (int i = 0; i < block->CountBlock("exempt"); ++i)
|
for (int i = 0; i < block->CountBlock("exempt"); ++i)
|
||||||
this->exempts.insert(block->Get<Anope::string>("ip"));
|
{
|
||||||
|
Configuration::Block *bl = block->GetBlock("exempt", i);
|
||||||
|
this->exempts.insert(bl->Get<Anope::string>("ip"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnUserConnect(User *user, bool &exempt) anope_override
|
void OnUserConnect(User *user, bool &exempt) anope_override
|
||||||
@@ -157,25 +160,26 @@ class ModuleDNSBL : public Module
|
|||||||
if (!this->check_on_netburst && !user->server->IsSynced())
|
if (!this->check_on_netburst && !user->server->IsSynced())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* At this time we only support IPv4 */
|
if (!user->ip.valid())
|
||||||
if (!user->ip.valid() || user->ip.sa.sa_family != AF_INET)
|
/* User doesn't have a valid IP (spoof/etc) */
|
||||||
/* User doesn't have a valid IPv4 IP (ipv6/spoof/etc) */
|
return;
|
||||||
|
|
||||||
|
if (this->blacklists.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this->exempts.count(user->ip.addr()))
|
if (this->exempts.count(user->ip.addr()))
|
||||||
|
{
|
||||||
|
Log(LOG_DEBUG) << "User " << user->nick << " is exempt from dnsbl check - ip: " << user->ip.addr();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned long &ip = user->ip.sa4.sin_addr.s_addr;
|
Anope::string reverse = user->ip.reverse();
|
||||||
unsigned long reverse_ip = (ip << 24) | ((ip & 0xFF00) << 8) | ((ip & 0xFF0000) >> 8) | (ip >> 24);
|
|
||||||
|
|
||||||
sockaddrs reverse = user->ip;
|
|
||||||
reverse.sa4.sin_addr.s_addr = reverse_ip;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < this->blacklists.size(); ++i)
|
for (unsigned i = 0; i < this->blacklists.size(); ++i)
|
||||||
{
|
{
|
||||||
const Blacklist &b = this->blacklists[i];
|
const Blacklist &b = this->blacklists[i];
|
||||||
|
|
||||||
Anope::string dnsbl_host = reverse.addr() + "." + b.name;
|
Anope::string dnsbl_host = reverse + "." + b.name;
|
||||||
DNSBLResolver *res = NULL;
|
DNSBLResolver *res = NULL;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
+9
-2
@@ -157,6 +157,11 @@ class MyRedisService : public Provider
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool IsSocketDead() anope_override
|
||||||
|
{
|
||||||
|
return this->sock && this->sock->flags[SF_DEAD];
|
||||||
|
}
|
||||||
|
|
||||||
void SendCommand(RedisSocket *s, Interface *i, const std::vector<Anope::string> &cmds)
|
void SendCommand(RedisSocket *s, Interface *i, const std::vector<Anope::string> &cmds)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<const char *, size_t> > args;
|
std::vector<std::pair<const char *, size_t> > args;
|
||||||
@@ -201,9 +206,11 @@ class MyRedisService : public Provider
|
|||||||
public:
|
public:
|
||||||
bool BlockAndProcess() anope_override
|
bool BlockAndProcess() anope_override
|
||||||
{
|
{
|
||||||
this->sock->ProcessWrite();
|
if (!this->sock->ProcessWrite())
|
||||||
|
this->sock->flags[SF_DEAD] = true;
|
||||||
this->sock->SetBlocking(true);
|
this->sock->SetBlocking(true);
|
||||||
this->sock->ProcessRead();
|
if (!this->sock->ProcessRead())
|
||||||
|
this->sock->flags[SF_DEAD] = true;
|
||||||
this->sock->SetBlocking(false);
|
this->sock->SetBlocking(false);
|
||||||
return !this->sock->interfaces.empty();
|
return !this->sock->interfaces.empty();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -111,13 +111,13 @@ class External : public Mechanism
|
|||||||
NickCore *nc = certs->FindAccountFromCert(mysess->cert);
|
NickCore *nc = certs->FindAccountFromCert(mysess->cert);
|
||||||
if (!nc || nc->HasExt("NS_SUSPENDED") || nc->HasExt("UNCONFIRMED"))
|
if (!nc || nc->HasExt("NS_SUSPENDED") || nc->HasExt("UNCONFIRMED"))
|
||||||
{
|
{
|
||||||
Log(Config->GetClient("NickServ"), "sasl") << user << " failed to identify using certificate " << mysess->cert << " using SASL EXTERNAL";
|
Log(this->owner, "sasl", Config->GetClient("NickServ")) << user << " failed to identify using certificate " << mysess->cert << " using SASL EXTERNAL";
|
||||||
sasl->Fail(sess);
|
sasl->Fail(sess);
|
||||||
delete sess;
|
delete sess;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(Config->GetClient("NickServ"), "sasl") << user << " identified to account " << nc->display << " using SASL EXTERNAL";
|
Log(this->owner, "sasl", Config->GetClient("NickServ")) << user << " identified to account " << nc->display << " using SASL EXTERNAL";
|
||||||
sasl->Succeed(sess, nc);
|
sasl->Succeed(sess, nc);
|
||||||
delete sess;
|
delete sess;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-14
@@ -107,7 +107,7 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
|
|||||||
prev = cur;
|
prev = cur;
|
||||||
cur.clear();
|
cur.clear();
|
||||||
|
|
||||||
int len = 0;
|
size_t len = 0;
|
||||||
istag = false;
|
istag = false;
|
||||||
|
|
||||||
if (content[0] == '<')
|
if (content[0] == '<')
|
||||||
@@ -120,20 +120,21 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
|
|||||||
len = content.find_first_of('<');
|
len = content.find_first_of('<');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len)
|
// len must advance
|
||||||
|
if (len == Anope::string::npos || len == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (istag)
|
||||||
{
|
{
|
||||||
if (istag)
|
cur = content.substr(1, len - 1);
|
||||||
{
|
content.erase(0, len + 1);
|
||||||
cur = content.substr(1, len - 1);
|
while (!content.empty() && content[0] == ' ')
|
||||||
content.erase(0, len + 1);
|
content.erase(content.begin());
|
||||||
while (!content.empty() && content[0] == ' ')
|
}
|
||||||
content.erase(content.begin());
|
else
|
||||||
}
|
{
|
||||||
else
|
cur = content.substr(0, len);
|
||||||
{
|
content.erase(0, len);
|
||||||
cur = content.substr(0,len);
|
|
||||||
content.erase(0, len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (istag && !content.empty());
|
while (istag && !content.empty());
|
||||||
|
|||||||
@@ -108,7 +108,8 @@ class MyXMLRPCEvent : public XMLRPCEvent
|
|||||||
}
|
}
|
||||||
reply(out);
|
reply(out);
|
||||||
|
|
||||||
CommandSource source(user, NULL, na ? *na->nc : NULL, &reply, bi);
|
User *u = User::Find(user, true);
|
||||||
|
CommandSource source(user, u, na ? *na->nc : NULL, &reply, bi);
|
||||||
Command::Run(source, command);
|
Command::Run(source, command);
|
||||||
|
|
||||||
if (!out.empty())
|
if (!out.empty())
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* ircd-hybrid-8 protocol module
|
/* ircd-hybrid-8 protocol module
|
||||||
*
|
*
|
||||||
* (C) 2003-2017 Anope Team <team@anope.org>
|
* (C) 2003-2017 Anope Team <team@anope.org>
|
||||||
* (C) 2012-2016 ircd-hybrid development team
|
* (C) 2012-2017 ircd-hybrid development team
|
||||||
*
|
*
|
||||||
* Please read COPYING and README for further details.
|
* Please read COPYING and README for further details.
|
||||||
*
|
*
|
||||||
@@ -184,12 +184,10 @@ class HybridProto : public IRCDProto
|
|||||||
UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
|
UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As of January 13, 2016, ircd-hybrid-8 does support the following capabilities
|
* As of March 19, 2017, ircd-hybrid-8 does support the following capabilities
|
||||||
* which are required to work with IRC-services:
|
* which are required to work with IRC-services:
|
||||||
*
|
*
|
||||||
* QS - Can handle quit storm removal
|
* QS - Can handle quit storm removal
|
||||||
* EX - Can do channel +e exemptions
|
|
||||||
* IE - Can do invite exceptions
|
|
||||||
* CHW - Can do channel wall @#
|
* CHW - Can do channel wall @#
|
||||||
* TBURST - Supports topic burst
|
* TBURST - Supports topic burst
|
||||||
* ENCAP - Supports ENCAP
|
* ENCAP - Supports ENCAP
|
||||||
@@ -197,7 +195,7 @@ class HybridProto : public IRCDProto
|
|||||||
* SVS - Supports services
|
* SVS - Supports services
|
||||||
* EOB - Supports End Of Burst message
|
* EOB - Supports End Of Burst message
|
||||||
*/
|
*/
|
||||||
UplinkSocket::Message() << "CAPAB :QS EX CHW IE ENCAP TBURST SVS HOPS EOB";
|
UplinkSocket::Message() << "CAPAB :QS CHW ENCAP TBURST SVS HOPS EOB";
|
||||||
|
|
||||||
SendServer(Me);
|
SendServer(Me);
|
||||||
|
|
||||||
@@ -662,7 +660,9 @@ class ProtoHybrid : public Module
|
|||||||
ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r'));
|
ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r'));
|
||||||
ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
|
ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
|
||||||
ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
|
ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
|
||||||
|
ModeManager::AddChannelMode(new ChannelMode("HIDEBMASKS", 'u'));
|
||||||
ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
|
ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
|
||||||
|
ModeManager::AddChannelMode(new ChannelModeOperOnly("LBAN", 'L'));
|
||||||
ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
|
ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
|
||||||
ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O'));
|
ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O'));
|
||||||
ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
|
ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
|
||||||
|
|||||||
@@ -151,13 +151,14 @@ class InspIRCd12Proto : public IRCDProto
|
|||||||
|
|
||||||
void SendVhostDel(User *u) anope_override
|
void SendVhostDel(User *u) anope_override
|
||||||
{
|
{
|
||||||
if (u->HasMode("CLOAK"))
|
UserMode *um = ModeManager::FindUserModeByName("CLOAK");
|
||||||
this->SendChgHostInternal(u->nick, u->chost);
|
|
||||||
else
|
|
||||||
this->SendChgHostInternal(u->nick, u->host);
|
|
||||||
|
|
||||||
if (Servers::Capab.count("CHGIDENT") && u->GetIdent() != u->GetVIdent())
|
if (um && !u->HasMode(um->name))
|
||||||
this->SendChgIdentInternal(u->nick, u->GetIdent());
|
// Just set +x if we can
|
||||||
|
u->SetMode(NULL, um);
|
||||||
|
else
|
||||||
|
// Try to restore cloaked host
|
||||||
|
this->SendChgHostInternal(u->nick, u->chost);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendAkill(User *u, XLine *x) anope_override
|
void SendAkill(User *u, XLine *x) anope_override
|
||||||
@@ -409,6 +410,11 @@ class InspIRCd12Proto : public IRCDProto
|
|||||||
void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override
|
void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override
|
||||||
{
|
{
|
||||||
UplinkSocket::Message(Me) << "METADATA " << uid << " accountname :" << acc;
|
UplinkSocket::Message(Me) << "METADATA " << uid << " accountname :" << acc;
|
||||||
|
|
||||||
|
if (!vident.empty())
|
||||||
|
UplinkSocket::Message(Me) << "ENCAP " << uid.substr(0, 3) << " CHGIDENT " << uid << " " << vident;
|
||||||
|
if (!vhost.empty())
|
||||||
|
UplinkSocket::Message(Me) << "ENCAP " << uid.substr(0, 3) << " CHGHOST " << uid << " " << vhost;
|
||||||
|
|
||||||
SASLUser su;
|
SASLUser su;
|
||||||
su.uid = uid;
|
su.uid = uid;
|
||||||
|
|||||||
@@ -174,10 +174,11 @@ class PlexusProto : public IRCDProto
|
|||||||
UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : message.target.substr(0, 3)) << " SASL " << message.source << " " << message.target << " " << message.type << " " << message.data << (message.ext.empty() ? "" : (" " + message.ext));
|
UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : message.target.substr(0, 3)) << " SASL " << message.source << " " << message.target << " " << message.type << " " << message.data << (message.ext.empty() ? "" : (" " + message.ext));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSVSLogin(const Anope::string &uid, const Anope::string &acc) anope_override
|
void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override
|
||||||
{
|
{
|
||||||
Server *s = Server::Find(uid.substr(0, 3));
|
Server *s = Server::Find(uid.substr(0, 3));
|
||||||
UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : uid.substr(0, 3)) << " SVSLOGIN " << uid << " * * * " << acc;
|
UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : uid.substr(0, 3)) << " SVSLOGIN " << uid << " * * "
|
||||||
|
<< (vhost.empty() ? "*" : vhost) << " " << acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSVSNOOP(const Server *server, bool set) anope_override
|
void SendSVSNOOP(const Server *server, bool set) anope_override
|
||||||
|
|||||||
@@ -158,7 +158,8 @@ class UnrealIRCdProto : public IRCDProto
|
|||||||
/* JOIN */
|
/* JOIN */
|
||||||
void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
|
void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
|
||||||
{
|
{
|
||||||
UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " :" << user->GetUID();
|
UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name
|
||||||
|
<< " +" << c->GetModes(true, true) << " :" << user->GetUID();
|
||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
/* First save the channel status incase uc->Status == status */
|
/* First save the channel status incase uc->Status == status */
|
||||||
@@ -204,6 +205,10 @@ class UnrealIRCdProto : public IRCDProto
|
|||||||
UplinkSocket::Message(Me) << "CHGIDENT " << u->GetUID() << " " << vIdent;
|
UplinkSocket::Message(Me) << "CHGIDENT " << u->GetUID() << " " << vIdent;
|
||||||
if (!vhost.empty())
|
if (!vhost.empty())
|
||||||
UplinkSocket::Message(Me) << "CHGHOST " << u->GetUID() << " " << vhost;
|
UplinkSocket::Message(Me) << "CHGHOST " << u->GetUID() << " " << vhost;
|
||||||
|
// Internally unreal sets +xt on chghost
|
||||||
|
BotInfo *bi = Config->GetClient("HostServ");
|
||||||
|
u->SetMode(bi, "CLOAK");
|
||||||
|
u->SetMode(bi, "VHOST");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendConnect() anope_override
|
void SendConnect() anope_override
|
||||||
@@ -227,6 +232,15 @@ class UnrealIRCdProto : public IRCDProto
|
|||||||
SendServer(Me);
|
SendServer(Me);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SendSASLMechanisms(std::vector<Anope::string> &mechanisms) anope_override
|
||||||
|
{
|
||||||
|
Anope::string mechlist;
|
||||||
|
for (unsigned i = 0; i < mechanisms.size(); ++i)
|
||||||
|
mechlist += "," + mechanisms[i];
|
||||||
|
|
||||||
|
UplinkSocket::Message() << "MD client " << Me->GetName() << " saslmechlist :" << (mechanisms.empty() ? "" : mechlist.substr(1));
|
||||||
|
}
|
||||||
|
|
||||||
/* SVSHOLD - set */
|
/* SVSHOLD - set */
|
||||||
void SendSVSHold(const Anope::string &nick, time_t t) anope_override
|
void SendSVSHold(const Anope::string &nick, time_t t) anope_override
|
||||||
{
|
{
|
||||||
@@ -352,22 +366,8 @@ class UnrealIRCdProto : public IRCDProto
|
|||||||
|
|
||||||
void SendChannel(Channel *c) anope_override
|
void SendChannel(Channel *c) anope_override
|
||||||
{
|
{
|
||||||
/* Unreal does not support updating a channels TS without actually joining a user,
|
UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name
|
||||||
* so we will join and part us now
|
<< " +" << c->GetModes(true, true) << " :";
|
||||||
*/
|
|
||||||
BotInfo *bi = c->ci->WhoSends();
|
|
||||||
if (!bi)
|
|
||||||
;
|
|
||||||
else if (c->FindUser(bi) == NULL)
|
|
||||||
{
|
|
||||||
bi->Join(c);
|
|
||||||
bi->Part(c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bi->Part(c);
|
|
||||||
bi->Join(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSASLMessage(const SASL::Message &message) anope_override
|
void SendSASLMessage(const SASL::Message &message) anope_override
|
||||||
|
|||||||
@@ -377,34 +377,36 @@ class ChanServCore : public Module, public ChanServService
|
|||||||
return EVENT_CONTINUE;
|
return EVENT_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnPreUplinkSync(Server *serv) anope_override
|
void OnPostInit() anope_override
|
||||||
{
|
{
|
||||||
if (!persist)
|
if (!persist)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ChannelMode *perm = ModeManager::FindChannelModeByName("PERM");
|
||||||
|
|
||||||
/* Find all persistent channels and create them, as we are about to finish burst to our uplink */
|
/* Find all persistent channels and create them, as we are about to finish burst to our uplink */
|
||||||
for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
|
for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
|
||||||
{
|
{
|
||||||
ChannelInfo *ci = it->second;
|
ChannelInfo *ci = it->second;
|
||||||
if (persist->HasExt(ci))
|
if (!persist->HasExt(ci))
|
||||||
{
|
continue;
|
||||||
bool c;
|
|
||||||
ci->c = Channel::FindOrCreate(ci->name, c, ci->time_registered);
|
|
||||||
|
|
||||||
if (ModeManager::FindChannelModeByName("PERM") != NULL)
|
bool c;
|
||||||
|
ci->c = Channel::FindOrCreate(ci->name, c, ci->time_registered);
|
||||||
|
ci->c->syncing |= created;
|
||||||
|
|
||||||
|
if (perm)
|
||||||
|
{
|
||||||
|
ci->c->SetMode(NULL, perm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ci->bi)
|
||||||
|
ci->WhoSends()->Assign(NULL, ci);
|
||||||
|
if (ci->c->FindUser(ci->bi) == NULL)
|
||||||
{
|
{
|
||||||
if (c)
|
ChannelStatus status(BotModes());
|
||||||
IRCD->SendChannel(ci->c);
|
ci->bi->Join(ci->c, &status);
|
||||||
ci->c->SetMode(NULL, "PERM");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ci->bi)
|
|
||||||
ci->WhoSends()->Assign(NULL, ci);
|
|
||||||
if (ci->c->FindUser(ci->bi) == NULL)
|
|
||||||
{
|
|
||||||
ChannelStatus status(BotModes());
|
|
||||||
ci->bi->Join(ci->c, &status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -493,13 +493,6 @@ class NickServCore : public Module, public NickServService
|
|||||||
"Accounts that are not used anymore are subject to\n"
|
"Accounts that are not used anymore are subject to\n"
|
||||||
"the automatic expiration, i.e. they will be deleted\n"
|
"the automatic expiration, i.e. they will be deleted\n"
|
||||||
"after %d days if not used."), nickserv_expire / 86400);
|
"after %d days if not used."), nickserv_expire / 86400);
|
||||||
source.Reply(_(" \n"
|
|
||||||
"\002NOTICE:\002 This service is intended to provide a way for\n"
|
|
||||||
"IRC users to ensure their identity is not compromised.\n"
|
|
||||||
"It is \002NOT\002 intended to facilitate \"stealing\" of\n"
|
|
||||||
"nicknames or other malicious actions. Abuse of %s\n"
|
|
||||||
"will result in, at minimum, loss of the abused\n"
|
|
||||||
"nickname(s)."), NickServ->nick.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnNickCoreCreate(NickCore *nc)
|
void OnNickCoreCreate(NickCore *nc)
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
|
|||||||
params.push_back("DEL");
|
params.push_back("DEL");
|
||||||
params.push_back(message.get_data["mask"]);
|
params.push_back(message.get_data["mask"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/access", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "ChanServ", "chanserv/access", params, replacements);
|
||||||
}
|
}
|
||||||
else if (message.post_data["mask"].empty() == false && message.post_data["access"].empty() == false && message.post_data["provider"].empty() == false)
|
else if (message.post_data["mask"].empty() == false && message.post_data["access"].empty() == false && message.post_data["provider"].empty() == false)
|
||||||
{
|
{
|
||||||
@@ -69,7 +69,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
|
|||||||
params.push_back(message.post_data["mask"]);
|
params.push_back(message.post_data["mask"]);
|
||||||
params.push_back(message.post_data["access"]);
|
params.push_back(message.post_data["access"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/access", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "ChanServ", "chanserv/access", params, replacements);
|
||||||
}
|
}
|
||||||
else if (provider == "chanserv/xop")
|
else if (provider == "chanserv/xop")
|
||||||
{
|
{
|
||||||
@@ -78,7 +78,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
|
|||||||
params.push_back("ADD");
|
params.push_back("ADD");
|
||||||
params.push_back(message.post_data["mask"]);
|
params.push_back(message.post_data["mask"]);
|
||||||
|
|
||||||
WebPanel::RunCommandWithName(na->nc, "ChanServ", "chanserv/xop", message.post_data["access"], params, replacements);
|
WebPanel::RunCommandWithName(client, na->nc, "ChanServ", "chanserv/xop", message.post_data["access"], params, replacements);
|
||||||
}
|
}
|
||||||
else if (provider == "chanserv/flags")
|
else if (provider == "chanserv/flags")
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
|
|||||||
params.push_back(message.post_data["mask"]);
|
params.push_back(message.post_data["mask"]);
|
||||||
params.push_back(message.post_data["access"]);
|
params.push_back(message.post_data["access"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/flags", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "ChanServ", "chanserv/flags", params, replacements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,9 +103,9 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
|
|||||||
{
|
{
|
||||||
ChanAccess *access = ci->GetAccess(i);
|
ChanAccess *access = ci->GetAccess(i);
|
||||||
|
|
||||||
replacements["MASKS"] = HTTPUtils::Escape(access->Mask());
|
replacements["MASKS"] = access->Mask();
|
||||||
replacements["ACCESSES"] = HTTPUtils::Escape(access->AccessSerialize());
|
replacements["ACCESSES"] = access->AccessSerialize();
|
||||||
replacements["CREATORS"] = HTTPUtils::Escape(access->creator);
|
replacements["CREATORS"] = access->creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Service::FindService("Command", "chanserv/access"))
|
if (Service::FindService("Command", "chanserv/access"))
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
params.push_back("DEL");
|
params.push_back("DEL");
|
||||||
params.push_back(message.get_data["mask"]);
|
params.push_back(message.get_data["mask"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/akick", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "ChanServ", "chanserv/akick", params, replacements);
|
||||||
}
|
}
|
||||||
else if (message.post_data["mask"].empty() == false)
|
else if (message.post_data["mask"].empty() == false)
|
||||||
{
|
{
|
||||||
@@ -64,7 +64,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
if (message.post_data["reason"].empty() == false)
|
if (message.post_data["reason"].empty() == false)
|
||||||
params.push_back(message.post_data["reason"]);
|
params.push_back(message.post_data["reason"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/akick", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "ChanServ", "chanserv/akick", params, replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname);
|
replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname);
|
||||||
@@ -74,11 +74,11 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
AutoKick *akick = ci->GetAkick(i);
|
AutoKick *akick = ci->GetAkick(i);
|
||||||
|
|
||||||
if (akick->nc)
|
if (akick->nc)
|
||||||
replacements["MASKS"] = HTTPUtils::Escape(akick->nc->display);
|
replacements["MASKS"] = akick->nc->display;
|
||||||
else
|
else
|
||||||
replacements["MASKS"] = HTTPUtils::Escape(akick->mask);
|
replacements["MASKS"] = akick->mask;
|
||||||
replacements["CREATORS"] = HTTPUtils::Escape(akick->creator);
|
replacements["CREATORS"] = akick->creator;
|
||||||
replacements["REASONS"] = HTTPUtils::Escape(akick->reason);
|
replacements["REASONS"] = akick->reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.Serve(server, page_name, client, message, reply, replacements);
|
Page.Serve(server, page_name, client, message, reply, replacements);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::str
|
|||||||
params.push_back(channel);
|
params.push_back(channel);
|
||||||
params.push_back(channel);
|
params.push_back(channel);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/drop", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "ChanServ", "chanserv/drop", params, replacements);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
replacements["MESSAGES"] = "Invalid Confirmation";
|
replacements["MESSAGES"] = "Invalid Confirmation";
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
params.push_back("SET");
|
params.push_back("SET");
|
||||||
params.push_back("-" + Anope::string(cm->mchar));
|
params.push_back("-" + Anope::string(cm->mchar));
|
||||||
params.push_back(message.get_data["mask"]);
|
params.push_back(message.get_data["mask"]);
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/mode", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "ChanServ", "chanserv/mode", params, replacements);
|
||||||
}
|
}
|
||||||
else if (message.post_data["mask"].empty() == false)
|
else if (message.post_data["mask"].empty() == false)
|
||||||
{
|
{
|
||||||
@@ -91,12 +91,12 @@ bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
params.push_back("SET");
|
params.push_back("SET");
|
||||||
params.push_back("+" + Anope::string(cm->mchar));
|
params.push_back("+" + Anope::string(cm->mchar));
|
||||||
params.push_back(message.post_data["mask"]);
|
params.push_back(message.post_data["mask"]);
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "ChanServ", "chanserv/mode", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "ChanServ", "chanserv/mode", params, replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Anope::string> v = c->GetModeList(cm->name);
|
std::vector<Anope::string> v = c->GetModeList(cm->name);
|
||||||
for (unsigned int i = 0; i < v.size(); ++i)
|
for (unsigned int i = 0; i < v.size(); ++i)
|
||||||
replacements["MASKS"] = HTTPUtils::Escape(v[i]);
|
replacements["MASKS"] = v[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.Serve(server, page_name, client, message, reply, replacements);
|
Page.Serve(server, page_name, client, message, reply, replacements);
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
replacements["CHANNEL"] = HTTPUtils::Escape(ci->name);
|
replacements["CHANNEL"] = ci->name;
|
||||||
replacements["CHANNEL_ESCAPED"] = HTTPUtils::URLEncode(ci->name);
|
replacements["CHANNEL_ESCAPED"] = HTTPUtils::URLEncode(ci->name);
|
||||||
if (ci->GetFounder())
|
if (ci->GetFounder())
|
||||||
replacements["FOUNDER"] = ci->GetFounder()->display;
|
replacements["FOUNDER"] = ci->GetFounder()->display;
|
||||||
@@ -114,8 +114,8 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri
|
|||||||
|
|
||||||
if (!ci->last_topic.empty())
|
if (!ci->last_topic.empty())
|
||||||
{
|
{
|
||||||
replacements["LAST_TOPIC"] = HTTPUtils::Escape(ci->last_topic);
|
replacements["LAST_TOPIC"] = ci->last_topic;
|
||||||
replacements["LAST_TOPIC_SETTER"] = HTTPUtils::Escape(ci->last_topic_setter);
|
replacements["LAST_TOPIC_SETTER"] = ci->last_topic_setter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_set)
|
if (can_set)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ bool WebCPanel::Confirm::OnRequest(HTTPProvider *server, const Anope::string &pa
|
|||||||
if (!email.empty())
|
if (!email.empty())
|
||||||
params.push_back(email);
|
params.push_back(email);
|
||||||
|
|
||||||
WebPanel::RunCommand(user, NULL, "NickServ", "nickserv/register", params, replacements);
|
WebPanel::RunCommand(client, user, NULL, "NickServ", "nickserv/register", params, replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplateFileServer page("confirm.html");
|
TemplateFileServer page("confirm.html");
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ bool WebCPanel::HostServ::Request::OnRequest(HTTPProvider *server, const Anope::
|
|||||||
std::vector<Anope::string> params;
|
std::vector<Anope::string> params;
|
||||||
params.push_back(HTTPUtils::URLDecode(message.post_data["req"]));
|
params.push_back(HTTPUtils::URLDecode(message.post_data["req"]));
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "HostServ", "hostserv/request", params, replacements, "CMDR");
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "HostServ", "hostserv/request", params, replacements, "CMDR");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (na->HasVhost())
|
if (na->HasVhost())
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ class WebpanelRequest : public IdentifyRequest
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rate limit logins to 1/sec
|
||||||
|
time_t *last_login = na->nc->GetExt<time_t>("webcpanel_last_login");
|
||||||
|
if (last_login != NULL && Anope::CurTime == *last_login)
|
||||||
|
{
|
||||||
|
this->OnFail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Anope::string id;
|
Anope::string id;
|
||||||
for (int i = 0; i < 64; ++i)
|
for (int i = 0; i < 64; ++i)
|
||||||
{
|
{
|
||||||
@@ -48,6 +56,7 @@ class WebpanelRequest : public IdentifyRequest
|
|||||||
|
|
||||||
na->Extend<Anope::string>("webcpanel_id", id);
|
na->Extend<Anope::string>("webcpanel_id", id);
|
||||||
na->Extend<Anope::string>("webcpanel_ip", client->GetIP());
|
na->Extend<Anope::string>("webcpanel_ip", client->GetIP());
|
||||||
|
na->nc->Extend<time_t>("webcpanel_last_login", Anope::CurTime);
|
||||||
|
|
||||||
{
|
{
|
||||||
HTTPReply::cookie c;
|
HTTPReply::cookie c;
|
||||||
@@ -91,6 +100,30 @@ bool WebCPanel::Index::OnRequest(HTTPProvider *server, const Anope::string &page
|
|||||||
if (!user.empty() && !pass.empty())
|
if (!user.empty() && !pass.empty())
|
||||||
{
|
{
|
||||||
// Rate limit check.
|
// Rate limit check.
|
||||||
|
Anope::string ip = client->clientaddr.addr();
|
||||||
|
|
||||||
|
Anope::hash_map<time_t>::iterator it = last_login_attempt.find(ip);
|
||||||
|
if (it != last_login_attempt.end())
|
||||||
|
{
|
||||||
|
time_t last_time = it->second;
|
||||||
|
|
||||||
|
if (last_time == Anope::CurTime)
|
||||||
|
{
|
||||||
|
replacements["INVALID_LOGIN"] = "Rate limited";
|
||||||
|
TemplateFileServer page("login.html");
|
||||||
|
page.Serve(server, page_name, client, message, reply, replacements);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't let ip hash grow too long
|
||||||
|
if (Anope::CurTime > last_clear + FLUSH_TIME)
|
||||||
|
{
|
||||||
|
last_login_attempt.clear();
|
||||||
|
last_clear = Anope::CurTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_login_attempt[ip] = Anope::CurTime;
|
||||||
|
|
||||||
WebpanelRequest *req = new WebpanelRequest(me, reply, message, server, page_name, client, replacements, user, pass);
|
WebpanelRequest *req = new WebpanelRequest(me, reply, message, server, page_name, client, replacements, user, pass);
|
||||||
FOREACH_MOD(OnCheckAuthentication, (NULL, req));
|
FOREACH_MOD(OnCheckAuthentication, (NULL, req));
|
||||||
|
|||||||
@@ -12,8 +12,13 @@ namespace WebCPanel
|
|||||||
|
|
||||||
class Index : public WebPanelPage
|
class Index : public WebPanelPage
|
||||||
{
|
{
|
||||||
|
static const int FLUSH_TIME = 60;
|
||||||
|
|
||||||
|
Anope::hash_map<time_t> last_login_attempt;
|
||||||
|
time_t last_clear;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Index(const Anope::string &u) : WebPanelPage(u) { }
|
Index(const Anope::string &u) : WebPanelPage(u), last_clear(0) { }
|
||||||
|
|
||||||
bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override;
|
bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
params.push_back(HTTPUtils::URLDecode(message.post_data["receiver"]));
|
params.push_back(HTTPUtils::URLDecode(message.post_data["receiver"]));
|
||||||
params.push_back(HTTPUtils::URLDecode(message.post_data["message"]));
|
params.push_back(HTTPUtils::URLDecode(message.post_data["message"]));
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "MemoServ", "memoserv/send", params, replacements, "CMDR");
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "MemoServ", "memoserv/send", params, replacements, "CMDR");
|
||||||
}
|
}
|
||||||
if (message.get_data.count("del") > 0 && message.get_data.count("number") > 0)
|
if (message.get_data.count("del") > 0 && message.get_data.count("number") > 0)
|
||||||
{
|
{
|
||||||
@@ -66,7 +66,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
params.push_back(chname);
|
params.push_back(chname);
|
||||||
params.push_back(message.get_data["number"]);
|
params.push_back(message.get_data["number"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "MemoServ", "memoserv/del", params, replacements, "CMDR");
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "MemoServ", "memoserv/del", params, replacements, "CMDR");
|
||||||
}
|
}
|
||||||
if (message.get_data.count("read") > 0 && message.get_data.count("number") > 0)
|
if (message.get_data.count("read") > 0 && message.get_data.count("number") > 0)
|
||||||
{
|
{
|
||||||
@@ -101,7 +101,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
replacements["NUMBER"] = stringify(i+1);
|
replacements["NUMBER"] = stringify(i+1);
|
||||||
replacements["SENDER"] = m->sender;
|
replacements["SENDER"] = m->sender;
|
||||||
replacements["TIME"] = Anope::strftime(m->time);
|
replacements["TIME"] = Anope::strftime(m->time);
|
||||||
replacements["TEXT"] = HTTPUtils::Escape(m->text);
|
replacements["TEXT"] = m->text;
|
||||||
if (m->unread)
|
if (m->unread)
|
||||||
replacements["UNREAD"] = "YES";
|
replacements["UNREAD"] = "YES";
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s
|
|||||||
params.push_back("ADD");
|
params.push_back("ADD");
|
||||||
params.push_back(message.post_data["access"]);
|
params.push_back(message.post_data["access"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/access", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "NickServ", "nickserv/access", params, replacements);
|
||||||
}
|
}
|
||||||
else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0)
|
else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0)
|
||||||
{
|
{
|
||||||
@@ -27,7 +27,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s
|
|||||||
params.push_back("DEL");
|
params.push_back("DEL");
|
||||||
params.push_back(message.get_data["mask"]);
|
params.push_back(message.get_data["mask"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/access", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "NickServ", "nickserv/access", params, replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < na->nc->access.size(); ++i)
|
for (unsigned i = 0; i < na->nc->access.size(); ++i)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str
|
|||||||
params.push_back("ADD");
|
params.push_back("ADD");
|
||||||
params.push_back(message.post_data["certfp"]);
|
params.push_back(message.post_data["certfp"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/cert", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "NickServ", "nickserv/cert", params, replacements);
|
||||||
}
|
}
|
||||||
else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0)
|
else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0)
|
||||||
{
|
{
|
||||||
@@ -28,7 +28,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str
|
|||||||
params.push_back("DEL");
|
params.push_back("DEL");
|
||||||
params.push_back(message.get_data["mask"]);
|
params.push_back(message.get_data["mask"]);
|
||||||
|
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "NickServ", "nickserv/cert", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "NickServ", "nickserv/cert", params, replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSCertList *cl = na->nc->GetExt<NSCertList>("certificates");
|
NSCertList *cl = na->nc->GetExt<NSCertList>("certificates");
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
replacements["DISPLAY"] = HTTPUtils::Escape(na->nc->display);
|
replacements["DISPLAY"] = na->nc->display;
|
||||||
if (na->nc->email.empty() == false)
|
if (na->nc->email.empty() == false)
|
||||||
replacements["EMAIL"] = HTTPUtils::Escape(na->nc->email);
|
replacements["EMAIL"] = na->nc->email;
|
||||||
replacements["TIME_REGISTERED"] = Anope::strftime(na->time_registered, na->nc);
|
replacements["TIME_REGISTERED"] = Anope::strftime(na->time_registered, na->nc);
|
||||||
if (na->HasVhost())
|
if (na->HasVhost())
|
||||||
{
|
{
|
||||||
@@ -97,7 +97,7 @@ bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str
|
|||||||
}
|
}
|
||||||
Anope::string *greet = na->nc->GetExt<Anope::string>("greet");
|
Anope::string *greet = na->nc->GetExt<Anope::string>("greet");
|
||||||
if (greet)
|
if (greet)
|
||||||
replacements["GREET"] = HTTPUtils::Escape(*greet);
|
replacements["GREET"] = *greet;
|
||||||
if (na->nc->HasExt("AUTOOP"))
|
if (na->nc->HasExt("AUTOOP"))
|
||||||
replacements["AUTOOP"];
|
replacements["AUTOOP"];
|
||||||
if (na->nc->HasExt("NS_PRIVATE"))
|
if (na->nc->HasExt("NS_PRIVATE"))
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
cmdstr << " " << HTTPUtils::URLDecode(message.post_data["mask"]);
|
cmdstr << " " << HTTPUtils::URLDecode(message.post_data["mask"]);
|
||||||
cmdstr << " " << HTTPUtils::URLDecode(message.post_data["reason"]);
|
cmdstr << " " << HTTPUtils::URLDecode(message.post_data["reason"]);
|
||||||
params.push_back(cmdstr.str());
|
params.push_back(cmdstr.str());
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "OperServ", "operserv/akill", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "OperServ", "operserv/akill", params, replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.get_data["del"] == "1" && message.get_data.count("number") > 0)
|
if (message.get_data["del"] == "1" && message.get_data.count("number") > 0)
|
||||||
@@ -42,7 +42,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st
|
|||||||
std::vector<Anope::string> params;
|
std::vector<Anope::string> params;
|
||||||
params.push_back("DEL");
|
params.push_back("DEL");
|
||||||
params.push_back(HTTPUtils::URLDecode(message.get_data["number"]));
|
params.push_back(HTTPUtils::URLDecode(message.get_data["number"]));
|
||||||
WebPanel::RunCommand(na->nc->display, na->nc, "OperServ", "operserv/akill", params, replacements);
|
WebPanel::RunCommand(client, na->nc->display, na->nc, "OperServ", "operserv/akill", params, replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0, end = akills->GetCount(); i < end; ++i)
|
for (unsigned i = 0, end = akills->GetCount(); i < end; ++i)
|
||||||
|
|||||||
@@ -238,7 +238,11 @@ void TemplateFileServer::Serve(HTTPProvider *server, const Anope::string &page_n
|
|||||||
|
|
||||||
if (ifok && forok)
|
if (ifok && forok)
|
||||||
{
|
{
|
||||||
const Anope::string &replacement = FindReplacement(r, content.substr(0, f - 1));
|
Anope::string replacement = FindReplacement(r, content.substr(0, f - 1));
|
||||||
|
|
||||||
|
// htmlescape all text replaced onto the page
|
||||||
|
replacement = HTTPUtils::Escape(replacement);
|
||||||
|
|
||||||
finished += replacement;
|
finished += replacement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class ModuleWebCPanel : public Module
|
|||||||
ServiceReference<HTTPProvider> provider;
|
ServiceReference<HTTPProvider> provider;
|
||||||
Panel panel;
|
Panel panel;
|
||||||
PrimitiveExtensibleItem<Anope::string> id, ip;
|
PrimitiveExtensibleItem<Anope::string> id, ip;
|
||||||
|
PrimitiveExtensibleItem<time_t> last_login;
|
||||||
|
|
||||||
StaticFileServer style_css, logo_png, cubes_png, favicon_ico;
|
StaticFileServer style_css, logo_png, cubes_png, favicon_ico;
|
||||||
|
|
||||||
@@ -44,7 +45,8 @@ class ModuleWebCPanel : public Module
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ModuleWebCPanel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
|
ModuleWebCPanel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
|
||||||
panel(this, "webcpanel"), id(this, "webcpanel_id"), ip(this, "webcpanel_ip"),
|
panel(this, "webcpanel"),
|
||||||
|
id(this, "webcpanel_id"), ip(this, "webcpanel_ip"), last_login(this, "webcpanel_last_login"),
|
||||||
style_css("style.css", "/static/style.css", "text/css"), logo_png("logo.png", "/static/logo.png", "image/png"), cubes_png("cubes.png", "/static/cubes.png", "image/png"), favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon"),
|
style_css("style.css", "/static/style.css", "text/css"), logo_png("logo.png", "/static/logo.png", "image/png"), cubes_png("cubes.png", "/static/cubes.png", "image/png"), favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon"),
|
||||||
index("/"), logout("/logout"), _register("/register"), confirm("/confirm"),
|
index("/"), logout("/logout"), _register("/register"), confirm("/confirm"),
|
||||||
nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"),
|
nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"),
|
||||||
@@ -231,7 +233,7 @@ class ModuleWebCPanel : public Module
|
|||||||
|
|
||||||
namespace WebPanel
|
namespace WebPanel
|
||||||
{
|
{
|
||||||
void RunCommand(const Anope::string &user, NickCore *nc, const Anope::string &service, const Anope::string &c, std::vector<Anope::string> ¶ms, TemplateFileServer::Replacements &r, const Anope::string &key)
|
void RunCommand(HTTPClient *client, const Anope::string &user, NickCore *nc, const Anope::string &service, const Anope::string &c, std::vector<Anope::string> ¶ms, TemplateFileServer::Replacements &r, const Anope::string &key)
|
||||||
{
|
{
|
||||||
ServiceReference<Command> cmd("Command", c);
|
ServiceReference<Command> cmd("Command", c);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
@@ -266,12 +268,15 @@ namespace WebPanel
|
|||||||
my_reply(r, key);
|
my_reply(r, key);
|
||||||
|
|
||||||
CommandSource source(user, NULL, nc, &my_reply, bi);
|
CommandSource source(user, NULL, nc, &my_reply, bi);
|
||||||
|
source.ip = client->clientaddr.addr();
|
||||||
|
|
||||||
CommandInfo info;
|
CommandInfo info;
|
||||||
info.name = c;
|
info.name = c;
|
||||||
|
|
||||||
cmd->Run(source, "", info, params);
|
cmd->Run(source, "", info, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunCommandWithName(NickCore *nc, const Anope::string &service, const Anope::string &c, const Anope::string &cmdname, std::vector<Anope::string> ¶ms, TemplateFileServer::Replacements &r, const Anope::string &key)
|
void RunCommandWithName(HTTPClient *client, NickCore *nc, const Anope::string &service, const Anope::string &c, const Anope::string &cmdname, std::vector<Anope::string> ¶ms, TemplateFileServer::Replacements &r, const Anope::string &key)
|
||||||
{
|
{
|
||||||
ServiceReference<Command> cmd("Command", c);
|
ServiceReference<Command> cmd("Command", c);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
@@ -303,6 +308,7 @@ namespace WebPanel
|
|||||||
my_reply(r, key);
|
my_reply(r, key);
|
||||||
|
|
||||||
CommandSource source(nc->display, NULL, nc, &my_reply, bi);
|
CommandSource source(nc->display, NULL, nc, &my_reply, bi);
|
||||||
|
source.ip = client->clientaddr.addr();
|
||||||
|
|
||||||
cmd->Run(source, cmdname, *info, params);
|
cmd->Run(source, cmdname, *info, params);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ class WebPanelProtectedPage : public WebPanelPage
|
|||||||
namespace WebPanel
|
namespace WebPanel
|
||||||
{
|
{
|
||||||
/** Run a command
|
/** Run a command
|
||||||
|
* @param client HTTP client command is being issued for
|
||||||
* @param User name to run command as, probably nc->display unless nc == NULL
|
* @param User name to run command as, probably nc->display unless nc == NULL
|
||||||
* @param nc Nick core to run command from
|
* @param nc Nick core to run command from
|
||||||
* @param service Service for source.owner and source.service
|
* @param service Service for source.owner and source.service
|
||||||
@@ -151,9 +152,9 @@ namespace WebPanel
|
|||||||
* @param r Replacements, reply from command goes back here into key
|
* @param r Replacements, reply from command goes back here into key
|
||||||
* @param key The key to put the replies into r
|
* @param key The key to put the replies into r
|
||||||
*/
|
*/
|
||||||
extern void RunCommand(const Anope::string &user, NickCore *nc, const Anope::string &service, const Anope::string &c, std::vector<Anope::string> ¶ms, TemplateFileServer::Replacements &r, const Anope::string &key = "MESSAGES");
|
extern void RunCommand(HTTPClient *client, const Anope::string &user, NickCore *nc, const Anope::string &service, const Anope::string &c, std::vector<Anope::string> ¶ms, TemplateFileServer::Replacements &r, const Anope::string &key = "MESSAGES");
|
||||||
|
|
||||||
extern void RunCommandWithName(NickCore *nc, const Anope::string &service, const Anope::string &c, const Anope::string &cmdname, std::vector<Anope::string> ¶ms, TemplateFileServer::Replacements &r, const Anope::string &key = "MESSAGES");
|
extern void RunCommandWithName(HTTPClient *client, NickCore *nc, const Anope::string &service, const Anope::string &c, const Anope::string &cmdname, std::vector<Anope::string> ¶ms, TemplateFileServer::Replacements &r, const Anope::string &key = "MESSAGES");
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "pages/index.h"
|
#include "pages/index.h"
|
||||||
|
|||||||
+14
-9
@@ -464,15 +464,21 @@ void Channel::SetMode(BotInfo *bi, const Anope::string &mname, const Anope::stri
|
|||||||
SetMode(bi, ModeManager::FindChannelModeByName(mname), param, enforce_mlock);
|
SetMode(bi, ModeManager::FindChannelModeByName(mname), param, enforce_mlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock)
|
void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string &wparam, bool enforce_mlock)
|
||||||
{
|
{
|
||||||
if (!cm)
|
if (!cm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Don't unset modes that arent set */
|
/* Don't unset modes that arent set */
|
||||||
if ((cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && !HasMode(cm->name))
|
if ((cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && !HasMode(cm->name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Unwrap to be sure we have the internal representation */
|
||||||
|
Anope::string param = wparam;
|
||||||
|
cm = cm->Unwrap(param);
|
||||||
|
|
||||||
/* Don't unset status that aren't set */
|
/* Don't unset status that aren't set */
|
||||||
else if (cm->type == MODE_STATUS)
|
if (cm->type == MODE_STATUS)
|
||||||
{
|
{
|
||||||
User *u = User::Find(param);
|
User *u = User::Find(param);
|
||||||
if (!u || !HasUserStatus(u, anope_dynamic_static_cast<ChannelModeStatus *>(cm)))
|
if (!u || !HasUserStatus(u, anope_dynamic_static_cast<ChannelModeStatus *>(cm)))
|
||||||
@@ -485,13 +491,12 @@ void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the param to send, if we need it */
|
/* Get the param to send, if we need it */
|
||||||
Anope::string realparam = param;
|
|
||||||
if (cm->type == MODE_PARAM)
|
if (cm->type == MODE_PARAM)
|
||||||
{
|
{
|
||||||
realparam.clear();
|
param.clear();
|
||||||
ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
|
ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
|
||||||
if (!cmp->minus_no_arg)
|
if (!cmp->minus_no_arg)
|
||||||
this->GetParam(cmp->name, realparam);
|
this->GetParam(cmp->name, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Me->IsSynced())
|
if (Me->IsSynced())
|
||||||
@@ -505,12 +510,12 @@ void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶
|
|||||||
this->chanserv_modecount++;
|
this->chanserv_modecount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Anope::string wparam = realparam;
|
/* Wrap to get ircd representation */
|
||||||
ChannelMode *wcm = cm->Wrap(wparam);
|
ChannelMode *wcm = cm->Wrap(param);
|
||||||
|
|
||||||
ModeManager::StackerAdd(bi, this, wcm, false, wparam);
|
ModeManager::StackerAdd(bi, this, wcm, false, param);
|
||||||
MessageSource ms(bi);
|
MessageSource ms(bi);
|
||||||
RemoveModeInternal(ms, wcm, wparam, enforce_mlock);
|
RemoveModeInternal(ms, wcm, param, enforce_mlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::RemoveMode(BotInfo *bi, const Anope::string &mname, const Anope::string ¶m, bool enforce_mlock)
|
void Channel::RemoveMode(BotInfo *bi, const Anope::string &mname, const Anope::string ¶m, bool enforce_mlock)
|
||||||
|
|||||||
+17
-3
@@ -157,7 +157,13 @@ Conf::Conf() : Block("")
|
|||||||
Block *serverinfo = this->GetBlock("serverinfo"), *options = this->GetBlock("options"),
|
Block *serverinfo = this->GetBlock("serverinfo"), *options = this->GetBlock("options"),
|
||||||
*mail = this->GetBlock("mail"), *networkinfo = this->GetBlock("networkinfo");
|
*mail = this->GetBlock("mail"), *networkinfo = this->GetBlock("networkinfo");
|
||||||
|
|
||||||
ValidateNotEmpty("serverinfo", "name", serverinfo->Get<const Anope::string>("name"));
|
const Anope::string &servername = serverinfo->Get<Anope::string>("name");
|
||||||
|
|
||||||
|
ValidateNotEmpty("serverinfo", "name", servername);
|
||||||
|
|
||||||
|
if (servername.find(' ') != Anope::string::npos || servername.find('.') == Anope::string::npos)
|
||||||
|
throw ConfigException("serverinfo:name is not a valid server name");
|
||||||
|
|
||||||
ValidateNotEmpty("serverinfo", "description", serverinfo->Get<const Anope::string>("description"));
|
ValidateNotEmpty("serverinfo", "description", serverinfo->Get<const Anope::string>("description"));
|
||||||
ValidateNotEmpty("serverinfo", "pid", serverinfo->Get<const Anope::string>("pid"));
|
ValidateNotEmpty("serverinfo", "pid", serverinfo->Get<const Anope::string>("pid"));
|
||||||
ValidateNotEmpty("serverinfo", "motd", serverinfo->Get<const Anope::string>("motd"));
|
ValidateNotEmpty("serverinfo", "motd", serverinfo->Get<const Anope::string>("motd"));
|
||||||
@@ -205,6 +211,9 @@ Conf::Conf() : Block("")
|
|||||||
ValidateNotZero("uplink", "port", port);
|
ValidateNotZero("uplink", "port", port);
|
||||||
ValidateNotEmpty("uplink", "password", password);
|
ValidateNotEmpty("uplink", "password", password);
|
||||||
|
|
||||||
|
if (password.find(' ') != Anope::string::npos || password[0] == ':')
|
||||||
|
throw ConfigException("uplink:password is not valid");
|
||||||
|
|
||||||
this->Uplinks.push_back(Uplink(host, port, password, ipv6));
|
this->Uplinks.push_back(Uplink(host, port, password, ipv6));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,6 +665,11 @@ const Anope::string &File::GetName() const
|
|||||||
return this->name;
|
return this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Anope::string File::GetPath() const
|
||||||
|
{
|
||||||
|
return (this->executable ? "" : Anope::ConfigDir + "/") + this->name;
|
||||||
|
}
|
||||||
|
|
||||||
bool File::IsOpen() const
|
bool File::IsOpen() const
|
||||||
{
|
{
|
||||||
return this->fp != NULL;
|
return this->fp != NULL;
|
||||||
@@ -713,14 +727,14 @@ void Conf::LoadConf(File &file)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!file.Open())
|
if (!file.Open())
|
||||||
throw ConfigException("File " + file.GetName() + " could not be opened.");
|
throw ConfigException("File " + file.GetPath() + " could not be opened.");
|
||||||
|
|
||||||
Anope::string itemname, wordbuffer;
|
Anope::string itemname, wordbuffer;
|
||||||
std::stack<Block *> block_stack;
|
std::stack<Block *> block_stack;
|
||||||
int linenumber = 0;
|
int linenumber = 0;
|
||||||
bool in_word = false, in_quote = false, in_comment = false;
|
bool in_word = false, in_quote = false, in_comment = false;
|
||||||
|
|
||||||
Log(LOG_DEBUG) << "Start to read conf " << file.GetName();
|
Log(LOG_DEBUG) << "Start to read conf " << file.GetPath();
|
||||||
// Start reading characters...
|
// Start reading characters...
|
||||||
while (!file.End())
|
while (!file.End())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -553,6 +553,8 @@ void Anope::Init(int ac, char **av)
|
|||||||
static_cast<void>(MOD_RESULT);
|
static_cast<void>(MOD_RESULT);
|
||||||
Log() << "Databases loaded";
|
Log() << "Databases loaded";
|
||||||
|
|
||||||
|
FOREACH_MOD(OnPostInit, ());
|
||||||
|
|
||||||
for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
|
for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
|
||||||
it->second->Sync();
|
it->second->Sync();
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -146,8 +146,13 @@ Anope::string Log::FormatSource() const
|
|||||||
else if (nc)
|
else if (nc)
|
||||||
return nc->display;
|
return nc->display;
|
||||||
else if (source)
|
else if (source)
|
||||||
return source->GetNick();
|
{
|
||||||
return "<unknown>";
|
Anope::string nickbuf = source->GetNick();
|
||||||
|
if (!nickbuf.empty() && !source->ip.empty())
|
||||||
|
nickbuf += " (" + source->ip + ")";
|
||||||
|
return nickbuf;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
Anope::string Log::FormatCommand() const
|
Anope::string Log::FormatCommand() const
|
||||||
|
|||||||
+3
-3
@@ -647,7 +647,7 @@ void ModeManager::ProcessModes()
|
|||||||
|
|
||||||
std::list<Anope::string> ModeStrings = BuildModeStrings(s);
|
std::list<Anope::string> ModeStrings = BuildModeStrings(s);
|
||||||
for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit)
|
for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit)
|
||||||
IRCD->SendMode(s->bi, u, lit->c_str());
|
IRCD->SendMode(s->bi, u, "%s", lit->c_str());
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
UserStackerObjects.clear();
|
UserStackerObjects.clear();
|
||||||
@@ -662,7 +662,7 @@ void ModeManager::ProcessModes()
|
|||||||
|
|
||||||
std::list<Anope::string> ModeStrings = BuildModeStrings(s);
|
std::list<Anope::string> ModeStrings = BuildModeStrings(s);
|
||||||
for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit)
|
for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit)
|
||||||
IRCD->SendMode(s->bi, c, lit->c_str());
|
IRCD->SendMode(s->bi, c, "%s", lit->c_str());
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
ChannelStackerObjects.clear();
|
ChannelStackerObjects.clear();
|
||||||
@@ -678,7 +678,7 @@ static void StackerDel(std::map<T *, StackerInfo *> &map, T *obj)
|
|||||||
StackerInfo *si = it->second;
|
StackerInfo *si = it->second;
|
||||||
std::list<Anope::string> ModeStrings = BuildModeStrings(si);
|
std::list<Anope::string> ModeStrings = BuildModeStrings(si);
|
||||||
for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit)
|
for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit)
|
||||||
IRCD->SendMode(si->bi, obj, lit->c_str());
|
IRCD->SendMode(si->bi, obj, "%s", lit->c_str());
|
||||||
|
|
||||||
delete si;
|
delete si;
|
||||||
map.erase(it);
|
map.erase(it);
|
||||||
|
|||||||
+2
-2
@@ -50,10 +50,10 @@ NickAlias::NickAlias(const Anope::string &nickname, NickCore* nickcore) : Serial
|
|||||||
|
|
||||||
NickAlias::~NickAlias()
|
NickAlias::~NickAlias()
|
||||||
{
|
{
|
||||||
UnsetExtensibles();
|
|
||||||
|
|
||||||
FOREACH_MOD(OnDelNick, (this));
|
FOREACH_MOD(OnDelNick, (this));
|
||||||
|
|
||||||
|
UnsetExtensibles();
|
||||||
|
|
||||||
/* Accept nicks that have no core, because of database load functions */
|
/* Accept nicks that have no core, because of database load functions */
|
||||||
if (this->nc)
|
if (this->nc)
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-2
@@ -37,10 +37,10 @@ NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"),
|
|||||||
|
|
||||||
NickCore::~NickCore()
|
NickCore::~NickCore()
|
||||||
{
|
{
|
||||||
UnsetExtensibles();
|
|
||||||
|
|
||||||
FOREACH_MOD(OnDelCore, (this));
|
FOREACH_MOD(OnDelCore, (this));
|
||||||
|
|
||||||
|
UnsetExtensibles();
|
||||||
|
|
||||||
if (!this->chanaccess->empty())
|
if (!this->chanaccess->empty())
|
||||||
Log(LOG_DEBUG) << "Non-empty chanaccess list in destructor!";
|
Log(LOG_DEBUG) << "Non-empty chanaccess list in destructor!";
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
std::vector<Oper *> Oper::opers;
|
std::vector<Oper *> Oper::opers;
|
||||||
|
|
||||||
Oper::Oper(const Anope::string &n, OperType *o) : name(n), ot(o), require_oper(false)
|
Oper::Oper(const Anope::string &n, OperType *o) : name(n), ot(o), require_oper(true)
|
||||||
{
|
{
|
||||||
opers.push_back(this);
|
opers.push_back(this);
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-5
@@ -33,9 +33,8 @@ AutoKick::~AutoKick()
|
|||||||
if (it != this->ci->akick->end())
|
if (it != this->ci->akick->end())
|
||||||
this->ci->akick->erase(it);
|
this->ci->akick->erase(it);
|
||||||
|
|
||||||
const NickAlias *na = NickAlias::Find(this->mask);
|
if (nc)
|
||||||
if (na != NULL)
|
nc->RemoveChannelReference(this->ci);
|
||||||
na->nc->RemoveChannelReference(this->ci);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,10 +140,10 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
|
|||||||
|
|
||||||
ChannelInfo::~ChannelInfo()
|
ChannelInfo::~ChannelInfo()
|
||||||
{
|
{
|
||||||
UnsetExtensibles();
|
|
||||||
|
|
||||||
FOREACH_MOD(OnDelChan, (this));
|
FOREACH_MOD(OnDelChan, (this));
|
||||||
|
|
||||||
|
UnsetExtensibles();
|
||||||
|
|
||||||
Log(LOG_DEBUG) << "Deleting channel " << this->name;
|
Log(LOG_DEBUG) << "Deleting channel " << this->name;
|
||||||
|
|
||||||
if (this->c)
|
if (this->c)
|
||||||
|
|||||||
@@ -95,6 +95,41 @@ Anope::string sockaddrs::addr() const
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Anope::string sockaddrs::reverse() const
|
||||||
|
{
|
||||||
|
char address[128];
|
||||||
|
|
||||||
|
switch (sa.sa_family)
|
||||||
|
{
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
static const char hex[] = "0123456789abcdef";
|
||||||
|
unsigned reverse_ip_count = 0;
|
||||||
|
for (int j = 15; j >= 0; --j)
|
||||||
|
{
|
||||||
|
address[reverse_ip_count++] = hex[sa6.sin6_addr.s6_addr[j] & 0xF];
|
||||||
|
address[reverse_ip_count++] = '.';
|
||||||
|
address[reverse_ip_count++] = hex[sa6.sin6_addr.s6_addr[j] >> 4];
|
||||||
|
address[reverse_ip_count++] = '.';
|
||||||
|
}
|
||||||
|
/* Remove the last '.' */
|
||||||
|
address[reverse_ip_count - 1] = 0;
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
unsigned long forward = sa4.sin_addr.s_addr;
|
||||||
|
in_addr rev;
|
||||||
|
rev.s_addr = forward << 24 | (forward & 0xFF00) << 8 | (forward & 0xFF0000) >> 8 | forward >> 24;
|
||||||
|
if (inet_ntop(AF_INET, &rev, address, sizeof(address)))
|
||||||
|
return address;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
bool sockaddrs::ipv6() const
|
bool sockaddrs::ipv6() const
|
||||||
{
|
{
|
||||||
return sa.sa_family == AF_INET6;
|
return sa.sa_family == AF_INET6;
|
||||||
|
|||||||
+1
-1
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
VERSION_MAJOR=2
|
VERSION_MAJOR=2
|
||||||
VERSION_MINOR=0
|
VERSION_MINOR=0
|
||||||
VERSION_PATCH=5
|
VERSION_PATCH=6
|
||||||
VERSION_EXTRA=""
|
VERSION_EXTRA=""
|
||||||
|
|||||||
Reference in New Issue
Block a user