1
0
mirror of https://github.com/anope/anope.git synced 2026-07-08 09:03:13 +02:00

Compare commits

...

29 Commits

Author SHA1 Message Date
Sadie Powell 3acf74483c Release 2.0.16. 2024-07-19 12:49:56 +01:00
Sadie Powell a3ec8329f4 Document the previous commit. 2024-07-19 12:48:44 +01:00
Sadie Powell 31bc597c81 Send the vhost/vident before the account name on InspIRCd.
This fixes IRCd-side account cloaks causing CHGHOST spam.
2024-07-19 01:11:32 +01:00
Sadie Powell 2de0dddb1c Fix joining channels with keys on InspIRCd v3. 2024-07-14 16:39:37 +01:00
Sadie Powell 41ea346551 Update the change log. 2024-07-11 01:13:59 +01:00
Sadie Powell 439ad3e736 Make it clear that inspircd3 also works with InspIRCd 4. 2024-07-11 01:13:59 +01:00
Sadie Powell 8105607257 Fix the default config for channel suspensions. 2024-06-23 13:51:53 +01:00
Sadie Powell ccc088d946 Log a user out fully when their nick gets suspended.
Closes #409.
2024-06-04 22:41:32 +01:00
Sadie Powell 8bb83f6b1a Explicitly specify ROW_FORMAT=DYNAMIC when creating tables.
Resolves the issues some people were having with extremely wide rows.
2024-05-16 17:29:25 +01:00
Sadie Powell da99a53dfa Don't specify a width for DT_INT columns.
This isn't actually used by MySQL for the column width.
2024-05-16 17:28:15 +01:00
Sadie Powell a9e9ac32a0 Store boolean extension items as DT_INT. 2024-05-16 17:28:15 +01:00
Sadie Powell 05e6df23a2 Mark boolean columns as DT_INT in bs_kick. 2024-05-16 16:50:41 +01:00
Sadie Powell 3f9fc23270 Remove some unnecessary advice. 2024-05-16 16:44:38 +01:00
Sadie Powell afe87bf693 Ensure we are connected to MySQL before trying to escape data. 2024-05-11 11:36:29 +01:00
Sadie Powell 0c5bf51378 Skip serializing data without a type in db_flatfile. 2024-04-29 08:16:45 +01:00
Sadie Powell d41764bfd6 Fix sending emails to nicks ending with a backslash. 2024-03-15 18:52:12 +00:00
Sadie Powell 10f4724b6b Dependabot requires that the target-branch is a string. 2024-03-15 12:17:15 +00:00
Sadie Powell 8d5be77c93 Send dependabot pull requests to the 2.1 branch. 2024-03-15 11:56:56 +00:00
Sadie Powell f4bd43e898 Add a workaround for users matching expired sqlines.
I'll fix this properly in 2.1 because I don't want to make big
changes to 2.0.

Closes #384.
2024-03-12 16:47:57 +00:00
Sadie Powell 7d7664444a Fix expiring forbids. 2024-03-12 16:26:33 +00:00
Sadie Powell 1a8bbd6004 Respect --noexpire in cs_suspend and ns_suspend. 2024-03-12 14:43:12 +00:00
Sadie Powell e725c880a9 Fix expiring channel suspensions.
Closes #386.
2024-03-12 14:12:37 +00:00
Sadie Powell f5abcd1c4c Fix expiring nick suspensions.
Closes #376.
2024-03-12 14:02:16 +00:00
Sadie Powell 1986aa6581 Fix duplicate messages when synconset/syncongroup is set.
Closes #366.
2024-03-12 13:26:25 +00:00
Sadie Powell 1a6060ac5b Fix sending SVSTOPIC when topiclock is loaded on InspIRCd. 2024-03-12 11:46:41 +00:00
Sadie Powell 6f57907416 Fix the TIME message on InspIRCd. 2024-03-11 22:38:15 +00:00
Bram Matthys b09632d1c3 Fix OS SQLINE expiry with UnrealIRCd 2024-03-11 18:30:55 +00:00
Sadie Powell cd614831de Fix feature detection on InspIRCd. 2024-03-08 16:49:55 +00:00
Sadie Powell 9649dc78a1 When using ldap/sql auth prevent displays expiring before their group.
This prevents zombie accounts from being left around that can't be
authenticated to.

Closes #355.
2024-03-04 12:08:28 +00:00
22 changed files with 181 additions and 90 deletions
+1
View File
@@ -4,3 +4,4 @@ updates:
directory: / directory: /
schedule: schedule:
interval: monthly interval: monthly
target-branch: "2.1"
+2 -3
View File
@@ -109,10 +109,9 @@ module
/* /*
* The length of time before a channel registration expires. * The length of time before a channel registration expires.
* *
* This directive is optional, but recommended. * This directive is optional. If not set, the default is never.
* If not set, the default is 14 days.
*/ */
expire = 14d #expire = 90d
/* /*
* The maximum number of entries on a channel's access list. * The maximum number of entries on a channel's access list.
+1 -6
View File
@@ -259,7 +259,7 @@ serverinfo
* - hybrid * - hybrid
* - inspircd12 * - inspircd12
* - inspircd20 * - inspircd20
* - inspircd3 * - inspircd3 (for 3.x and 4.x)
* - ngircd * - ngircd
* - plexus * - plexus
* - ratbox * - ratbox
@@ -1153,11 +1153,6 @@ module
* This is only useful with very large databases, with hundreds * This is only useful with very large databases, with hundreds
* of thousands of objects, that have a noticeable delay from * of thousands of objects, that have a noticeable delay from
* writing databases. * writing databases.
*
* If your database is large enough cause a noticeable delay when
* saving you should consider a more powerful alternative such
* as db_sql or db_redis, which incrementally update their
* databases asynchronously in real time.
*/ */
fork = no fork = no
} }
+1 -1
View File
@@ -256,7 +256,7 @@ serverinfo
* - hybrid * - hybrid
* - inspircd12 * - inspircd12
* - inspircd20 * - inspircd20
* - inspircd3 * - inspircd3 (for 3.x and 4.x)
* - ngircd * - ngircd
* - plexus * - plexus
* - ratbox * - ratbox
+24 -3
View File
@@ -1,6 +1,27 @@
Anope Version 2.0.16-git Anope Version 2.0.16
------------------------ --------------------
No significant changes. Added a workaround for users matching expired sqlines.
Fixed a copy/paste error in webcpanel.
Fixed a crash in db_flatfile caused by trying to serialize data without a type.
Fixed duplicate messages when synconset/syncongroup is set.
Fixed expiring channel suspensions.
Fixed expiring forbids.
Fixed expiring nick suspensions.
Fixed feature detection on InspIRCd.
Fixed InspIRCd account cloaks causing CHGHOST spam when a user also has a services vhost.
Fixed joining users to channels with a key set on InspIRCd.
Fixed logging users out fully when their nick gets suspended.
Fixed marking boolean columns in SQL as TEXT instead of INT.
Fixed matching extbans on InspIRCd and implement missing matchers.
Fixed operserv/sqline expiry on UnrealIRCd
Fixed respecting --noexpire in cs_suspend and ns_suspend.
Fixed sending emails to nicks ending with a backslash.
Fixed sending SVSTOPIC when topiclock is loaded on InspIRCd.
Fixed some SQL tables taking up too much space on disk.
Fixed the default config for channel suspensions.
Fixed the TIME message on InspIRCd.
Fixed trying to escape SQL data when not connected to MySQL.
Fixed {ldap,sql}_authentication creating zombie accounts on expiry.
Anope Version 2.0.15 Anope Version 2.0.15
-------------------- --------------------
+2 -2
View File
@@ -1,5 +1,5 @@
Anope Version 2.0.16-git Anope Version 2.0.16
------------------------ --------------------
No significant changes. No significant changes.
Anope Version 2.0.15 Anope Version 2.0.15
+1
View File
@@ -190,6 +190,7 @@ class SerializableExtensibleItem<bool> : public PrimitiveExtensibleItem<bool>
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
{ {
data.SetType(this->name, Serialize::Data::DT_INT);
data[this->name] << true; data[this->name] << true;
} }
+10 -11
View File
@@ -51,17 +51,16 @@ struct KickerDataImpl : KickerData
if (kd == NULL) if (kd == NULL)
return; return;
data["kickerdata:amsgs"] << kd->amsgs; data.SetType("kickerdata:amsgs", Serialize::Data::DT_INT); data["kickerdata:amsgs"] << kd->amsgs;
data["kickerdata:badwords"] << kd->badwords; data.SetType("kickerdata:badwords", Serialize::Data::DT_INT); data["kickerdata:badwords"] << kd->badwords;
data["kickerdata:bolds"] << kd->bolds; data.SetType("kickerdata:bolds", Serialize::Data::DT_INT); data["kickerdata:bolds"] << kd->bolds;
data["kickerdata:caps"] << kd->caps; data.SetType("kickerdata:caps", Serialize::Data::DT_INT); data["kickerdata:caps"] << kd->caps;
data["kickerdata:colors"] << kd->colors; data.SetType("kickerdata:colors", Serialize::Data::DT_INT); data["kickerdata:colors"] << kd->colors;
data["kickerdata:flood"] << kd->flood; data.SetType("kickerdata:flood", Serialize::Data::DT_INT); data["kickerdata:flood"] << kd->flood;
data["kickerdata:italics"] << kd->italics; data.SetType("kickerdata:italics", Serialize::Data::DT_INT); data["kickerdata:italics"] << kd->italics;
data["kickerdata:repeat"] << kd->repeat; data.SetType("kickerdata:repeat", Serialize::Data::DT_INT); data["kickerdata:repeat"] << kd->repeat;
data["kickerdata:reverses"] << kd->reverses; data.SetType("kickerdata:reverses", Serialize::Data::DT_INT); data["kickerdata:reverses"] << kd->reverses;
data["kickerdata:underlines"] << kd->underlines; data.SetType("kickerdata:underlines", Serialize::Data::DT_INT); data["kickerdata:underlines"] << kd->underlines;
data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << kd->capsmin; data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << kd->capsmin;
data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << kd->capspercent; data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << kd->capspercent;
data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << kd->floodlines; data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << kd->floodlines;
+20 -8
View File
@@ -210,6 +210,13 @@ class CSSuspend : public Module
} }
}; };
void Expire(ChannelInfo *ci)
{
suspend.Unset(ci);
Log(this) << "Expiring suspend for " << ci->name;
}
bool Show(CommandSource &source, const Anope::string &what) const bool Show(CommandSource &source, const Anope::string &what) const
{ {
return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end(); return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
@@ -255,23 +262,28 @@ class CSSuspend : public Module
expire = false; expire = false;
if (!si->expires) if (!Anope::NoExpire && si->expires && si->expires < Anope::CurTime)
return;
if (si->expires < Anope::CurTime)
{ {
ci->last_used = Anope::CurTime; ci->last_used = Anope::CurTime;
suspend.Unset(ci); Expire(ci);
Log(this) << "Expiring suspend for " << ci->name;
} }
} }
EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
{ {
if (u->HasMode("OPER") || !c->ci || !suspend.HasExt(c->ci)) if (u->HasMode("OPER") || !c->ci)
return EVENT_CONTINUE; return EVENT_CONTINUE;
CSSuspendInfo *si = suspend.Get(c->ci);
if (!si)
return EVENT_CONTINUE;
if (!Anope::NoExpire && si->expires && si->expires < Anope::CurTime)
{
Expire(c->ci);
return EVENT_CONTINUE;
}
reason = Language::Translate(u, _("This channel may not be used.")); reason = Language::Translate(u, _("This channel may not be used."));
return EVENT_STOP; return EVENT_STOP;
} }
+1 -1
View File
@@ -28,7 +28,7 @@ class CommandHSGroup : public Command
for (unsigned i = 0; i < na->nc->aliases->size(); ++i) for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
{ {
NickAlias *nick = na->nc->aliases->at(i); NickAlias *nick = na->nc->aliases->at(i);
if (nick) if (nick && nick != na)
{ {
nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator()); nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
FOREACH_MOD(OnSetVhost, (nick)); FOREACH_MOD(OnSetVhost, (nick));
+1 -1
View File
@@ -114,7 +114,7 @@ class CommandHSSetAll : public Command
for (unsigned i = 0; i < na->nc->aliases->size(); ++i) for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
{ {
NickAlias *nick = na->nc->aliases->at(i); NickAlias *nick = na->nc->aliases->at(i);
if (nick) if (nick && nick != na)
nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator()); nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
} }
} }
+16 -7
View File
@@ -127,6 +127,8 @@ class CommandNSSuspend : public Command
User *u2 = User::Find(na2->nick, true); User *u2 = User::Find(na2->nick, true);
if (u2) if (u2)
{ {
IRCD->SendLogout(u2);
u2->RemoveMode(source.service, "REGISTERED");
u2->Logout(); u2->Logout();
if (nickserv) if (nickserv)
nickserv->Collide(u2, na2); nickserv->Collide(u2, na2);
@@ -222,6 +224,12 @@ class NSSuspend : public Module
return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end(); return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
} }
void Expire(NickAlias *na)
{
suspend.Unset(na->nc);
Log(LOG_NORMAL, "nickserv/expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
}
public: public:
NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnssuspend(this), commandnsunsuspend(this), suspend(this, "NS_SUSPENDED"), commandnssuspend(this), commandnsunsuspend(this), suspend(this, "NS_SUSPENDED"),
@@ -262,15 +270,10 @@ class NSSuspend : public Module
expire = false; expire = false;
if (!s->expires) if (!Anope::NoExpire && s->expires && s->expires < Anope::CurTime)
return;
if (s->expires < Anope::CurTime)
{ {
na->last_seen = Anope::CurTime; na->last_seen = Anope::CurTime;
suspend.Unset(na->nc); Expire(na);
Log(LOG_NORMAL, "nickserv/expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
} }
} }
@@ -280,6 +283,12 @@ class NSSuspend : public Module
if (!s) if (!s)
return EVENT_CONTINUE; return EVENT_CONTINUE;
if (!Anope::NoExpire && s->expires && s->expires < Anope::CurTime)
{
Expire(na);
return EVENT_CONTINUE;
}
u->SendMessage(Config->GetClient("NickServ"), NICK_X_SUSPENDED, u->nick.c_str()); u->SendMessage(Config->GetClient("NickServ"), NICK_X_SUSPENDED, u->nick.c_str());
return EVENT_STOP; return EVENT_STOP;
} }
+40 -13
View File
@@ -65,6 +65,33 @@ class MyForbidService : public ForbidService
inline std::vector<ForbidData *>& forbids(unsigned t) { return (*this->forbid_data)[t - 1]; } inline std::vector<ForbidData *>& forbids(unsigned t) { return (*this->forbid_data)[t - 1]; }
void Expire(ForbidData *fd, unsigned ft, size_t idx)
{
Anope::string typestr;
switch (ft)
{
case FT_NICK:
typestr = "nick";
break;
case FT_CHAN:
typestr = "chan";
break;
case FT_EMAIL:
typestr = "email";
break;
case FT_REGISTER:
typestr = "register";
break;
default:
typestr = "unknown";
break;
}
Log(LOG_NORMAL, "expire/forbid", Config->GetClient("OperServ")) << "Expiring forbid for " << fd->mask << " type " << typestr;
this->forbids(ft).erase(this->forbids(ft).begin() + idx);
delete fd;
}
public: public:
MyForbidService(Module *m) : ForbidService(m), forbid_data("ForbidData") { } MyForbidService(Module *m) : ForbidService(m), forbid_data("ForbidData") { }
@@ -99,6 +126,12 @@ class MyForbidService : public ForbidService
{ {
ForbidData *d = this->forbids(ftype)[i - 1]; ForbidData *d = this->forbids(ftype)[i - 1];
if (!Anope::NoExpire && d->expires && Anope::CurTime >= d->expires)
{
Expire(d, ftype, i - 1);
continue;
}
if (Anope::Match(mask, d->mask, false, true)) if (Anope::Match(mask, d->mask, false, true))
return d; return d;
} }
@@ -111,6 +144,12 @@ class MyForbidService : public ForbidService
{ {
ForbidData *d = this->forbids(ftype)[i - 1]; ForbidData *d = this->forbids(ftype)[i - 1];
if (!Anope::NoExpire && d->expires && Anope::CurTime >= d->expires)
{
Expire(d, ftype, i - 1);
continue;
}
if (d->mask.equals_ci(mask)) if (d->mask.equals_ci(mask))
return d; return d;
} }
@@ -126,19 +165,7 @@ class MyForbidService : public ForbidService
ForbidData *d = this->forbids(j).at(i - 1); ForbidData *d = this->forbids(j).at(i - 1);
if (d->expires && !Anope::NoExpire && Anope::CurTime >= d->expires) if (d->expires && !Anope::NoExpire && Anope::CurTime >= d->expires)
{ Expire(d, j, i - 1);
Anope::string ftype = "none";
if (d->type == FT_NICK)
ftype = "nick";
else if (d->type == FT_CHAN)
ftype = "chan";
else if (d->type == FT_EMAIL)
ftype = "email";
Log(LOG_NORMAL, "expire/forbid", Config->GetClient("OperServ")) << "Expiring forbid for " << d->mask << " type " << ftype;
this->forbids(j).erase(this->forbids(j).begin() + i - 1);
delete d;
}
else else
f.push_back(d); f.push_back(d);
} }
+2
View File
@@ -324,6 +324,8 @@ class DBFlatFile : public Module, public Pipe
{ {
Serializable *base = *it; Serializable *base = *it;
Serialize::Type *s_type = base->GetSerializableType(); Serialize::Type *s_type = base->GetSerializableType();
if (!s_type)
continue;
data.fs = databases[s_type->GetOwner()]; data.fs = databases[s_type->GetOwner()];
if (!data.fs || !data.fs->is_open()) if (!data.fs || !data.fs->is_open())
+9
View File
@@ -299,6 +299,15 @@ class ModuleLDAPAuthentication : public Module
Anope::string new_dn = username_attribute + "=" + na->nick + "," + basedn; Anope::string new_dn = username_attribute + "=" + na->nick + "," + basedn;
this->ldap->Add(&this->orinterface, new_dn, attributes); this->ldap->Add(&this->orinterface, new_dn, attributes);
} }
void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
{
// We can't let nicks expire if they still have a group or
// there will be a zombie account left over that can't be
// authenticated to.
if (na->nick == na->nc->display && na->nc->aliases->size() > 1)
expire = false;
}
}; };
MODULE_INIT(ModuleLDAPAuthentication) MODULE_INIT(ModuleLDAPAuthentication)
+10 -5
View File
@@ -339,9 +339,14 @@ Result MySQLService::RunQuery(const Query &query)
{ {
this->Lock.Lock(); this->Lock.Lock();
Anope::string real_query = this->BuildQuery(query); if (!this->CheckConnection())
{
this->Lock.Unlock();
return MySQLResult(query, query.query, mysql_error(this->sql));
}
if (this->CheckConnection() && !mysql_real_query(this->sql, real_query.c_str(), real_query.length())) Anope::string real_query = this->BuildQuery(query);
if (!mysql_real_query(this->sql, real_query.c_str(), real_query.length()))
{ {
MYSQL_RES *res = mysql_store_result(this->sql); MYSQL_RES *res = mysql_store_result(this->sql);
unsigned int id = mysql_insert_id(this->sql); unsigned int id = mysql_insert_id(this->sql);
@@ -395,11 +400,11 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const D
query_text += ", `" + it->first + "` "; query_text += ", `" + it->first + "` ";
if (data.GetType(it->first) == Serialize::Data::DT_INT) if (data.GetType(it->first) == Serialize::Data::DT_INT)
query_text += "int(11)"; query_text += "int";
else else
query_text += "text"; query_text += "text";
} }
query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`))"; query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`)) ROW_FORMAT=DYNAMIC";
queries.push_back(query_text); queries.push_back(query_text);
} }
else else
@@ -412,7 +417,7 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const D
Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` "; Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` ";
if (data.GetType(it->first) == Serialize::Data::DT_INT) if (data.GetType(it->first) == Serialize::Data::DT_INT)
query_text += "int(11)"; query_text += "int";
else else
query_text += "text"; query_text += "text";
+9
View File
@@ -143,6 +143,15 @@ class ModuleSQLAuthentication : public Module
Log(LOG_DEBUG) << "m_sql_authentication: Checking authentication for " << req->GetAccount(); Log(LOG_DEBUG) << "m_sql_authentication: Checking authentication for " << req->GetAccount();
} }
void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
{
// We can't let nicks expire if they still have a group or
// there will be a zombie account left over that can't be
// authenticated to.
if (na->nick == na->nc->display && na->nc->aliases->size() > 1)
expire = false;
}
}; };
MODULE_INIT(ModuleSQLAuthentication) MODULE_INIT(ModuleSQLAuthentication)
+25 -26
View File
@@ -66,9 +66,7 @@ class InspIRCd3Proto : public IRCDProto
CanSetVHost = true; CanSetVHost = true;
CanSetVIdent = true; CanSetVIdent = true;
CanSQLine = true; CanSQLine = true;
CanSQLineChannel = true;
CanSZLine = true; CanSZLine = true;
CanSVSHold = true;
CanCertFP = true; CanCertFP = true;
RequiresID = true; RequiresID = true;
MaxModes = 20; MaxModes = 20;
@@ -182,7 +180,7 @@ class InspIRCd3Proto : public IRCDProto
void SendTopic(const MessageSource &source, Channel *c) anope_override void SendTopic(const MessageSource &source, Channel *c) anope_override
{ {
if (Servers::Capab.count("SVSTOPIC")) if (Servers::Capab.count("TOPICLOCK"))
{ {
UplinkSocket::Message(c->WhoSends()) << "SVSTOPIC " << c->name << " " << c->topic_ts << " " << c->topic_setter << " :" << c->topic; UplinkSocket::Message(c->WhoSends()) << "SVSTOPIC " << c->name << " " << c->topic_ts << " " << c->topic_setter << " :" << c->topic;
} }
@@ -396,9 +394,12 @@ class InspIRCd3Proto : public IRCDProto
SendAddLine("Z", x->GetHost(), timeleft, x->by, x->GetReason()); SendAddLine("Z", x->GetHost(), timeleft, x->by, x->GetReason());
} }
void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &other) anope_override void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) anope_override
{ {
UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan; if (key.empty())
UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan;
else
UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan << " :" << key;
} }
void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) anope_override void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) anope_override
@@ -444,6 +445,7 @@ class InspIRCd3Proto : public IRCDProto
if (na->nc->HasExt("UNCONFIRMED")) if (na->nc->HasExt("UNCONFIRMED"))
return; return;
IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountid :" << na->nc->GetId(); UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountid :" << na->nc->GetId();
UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountname :" << na->nc->display; UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountname :" << na->nc->display;
} }
@@ -931,8 +933,7 @@ struct IRCDMessageCapab : Message::Capab
} }
/* reset CAPAB */ /* reset CAPAB */
Servers::Capab.insert("SERVERS"); Servers::Capab.clear();
Servers::Capab.insert("TOPICLOCK");
IRCD->CanSQLineChannel = false; IRCD->CanSQLineChannel = false;
IRCD->CanSVSHold = false; IRCD->CanSVSHold = false;
IRCD->DefaultPseudoclientModes = "+oI"; IRCD->DefaultPseudoclientModes = "+oI";
@@ -1238,11 +1239,15 @@ struct IRCDMessageCapab : Message::Capab
return; return;
} }
if (!IRCD->CanSVSHold) if (!IRCD->CanSVSHold)
Log() << "SVSHOLD missing, Usage disabled until module is loaded."; Log() << "The remote server does not have the svshold module; fake users will be used for nick protection until the module is loaded.";
if (!IRCD->CanSQLineChannel)
Log() << "The remote server does not have the cban module; services will manually enforce forbidden channels until the module is loaded.";
if (!Servers::Capab.count("CHGHOST")) if (!Servers::Capab.count("CHGHOST"))
Log() << "CHGHOST missing, Usage disabled until module is loaded."; Log() << "The remote server does not have the chghost module; vhosts are disabled until the module is loaded.";
if (!Servers::Capab.count("CHGIDENT")) if (!Servers::Capab.count("CHGIDENT"))
Log() << "CHGIDENT missing, Usage disabled until module is loaded."; Log() << "The remote server does not have the chgident module; vidents are disabled until the module is loaded.";
if (!Servers::Capab.count("GLOBOPS"))
Log() << "The remote server does not have the globops module; oper notices will be sent as announcements until the module is loaded.";
} }
Message::Capab::Run(source, params); Message::Capab::Run(source, params);
@@ -1484,12 +1489,16 @@ class IRCDMessageMetadata : IRCDMessage
required = true; required = true;
else if (module.equals_cs("m_hidechans.so")) else if (module.equals_cs("m_hidechans.so"))
required = true; required = true;
else if (module.equals_cs("m_cban.so=glob") && plus)
IRCD->CanSQLineChannel = true;
if (module.equals_cs("m_cban.so") && !plus)
IRCD->CanSQLineChannel = false;
else if (module.equals_cs("m_chghost.so")) else if (module.equals_cs("m_chghost.so"))
capab = "CHGHOST"; capab = "CHGHOST";
else if (module.equals_cs("m_chgident.so")) else if (module.equals_cs("m_chgident.so"))
capab = "CHGIDENT"; capab = "CHGIDENT";
else if (module.equals_cs("m_svshold.so")) else if (module.equals_cs("m_svshold.so"))
capab = "SVSHOLD"; IRCD->CanSVSHold = plus;
else if (module.equals_cs("m_rline.so")) else if (module.equals_cs("m_rline.so"))
capab = "RLINE"; capab = "RLINE";
else if (module.equals_cs("m_topiclock.so")) else if (module.equals_cs("m_topiclock.so"))
@@ -1504,9 +1513,9 @@ class IRCDMessageMetadata : IRCDMessage
} }
else else
{ {
if (plus) if (plus && !capab.empty())
Servers::Capab.insert(capab); Servers::Capab.insert(capab);
else else if (!capab.empty())
Servers::Capab.erase(capab); Servers::Capab.erase(capab);
Log() << "InspIRCd " << (plus ? "loaded" : "unloaded") << " module " << module << ", adjusted functionality"; Log() << "InspIRCd " << (plus ? "loaded" : "unloaded") << " module " << module << ", adjusted functionality";
@@ -1828,16 +1837,6 @@ struct IRCDMessageSQuit : Message::SQuit
} }
}; };
struct IRCDMessageTime : IRCDMessage
{
IRCDMessageTime(Module *creator) : IRCDMessage(creator, "TIME", 2) { }
void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
UplinkSocket::Message(Me) << "TIME " << source.GetSource() << " " << params[1] << " " << Anope::CurTime;
}
};
struct IRCDMessageUID : IRCDMessage struct IRCDMessageUID : IRCDMessage
{ {
IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
@@ -1901,6 +1900,7 @@ class ProtoInspIRCd3 : public Module
Message::Privmsg message_privmsg; Message::Privmsg message_privmsg;
Message::Quit message_quit; Message::Quit message_quit;
Message::Stats message_stats; Message::Stats message_stats;
Message::Time message_time;
/* Our message handlers */ /* Our message handlers */
IRCDMessageAway message_away; IRCDMessageAway message_away;
@@ -1924,7 +1924,6 @@ class ProtoInspIRCd3 : public Module
IRCDMessageSave message_save; IRCDMessageSave message_save;
IRCDMessageServer message_server; IRCDMessageServer message_server;
IRCDMessageSQuit message_squit; IRCDMessageSQuit message_squit;
IRCDMessageTime message_time;
IRCDMessageUID message_uid; IRCDMessageUID message_uid;
bool use_server_side_topiclock, use_server_side_mlock; bool use_server_side_topiclock, use_server_side_mlock;
@@ -1938,12 +1937,12 @@ class ProtoInspIRCd3 : public Module
ProtoInspIRCd3(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), ProtoInspIRCd3(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
ircd_proto(this), ssl(this, "ssl"), ircd_proto(this), ssl(this, "ssl"),
message_error(this), message_invite(this), message_kill(this), message_motd(this), message_notice(this), message_error(this), message_invite(this), message_kill(this), message_motd(this), message_notice(this),
message_part(this), message_privmsg(this), message_quit(this), message_stats(this), message_part(this), message_privmsg(this), message_quit(this), message_stats(this), message_time(this),
message_away(this), message_capab(this), message_encap(this), message_endburst(this), message_fhost(this), message_away(this), message_capab(this), message_encap(this), message_endburst(this), message_fhost(this),
message_fident(this), message_fjoin(this), message_fmode(this), message_ftopic(this), message_idle(this), message_fident(this), message_fjoin(this), message_fmode(this), message_ftopic(this), message_idle(this),
message_ijoin(this), message_kick(this), message_metadata(this, use_server_side_topiclock, use_server_side_mlock, ircd_proto.maxlist), message_ijoin(this), message_kick(this), message_metadata(this, use_server_side_topiclock, use_server_side_mlock, ircd_proto.maxlist),
message_mode(this), message_nick(this), message_opertype(this), message_ping(this), message_rsquit(this), message_mode(this), message_nick(this), message_opertype(this), message_ping(this), message_rsquit(this),
message_save(this), message_server(this), message_squit(this), message_time(this), message_uid(this) message_save(this), message_server(this), message_squit(this), message_uid(this)
{ {
} }
+1 -1
View File
@@ -196,7 +196,7 @@ class UnrealIRCdProto : public IRCDProto
*/ */
void SendSQLine(User *, const XLine *x) anope_override void SendSQLine(User *, const XLine *x) anope_override
{ {
UplinkSocket::Message() << "SQLINE " << x->mask << " :" << x->GetReason(); UplinkSocket::Message() << "TKL + Q * " << x->mask << " " << x->by << " " << x->expires << " " << x->created << " :" << x->GetReason();
} }
/* Functions that use serval cmd functions */ /* Functions that use serval cmd functions */
+3
View File
@@ -126,6 +126,9 @@ class SQLineManager : public XLineManager
{ {
XLine *x = *it; XLine *x = *it;
if (!Anope::NoExpire && x->expires && x->expires < Anope::CurTime)
continue; // Skip expired lines.
if (x->regex) if (x->regex)
{ {
if (x->regex->Matches(c->name)) if (x->regex->Matches(c->name))
+1 -1
View File
@@ -48,7 +48,7 @@ void Mail::Message::Run()
if (this->dont_quote_addresses) if (this->dont_quote_addresses)
fprintf(pipe, "To: %s <%s>\r\n", mail_to.c_str(), addr.c_str()); fprintf(pipe, "To: %s <%s>\r\n", mail_to.c_str(), addr.c_str());
else else
fprintf(pipe, "To: \"%s\" <%s>\r\n", mail_to.c_str(), addr.c_str()); fprintf(pipe, "To: \"%s\" <%s>\r\n", mail_to.replace_all_cs("\\", "\\\\").c_str(), addr.c_str());
fprintf(pipe, "Subject: %s\r\n", subject.c_str()); fprintf(pipe, "Subject: %s\r\n", subject.c_str());
fprintf(pipe, "Content-Type: %s\r\n", content_type.c_str()); fprintf(pipe, "Content-Type: %s\r\n", content_type.c_str());
fprintf(pipe, "Content-Transfer-Encoding: 8bit\r\n"); fprintf(pipe, "Content-Transfer-Encoding: 8bit\r\n");
+1 -1
View File
@@ -3,4 +3,4 @@
VERSION_MAJOR=2 VERSION_MAJOR=2
VERSION_MINOR=0 VERSION_MINOR=0
VERSION_PATCH=16 VERSION_PATCH=16
VERSION_EXTRA="-git" VERSION_EXTRA=""