diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/protocol/inspircd-ts6.h | 9 | ||||
-rw-r--r-- | modules/protocol/inspircd20.cpp | 60 | ||||
-rw-r--r-- | modules/protocol/unreal.cpp | 80 |
3 files changed, 145 insertions, 4 deletions
diff --git a/modules/protocol/inspircd-ts6.h b/modules/protocol/inspircd-ts6.h index b3d3a7a36..fefff1d15 100644 --- a/modules/protocol/inspircd-ts6.h +++ b/modules/protocol/inspircd-ts6.h @@ -579,9 +579,16 @@ struct IRCDMessageMetadata : IRCDMessage { u->Login(nc); + const BotInfo *bi = findbot(Config->NickServ); const NickAlias *user_na = findnick(u->nick); if (!Config->NoNicknameOwnership && nickserv && user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(findbot(Config->NickServ), UMODE_REGISTERED); + u->SetMode(bi, UMODE_REGISTERED); + + /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if + * their server isn't syncing) and then we receive this.. so tell them about it. + */ + if (bi) + u->SendMessage(bi, _("You have been logged in as \2%s\2."), nc->display.c_str()); } } diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index c547a11d6..2d3a3c4f2 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -447,7 +447,9 @@ struct IRCDMessageCapab : IRCDMessage struct IRCDMessageEncap : IRCDMessage { - IRCDMessageEncap() : IRCDMessage("ENCAP", 4) { } + Module *me; + + IRCDMessageEncap(Module *m) : IRCDMessage("ENCAP", 4), me(m) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { @@ -481,6 +483,60 @@ struct IRCDMessageEncap : IRCDMessage u->SetRealname(params[3]); UplinkSocket::Message(u) << "FNAME " << params[3]; } + else if (params[1] == "SASL" && params.size() == 6) + { + class InspIRCDSASLIdentifyRequest : public IdentifyRequest + { + Anope::string uid; + + public: + InspIRCDSASLIdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(m, acc, pass), uid(id) { } + + void OnSuccess() anope_override + { + UplinkSocket::Message(Me) << "METADATA " << this->uid << " accountname :" << this->GetAccount(); + UplinkSocket::Message(Me) << "ENCAP " << this->uid.substr(0, 3) << " SASL " << Me->GetSID() << " " << this->uid << " D S"; + } + + void OnFail() anope_override + { + UplinkSocket::Message(Me) << "ENCAP " << this->uid.substr(0, 3) << " SASL " << Me->GetSID() << " " << this->uid << " " << " D F"; + } + }; + + /* + Received: :869 ENCAP * SASL 869AAAAAH * S PLAIN + Sent: :00B ENCAP 869 SASL 00B 869AAAAAH C + + Received: :869 ENCAP * SASL 869AAAAAH 00B C QWRhbQBBZGFtAG1vbw== + base64(account\0account\0pass) + */ + if (params[4] == "S") + UplinkSocket::Message(Me) << "ENCAP " << params[2].substr(0, 3) << " SASL " << Me->GetSID() << " " << params[2] << " C +"; + else if (params[4] == "C") + { + Anope::string decoded; + Anope::B64Decode(params[5], decoded); + + size_t p = decoded.find('\0'); + if (p == Anope::string::npos) + return true; + decoded = decoded.substr(p + 1); + + p = decoded.find('\0'); + if (p == Anope::string::npos) + return true; + + Anope::string acc = decoded.substr(0, p), + pass = decoded.substr(p + 1); + + if (acc.empty() || pass.empty()) + return true; + + IdentifyRequest *req = new InspIRCDSASLIdentifyRequest(me, params[2], acc, pass); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(NULL, req)); + req->Dispatch(); + } + } return true; } @@ -546,7 +602,7 @@ class ProtoInspIRCd : public Module public: ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), - message_fhost("FHOST") + message_fhost("FHOST"), message_encap(this) { this->SetAuthor("Anope"); diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index c22bf42b1..bafca8016 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -851,6 +851,83 @@ struct IRCDMessagePong : IRCDMessage } }; +struct IRCDMessageSASL : IRCDMessage +{ + class UnrealSASLIdentifyRequest : public IdentifyRequest + { + Anope::string uid; + + public: + UnrealSASLIdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(m, acc, pass), uid(id) { } + + void OnSuccess() anope_override + { + size_t p = this->uid.find('!'); + if (p == Anope::string::npos) + return; + + UplinkSocket::Message(Me) << "SVSLOGIN " << this->uid.substr(0, p) << " " << this->uid << " " << this->GetAccount(); + UplinkSocket::Message(findbot(Config->NickServ)) << "SASL " << this->uid.substr(0, p) << " " << this->uid << " D S"; + } + + void OnFail() anope_override + { + size_t p = this->uid.find('!'); + if (p == Anope::string::npos) + return; + + UplinkSocket::Message(findbot(Config->NickServ)) << "SASL " << this->uid.substr(0, p) << " " << this->uid << " D F"; + } + }; + + Module *me; + + IRCDMessageSASL(Module *m) : IRCDMessage("SASL", 4), me(m) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + + /* Received: :irc.foonet.com SASL services.localhost.net irc.foonet.com!1.57290 S PLAIN + * uid + * + * Received: :irc.foonet.com SASL services.localhost.net irc.foonet.com!3.56270 C QWRhbQBBZGFtAHF3ZXJ0eQ== + * uid base64(account\0account\0pass) + */ + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + size_t p = params[1].find('!'); + if (p == Anope::string::npos) + return true; + + /* Unreal segfaults if we send from Me */ + if (params[2] == "S") + UplinkSocket::Message(findbot(Config->NickServ)) << "SASL " << params[1].substr(0, p) << " " << params[1] << " C +"; + else if (params[2] == "C") + { + Anope::string decoded; + Anope::B64Decode(params[3], decoded); + + p = decoded.find('\0'); + if (p == Anope::string::npos) + return true; + decoded = decoded.substr(p + 1); + + p = decoded.find('\0'); + if (p == Anope::string::npos) + return true; + + Anope::string acc = decoded.substr(0, p), + pass = decoded.substr(p + 1); + + if (acc.empty() || pass.empty()) + return true; + + IdentifyRequest *req = new UnrealSASLIdentifyRequest(me, params[1], acc, pass); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(NULL, req)); + req->Dispatch(); + } + + return true; + } +}; + struct IRCDMessageSDesc : IRCDMessage { IRCDMessageSDesc() : IRCDMessage("SDESC", 1) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } @@ -1124,6 +1201,7 @@ class ProtoUnreal : public Module IRCDMessageNetInfo message_netinfo; IRCDMessageNick message_nick; IRCDMessagePong message_pong; + IRCDMessageSASL message_sasl; IRCDMessageSDesc message_sdesc; IRCDMessageSetHost message_sethost; IRCDMessageSetIdent message_setident; @@ -1173,7 +1251,7 @@ class ProtoUnreal : public Module public: ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), - message_mode("MODE"), message_svsmode("SVSMODE"), message_svs2mode("SVS2MODE") + message_mode("MODE"), message_svsmode("SVSMODE"), message_svs2mode("SVS2MODE"), message_sasl(this) { this->SetAuthor("Anope"); |