summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <adam@sigterm.info>2014-02-14 19:15:43 -0500
committerAdam <adam@sigterm.info>2014-02-14 19:15:43 -0500
commit50d7bf710ec0501b7309892646a31da065aaae5a (patch)
tree85e664dfdeb38c1cae4bb03bddc76a183ab2d34e
parentca85df2d7475d42579c29d822f424d2c9713774b (diff)
parentd44bcef31b7a6cbb607249bf39273c0e32b1f60a (diff)
Merge pull request #48 from ShutterQuick/2.0+nnghsasl
Add SASL mechanisms DH-AES and DH-BLOWFISH
-rw-r--r--data/modules.example.conf18
-rw-r--r--include/anope.h1
-rw-r--r--include/modules/sasl.h80
-rw-r--r--modules/extra/m_sasl_dh-aes.cpp183
-rw-r--r--modules/extra/m_sasl_dh-blowfish.cpp193
-rw-r--r--modules/m_sasl.cpp96
-rw-r--r--modules/protocol/charybdis.cpp4
-rw-r--r--modules/protocol/inspircd12.cpp6
-rw-r--r--modules/protocol/unreal.cpp4
-rw-r--r--src/base64.cpp2
10 files changed, 511 insertions, 76 deletions
diff --git a/data/modules.example.conf b/data/modules.example.conf
index 319bc1e27..df2077b4d 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -428,12 +428,28 @@ module { name = "help" }
*
* Some IRCds allow "SASL" authentication to let users identify to Services
* during the IRCd user registration process. If this module is loaded, Services will allow
- * authenticating users through this mechanism. Currently supported mechanisms are:
+ * authenticating users through this mechanism. Supported mechanisms are:
* PLAIN, EXTERNAL.
*/
#module { name = "m_sasl" }
/*
+ * m_sasl_dh-aes [EXTRA]
+ *
+ * Add the DH-AES mechanism to SASL.
+ * Requires m_sasl to be loaded.
+ */
+#module { name = "m_sasl_dh-aes" }
+
+/*
+ * m_sasl_dh-aes [EXTRA]
+ *
+ * Add the DH-BLOWFISH mechanism to SASL.
+ * Requires m_sasl to be loaded.
+ */
+#module { name = "m_sasl_dh-blowfish" }
+
+/*
* m_sql_authentication [EXTRA]
*
* This module allows authenticating users against an external SQL database using a custom
diff --git a/include/anope.h b/include/anope.h
index 28bc50512..638661440 100644
--- a/include/anope.h
+++ b/include/anope.h
@@ -115,6 +115,7 @@ namespace Anope
* The following functions return the various types of strings.
*/
inline const char *c_str() const { return this->_string.c_str(); }
+ inline const char *data() const { return this->_string.data(); }
inline std::string &str() { return this->_string; }
inline const std::string &str() const { return this->_string; }
inline ci::string ci_str() const { return ci::string(this->_string.c_str()); }
diff --git a/include/modules/sasl.h b/include/modules/sasl.h
index 836c26d19..a7c440110 100644
--- a/include/modules/sasl.h
+++ b/include/modules/sasl.h
@@ -18,6 +18,29 @@ namespace SASL
};
class Mechanism;
+ struct Session;
+
+ class Service : public ::Service
+ {
+ public:
+ Service(Module *o) : ::Service(o, "SASL::Service", "sasl") { }
+
+ virtual void ProcessMessage(const Message &) = 0;
+
+ virtual Anope::string GetAgent() = 0;
+
+ virtual Session* GetSession(const Anope::string &uid) = 0;
+
+ virtual void SendMessage(SASL::Session *session, const Anope::string &type, const Anope::string &data) = 0;
+
+ virtual void Succeed(Session *, NickCore *) = 0;
+ virtual void Fail(Session *) = 0;
+ virtual void SendMechs(Session *) = 0;
+ virtual void DeleteSessions(Mechanism *, bool = false) = 0;
+ virtual void RemoveSession(Session *) = 0;
+ };
+
+ static ServiceReference<SASL::Service> sasl("SASL::Service", "sasl");
struct Session
{
@@ -26,11 +49,15 @@ namespace SASL
Reference<Mechanism> mech;
Session(Mechanism *m, const Anope::string &u) : created(Anope::CurTime), uid(u), mech(m) { }
- virtual ~Session() { }
+ virtual ~Session()
+ {
+ if (sasl)
+ sasl->RemoveSession(this);
+ }
};
/* PLAIN, EXTERNAL, etc */
- class Mechanism : public Service
+ class Mechanism : public ::Service
{
public:
Mechanism(Module *o, const Anope::string &sname) : Service(o, "SASL::Mechanism", sname) { }
@@ -38,26 +65,51 @@ namespace SASL
virtual Session* CreateSession(const Anope::string &uid) { return new Session(this, uid); }
virtual void ProcessMessage(Session *session, const Message &) = 0;
+
+ virtual ~Mechanism()
+ {
+ if (sasl)
+ sasl->DeleteSessions(this, true);
+ }
};
- class Service : public ::Service
+ class IdentifyRequest : public ::IdentifyRequest
{
+ Anope::string uid;
+
public:
- Service(Module *o) : ::Service(o, "SASL::Service", "sasl") { }
+ IdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass) : ::IdentifyRequest(m, acc, pass), uid(id) { }
- virtual void ProcessMessage(const Message &) = 0;
+ void OnSuccess() anope_override
+ {
+ if (!sasl)
+ return;
- virtual Anope::string GetAgent() = 0;
+ NickAlias *na = NickAlias::Find(GetAccount());
+ if (!na)
+ return OnFail();
- virtual Session* GetSession(const Anope::string &uid) = 0;
+ Session *s = sasl->GetSession(uid);
+ if (s)
+ {
+ sasl->Succeed(s, na->nc);
+ delete s;
+ }
+ }
- virtual void SendMessage(SASL::Session *session, const Anope::string &type, const Anope::string &data) = 0;
+ void OnFail() anope_override
+ {
+ if (!sasl)
+ return;
- virtual void Succeed(Session *, NickCore *) = 0;
- virtual void Fail(Session *) = 0;
- virtual void SendMechs(Session *) = 0;
+ Session *s = sasl->GetSession(uid);
+ if (s)
+ {
+ sasl->Fail(s);
+ delete s;
+ }
+
+ Log(Config->GetClient("NickServ")) << "A user failed to identify for account " << this->GetAccount() << " using SASL";
+ }
};
}
-
-static ServiceReference<SASL::Service> sasl("SASL::Service", "sasl");
-
diff --git a/modules/extra/m_sasl_dh-aes.cpp b/modules/extra/m_sasl_dh-aes.cpp
new file mode 100644
index 000000000..c61430a62
--- /dev/null
+++ b/modules/extra/m_sasl_dh-aes.cpp
@@ -0,0 +1,183 @@
+/* RequiredLibraries: ssl,crypto */
+
+#include "module.h"
+#include "modules/sasl.h"
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/aes.h>
+
+using namespace SASL;
+
+class DHAES : public Mechanism
+{
+ void Err(Session* sess, BIGNUM* key = NULL)
+ {
+ if (key)
+ BN_free(key);
+
+ sasl->Fail(sess);
+ return delete sess;
+ }
+
+ public:
+ struct Session : SASL::Session
+ {
+ DH* dh;
+ Session(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u)
+ {
+ if (!(dh = DH_new()))
+ return;
+
+ dh->g = BN_dup(dh_params->g);
+ dh->p = BN_dup(dh_params->p);
+
+ if (!DH_generate_key(dh))
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+ }
+
+ ~Session()
+ {
+ if (dh)
+ DH_free(dh);
+ }
+ };
+
+ DH* dh_params;
+ const size_t keysize;
+ SASL::Session* CreateSession(const Anope::string &uid) anope_override
+ {
+ return new Session(this, uid, dh_params);
+ }
+
+ DHAES(Module *o) : Mechanism(o, "DH-AES"), keysize(256 / 8)
+ {
+ if (!(dh_params = DH_new()))
+ throw ModuleException("DH_new() failed!");
+
+ if (!DH_generate_parameters_ex(dh_params, keysize * 8, 5, NULL))
+ {
+ DH_free(dh_params);
+ throw ModuleException("Could not generate DH-params");
+ }
+ }
+
+ ~DHAES()
+ {
+ DH_free(dh_params);
+ }
+
+ void ProcessMessage(SASL::Session *session, const SASL::Message &m) anope_override
+ {
+ Session *sess = anope_dynamic_static_cast<Session *>(session);
+
+ if (!sess->dh)
+ {
+ sasl->SendMessage(sess, "D", "A");
+ delete sess;
+ return;
+ }
+
+ if (m.type == "S")
+ {
+ // Format: [ss]<p>[ss]<g>[ss]<pub_key>
+ // Where ss is a unsigned short with the size of the key
+ const BIGNUM* dhval[] = { sess->dh->p, sess->dh->g, sess->dh->pub_key };
+
+ // Find the size of our buffer - initialized at 6 because of string size data
+ size_t size = 6;
+ for (size_t i = 0; i < 3; i++)
+ size += BN_num_bytes(dhval[i]);
+
+ // Fill in the DH data
+ std::vector<unsigned char> buffer(size);
+ for (size_t i = 0, pos = 0; i < 3; i++)
+ {
+ *reinterpret_cast<uint16_t*>(&buffer[pos]) = htons(BN_num_bytes(dhval[i]));
+ pos += 2;
+ BN_bn2bin(dhval[i], &buffer[pos]);
+ pos += BN_num_bytes(dhval[i]);
+ }
+
+ Anope::string encoded;
+ Anope::B64Encode(Anope::string(buffer.begin(), buffer.end()), encoded);
+ sasl->SendMessage(sess, "C", encoded);
+ }
+ else if (m.type == "C")
+ {
+ // Make sure we have some data - actual size check is done later
+ if (m.data.length() < 10)
+ return Err(sess);
+
+ // Format: [ss]<key>[ss]<iv>[ss]<encrypted>
+ // <encrypted> = <username>\0<password>\0
+
+ Anope::string decoded;
+ Anope::B64Decode(m.data, decoded);
+
+ // Make sure we have an IV and at least one encrypted block
+ if ((decoded.length() < keysize + 2 + (AES_BLOCK_SIZE * 2)) || ((decoded.length() - keysize - 2) % AES_BLOCK_SIZE))
+ return Err(sess);
+
+ const unsigned char* data = reinterpret_cast<const unsigned char*>(decoded.data());
+
+ // Control the size of the key
+ if (ntohs(*reinterpret_cast<const uint16_t*>(&data[0])) != keysize)
+ return Err(sess);
+
+ // Convert pubkey from binary
+ size_t pos = 2;
+ BIGNUM* pubkey = BN_bin2bn(&data[pos], keysize, NULL);
+ if (!pubkey)
+ return Err(sess);
+
+ // Find shared key
+ std::vector<unsigned char> secretkey(keysize);
+ if (DH_compute_key(&secretkey[0], pubkey, sess->dh) != static_cast<int>(keysize))
+ return Err(sess, pubkey);
+
+ // Set decryption key
+ AES_KEY AESKey;
+ AES_set_decrypt_key(&secretkey[0], keysize * 8, &AESKey);
+
+ // Fetch IV
+ pos += keysize;
+ std::vector<unsigned char> IV(data + pos, data + pos + AES_BLOCK_SIZE);
+
+ // Find encrypted blocks, and decrypt
+ pos += AES_BLOCK_SIZE;
+ size_t size = decoded.length() - pos;
+ std::vector<char> decrypted(size + 2, 0);
+ AES_cbc_encrypt(&data[pos], reinterpret_cast<unsigned char*>(&decrypted[0]), size, &AESKey, &IV[0], AES_DECRYPT);
+
+ std::string username = &decrypted[0];
+ std::string password = &decrypted[username.length() + 1];
+
+ if (username.empty() || password.empty())
+ return Err(sess, pubkey);
+
+ SASL::IdentifyRequest* req = new SASL::IdentifyRequest(this->owner, m.source, username, password);
+ FOREACH_MOD(OnCheckAuthentication, (NULL, req));
+ req->Dispatch();
+
+ BN_free(pubkey);
+ }
+ }
+};
+
+
+class ModuleSASLDHAES : public Module
+{
+ DHAES dhaes;
+
+ public:
+ ModuleSASLDHAES(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA),
+ dhaes(this)
+ {
+ }
+};
+
+MODULE_INIT(ModuleSASLDHAES)
diff --git a/modules/extra/m_sasl_dh-blowfish.cpp b/modules/extra/m_sasl_dh-blowfish.cpp
new file mode 100644
index 000000000..a31d4727b
--- /dev/null
+++ b/modules/extra/m_sasl_dh-blowfish.cpp
@@ -0,0 +1,193 @@
+/* RequiredLibraries: ssl,crypto */
+
+#include "module.h"
+#include "modules/sasl.h"
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/blowfish.h>
+
+using namespace SASL;
+
+class DHBS : public Mechanism
+{
+ void Err(Session* sess, BIGNUM* key = NULL)
+ {
+ if (key)
+ BN_free(key);
+
+ sasl->Fail(sess);
+ return delete sess;
+ }
+
+ public:
+ struct Session : SASL::Session
+ {
+ DH* dh;
+ Session(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u)
+ {
+ if (!(dh = DH_new()))
+ return;
+
+ dh->g = BN_dup(dh_params->g);
+ dh->p = BN_dup(dh_params->p);
+
+ if (!DH_generate_key(dh))
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+ }
+
+ ~Session()
+ {
+ if (dh)
+ DH_free(dh);
+ }
+ };
+
+ DH* dh_params;
+ const size_t keysize;
+ SASL::Session* CreateSession(const Anope::string &uid) anope_override
+ {
+ return new Session(this, uid, dh_params);
+ }
+
+ DHBS(Module *o) : Mechanism(o, "DH-BLOWFISH"), keysize(256 / 8)
+ {
+ if (!(dh_params = DH_new()))
+ throw ModuleException("DH_new() failed!");
+
+ if (!DH_generate_parameters_ex(dh_params, keysize * 8, 5, NULL))
+ {
+ DH_free(dh_params);
+ throw ModuleException("Could not generate DH-params");
+ }
+ }
+
+ ~DHBS()
+ {
+ DH_free(dh_params);
+ }
+
+ void ProcessMessage(SASL::Session *session, const SASL::Message &m) anope_override
+ {
+ Session *sess = anope_dynamic_static_cast<Session *>(session);
+
+ if (!sess->dh)
+ {
+ sasl->SendMessage(sess, "D", "A");
+ delete sess;
+ return;
+ }
+
+ if (m.type == "S")
+ {
+ // Format: [ss]<p>[ss]<g>[ss]<pub_key>
+ // Where ss is a unsigned short with the size of the key
+ const BIGNUM* dhval[] = { sess->dh->p, sess->dh->g, sess->dh->pub_key };
+
+ // Find the size of our buffer - initialized at 6 because of string size data
+ size_t size = 6;
+ for (size_t i = 0; i < 3; i++)
+ size += BN_num_bytes(dhval[i]);
+
+ // Fill in the DH data
+ std::vector<unsigned char> buffer(size);
+ for (size_t i = 0, pos = 0; i < 3; i++)
+ {
+ *reinterpret_cast<uint16_t*>(&buffer[pos]) = htons(BN_num_bytes(dhval[i]));
+ pos += 2;
+ BN_bn2bin(dhval[i], &buffer[pos]);
+ pos += BN_num_bytes(dhval[i]);
+ }
+
+ Anope::string encoded;
+ Anope::B64Encode(Anope::string(buffer.begin(), buffer.end()), encoded);
+ sasl->SendMessage(sess, "C", encoded);
+ }
+ else if (m.type == "C")
+ {
+ // Make sure we have some data - actual size check is done later
+ if (m.data.length() < 10)
+ return Err(sess);
+
+ // Format: [ss]<key><username><\0><encrypted>
+
+ Anope::string decoded;
+ Anope::B64Decode(m.data, decoded);
+
+ // As we rely on the client giving us a null terminator at the right place,
+ // let's add one extra in case the client tries to crash us
+ const size_t decodedlen = decoded.length();
+ decoded.push_back('\0');
+
+ // Make sure we have enough data for at least the key, a one letter username, and a block of data
+ if (decodedlen < keysize + 2 + 2 + 8)
+ return Err(sess);
+
+ const unsigned char* data = reinterpret_cast<const unsigned char*>(decoded.data());
+
+ // Control the size of the key
+ if (ntohs(*reinterpret_cast<const uint16_t*>(&data[0])) != keysize)
+ return Err(sess);
+
+ // Convert pubkey from binary
+ size_t pos = 2;
+ BIGNUM* pubkey = BN_bin2bn(&data[pos], keysize, NULL);
+ if (!pubkey)
+ return Err(sess);
+
+ // Find shared key
+ std::vector<unsigned char> secretkey(DH_size(sess->dh) + 1, 0);
+ if (DH_compute_key(&secretkey[0], pubkey, sess->dh) != static_cast<int>(keysize))
+ return Err(sess, pubkey);
+
+ // Set decryption key
+ BF_KEY BFKey;
+ BF_set_key(&BFKey, keysize, &secretkey[0]);
+
+ pos += keysize;
+ const Anope::string username = reinterpret_cast<const char*>(&data[pos]);
+ // Check that the username is valid, and that we have at least one block of data
+ // 2 + 1 + 8 = uint16_t size for keylen, \0 for username, 8 for one block of data
+ if (username.empty() || username.length() + keysize + 2 + 1 + 8 > decodedlen)
+ return Err(sess, pubkey);
+
+ pos += username.length() + 1;
+ size_t size = decodedlen - pos;
+
+ // Blowfish data blocks are 64 bits wide - valid format?
+ if (size % 8)
+ return Err(sess, pubkey);
+
+ std::vector<char> decrypted(size + 1, 0);
+ for (size_t i = 0; i < size; i += 8)
+ BF_ecb_encrypt(&data[pos + i], reinterpret_cast<unsigned char*>(&decrypted[i]), &BFKey, BF_DECRYPT);
+
+ std::string password = &decrypted[0];
+ if (password.empty())
+ return Err(sess, pubkey);
+
+ SASL::IdentifyRequest* req = new SASL::IdentifyRequest(this->owner, m.source, username, password);
+ FOREACH_MOD(OnCheckAuthentication, (NULL, req));
+ req->Dispatch();
+
+ BN_free(pubkey);
+ }
+ }
+};
+
+
+class ModuleSASLDHBS : public Module
+{
+ DHBS dhbs;
+
+ public:
+ ModuleSASLDHBS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA),
+ dhbs(this)
+ {
+ }
+};
+
+MODULE_INIT(ModuleSASLDHBS)
diff --git a/modules/m_sasl.cpp b/modules/m_sasl.cpp
index bdc0ef1a2..c99f052ae 100644
--- a/modules/m_sasl.cpp
+++ b/modules/m_sasl.cpp
@@ -10,46 +10,14 @@
#include "modules/sasl.h"
#include "modules/ns_cert.h"
-class Plain : public SASL::Mechanism
-{
- class IdentifyRequest : public ::IdentifyRequest
- {
- Anope::string uid;
-
- public:
- IdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass) : ::IdentifyRequest(m, acc, pass), uid(id) { }
-
- void OnSuccess() anope_override
- {
- if (!sasl)
- return;
-
- NickAlias *na = NickAlias::Find(GetAccount());
- if (!na)
- return OnFail();
-
- SASL::Session *s = sasl->GetSession(uid);
- if (s)
- sasl->Succeed(s, na->nc);
- }
-
- void OnFail() anope_override
- {
- if (!sasl)
- return;
-
- SASL::Session *s = sasl->GetSession(uid);
- if (s)
- sasl->Fail(s);
-
- Log(Config->GetClient("NickServ")) << "A user failed to identify for account " << this->GetAccount() << " using SASL";
- }
- };
+using namespace SASL;
+class Plain : public Mechanism
+{
public:
- Plain(Module *o) : SASL::Mechanism(o, "PLAIN") { }
+ Plain(Module *o) : Mechanism(o, "PLAIN") { }
- void ProcessMessage(SASL::Session *sess, const SASL::Message &m) anope_override
+ void ProcessMessage(Session *sess, const SASL::Message &m) anope_override
{
if (m.type == "S")
{
@@ -75,14 +43,14 @@ class Plain : public SASL::Mechanism
if (acc.empty() || pass.empty())
return;
- IdentifyRequest *req = new IdentifyRequest(this->owner, m.source, acc, pass);
+ SASL::IdentifyRequest *req = new SASL::IdentifyRequest(this->owner, m.source, acc, pass);
FOREACH_MOD(OnCheckAuthentication, (NULL, req));
req->Dispatch();
}
}
};
-class External : public SASL::Mechanism
+class External : public Mechanism
{
struct Session : SASL::Session
{
@@ -92,13 +60,13 @@ class External : public SASL::Mechanism
};
public:
- External(Module *o) : SASL::Mechanism(o, "EXTERNAL")
+ External(Module *o) : Mechanism(o, "EXTERNAL")
{
if (!IRCD || !IRCD->CanCertFP)
throw ModuleException("No CertFP");
}
- SASL::Session* CreateSession(const Anope::string &uid) anope_override
+ Session* CreateSession(const Anope::string &uid) anope_override
{
return new Session(this, uid);
}
@@ -122,6 +90,7 @@ class External : public SASL::Mechanism
if (!na)
{
sasl->Fail(sess);
+ delete sess;
return;
}
@@ -129,10 +98,12 @@ class External : public SASL::Mechanism
if (cl == NULL || !cl->FindCert(mysess->cert))
{
sasl->Fail(sess);
+ delete sess;
return;
}
sasl->Succeed(sess, na->nc);
+ delete sess;
}
}
};
@@ -146,7 +117,7 @@ class SASLService : public SASL::Service, public Timer
~SASLService()
{
- for (std::map<Anope::string, SASL::Session *>::iterator it = sessions.begin(); it != sessions.end();)
+ for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end(); it++)
delete it->second;
}
@@ -163,14 +134,14 @@ class SASLService : public SASL::Service, public Timer
}
}
- SASL::Session* &session = sessions[m.source];
+ Session* &session = sessions[m.source];
if (m.type == "S")
{
- ServiceReference<SASL::Mechanism> mech("SASL::Mechanism", m.data);
+ ServiceReference<Mechanism> mech("SASL::Mechanism", m.data);
if (!mech)
{
- SASL::Session tmp(NULL, m.source);
+ Session tmp(NULL, m.source);
sasl->SendMechs(&tmp);
sasl->Fail(&tmp);
@@ -200,15 +171,34 @@ class SASLService : public SASL::Service, public Timer
return agent;
}
- SASL::Session* GetSession(const Anope::string &uid) anope_override
+ Session* GetSession(const Anope::string &uid) anope_override
{
- std::map<Anope::string, SASL::Session *>::iterator it = sessions.find(uid);
+ std::map<Anope::string, Session *>::iterator it = sessions.find(uid);
if (it != sessions.end())
return it->second;
return NULL;
}
- void SendMessage(SASL::Session *session, const Anope::string &mtype, const Anope::string &data) anope_override
+ void RemoveSession(Session *sess) anope_override
+ {
+ sessions.erase(sess->uid);
+ }
+
+ void DeleteSessions(Mechanism *mech, bool da) anope_override
+ {
+ for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end();)
+ {
+ std::map<Anope::string, Session *>::iterator del = it++;
+ if (*del->second->mech == mech)
+ {
+ if (da)
+ this->SendMessage(del->second, "D", "A");
+ delete del->second;
+ }
+ }
+ }
+
+ void SendMessage(Session *session, const Anope::string &mtype, const Anope::string &data) anope_override
{
SASL::Message msg;
msg.source = this->GetAgent();
@@ -219,18 +209,18 @@ class SASLService : public SASL::Service, public Timer
IRCD->SendSASLMessage(msg);
}
- void Succeed(SASL::Session *session, NickCore *nc) anope_override
+ void Succeed(Session *session, NickCore *nc) anope_override
{
IRCD->SendSVSLogin(session->uid, nc->display);
this->SendMessage(session, "D", "S");
}
- void Fail(SASL::Session *session) anope_override
+ void Fail(Session *session) anope_override
{
this->SendMessage(session, "D", "F");
}
- void SendMechs(SASL::Session *session) anope_override
+ void SendMechs(Session *session) anope_override
{
std::vector<Anope::string> mechs = Service::GetServiceKeys("SASL::Mechanism");
Anope::string buf;
@@ -242,10 +232,10 @@ class SASLService : public SASL::Service, public Timer
void Tick(time_t) anope_override
{
- for (std::map<Anope::string, SASL::Session *>::iterator it = sessions.begin(); it != sessions.end();)
+ for (std::map<Anope::string, Session *>::iterator it = sessions.begin(); it != sessions.end();)
{
Anope::string key = it->first;
- SASL::Session *s = it->second;
+ Session *s = it->second;
++it;
if (!s || !s->mech || s->created + 60 < Anope::CurTime)
diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp
index e9ea89673..a0c10be83 100644
--- a/modules/protocol/charybdis.cpp
+++ b/modules/protocol/charybdis.cpp
@@ -188,7 +188,7 @@ struct IRCDMessageEncap : IRCDMessage
*
* Charybdis only accepts messages from SASL agents; these must have umode +S
*/
- if (params[1] == "SASL" && sasl && params.size() >= 6)
+ if (params[1] == "SASL" && SASL::sasl && params.size() >= 6)
{
SASL::Message m;
m.source = params[2];
@@ -197,7 +197,7 @@ struct IRCDMessageEncap : IRCDMessage
m.data = params[5];
m.ext = params.size() > 6 ? params[6] : "";
- sasl->ProcessMessage(m);
+ SASL::sasl->ProcessMessage(m);
}
}
};
diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp
index e64079dca..eded20306 100644
--- a/modules/protocol/inspircd12.cpp
+++ b/modules/protocol/inspircd12.cpp
@@ -873,7 +873,7 @@ struct IRCDMessageEncap : IRCDMessage
if (Anope::Match(Me->GetSID(), params[0]) == false)
return;
- if (sasl && params[1] == "SASL" && params.size() >= 6)
+ if (SASL::sasl && params[1] == "SASL" && params.size() >= 6)
{
SASL::Message m;
m.source = params[2];
@@ -882,7 +882,7 @@ struct IRCDMessageEncap : IRCDMessage
m.data = params[5];
m.ext = params.size() > 6 ? params[6] : "";
- sasl->ProcessMessage(m);
+ SASL::sasl->ProcessMessage(m);
}
}
};
@@ -1283,7 +1283,7 @@ struct IRCDMessageUID : IRCDMessage
modes += " " + params[i];
NickAlias *na = NULL;
- if (sasl)
+ if (SASL::sasl)
for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();)
{
SASLUser &u = *it;
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index e0f051aa6..f0d01ce9d 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -889,7 +889,7 @@ struct IRCDMessageSASL : IRCDMessage
void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
size_t p = params[1].find('!');
- if (!sasl || p == Anope::string::npos)
+ if (!SASL::sasl || p == Anope::string::npos)
return;
SASL::Message m;
@@ -899,7 +899,7 @@ struct IRCDMessageSASL : IRCDMessage
m.data = params[3];
m.ext = params.size() > 4 ? params[4] : "";
- sasl->ProcessMessage(m);
+ SASL::sasl->ProcessMessage(m);
}
};
diff --git a/src/base64.cpp b/src/base64.cpp
index 420290a34..d4d9ff43e 100644
--- a/src/base64.cpp
+++ b/src/base64.cpp
@@ -159,7 +159,7 @@ void Anope::B64Decode(const Anope::string &src, Anope::string &target)
state = 0;
}
}
- if (!target[target.length() - 1])
+ if (!target.empty() && !target[target.length() - 1])
target.erase(target.length() - 1);
}