summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-04-03 18:07:58 -0400
committerAdam <Adam@anope.org>2011-04-03 18:07:58 -0400
commit905207093b89a3c71ee3732d051555870c4d39f5 (patch)
treef940bf01272cae4a118a30e0701200e0f55a68fd
parentd1328d876a988329b3bdeb94999cfd696e6aa7a5 (diff)
Made LDAP support recover, release, resetpass, etc.
-rw-r--r--data/example.conf77
-rw-r--r--include/extern.h1
-rw-r--r--include/modules.h15
-rw-r--r--modules/core/enc_md5.cpp28
-rw-r--r--modules/core/enc_none.cpp28
-rw-r--r--modules/core/enc_old.cpp28
-rw-r--r--modules/core/enc_sha1.cpp29
-rw-r--r--modules/core/enc_sha256.cpp31
-rw-r--r--modules/core/ns_ghost.cpp56
-rw-r--r--modules/core/ns_group.cpp23
-rw-r--r--modules/core/ns_identify.cpp24
-rw-r--r--modules/core/ns_recover.cpp18
-rw-r--r--modules/core/ns_release.cpp17
-rw-r--r--modules/extra/m_ldap_authentication.cpp (renamed from modules/extra/ns_identify_ldap.cpp)154
-rw-r--r--modules/extra/m_xmlrpc_main.cpp15
-rw-r--r--src/encrypt.cpp23
16 files changed, 319 insertions, 248 deletions
diff --git a/data/example.conf b/data/example.conf
index a677e3067..f05969403 100644
--- a/data/example.conf
+++ b/data/example.conf
@@ -2024,7 +2024,7 @@ m_helpchan
/*
* m_ldap
*
- * This module allows other modules to use LDAP.
+ * This module allows other modules to use LDAP. By itself, this module does nothing useful.
*/
#module { name = "m_ldap" }
ldap
@@ -2034,10 +2034,47 @@ ldap
}
/*
+ * m_ldap_authentication
+ *
+ * This module allows many commands such as IDENTIFY, RELEASE, RECOVER, GHOST, etc. use
+ * LDAP to authenticate users. Requires m_ldap.
+*/
+#module { name = "m_ldap_authentication" }
+m_ldap_authentication
+{
+ /*
+ * The distinguished name we should bind to when a user tries to identify.
+ */
+ binddn = "ou=users,dc=anope,dc=org"
+
+ /*
+ * The attribute value used for account names.
+ */
+ username_attribute = "uid"
+
+ /*
+ * The attribute value used for email addresses.
+ * This directive is optional.
+ */
+ email_attribute = "email"
+
+ /*
+ * Enable to have this module disable /nickserv register.
+ */
+ disable_ns_register = true
+
+ /*
+ * The reason to give the users who try to /ns register.
+ */
+ disable_reason = "Registration has been disabled."
+ #disable_reason = "To register on this network visit http://some.misconfigured.site/register"
+}
+
+/*
* m_ldap_oper
*
* This module dynamically ties users to Anope opertypes when they identify
- * via LDAP group membership.
+ * via LDAP group membership. Requires m_ldap.
*
* Note that this doesn't give the user privileges on the IRCd, only in Services.
*/
@@ -2129,42 +2166,6 @@ m_xmlrpc
#module { name = "m_xmlrpc_main" }
/*
- * ns_identify_ldap
- *
- * Allows you to use a LDAP server for authentication of users.
- */
-#module { name = "ns_identify_ldap" }
-ns_identify_ldap
-{
- /*
- * The distinguished name we should bind to when a user tries to identify.
- */
- binddn = "ou=users,dc=anope,dc=org"
-
- /*
- * The attribute value used for account names.
- */
- username_attribute = "uid"
-
- /*
- * The attribute value used for email addresses.
- * This directive is optional.
- */
- email_attribute = "email"
-
- /*
- * Enable to have this module disable /nickserv register.
- */
- disable_ns_register = true
-
- /*
- * The reason to give the users who try to /ns register.
- */
- disable_reason = "Registration has been disabled."
- #disable_reason = "To register on this network visit http://some.misconfigured.site/register"
-}
-
-/*
* ns_maxemail
*
* Limits how many times the same email address may be used in Anope
diff --git a/include/extern.h b/include/extern.h
index 8c351eecf..0b29c0d03 100644
--- a/include/extern.h
+++ b/include/extern.h
@@ -118,7 +118,6 @@ E void HostServSyncVhosts(NickAlias *na);
/**** encrypt.c ****/
E int enc_encrypt(const Anope::string &src, Anope::string &dest);
E int enc_decrypt(const Anope::string &src, Anope::string &dest);
-E int enc_check_password(Anope::string &plaintext, Anope::string &password);
/**** hostserv.c ****/
E void get_hostserv_stats(long *nrec, long *memuse);
diff --git a/include/modules.h b/include/modules.h
index 0918a67f8..51a550316 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -404,7 +404,6 @@ class CoreExport Module : public Extensible
*/
virtual EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) { return EVENT_CONTINUE; }
virtual EventReturn OnDecrypt(const Anope::string &hashm, const Anope::string &src, Anope::string &dest) { return EVENT_CONTINUE; }
- virtual EventReturn OnCheckPassword(const Anope::string &hashm, Anope::string &plaintext, Anope::string &password) { return EVENT_CONTINUE; }
/** Called on fantasy command
* @param command The command
@@ -923,6 +922,16 @@ class CoreExport Module : public Extensible
*/
virtual void OnFindCore(const Anope::string &nick) { }
+ /** Check whether a users password is correct.
+ * @param u The user
+ * @param command The command the user is doing
+ * @param params Command params
+ * @param account The account the password should be checked against
+ * @param password The password
+ * @return EVENT_ALLOW to allow the password, EVENT_STOP to stop processing completely
+ */
+ virtual EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password) { return EVENT_CONTINUE; }
+
/** Called when we get informed about a users SSL fingerprint
* when we call this, the fingerprint should already be stored in the user struct
* @param u pointer to the user
@@ -1077,7 +1086,7 @@ enum Implementation
I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay,
I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess,
I_OnNickClearCert, I_OnNickAddCert, I_OnNickEraseCert,
- I_OnNickInfo, I_OnFindNick, I_OnFindCore,
+ I_OnNickInfo, I_OnFindNick, I_OnFindCore, I_OnCheckAuthentication,
/* ChanServ */
I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd, I_OnAccessChange,
@@ -1115,7 +1124,7 @@ enum Implementation
I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect, I_OnPreCommandRun,
I_OnPreCommand, I_OnPostCommand, I_OnPreDatabaseExpire, I_OnPreRestart, I_OnRestart, I_OnPreShutdown, I_OnShutdown, I_OnSignal,
I_OnServerQuit, I_OnTopicUpdated,
- I_OnEncrypt, I_OnEncryptCheckLen, I_OnDecrypt, I_OnCheckPassword,
+ I_OnEncrypt, I_OnDecrypt,
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnObjectDestroy,
I_END
diff --git a/modules/core/enc_md5.cpp b/modules/core/enc_md5.cpp
index a57ed86ad..0cf38e4fb 100644
--- a/modules/core/enc_md5.cpp
+++ b/modules/core/enc_md5.cpp
@@ -320,9 +320,8 @@ class EMD5 : public Module
this->SetAuthor("Anope");
this->SetType(ENCRYPTION);
- ModuleManager::Attach(I_OnEncrypt, this);
- ModuleManager::Attach(I_OnDecrypt, this);
- ModuleManager::Attach(I_OnCheckPassword, this);
+ Implementation i[] = { I_OnEncrypt, I_OnDecrypt, I_OnCheckAuthentication };
+ ModuleManager::Attach(i, this, 3);
}
EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest)
@@ -348,22 +347,33 @@ class EMD5 : public Module
return EVENT_STOP;
}
- EventReturn OnCheckPassword(const Anope::string &hashm, Anope::string &plaintext, Anope::string &password)
+ EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
- if (!hashm.equals_cs("md5"))
+ NickAlias *na = findnick(account);
+ NickCore *nc = na ? na->nc : NULL;
+ if (na == NULL)
+ return EVENT_CONTINUE;
+
+ size_t pos = nc->pass.find(':');
+ if (pos == Anope::string::npos)
+ return EVENT_CONTINUE;
+ Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ if (!hash_method.equals_cs("md5"))
return EVENT_CONTINUE;
+
Anope::string buf;
- this->OnEncrypt(plaintext, buf);
- if (password.equals_cs(buf))
+ this->OnEncrypt(password, buf);
+ if (nc->pass.equals_cs(buf))
{
/* if we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
*/
if (!this->name.equals_ci(Config->EncModuleList.front()))
- enc_encrypt(plaintext, password);
+ enc_encrypt(password, nc->pass);
return EVENT_ALLOW;
}
- return EVENT_STOP;
+
+ return EVENT_CONTINUE;
}
};
diff --git a/modules/core/enc_none.cpp b/modules/core/enc_none.cpp
index 79c047c3f..c1b403235 100644
--- a/modules/core/enc_none.cpp
+++ b/modules/core/enc_none.cpp
@@ -17,9 +17,8 @@ class ENone : public Module
this->SetAuthor("Anope");
this->SetType(ENCRYPTION);
- ModuleManager::Attach(I_OnEncrypt, this);
- ModuleManager::Attach(I_OnDecrypt, this);
- ModuleManager::Attach(I_OnCheckPassword, this);
+ Implementation i[] = { I_OnEncrypt, I_OnDecrypt, I_OnCheckAuthentication };
+ ModuleManager::Attach(i, this, 3);
}
EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest)
@@ -43,22 +42,33 @@ class ENone : public Module
return EVENT_ALLOW;
}
- EventReturn OnCheckPassword(const Anope::string &hashm, Anope::string &plaintext, Anope::string &password)
+ EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
- if (!hashm.equals_cs("plain"))
+ NickAlias *na = findnick(account);
+ NickCore *nc = na ? na->nc : NULL;
+ if (na == NULL)
+ return EVENT_CONTINUE;
+
+ size_t pos = nc->pass.find(':');
+ if (pos == Anope::string::npos)
return EVENT_CONTINUE;
+ Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ if (!hash_method.equals_cs("plain"))
+ return EVENT_CONTINUE;
+
Anope::string buf;
- this->OnEncrypt(plaintext, buf);
- if (password.equals_cs(buf))
+ this->OnEncrypt(password, buf);
+ if (nc->pass.equals_cs(buf))
{
/* if we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
*/
if (!this->name.equals_ci(Config->EncModuleList.front()))
- enc_encrypt(plaintext, password);
+ enc_encrypt(password, nc->pass);
return EVENT_ALLOW;
}
- return EVENT_STOP;
+
+ return EVENT_CONTINUE;
}
};
diff --git a/modules/core/enc_old.cpp b/modules/core/enc_old.cpp
index 52ba4734c..5fb863110 100644
--- a/modules/core/enc_old.cpp
+++ b/modules/core/enc_old.cpp
@@ -325,9 +325,8 @@ class EOld : public Module
this->SetAuthor("Anope");
this->SetType(ENCRYPTION);
- ModuleManager::Attach(I_OnEncrypt, this);
- ModuleManager::Attach(I_OnDecrypt, this);
- ModuleManager::Attach(I_OnCheckPassword, this);
+ Implementation i[] = { I_OnEncrypt, I_OnDecrypt, I_OnCheckAuthentication };
+ ModuleManager::Attach(i, this, 3);
}
EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest)
@@ -358,22 +357,33 @@ class EOld : public Module
return EVENT_STOP;
}
- EventReturn OnCheckPassword(const Anope::string &hashm, Anope::string &plaintext, Anope::string &password)
+ EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
- if (!hashm.equals_cs("oldmd5"))
+ NickAlias *na = findnick(account);
+ NickCore *nc = na ? na->nc : NULL;
+ if (na == NULL)
+ return EVENT_CONTINUE;
+
+ size_t pos = nc->pass.find(':');
+ if (pos == Anope::string::npos)
+ return EVENT_CONTINUE;
+ Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ if (!hash_method.equals_cs("oldmd5"))
return EVENT_CONTINUE;
+
Anope::string buf;
- this->OnEncrypt(plaintext, buf);
- if (password.equals_cs(buf))
+ this->OnEncrypt(password, buf);
+ if (nc->pass.equals_cs(buf))
{
/* if we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
*/
if (!this->name.equals_ci(Config->EncModuleList.front()))
- enc_encrypt(plaintext, password);
+ enc_encrypt(password, nc->pass);
return EVENT_ALLOW;
}
- return EVENT_STOP;
+
+ return EVENT_CONTINUE;
}
};
diff --git a/modules/core/enc_sha1.cpp b/modules/core/enc_sha1.cpp
index 8dc3b57ab..8ec387d0d 100644
--- a/modules/core/enc_sha1.cpp
+++ b/modules/core/enc_sha1.cpp
@@ -173,10 +173,8 @@ class ESHA1 : public Module
this->SetAuthor("Anope");
this->SetType(ENCRYPTION);
- ModuleManager::Attach(I_OnEncrypt, this);
- ModuleManager::Attach(I_OnEncryptCheckLen, this);
- ModuleManager::Attach(I_OnDecrypt, this);
- ModuleManager::Attach(I_OnCheckPassword, this);
+ Implementation i[] = { I_OnEncrypt, I_OnDecrypt, I_OnCheckAuthentication };
+ ModuleManager::Attach(i, this, 3);
}
EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest)
@@ -202,22 +200,33 @@ class ESHA1 : public Module
return EVENT_STOP;
}
- EventReturn OnCheckPassword(const Anope::string &hashm, Anope::string &plaintext, Anope::string &password)
+ EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
- if (!hashm.equals_cs("sha1"))
+ NickAlias *na = findnick(account);
+ NickCore *nc = na ? na->nc : NULL;
+ if (na == NULL)
+ return EVENT_CONTINUE;
+
+ size_t pos = nc->pass.find(':');
+ if (pos == Anope::string::npos)
+ return EVENT_CONTINUE;
+ Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ if (!hash_method.equals_cs("sha1"))
return EVENT_CONTINUE;
+
Anope::string buf;
- this->OnEncrypt(plaintext, buf);
- if (password.equals_cs(buf))
+ this->OnEncrypt(password, buf);
+ if (nc->pass.equals_cs(buf))
{
/* when we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
*/
if (!this->name.equals_ci(Config->EncModuleList.front()))
- enc_encrypt(plaintext, password);
+ enc_encrypt(password, nc->pass);
return EVENT_ALLOW;
}
- return EVENT_STOP;
+
+ return EVENT_CONTINUE;
}
};
diff --git a/modules/core/enc_sha256.cpp b/modules/core/enc_sha256.cpp
index 45fc3433c..06154ada0 100644
--- a/modules/core/enc_sha256.cpp
+++ b/modules/core/enc_sha256.cpp
@@ -252,9 +252,8 @@ class ESHA256 : public Module
this->SetAuthor("Anope");
this->SetType(ENCRYPTION);
- ModuleManager::Attach(I_OnEncrypt, this);
- ModuleManager::Attach(I_OnDecrypt, this);
- ModuleManager::Attach(I_OnCheckPassword, this);
+ Implementation i[] = { I_OnEncrypt, I_OnDecrypt, I_OnCheckAuthentication };
+ ModuleManager::Attach(i, this, 3);
use_iv = false;
}
@@ -287,26 +286,36 @@ class ESHA256 : public Module
return EVENT_STOP;
}
- EventReturn OnCheckPassword(const Anope::string &hashm, Anope::string &plaintext, Anope::string &password)
+ EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
{
- if (!hashm.equals_cs("sha256"))
+ NickAlias *na = findnick(account);
+ NickCore *nc = na ? na->nc : NULL;
+ if (na == NULL)
+ return EVENT_CONTINUE;
+
+ size_t pos = nc->pass.find(':');
+ if (pos == Anope::string::npos)
+ return EVENT_CONTINUE;
+ Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos);
+ if (!hash_method.equals_cs("sha256"))
return EVENT_CONTINUE;
- Anope::string buf;
- GetIVFromPass(password);
+ GetIVFromPass(nc->pass);
use_iv = true;
- this->OnEncrypt(plaintext, buf);
+ Anope::string buf;
+ this->OnEncrypt(password, buf);
- if (password.equals_cs(buf))
+ if (nc->pass.equals_cs(buf))
{
/* if we are NOT the first module in the list,
* we want to re-encrypt the pass with the new encryption
*/
if (!this->name.equals_ci(Config->EncModuleList.front()))
- enc_encrypt(plaintext, password);
+ enc_encrypt(password, nc->pass);
return EVENT_ALLOW;
}
- return EVENT_STOP;
+
+ return EVENT_CONTINUE;
}
};
diff --git a/modules/core/ns_ghost.cpp b/modules/core/ns_ghost.cpp
index dbc11e5f6..d8e0faf64 100644
--- a/modules/core/ns_ghost.cpp
+++ b/modules/core/ns_ghost.cpp
@@ -25,7 +25,7 @@ class CommandNSGhost : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params[0];
- Anope::string pass = params.size() > 1 ? params[1] : "";
+ const Anope::string &pass = params.size() > 1 ? params[1] : "";
User *u = source.u;
User *user = finduser(nick);
@@ -41,28 +41,46 @@ class CommandNSGhost : public Command
source.Reply(_(NICK_X_SUSPENDED), na->nick.c_str());
else if (nick.equals_ci(u->nick))
source.Reply(_("You can't ghost yourself!"));
- else if ((u->Account() == na->nc || (!na->nc->HasFlag(NI_SECURE) && is_on_access(u, na->nc))) ||
- (!pass.empty() && enc_check_password(pass, na->nc->pass) == 1) ||
- (!u->fingerprint.empty() && na->nc->FindCert(u->fingerprint)))
+ else
{
- if (!user->IsIdentified() && FindCommand(NickServ, "RECOVER"))
- source.Reply(_("You may not ghost an unidentified user, use RECOVER instead."));
- else
+ bool ok = false;
+ if (u->Account() == na->nc)
+ ok = true;
+ else if (!na->nc->HasFlag(NI_SECURE) && is_on_access(u, na->nc))
+ ok = true;
+ else if (!u->fingerprint.empty() && na->nc->FindCert(u->fingerprint))
+ ok = true;
+ else if (!pass.empty())
{
- Log(LOG_COMMAND, u, this) << "for " << nick;
- Anope::string buf = "GHOST command used by " + u->nick;
- kill_user(Config->s_NickServ, user, buf);
- source.Reply(_("Ghost with your nick has been killed."), nick.c_str());
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(u, this, params, na->nc->display, pass));
+ if (MOD_RESULT == EVENT_STOP)
+ return MOD_CONT;
+ else if (MOD_RESULT == EVENT_ALLOW)
+ ok = true;
}
- }
- else
- {
- source.Reply(_(ACCESS_DENIED));
- if (!pass.empty())
+
+ if (ok)
+ {
+ if (!user->IsIdentified() && FindCommand(NickServ, "RECOVER"))
+ source.Reply(_("You may not ghost an unidentified user, use RECOVER instead."));
+ else
+ {
+ Log(LOG_COMMAND, u, this) << "for " << nick;
+ Anope::string buf = "GHOST command used by " + u->nick;
+ kill_user(Config->s_NickServ, user, buf);
+ source.Reply(_("Ghost with your nick has been killed."), nick.c_str());
+ }
+ }
+ else
{
- Log(LOG_COMMAND, u, this) << "with an invalid password for " << nick;
- if (bad_password(u))
- return MOD_STOP;
+ source.Reply(_(ACCESS_DENIED));
+ if (!pass.empty())
+ {
+ Log(LOG_COMMAND, u, this) << "with an invalid password for " << nick;
+ if (bad_password(u))
+ return MOD_STOP;
+ }
}
}
diff --git a/modules/core/ns_group.cpp b/modules/core/ns_group.cpp
index 4b0fda4c4..463d36be6 100644
--- a/modules/core/ns_group.cpp
+++ b/modules/core/ns_group.cpp
@@ -27,7 +27,7 @@ class CommandNSGroup : public Command
User *u = source.u;
const Anope::string &nick = params[0];
- Anope::string pass = params.size() > 1 ? params[1] : "";
+ const Anope::string &pass = params.size() > 1 ? params[1] : "";
if (readonly)
{
@@ -82,8 +82,19 @@ class CommandNSGroup : public Command
"for more information."), target->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
else
{
- if ((!pass.empty() && enc_check_password(pass, target->nc->pass)) ||
- (!u->fingerprint.empty() && target->nc->FindCert(u->fingerprint)))
+ bool ok = false;
+ if (!u->fingerprint.empty() && target->nc->FindCert(u->fingerprint))
+ ok = true;
+ else if (!pass.empty())
+ {
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(u, this, params, target->nc->display, pass));
+ if (MOD_RESULT == EVENT_STOP)
+ return MOD_CONT;
+ else if (MOD_RESULT == EVENT_ALLOW)
+ ok = true;
+ }
+ if (ok)
{
/* If the nick is already registered, drop it.
* If not, check that it is valid.
@@ -122,13 +133,9 @@ class CommandNSGroup : public Command
check_memos(u);
}
- else if (pass.empty())
- {
- this->OnSyntaxError(source, "");
- }
else
{
- Log(LOG_COMMAND, u, this) << "failed group for " << target->nick << " (invalid password)";
+ Log(LOG_COMMAND, u, this) << "failed group for " << target->nick;
source.Reply(_(PASSWORD_INCORRECT));
if (bad_password(u))
return MOD_STOP;
diff --git a/modules/core/ns_identify.cpp b/modules/core/ns_identify.cpp
index 742fe986a..15f2ade94 100644
--- a/modules/core/ns_identify.cpp
+++ b/modules/core/ns_identify.cpp
@@ -30,30 +30,28 @@ class CommandNSIdentify : public Command
Anope::string pass = params[params.size() - 1];
NickAlias *na = findnick(nick);
- if (!na)
- source.Reply(_(NICK_NOT_REGISTERED));
- else if (na->HasFlag(NS_FORBIDDEN))
+ if (na && na->HasFlag(NS_FORBIDDEN))
source.Reply(_(NICK_X_FORBIDDEN), na->nick.c_str());
- else if (na->nc->HasFlag(NI_SUSPENDED))
+ else if (na && na->nc->HasFlag(NI_SUSPENDED))
source.Reply(_(NICK_X_SUSPENDED), na->nick.c_str());
- /* You can now identify for other nicks without logging out first,
- * however you can not identify again for the group you're already
- * identified as
- */
- else if (u->Account() && u->Account() == na->nc)
+ else if (u->Account() && na && u->Account() == na->nc)
source.Reply(_("You are already identified."));
else
{
- int res = enc_check_password(pass, na->nc->pass);
- if (!res)
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(u, this, params, nick, pass));
+ if (MOD_RESULT == EVENT_STOP)
+ return MOD_CONT;
+
+ if (!na)
+ source.Reply(_(NICK_X_NOT_REGISTERED), nick.c_str());
+ else if (MOD_RESULT != EVENT_ALLOW)
{
Log(LOG_COMMAND, u, this) << "and failed to identify";
source.Reply(_(PASSWORD_INCORRECT));
if (bad_password(u))
return MOD_STOP;
}
- else if (res == -1)
- source.Reply(_("Sorry, identification failed."));
else
{
if (u->IsIdentified())
diff --git a/modules/core/ns_recover.cpp b/modules/core/ns_recover.cpp
index 416b0e184..d78955f51 100644
--- a/modules/core/ns_recover.cpp
+++ b/modules/core/ns_recover.cpp
@@ -27,7 +27,7 @@ class CommandNSRecover : public Command
User *u = source.u;
const Anope::string &nick = params[0];
- Anope::string pass = params.size() > 1 ? params[1] : "";
+ const Anope::string &pass = params.size() > 1 ? params[1] : "";
NickAlias *na;
User *u2;
@@ -43,9 +43,12 @@ class CommandNSRecover : public Command
source.Reply(_("You can't recover yourself!"));
else if (!pass.empty())
{
- int res = enc_check_password(pass, na->nc->pass);
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(u, this, params, na->nc->display, pass));
+ if (MOD_RESULT == EVENT_STOP)
+ return MOD_CONT;
- if (res == 1)
+ if (MOD_RESULT == EVENT_ALLOW)
{
u2->SendMessage(NickServ, _(FORCENICKCHANGE_NOW));
u2->Collide(na);
@@ -58,12 +61,9 @@ class CommandNSRecover : public Command
else
{
source.Reply(_(ACCESS_DENIED));
- if (!res)
- {
- Log(LOG_COMMAND, u, this) << "with invalid password for " << nick;
- if (bad_password(u))
- return MOD_STOP;
- }
+ Log(LOG_COMMAND, u, this) << "with invalid password for " << nick;
+ if (bad_password(u))
+ return MOD_STOP;
}
}
else
diff --git a/modules/core/ns_release.cpp b/modules/core/ns_release.cpp
index 94a778218..94126eef8 100644
--- a/modules/core/ns_release.cpp
+++ b/modules/core/ns_release.cpp
@@ -39,8 +39,12 @@ class CommandNSRelease : public Command
source.Reply(_("Nick \002%s\002 isn't being held."), nick.c_str());
else if (!pass.empty())
{
- int res = enc_check_password(pass, na->nc->pass);
- if (res == 1)
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(u, this, params, na->nc->display, pass));
+ if (MOD_RESULT == EVENT_STOP)
+ return MOD_CONT;
+
+ if (MOD_RESULT == EVENT_ALLOW)
{
Log(LOG_COMMAND, u, this) << "released " << na->nick;
na->Release();
@@ -49,12 +53,9 @@ class CommandNSRelease : public Command
else
{
source.Reply(_(ACCESS_DENIED));
- if (!res)
- {
- Log(LOG_COMMAND, u, this) << "invalid password for " << nick;
- if (bad_password(u))
- return MOD_STOP;
- }
+ Log(LOG_COMMAND, u, this) << "invalid password for " << nick;
+ if (bad_password(u))
+ return MOD_STOP;
}
}
else
diff --git a/modules/extra/ns_identify_ldap.cpp b/modules/extra/m_ldap_authentication.cpp
index 8a65c5438..fa60247e5 100644
--- a/modules/extra/ns_identify_ldap.cpp
+++ b/modules/extra/m_ldap_authentication.cpp
@@ -6,24 +6,21 @@ static Anope::string email_attribute;
struct IdentifyInfo
{
dynamic_reference<User> user;
+ dynamic_reference<Command> command;
+ std::vector<Anope::string> params;
Anope::string account;
Anope::string pass;
- IdentifyInfo(User *u, const Anope::string &a, const Anope::string &p) : user(u), account(a), pass(p) { }
+ IdentifyInfo(User *u, Command *c, const std::vector<Anope::string> &pa, const Anope::string &a, const Anope::string &p) : user(u), command(c), params(pa), account(a), pass(p) { }
};
-class IdentifyInterface : public LDAPInterface, public Command
+class IdentifyInterface : public LDAPInterface
{
std::map<LDAPQuery, IdentifyInfo *> requests;
public:
- IdentifyInterface(Module *m) : LDAPInterface(m), Command("IDENTIFY", 0, 0)
- {
- this->service = NickServ;
- }
-
- CommandReturn Execute(CommandSource &, const std::vector<Anope::string> &) { return MOD_STOP; }
+ IdentifyInterface(Module *m) : LDAPInterface(m) { }
void Add(LDAPQuery id, IdentifyInfo *ii)
{
@@ -41,28 +38,34 @@ class IdentifyInterface : public LDAPInterface, public Command
IdentifyInfo *ii = it->second;
this->requests.erase(it);
+ if (!ii->user || !ii->command)
+ {
+ delete this;
+ return;
+ }
+
User *u = *ii->user;
- NickAlias *na = findnick(ii->account);
+ Command *c = *ii->command;
+
+ u->Extend("m_ldap_authentication_authenticated");
- if (!na)
+ NickAlias *na = findnick(ii->account);
+ if (na == NULL)
{
na = new NickAlias(ii->account, new NickCore(ii->account));
- enc_encrypt(ii->pass, na->nc->pass);
-
- Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
- na->last_usermask = last_usermask;
- na->last_realname = u->realname;
if (Config->NSAddAccessOnReg)
na->nc->AddAccess(create_mask(u));
- u->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), ii->account.c_str());
+ u->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
}
- if (u->Account())
- Log(LOG_COMMAND, u, this) << "to log out of account " << u->Account()->display;
- Log(LOG_COMMAND, u, this) << "and identified for account " << na->nc->display << " using LDAP";
- u->SendMessage(NickServ, _("Password accepted - you are now recognized."));
- u->Identify(na);
+ enc_encrypt(ii->pass, na->nc->pass);
+
+ Anope::string params;
+ for (unsigned i = 0; i < ii->params.size(); ++i)
+ params += ii->params[i] + " ";
+ mod_run_cmd(c->service, u, NULL, c, c->name, params);
+
delete ii;
}
@@ -74,17 +77,22 @@ class IdentifyInterface : public LDAPInterface, public Command
IdentifyInfo *ii = it->second;
this->requests.erase(it);
- if (!ii->user)
+ if (!ii->user || !ii->command)
{
- delete this;
+ delete ii;
return;
}
User *u = *ii->user;
+ Command *c = *ii->command;
+
+ u->Extend("m_ldap_authentication_error");
+
+ Anope::string params;
+ for (unsigned i = 0; i < ii->params.size(); ++i)
+ params += ii->params[i] + " ";
+ mod_run_cmd(c->service, u, NULL, c, c->name, params);
- Log(LOG_COMMAND, u, this) << "and failed to identify for account " << ii->account << ". LDAP error: " << r.getError();
- u->SendMessage(NickServ, _(PASSWORD_INCORRECT));
- bad_password(u);
delete ii;
}
};
@@ -121,19 +129,19 @@ class OnIdentifyInterface : public LDAPInterface
{
u->Account()->email = email;
u->SendMessage(NickServ, _("Your email has been updated to \002%s\002"), email.c_str());
- Log() << "ns_identify_ldap: Updated email address for " << u->nick << " (" << u->Account()->display << ") to " << email;
+ Log() << "m_ldap_authentication: Updated email address for " << u->nick << " (" << u->Account()->display << ") to " << email;
}
}
catch (const LDAPException &ex)
{
- Log() << "ns_identify_ldap: " << ex.GetReason();
+ Log() << "m_ldap_authentication: " << ex.GetReason();
}
}
void OnError(const LDAPResult &r)
{
this->requests.erase(r.id);
- Log() << "ns_identify_ldap: " << r.error;
+ Log() << "m_ldap_authentication: " << r.error;
}
};
@@ -154,8 +162,9 @@ class NSIdentifyLDAP : public Module
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- Implementation i[] = { I_OnReload, I_OnPreCommand, I_OnNickIdentify };
- ModuleManager::Attach(i, this, 3);
+ Implementation i[] = { I_OnReload, I_OnPreCommand, I_OnCheckAuthentication, I_OnNickIdentify };
+ ModuleManager::Attach(i, this, 4);
+ ModuleManager::SetPriority(this, PRIORITY_FIRST);
OnReload(false);
}
@@ -164,57 +173,56 @@ class NSIdentifyLDAP : public Module
{
ConfigReader config;
- this->binddn = config.ReadValue("ns_identify_ldap", "binddn", "", 0);
- this->username_attribute = config.ReadValue("ns_identify_ldap", "username_attribute", "", 0);
- email_attribute = config.ReadValue("ns_identify_ldap", "email_attribute", "", 0);
- this->disable_register = config.ReadFlag("ns_identify_ldap", "disable_ns_register", "false", 0);
- this->disable_reason = config.ReadValue("ns_identify_ldap", "disable_reason", "", 0);
+ this->binddn = config.ReadValue("m_ldap_authentication", "binddn", "", 0);
+ this->username_attribute = config.ReadValue("m_ldap_authentication", "username_attribute", "", 0);
+ email_attribute = config.ReadValue("m_ldap_authentication", "email_attribute", "", 0);
+ this->disable_register = config.ReadFlag("m_ldap_authentication", "disable_ns_register", "false", 0);
+ this->disable_reason = config.ReadValue("m_ldap_authentication", "disable_reason", "", 0);
}
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
- if (command->service == NickServ)
+ if (this->disable_register && command->service == NickServ && command->name == "REGISTER")
{
- if (this->disable_register && command->name == "REGISTER")
- {
- source.Reply(_(this->disable_reason.c_str()));
- return EVENT_STOP;
- }
- else if (command->name == "IDENTIFY" && !params.empty() && this->ldap)
- {
- Anope::string account = params.size() > 1 ? params[0] : source.u->nick;
- Anope::string pass = params.size() > 1 ? params[1] : params[0];
-
- NickAlias *na = findnick(account);
- if (na)
- {
- account = na->nc->display;
-
- if (na->HasFlag(NS_FORBIDDEN) || na->nc->HasFlag(NI_SUSPENDED) || source.u->Account() == na->nc)
- return EVENT_CONTINUE;
- }
-
- IdentifyInfo *ii = new IdentifyInfo(source.u, account, pass);
- try
- {
- Anope::string full_binddn = this->username_attribute + "=" + account + "," + this->binddn;
- LDAPQuery id = this->ldap->Bind(&this->iinterface, full_binddn, pass);
- this->iinterface.Add(id, ii);
- }
- catch (const LDAPException &ex)
- {
- delete ii;
- Log() << "ns_identify_ldap: " << ex.GetReason();
- return EVENT_CONTINUE;
- }
-
- return EVENT_STOP;
- }
+ source.Reply(_(this->disable_reason.c_str()));
+ return EVENT_STOP;
}
return EVENT_CONTINUE;
}
+ EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> &params, const Anope::string &account, const Anope::string &password)
+ {
+ if (u == NULL || c == NULL || !this->ldap)
+ return EVENT_CONTINUE;
+ else if (u->GetExt("m_ldap_authentication_authenticated"))
+ {
+ u->Shrink("m_ldap_authentication_authenticated");
+ return EVENT_ALLOW;
+ }
+ else if (u->GetExt("m_ldap_authentication_error"))
+ {
+ u->Shrink("m_ldap_authentication_error");
+ return EVENT_CONTINUE;;
+ }
+
+ IdentifyInfo *ii = new IdentifyInfo(u, c, params, account, password);
+ try
+ {
+ Anope::string full_binddn = this->username_attribute + "=" + account + "," + this->binddn;
+ LDAPQuery id = this->ldap->Bind(&this->iinterface, full_binddn, password);
+ this->iinterface.Add(id, ii);
+ }
+ catch (const LDAPException &ex)
+ {
+ delete ii;
+ Log() << "ns_identify_ldap: " << ex.GetReason();
+ return EVENT_CONTINUE;
+ }
+
+ return EVENT_STOP;
+ }
+
void OnNickIdentify(User *u)
{
if (email_attribute.empty() || !this->ldap)
@@ -227,7 +235,7 @@ class NSIdentifyLDAP : public Module
}
catch (const LDAPException &ex)
{
- Log() << "ns_identify_ldap: " << ex.GetReason();
+ Log() << "m_ldap_authentication: " << ex.GetReason();
}
}
};
diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp
index 33cf3818c..593aba6ef 100644
--- a/modules/extra/m_xmlrpc_main.cpp
+++ b/modules/extra/m_xmlrpc_main.cpp
@@ -113,13 +113,18 @@ class MyXMLRPCEvent : public XMLRPCEvent
if (!na)
request->reply("error", "Invalid account");
- else if (enc_check_password(password, na->nc->pass) == 1)
+ else
{
- request->reply("result", "Success");
- request->reply("account", na->nc->display);
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(NULL, NULL, std::vector<Anope::string>(), na->nc->display, password));
+ if (MOD_RESULT == EVENT_ALLOW)
+ {
+ request->reply("result", "Success");
+ request->reply("account", na->nc->display);
+ }
+ else
+ request->reply("error", "Invalid password");
}
- else
- request->reply("error", "Invalid password");
}
}
diff --git a/src/encrypt.cpp b/src/encrypt.cpp
index 8063a6567..2414bf7bc 100644
--- a/src/encrypt.cpp
+++ b/src/encrypt.cpp
@@ -50,26 +50,3 @@ int enc_decrypt(const Anope::string &src, Anope::string &dest)
return -1;
}
-/**
- * Check an input password `plaintext' against a stored, encrypted password
- * `password'. Return value is:
- * 1 if the password matches
- * 0 if the password does not match
- * 0 if an error occurred while checking
- **/
-int enc_check_password(Anope::string &plaintext, Anope::string &password)
-{
- size_t pos = password.find(':');
- if (pos == Anope::string::npos)
- {
- Log() << "Error: enc_check_password() called with invalid password string (" << password << ")";
- return 0;
- }
- Anope::string hashm(password.begin(), password.begin() + pos);
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnCheckPassword, OnCheckPassword(hashm, plaintext, password));
- if (MOD_RESULT == EVENT_ALLOW)
- return 1;
- return 0;
-}