summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-11-16 17:59:06 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-11-16 17:59:06 +0000
commit54fb0cd5aa7d090d5c3da5ab54988c86ba8a2e8e (patch)
treebc20ce6dca41b2d16349ae4c8212861c10e3685e /src/modules
parent3bfd0db65ff01c026e968af4de074cc1155a4061 (diff)
Use ServiceProvider for inter-module dependencies
This will stop dependency chains from preventing module reloads when it is not actually needed; however, it removes some failsafes that will need to be reimplemented in order to avoid unmapped vtables. This deprecates Request as an inter-module signaling mechanism, although SQL still uses it. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12140 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/extra/m_mssql.cpp16
-rw-r--r--src/modules/extra/m_mysql.cpp19
-rw-r--r--src/modules/extra/m_pgsql.cpp16
-rw-r--r--src/modules/extra/m_regex_pcre.cpp36
-rw-r--r--src/modules/extra/m_regex_posix.cpp43
-rw-r--r--src/modules/extra/m_regex_tre.cpp33
-rw-r--r--src/modules/extra/m_sqlite3.cpp14
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp7
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp6
-rw-r--r--src/modules/extra/m_ziplink.cpp3
-rw-r--r--src/modules/m_chanfilter.cpp2
-rw-r--r--src/modules/m_cloaking.cpp50
-rw-r--r--src/modules/m_exemptchanops.cpp6
-rw-r--r--src/modules/m_filter.cpp358
-rw-r--r--src/modules/m_hash.h84
-rw-r--r--src/modules/m_md5.cpp45
-rw-r--r--src/modules/m_password_hash.cpp94
-rw-r--r--src/modules/m_regex.h34
-rw-r--r--src/modules/m_regex_glob.cpp37
-rw-r--r--src/modules/m_ripemd160.cpp39
-rw-r--r--src/modules/m_rline.cpp84
-rw-r--r--src/modules/m_sasl.cpp4
-rw-r--r--src/modules/m_sha256.cpp34
-rw-r--r--src/modules/m_spanningtree/compat.cpp1
-rw-r--r--src/modules/m_spanningtree/hmac.cpp32
-rw-r--r--src/modules/m_spanningtree/main.cpp20
-rw-r--r--src/modules/m_spanningtree/treesocket1.cpp22
-rw-r--r--src/modules/m_sqlauth.cpp29
-rw-r--r--src/modules/m_sqllog.cpp17
-rw-r--r--src/modules/m_sqloper.cpp76
-rw-r--r--src/modules/m_sqlutils.cpp2
-rw-r--r--src/modules/m_sslinfo.cpp6
-rw-r--r--src/modules/m_testclient.cpp5
33 files changed, 410 insertions, 864 deletions
diff --git a/src/modules/extra/m_mssql.cpp b/src/modules/extra/m_mssql.cpp
index 455a4fa47..13f25d4fc 100644
--- a/src/modules/extra/m_mssql.cpp
+++ b/src/modules/extra/m_mssql.cpp
@@ -636,29 +636,23 @@ class ModuleMsSQL : public Module
private:
unsigned long currid;
QueryThread* queryDispatcher;
+ ServiceProvider sqlserv;
public:
ModuleMsSQL()
- : currid(0)
+ : currid(0), sqlserv(this, "SQL/mssql", SERVICE_DATA)
{
LoggingMutex = new Mutex();
ResultsMutex = new Mutex();
- ServerInstance->Modules->UseInterface("SQLutils");
-
- if (!ServerInstance->Modules->PublishFeature("SQL", this))
- {
- throw ModuleException("m_mssql: Unable to publish feature 'SQL'");
- }
-
ReadConf();
queryDispatcher = new QueryThread(this);
ServerInstance->Threads->Start(queryDispatcher);
- ServerInstance->Modules->PublishInterface("SQL", this);
Implementation eventlist[] = { I_OnRehash };
ServerInstance->Modules->Attach(eventlist, this, 1);
+ ServerInstance->Modules->AddService(sqlserv);
}
virtual ~ModuleMsSQL()
@@ -668,10 +662,6 @@ class ModuleMsSQL : public Module
ClearQueue();
ClearAllConnections();
- ServerInstance->Modules->UnpublishInterface("SQL", this);
- ServerInstance->Modules->UnpublishFeature("SQL");
- ServerInstance->Modules->DoneWithInterface("SQLutils");
-
delete LoggingMutex;
delete ResultsMutex;
}
diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp
index 358f5e992..c294befdc 100644
--- a/src/modules/extra/m_mysql.cpp
+++ b/src/modules/extra/m_mysql.cpp
@@ -93,6 +93,7 @@ class ModuleSQL : public Module
Mutex ResultsMutex;
Mutex LoggingMutex;
Mutex ConnMutex;
+ ServiceProvider sqlserv;
ModuleSQL();
~ModuleSQL();
@@ -666,8 +667,6 @@ ConnMap::iterator GetCharId(char id)
return Connections.end();
}
-class ModuleSQL;
-
class DispatcherThread : public SocketThread
{
private:
@@ -679,24 +678,13 @@ class DispatcherThread : public SocketThread
virtual void OnNotify();
};
-ModuleSQL::ModuleSQL() : rehashing(false)
+ModuleSQL::ModuleSQL() : rehashing(false), sqlserv(this, "SQL/mysql", SERVICE_DATA)
{
- ServerInstance->Modules->UseInterface("SQLutils");
-
currid = 0;
Dispatcher = new DispatcherThread(this);
ServerInstance->Threads->Start(Dispatcher);
- if (!ServerInstance->Modules->PublishFeature("SQL", this))
- {
- Dispatcher->join();
- delete Dispatcher;
- ServerInstance->Modules->DoneWithInterface("SQLutils");
- throw ModuleException("m_mysql: Unable to publish feature 'SQL'");
- }
-
- ServerInstance->Modules->PublishInterface("SQL", this);
Implementation eventlist[] = { I_OnRehash };
ServerInstance->Modules->Attach(eventlist, this, 1);
}
@@ -705,9 +693,6 @@ ModuleSQL::~ModuleSQL()
{
delete Dispatcher;
ClearAllConnections();
- ServerInstance->Modules->UnpublishInterface("SQL", this);
- ServerInstance->Modules->UnpublishFeature("SQL");
- ServerInstance->Modules->DoneWithInterface("SQLutils");
}
unsigned long ModuleSQL::NewID()
diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp
index f362125cb..4fb3d3ab6 100644
--- a/src/modules/extra/m_pgsql.cpp
+++ b/src/modules/extra/m_pgsql.cpp
@@ -763,25 +763,18 @@ class ModulePgSQL : public Module
unsigned long currid;
char* sqlsuccess;
ReconnectTimer* retimer;
-
+ ServiceProvider sqlserv;
public:
ModulePgSQL()
- : currid(0)
+ : currid(0), sqlserv(this, "SQL/pgsql", SERVICE_DATA)
{
- ServerInstance->Modules->UseInterface("SQLutils");
-
sqlsuccess = new char[strlen(SQLSUCCESS)+1];
strlcpy(sqlsuccess, SQLSUCCESS, strlen(SQLSUCCESS));
- if (!ServerInstance->Modules->PublishFeature("SQL", this))
- {
- throw ModuleException("BUG: PgSQL Unable to publish feature 'SQL'");
- }
-
ReadConf();
- ServerInstance->Modules->PublishInterface("SQL", this);
+ ServerInstance->Modules->AddService(sqlserv);
Implementation eventlist[] = { I_OnUnloadModule, I_OnRehash };
ServerInstance->Modules->Attach(eventlist, this, 2);
}
@@ -792,9 +785,6 @@ class ModulePgSQL : public Module
ServerInstance->Timers->DelTimer(retimer);
ClearAllConnections();
delete[] sqlsuccess;
- ServerInstance->Modules->UnpublishInterface("SQL", this);
- ServerInstance->Modules->UnpublishFeature("SQL");
- ServerInstance->Modules->DoneWithInterface("SQLutils");
}
diff --git a/src/modules/extra/m_regex_pcre.cpp b/src/modules/extra/m_regex_pcre.cpp
index 9e8aff159..c286162e8 100644
--- a/src/modules/extra/m_regex_pcre.cpp
+++ b/src/modules/extra/m_regex_pcre.cpp
@@ -67,35 +67,27 @@ public:
}
};
-class ModuleRegexPCRE : public Module
+class PCREFactory : public RegexFactory
{
-public:
- ModuleRegexPCRE() {
- ServerInstance->Modules->PublishInterface("RegularExpression", this);
- }
-
- virtual Version GetVersion()
+ public:
+ PCREFactory(Module* m) : RegexFactory(m, "regex/pcre") {}
+ Regex* Create(const std::string& expr)
{
- return Version("Regex Provider Module for PCRE", VF_COMMON | VF_VENDOR);
+ return new PCRERegex(expr);
}
+};
- virtual ~ModuleRegexPCRE()
- {
- ServerInstance->Modules->UnpublishInterface("RegularExpression", this);
+class ModuleRegexPCRE : public Module
+{
+public:
+ PCREFactory ref;
+ ModuleRegexPCRE() : ref(this) {
+ ServerInstance->Modules->AddService(ref);
}
- void OnRequest(Request& request)
+ Version GetVersion()
{
- if (strcmp("REGEX-NAME", request.id) == 0)
- {
- static_cast<RegexNameRequest&>(request).result = "pcre";
- }
- else if (strcmp("REGEX", request.id) == 0)
- {
- RegexFactoryRequest& rfr = (RegexFactoryRequest&)request;
- std::string rx = rfr.GetRegex();
- rfr.result = new PCRERegex(rx);
- }
+ return Version("Regex Provider Module for PCRE", VF_OPTCOMMON | VF_VENDOR);
}
};
diff --git a/src/modules/extra/m_regex_posix.cpp b/src/modules/extra/m_regex_posix.cpp
index ea016ae64..837f2ac1f 100644
--- a/src/modules/extra/m_regex_posix.cpp
+++ b/src/modules/extra/m_regex_posix.cpp
@@ -71,46 +71,37 @@ public:
}
};
-class ModuleRegexPOSIX : public Module
+class PosixFactory : public RegexFactory
{
-private:
+ public:
bool extended;
+ PosixFactory(Module* m) : RegexFactory(m, "regex/posix") {}
+ Regex* Create(const std::string& expr)
+ {
+ return new POSIXRegex(expr, extended);
+ }
+};
+
+class ModuleRegexPOSIX : public Module
+{
+ PosixFactory ref;
public:
- ModuleRegexPOSIX() {
- ServerInstance->Modules->PublishInterface("RegularExpression", this);
+ ModuleRegexPOSIX() : ref(this) {
+ ServerInstance->Modules->AddService(ref);
Implementation eventlist[] = { I_OnRehash };
ServerInstance->Modules->Attach(eventlist, this, 1);
OnRehash(NULL);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("Regex Provider Module for POSIX Regular Expressions", VF_COMMON | VF_VENDOR);
}
- virtual ~ModuleRegexPOSIX()
- {
- ServerInstance->Modules->UnpublishInterface("RegularExpression", this);
- }
-
- virtual void OnRehash(User* u)
+ void OnRehash(User* u)
{
ConfigReader Conf;
- extended = Conf.ReadFlag("posix", "extended", 0);
- }
-
- void OnRequest(Request& request)
- {
- if (strcmp("REGEX-NAME", request.id) == 0)
- {
- static_cast<RegexNameRequest&>(request).result = "posix";
- }
- else if (strcmp("REGEX", request.id) == 0)
- {
- RegexFactoryRequest& rfr = (RegexFactoryRequest&)request;
- std::string rx = rfr.GetRegex();
- rfr.result = new POSIXRegex(rx, extended);
- }
+ ref.extended = Conf.ReadFlag("posix", "extended", 0);
}
};
diff --git a/src/modules/extra/m_regex_tre.cpp b/src/modules/extra/m_regex_tre.cpp
index 01c6ebf4a..5a208ec8a 100644
--- a/src/modules/extra/m_regex_tre.cpp
+++ b/src/modules/extra/m_regex_tre.cpp
@@ -73,35 +73,30 @@ public:
}
};
+class TREFactory : public RegexFactory {
+ public:
+ TREFactory(Module* m) : RegexFactory(m, "regex/tre") {}
+ Regex* Create(const std::string& expr)
+ {
+ return new TRERegex(expr);
+ }
+};
+
class ModuleRegexTRE : public Module
{
+ TREFactory trf;
public:
- ModuleRegexTRE() {
- ServerInstance->Modules->PublishInterface("RegularExpression", this);
+ ModuleRegexTRE() : trf(this) {
+ ServerInstance->Modules->AddService(trf);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("Regex Provider Module for TRE Regular Expressions", VF_COMMON | VF_VENDOR);
}
- virtual ~ModuleRegexTRE()
+ ~ModuleRegexTRE()
{
- ServerInstance->Modules->UnpublishInterface("RegularExpression", this);
- }
-
- void OnRequest(Request& request)
- {
- if (strcmp("REGEX-NAME", request.id) == 0)
- {
- static_cast<RegexNameRequest&>(request).result = "tre";
- }
- else if (strcmp("REGEX", request.id) == 0)
- {
- RegexFactoryRequest& rfr = (RegexFactoryRequest&)request;
- std::string rx = rfr.GetRegex();
- rfr.result = new TRERegex(rx);
- }
}
};
diff --git a/src/modules/extra/m_sqlite3.cpp b/src/modules/extra/m_sqlite3.cpp
index e5693b61f..58a33c510 100644
--- a/src/modules/extra/m_sqlite3.cpp
+++ b/src/modules/extra/m_sqlite3.cpp
@@ -446,21 +446,15 @@ class ModuleSQLite3 : public Module
private:
ConnMap connections;
unsigned long currid;
+ ServiceProvider sqlserv;
public:
ModuleSQLite3()
- : currid(0)
+ : currid(0), sqlserv(this, "SQL/sqlite", SERVICE_DATA)
{
- ServerInstance->Modules->UseInterface("SQLutils");
-
- if (!ServerInstance->Modules->PublishFeature("SQL", this))
- {
- throw ModuleException("m_sqlite3: Unable to publish feature 'SQL'");
- }
ReadConf();
- ServerInstance->Modules->PublishInterface("SQL", this);
Implementation eventlist[] = { I_OnRehash };
ServerInstance->Modules->Attach(eventlist, this, 1);
}
@@ -469,10 +463,6 @@ class ModuleSQLite3 : public Module
{
ClearQueue();
ClearAllConnections();
-
- ServerInstance->Modules->UnpublishInterface("SQL", this);
- ServerInstance->Modules->UnpublishFeature("SQL");
- ServerInstance->Modules->DoneWithInterface("SQLutils");
}
void ClearQueue()
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index 8ec787465..7ba611547 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -137,13 +137,12 @@ class ModuleSSLGnuTLS : public Module
CommandStartTLS starttls;
GenericCap capHandler;
+ ServiceProvider iohook;
public:
ModuleSSLGnuTLS()
- : starttls(this), capHandler(this, "tls")
+ : starttls(this), capHandler(this, "tls"), iohook(this, "ssl/gnutls", SERVICE_IOHOOK)
{
- ServerInstance->Modules->PublishInterface("BufferedSocketHook", this);
-
sessions = new issl_session[ServerInstance->SE->GetMaxFds()];
gnutls_global_init(); // This must be called once in the program
@@ -160,6 +159,7 @@ class ModuleSSLGnuTLS : public Module
I_OnEvent, I_OnHookIO };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
+ ServerInstance->Modules->AddService(iohook);
ServerInstance->AddCommand(&starttls);
}
@@ -286,7 +286,6 @@ class ModuleSSLGnuTLS : public Module
gnutls_dh_params_deinit(dh_params);
gnutls_certificate_free_credentials(x509_cred);
gnutls_global_deinit();
- ServerInstance->Modules->UnpublishInterface("BufferedSocketHook", this);
delete[] sessions;
}
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index 03c460be2..7524c0d07 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -97,11 +97,11 @@ class ModuleSSLOpenSSL : public Module
std::string dhfile;
std::string sslports;
+ ServiceProvider iohook;
public:
- ModuleSSLOpenSSL()
+ ModuleSSLOpenSSL() : iohook(this, "ssl/openssl", SERVICE_IOHOOK)
{
- ServerInstance->Modules->PublishInterface("BufferedSocketHook", this);
sessions = new issl_session[ServerInstance->SE->GetMaxFds()];
@@ -128,6 +128,7 @@ class ModuleSSLOpenSSL : public Module
OnModuleRehash(NULL,"ssl");
Implementation eventlist[] = { I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnHookIO, I_OnUserConnect };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
+ ServerInstance->Modules->AddService(iohook);
}
void OnHookIO(StreamSocket* user, ListenSocket* lsb)
@@ -241,7 +242,6 @@ class ModuleSSLOpenSSL : public Module
{
SSL_CTX_free(ctx);
SSL_CTX_free(clictx);
- ServerInstance->Modules->UnpublishInterface("BufferedSocketHook", this);
delete[] sessions;
}
diff --git a/src/modules/extra/m_ziplink.cpp b/src/modules/extra/m_ziplink.cpp
index 2aeb4b9e6..2ac358769 100644
--- a/src/modules/extra/m_ziplink.cpp
+++ b/src/modules/extra/m_ziplink.cpp
@@ -56,8 +56,6 @@ class ModuleZLib : public Module
ModuleZLib()
{
- ServerInstance->Modules->PublishInterface("BufferedSocketHook", this);
-
sessions = new izip_session[ServerInstance->SE->GetMaxFds()];
for (int i = 0; i < ServerInstance->SE->GetMaxFds(); i++)
sessions[i].status = IZIP_CLOSED;
@@ -74,7 +72,6 @@ class ModuleZLib : public Module
~ModuleZLib()
{
- ServerInstance->Modules->UnpublishInterface("BufferedSocketHook", this);
delete[] sessions;
delete[] net_buffer;
}
diff --git a/src/modules/m_chanfilter.cpp b/src/modules/m_chanfilter.cpp
index a466978e3..5bb5a91b0 100644
--- a/src/modules/m_chanfilter.cpp
+++ b/src/modules/m_chanfilter.cpp
@@ -72,7 +72,6 @@ class ModuleChanFilter : public Module
ServerInstance->Modules->Attach(eventlist, this, 4);
OnRehash(NULL);
- ServerInstance->Modules->PublishInterface("ChannelBanList", this);
}
virtual void OnRehash(User* user)
@@ -141,7 +140,6 @@ class ModuleChanFilter : public Module
virtual ~ModuleChanFilter()
{
- ServerInstance->Modules->UnpublishInterface("ChannelBanList", this);
}
};
diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp
index 0a4e58edf..c4cbbef21 100644
--- a/src/modules/m_cloaking.cpp
+++ b/src/modules/m_cloaking.cpp
@@ -116,29 +116,21 @@ class ModuleCloaking : public Module
std::string key;
unsigned int compatkey[4];
const char* xtab[4];
- Module* HashProvider;
+ dynamic_reference<HashProvider> Hash;
public:
- ModuleCloaking() : cu(this)
+ ModuleCloaking() : cu(this), Hash(this, "hash/md5")
{
- /* Attempt to locate the md5 service provider, bail if we can't find it */
- HashProvider = ServerInstance->Modules->Find("m_md5.so");
- if (!HashProvider)
- throw ModuleException("Can't find m_md5.so. Please load m_md5.so before m_cloaking.so.");
-
OnRehash(NULL);
/* Register it with the core */
if (!ServerInstance->Modes->AddMode(&cu))
throw ModuleException("Could not add new modes!");
- ServerInstance->Modules->UseInterface("HashRequest");
ServerInstance->Extensions.Register(&cu.ext);
Implementation eventlist[] = { I_OnRehash, I_OnCheckBan, I_OnUserConnect };
ServerInstance->Modules->Attach(eventlist, this, 3);
-
- CloakExistingUsers();
}
/** This function takes a domain name string and returns just the last two domain parts,
@@ -195,8 +187,7 @@ class ModuleCloaking : public Module
/* Send the Hash module a different hex table for each octet group's Hash sum */
for (int k = 0; k < 4; k++)
{
- HashRequestIV hash(this, HashProvider, compatkey, xtab[(compatkey[k]+i[k]) % 4], octet[k]);
- rv.append(hash.result.substr(0,6));
+ rv.append(Hash->sumIV(compatkey, xtab[(compatkey[k]+i[k]) % 4], octet[k]).substr(0,6));
if (k < 3)
rv.append(".");
}
@@ -217,16 +208,14 @@ class ModuleCloaking : public Module
item += *input;
if (item.length() > 7)
{
- HashRequestIV hash(this, HashProvider, compatkey, xtab[(compatkey[1]+rounds) % 4], item);
- hashies.push_back(hash.result.substr(0,8));
+ hashies.push_back(Hash->sumIV(compatkey, xtab[(compatkey[1]+rounds) % 4], item).substr(0,8));
item.clear();
}
rounds++;
}
if (!item.empty())
{
- HashRequestIV hash(this, HashProvider, compatkey, xtab[(compatkey[1]+rounds) % 4], item);
- hashies.push_back(hash.result.substr(0,8));
+ hashies.push_back(Hash->sumIV(compatkey, xtab[(compatkey[1]+rounds) % 4], item).substr(0,8));
}
/* Stick them all together */
return irc::stringjoiner(":", hashies, 0, hashies.size() - 1).GetJoined();
@@ -301,8 +290,7 @@ class ModuleCloaking : public Module
input.append(1, 0); // null does not terminate a C++ string
input.append(item);
- HashRequest hash(this, HashProvider, input);
- std::string rv = hash.binresult.substr(0,6);
+ std::string rv = Hash->sum(input).substr(0,6);
for(int i=0; i < 6; i++)
{
// this discards 3 bits per byte. We have an
@@ -313,26 +301,18 @@ class ModuleCloaking : public Module
return rv;
}
- void CloakExistingUsers()
- {
- std::string* cloak;
- for (std::vector<LocalUser*>::iterator u = ServerInstance->Users->local_users.begin(); u != ServerInstance->Users->local_users.end(); u++)
- {
- cloak = cu.ext.get(*u);
- if (!cloak)
- {
- OnUserConnect(*u);
- }
- }
- }
-
ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask)
{
- char cmask[MAXBUF];
+ LocalUser* lu = IS_LOCAL(user);
+ if (!lu)
+ return MOD_RES_PASSTHRU;
+
+ OnUserConnect(lu);
std::string* cloak = cu.ext.get(user);
/* Check if they have a cloaked host, but are not using it */
if (cloak && *cloak != user->dhost)
{
+ char cmask[MAXBUF];
snprintf(cmask, MAXBUF, "%s!%s@%s", user->nick.c_str(), user->ident.c_str(), cloak->c_str());
if (InspIRCd::Match(cmask,mask))
return MOD_RES_DENY;
@@ -348,7 +328,6 @@ class ModuleCloaking : public Module
~ModuleCloaking()
{
- ServerInstance->Modules->DoneWithInterface("HashRequest");
}
Version GetVersion()
@@ -455,11 +434,8 @@ class ModuleCloaking : public Module
{
std::string tail = LastTwoDomainParts(dest->host);
- /** Reset the Hash module, and send it our IV and hex table */
- HashRequestIV hash(this, HashProvider, compatkey, xtab[(dest->host[0]) % 4], dest->host);
-
/* Generate a cloak using specialized Hash */
- chost = prefix + "-" + hash.result.substr(0,8) + tail;
+ chost = prefix + "-" + Hash->sumIV(compatkey, xtab[(dest->host[0]) % 4], dest->host).substr(0,8) + tail;
/* Fix by brain - if the cloaked host is > the max length of a host (64 bytes
* according to the DNS RFC) then they get cloaked as an IP.
diff --git a/src/modules/m_exemptchanops.cpp b/src/modules/m_exemptchanops.cpp
index 9e6b735ed..8b3fbf074 100644
--- a/src/modules/m_exemptchanops.cpp
+++ b/src/modules/m_exemptchanops.cpp
@@ -73,7 +73,6 @@ class ModuleExemptChanOps : public Module
ServerInstance->Modules->Attach(eventlist, this, 4);
OnRehash(NULL);
- ServerInstance->Modules->PublishInterface("ChannelBanList", this);
}
virtual Version GetVersion()
@@ -120,11 +119,6 @@ class ModuleExemptChanOps : public Module
return MOD_RES_PASSTHRU;
}
-
- virtual ~ModuleExemptChanOps()
- {
- ServerInstance->Modules->UnpublishInterface("ChannelBanList", this);
- }
};
MODULE_INIT(ModuleExemptChanOps)
diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp
index 0220a3a44..55ef734ba 100644
--- a/src/modules/m_filter.cpp
+++ b/src/modules/m_filter.cpp
@@ -17,8 +17,7 @@
/* $ModDesc: Text (spam) filtering */
-static std::string RegexEngine = "";
-static Module* rxengine = NULL;
+class ModuleFilter;
enum FilterFlags
{
@@ -90,19 +89,16 @@ class FilterResult
{
}
- virtual ~FilterResult()
+ ~FilterResult()
{
}
};
-class FilterBase;
-
class CommandFilter : public Command
{
- FilterBase* Base;
public:
- CommandFilter(FilterBase* f)
- : Command(reinterpret_cast<Module*>(f), "FILTER", 1, 5), Base(f)
+ CommandFilter(Module* f)
+ : Command(f, "FILTER", 1, 5)
{
flags_needed = 'o';
this->syntax = "<filter-definition> <action> <flags> [<gline-duration>] :<reason>";
@@ -120,33 +116,48 @@ class CommandFilter : public Command
}
};
-class FilterBase : public Module
+class ImplFilter : public FilterResult
{
+ public:
+ Regex* regex;
+
+ ImplFilter(ModuleFilter* mymodule, const std::string &rea, const std::string &act, long glinetime, const std::string &pat, const std::string &flgs);
+};
+
+
+class ModuleFilter : public Module
+{
+ public:
CommandFilter filtcommand;
+ dynamic_reference<RegexFactory> RegexEngine;
+
+ std::vector<ImplFilter> filters;
+ const char *error;
+ int erroffset;
int flags;
-protected:
+
std::vector<std::string> exemptfromfilter; // List of channel names excluded from filtering.
- public:
- FilterBase();
- virtual ~FilterBase();
- virtual ModResult OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list);
- virtual FilterResult* FilterMatch(User* user, const std::string &text, int flags) = 0;
- virtual bool DeleteFilter(const std::string &freeform) = 0;
- virtual void SyncFilters(Module* proto, void* opaque) = 0;
- virtual void SendFilter(Module* proto, void* opaque, FilterResult* iter);
- virtual std::pair<bool, std::string> AddFilter(const std::string &freeform, const std::string &type, const std::string &reason, long duration, const std::string &flags) = 0;
- virtual ModResult OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list);
- virtual void OnRehash(User* user);
- virtual Version GetVersion();
+
+ ModuleFilter();
+
+ ~ModuleFilter();
+ ModResult OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list);
+ FilterResult* FilterMatch(User* user, const std::string &text, int flags);
+ bool DeleteFilter(const std::string &freeform);
+ void SyncFilters(Module* proto, void* opaque);
+ void SendFilter(Module* proto, void* opaque, FilterResult* iter);
+ std::pair<bool, std::string> AddFilter(const std::string &freeform, const std::string &type, const std::string &reason, long duration, const std::string &flags);
+ ModResult OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list);
+ void OnRehash(User* user);
+ Version GetVersion();
std::string EncodeFilter(FilterResult* filter);
FilterResult DecodeFilter(const std::string &data);
- virtual void OnSyncNetwork(Module* proto, void* opaque);
- virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
- virtual ModResult OnStats(char symbol, User* user, string_list &results) = 0;
- virtual ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line);
+ void OnSyncNetwork(Module* proto, void* opaque);
+ void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
+ ModResult OnStats(char symbol, User* user, string_list &results);
+ ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line);
bool AppliesToMe(User* user, FilterResult* filter, int flags);
- void OnLoadModule(Module* mod);
- virtual void ReadFilters(ConfigReader &MyConf) = 0;
+ void ReadFilters(ConfigReader &MyConf);
};
CmdResult CommandFilter::Handle(const std::vector<std::string> &parameters, User *user)
@@ -154,7 +165,7 @@ CmdResult CommandFilter::Handle(const std::vector<std::string> &parameters, User
if (parameters.size() == 1)
{
/* Deleting a filter */
- if (Base->DeleteFilter(parameters[0]))
+ if (static_cast<ModuleFilter&>(*creator).DeleteFilter(parameters[0]))
{
user->WriteServ("NOTICE %s :*** Removed filter '%s'", user->nick.c_str(), parameters[0].c_str());
ServerInstance->SNO->WriteToSnoMask(IS_LOCAL(user) ? 'a' : 'A', std::string("FILTER: ")+user->nick+" removed filter '"+parameters[0]+"'");
@@ -201,7 +212,7 @@ CmdResult CommandFilter::Handle(const std::vector<std::string> &parameters, User
{
reason = parameters[3];
}
- std::pair<bool, std::string> result = Base->AddFilter(freeform, type, reason, duration, flags);
+ std::pair<bool, std::string> result = static_cast<ModuleFilter&>(*creator).AddFilter(freeform, type, reason, duration, flags);
if (result.first)
{
user->WriteServ("NOTICE %s :*** Added filter '%s', type '%s'%s%s, flags '%s', reason: '%s'", user->nick.c_str(), freeform.c_str(),
@@ -227,7 +238,7 @@ CmdResult CommandFilter::Handle(const std::vector<std::string> &parameters, User
}
}
-bool FilterBase::AppliesToMe(User* user, FilterResult* filter, int iflags)
+bool ModuleFilter::AppliesToMe(User* user, FilterResult* filter, int iflags)
{
if ((filter->flag_no_opers) && IS_OPER(user))
return false;
@@ -242,20 +253,19 @@ bool FilterBase::AppliesToMe(User* user, FilterResult* filter, int iflags)
return true;
}
-FilterBase::FilterBase() : filtcommand(this)
+ModuleFilter::ModuleFilter() : filtcommand(this), RegexEngine(this, "regex")
{
- ServerInstance->Modules->UseInterface("RegularExpression");
ServerInstance->AddCommand(&filtcommand);
- Implementation eventlist[] = { I_OnPreCommand, I_OnStats, I_OnSyncNetwork, I_OnDecodeMetaData, I_OnUserPreMessage, I_OnUserPreNotice, I_OnRehash, I_OnLoadModule };
- ServerInstance->Modules->Attach(eventlist, this, 8);
+ Implementation eventlist[] = { I_OnPreCommand, I_OnStats, I_OnSyncNetwork, I_OnDecodeMetaData, I_OnUserPreMessage, I_OnUserPreNotice, I_OnRehash };
+ ServerInstance->Modules->Attach(eventlist, this, 7);
+ OnRehash(NULL);
}
-FilterBase::~FilterBase()
+ModuleFilter::~ModuleFilter()
{
- ServerInstance->Modules->DoneWithInterface("RegularExpression");
}
-ModResult FilterBase::OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
+ModResult ModuleFilter::OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
{
if (!IS_LOCAL(user))
return MOD_RES_PASSTHRU;
@@ -264,7 +274,7 @@ ModResult FilterBase::OnUserPreMessage(User* user,void* dest,int target_type, st
return OnUserPreNotice(user,dest,target_type,text,status,exempt_list);
}
-ModResult FilterBase::OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
+ModResult ModuleFilter::OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
{
/* Leave ulines alone */
if ((ServerInstance->ULine(user->server)) || (!IS_LOCAL(user)))
@@ -325,7 +335,7 @@ ModResult FilterBase::OnUserPreNotice(User* user,void* dest,int target_type, std
return MOD_RES_PASSTHRU;
}
-ModResult FilterBase::OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
+ModResult ModuleFilter::OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
{
flags = 0;
if (validated && IS_LOCAL(user))
@@ -415,7 +425,7 @@ ModResult FilterBase::OnPreCommand(std::string &command, std::vector<std::string
return MOD_RES_PASSTHRU;
}
-void FilterBase::OnRehash(User* user)
+void ModuleFilter::OnRehash(User* user)
{
ConfigReader MyConf;
std::vector<std::string>().swap(exemptfromfilter);
@@ -426,62 +436,28 @@ void FilterBase::OnRehash(User* user)
exemptfromfilter.push_back(chan);
}
}
- std::string newrxengine = MyConf.ReadValue("filteropts", "engine", 0);
- if (!RegexEngine.empty())
- {
- if (RegexEngine == newrxengine)
- return;
-
- ServerInstance->SNO->WriteGlobalSno('a', "Dumping all filters due to regex engine change (was '%s', now '%s')", RegexEngine.c_str(), newrxengine.c_str());
- //ServerInstance->XLines->DelAll("R");
- }
- rxengine = NULL;
+ std::string newrxengine = "regex/" + MyConf.ReadValue("filteropts", "engine", 0);
+ if (RegexEngine.GetProvider() == newrxengine)
+ return;
- RegexEngine = newrxengine;
- modulelist* ml = ServerInstance->Modules->FindInterface("RegularExpression");
- if (ml)
- {
- for (modulelist::iterator i = ml->begin(); i != ml->end(); ++i)
- {
- if (RegexNameRequest(this, *i).result == newrxengine)
- {
- ServerInstance->SNO->WriteGlobalSno('a', "Filter now using engine '%s'", RegexEngine.c_str());
- rxengine = *i;
- }
- }
- }
- if (!rxengine)
- {
- ServerInstance->SNO->WriteGlobalSno('a', "WARNING: Regex engine '%s' is not loaded - Filter functionality disabled until this is corrected.", RegexEngine.c_str());
- }
-}
+ //ServerInstance->SNO->WriteGlobalSno('a', "Dumping all filters due to regex engine change (was '%s', now '%s')", RegexEngine.GetProvider().c_str(), newrxengine.c_str());
+ //ServerInstance->XLines->DelAll("R");
-void FilterBase::OnLoadModule(Module* mod)
-{
- if (ServerInstance->Modules->ModuleHasInterface(mod, "RegularExpression"))
+ RegexEngine.SetProvider(newrxengine);
+ if (!RegexEngine)
{
- std::string rxname = RegexNameRequest(this, mod).result;
- if (rxname == RegexEngine)
- {
- rxengine = mod;
- /* Force a rehash to make sure that any filters that couldnt be applied from the conf
- * on startup or on load are applied right now.
- */
- ConfigReader Config;
- ServerInstance->SNO->WriteGlobalSno('a', "Found and activated regex module '%s' for m_filter.so.", RegexEngine.c_str());
- ReadFilters(Config);
- }
+ ServerInstance->SNO->WriteGlobalSno('a', "WARNING: Regex engine '%s' is not loaded - Filter functionality disabled until this is corrected.", RegexEngine.GetProvider().c_str());
}
+ ReadFilters(MyConf);
}
-
-Version FilterBase::GetVersion()
+Version ModuleFilter::GetVersion()
{
return Version("Text (spam) filtering", VF_VENDOR | VF_COMMON);
}
-std::string FilterBase::EncodeFilter(FilterResult* filter)
+std::string ModuleFilter::EncodeFilter(FilterResult* filter)
{
std::ostringstream stream;
std::string x = filter->freeform;
@@ -495,7 +471,7 @@ std::string FilterBase::EncodeFilter(FilterResult* filter)
return stream.str();
}
-FilterResult FilterBase::DecodeFilter(const std::string &data)
+FilterResult ModuleFilter::DecodeFilter(const std::string &data)
{
FilterResult res;
irc::tokenstream tokens(data);
@@ -516,17 +492,17 @@ FilterResult FilterBase::DecodeFilter(const std::string &data)
return res;
}
-void FilterBase::OnSyncNetwork(Module* proto, void* opaque)
+void ModuleFilter::OnSyncNetwork(Module* proto, void* opaque)
{
this->SyncFilters(proto, opaque);
}
-void FilterBase::SendFilter(Module* proto, void* opaque, FilterResult* iter)
+void ModuleFilter::SendFilter(Module* proto, void* opaque, FilterResult* iter)
{
proto->ProtoSendMetaData(opaque, NULL, "filter", EncodeFilter(iter));
}
-void FilterBase::OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata)
+void ModuleFilter::OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata)
{
if ((target == NULL) && (extname == "filter"))
{
@@ -535,163 +511,127 @@ void FilterBase::OnDecodeMetaData(Extensible* target, const std::string &extname
}
}
-class ImplFilter : public FilterResult
+ImplFilter::ImplFilter(ModuleFilter* mymodule, const std::string &rea, const std::string &act, long glinetime, const std::string &pat, const std::string &flgs)
+ : FilterResult(pat, rea, act, glinetime, flgs)
{
- public:
- Regex* regex;
+ if (!mymodule->RegexEngine)
+ throw ModuleException("Regex module implementing '"+mymodule->RegexEngine.GetProvider()+"' is not loaded!");
+ regex = mymodule->RegexEngine->Create(pat);
+}
- ImplFilter(Module* mymodule, const std::string &rea, const std::string &act, long glinetime, const std::string &pat, const std::string &flgs)
- : FilterResult(pat, rea, act, glinetime, flgs)
+FilterResult* ModuleFilter::FilterMatch(User* user, const std::string &text, int flgs)
+{
+ for (std::vector<ImplFilter>::iterator index = filters.begin(); index != filters.end(); index++)
{
- if (!rxengine)
- throw ModuleException("Regex module implementing '"+RegexEngine+"' is not loaded!");
-
- regex = RegexFactoryRequest(mymodule, rxengine, pat).Create();
- }
+ /* Skip ones that dont apply to us */
+ if (!AppliesToMe(user, dynamic_cast<FilterResult*>(&(*index)), flgs))
+ continue;
- ImplFilter()
- {
+ //ServerInstance->Logs->Log("m_filter", DEBUG, "Match '%s' against '%s'", text.c_str(), index->freeform.c_str());
+ if (index->regex->Matches(text))
+ {
+ //ServerInstance->Logs->Log("m_filter", DEBUG, "MATCH");
+ ImplFilter fr = *index;
+ if (index != filters.begin())
+ {
+ /* Move to head of list for efficiency */
+ filters.erase(index);
+ filters.insert(filters.begin(), fr);
+ }
+ return &*filters.begin();
+ }
+ //ServerInstance->Logs->Log("m_filter", DEBUG, "NO MATCH");
}
-};
+ return NULL;
+}
-class ModuleFilter : public FilterBase
+bool ModuleFilter::DeleteFilter(const std::string &freeform)
{
- std::vector<ImplFilter> filters;
- const char *error;
- int erroffset;
- ImplFilter fr;
-
- public:
- ModuleFilter()
+ for (std::vector<ImplFilter>::iterator i = filters.begin(); i != filters.end(); i++)
{
- OnRehash(NULL);
+ if (i->freeform == freeform)
+ {
+ delete i->regex;
+ filters.erase(i);
+ return true;
+ }
}
+ return false;
+}
- virtual ~ModuleFilter()
+void ModuleFilter::SyncFilters(Module* proto, void* opaque)
+{
+ for (std::vector<ImplFilter>::iterator i = filters.begin(); i != filters.end(); i++)
{
+ this->SendFilter(proto, opaque, &(*i));
}
+}
- virtual FilterResult* FilterMatch(User* user, const std::string &text, int flgs)
+std::pair<bool, std::string> ModuleFilter::AddFilter(const std::string &freeform, const std::string &type, const std::string &reason, long duration, const std::string &flgs)
+{
+ for (std::vector<ImplFilter>::iterator i = filters.begin(); i != filters.end(); i++)
{
- for (std::vector<ImplFilter>::iterator index = filters.begin(); index != filters.end(); index++)
+ if (i->freeform == freeform)
{
- /* Skip ones that dont apply to us */
- if (!FilterBase::AppliesToMe(user, dynamic_cast<FilterResult*>(&(*index)), flgs))
- continue;
-
- //ServerInstance->Logs->Log("m_filter", DEBUG, "Match '%s' against '%s'", text.c_str(), index->freeform.c_str());
- if (index->regex->Matches(text))
- {
- //ServerInstance->Logs->Log("m_filter", DEBUG, "MATCH");
- fr = *index;
- if (index != filters.begin())
- {
- /* Move to head of list for efficiency */
- filters.erase(index);
- filters.insert(filters.begin(), fr);
- }
- return &fr;
- }
- //ServerInstance->Logs->Log("m_filter", DEBUG, "NO MATCH");
+ return std::make_pair(false, "Filter already exists");
}
- return NULL;
}
- virtual bool DeleteFilter(const std::string &freeform)
+ try
{
- for (std::vector<ImplFilter>::iterator i = filters.begin(); i != filters.end(); i++)
- {
- if (i->freeform == freeform)
- {
- delete i->regex;
- filters.erase(i);
- return true;
- }
- }
- return false;
+ filters.push_back(ImplFilter(this, reason, type, duration, freeform, flgs));
}
-
- virtual void SyncFilters(Module* proto, void* opaque)
+ catch (ModuleException &e)
{
- for (std::vector<ImplFilter>::iterator i = filters.begin(); i != filters.end(); i++)
- {
- this->SendFilter(proto, opaque, &(*i));
- }
+ ServerInstance->Logs->Log("m_filter", DEFAULT, "Error in regular expression '%s': %s", freeform.c_str(), e.GetReason());
+ return std::make_pair(false, e.GetReason());
}
+ return std::make_pair(true, "");
+}
- virtual std::pair<bool, std::string> AddFilter(const std::string &freeform, const std::string &type, const std::string &reason, long duration, const std::string &flgs)
+void ModuleFilter::ReadFilters(ConfigReader &MyConf)
+{
+ for (int index = 0; index < MyConf.Enumerate("keyword"); index++)
{
- for (std::vector<ImplFilter>::iterator i = filters.begin(); i != filters.end(); i++)
- {
- if (i->freeform == freeform)
- {
- return std::make_pair(false, "Filter already exists");
- }
- }
+ this->DeleteFilter(MyConf.ReadValue("keyword", "pattern", index));
+
+ std::string pattern = MyConf.ReadValue("keyword", "pattern", index);
+ std::string reason = MyConf.ReadValue("keyword", "reason", index);
+ std::string action = MyConf.ReadValue("keyword", "action", index);
+ std::string flgs = MyConf.ReadValue("keyword", "flags", index);
+ long gline_time = ServerInstance->Duration(MyConf.ReadValue("keyword", "duration", index));
+ if (action.empty())
+ action = "none";
+ if (flgs.empty())
+ flgs = "*";
try
{
- filters.push_back(ImplFilter(this, reason, type, duration, freeform, flgs));
+ filters.push_back(ImplFilter(this, reason, action, gline_time, pattern, flgs));
+ ServerInstance->Logs->Log("m_filter", DEFAULT, "Regular expression %s loaded.", pattern.c_str());
}
catch (ModuleException &e)
{
- ServerInstance->Logs->Log("m_filter", DEFAULT, "Error in regular expression '%s': %s", freeform.c_str(), e.GetReason());
- return std::make_pair(false, e.GetReason());
+ ServerInstance->Logs->Log("m_filter", DEFAULT, "Error in regular expression '%s': %s", pattern.c_str(), e.GetReason());
}
- return std::make_pair(true, "");
- }
-
- virtual void OnRehash(User* user)
- {
- ConfigReader MyConf;
- FilterBase::OnRehash(user);
- ReadFilters(MyConf);
}
+}
- void ReadFilters(ConfigReader &MyConf)
+ModResult ModuleFilter::OnStats(char symbol, User* user, string_list &results)
+{
+ if (symbol == 's')
{
- for (int index = 0; index < MyConf.Enumerate("keyword"); index++)
+ std::string sn = ServerInstance->Config->ServerName;
+ for (std::vector<ImplFilter>::iterator i = filters.begin(); i != filters.end(); i++)
{
- this->DeleteFilter(MyConf.ReadValue("keyword", "pattern", index));
-
- std::string pattern = MyConf.ReadValue("keyword", "pattern", index);
- std::string reason = MyConf.ReadValue("keyword", "reason", index);
- std::string action = MyConf.ReadValue("keyword", "action", index);
- std::string flgs = MyConf.ReadValue("keyword", "flags", index);
- long gline_time = ServerInstance->Duration(MyConf.ReadValue("keyword", "duration", index));
- if (action.empty())
- action = "none";
- if (flgs.empty())
- flgs = "*";
-
- try
- {
- filters.push_back(ImplFilter(this, reason, action, gline_time, pattern, flgs));
- ServerInstance->Logs->Log("m_filter", DEFAULT, "Regular expression %s loaded.", pattern.c_str());
- }
- catch (ModuleException &e)
- {
- ServerInstance->Logs->Log("m_filter", DEFAULT, "Error in regular expression '%s': %s", pattern.c_str(), e.GetReason());
- }
+ results.push_back(sn+" 223 "+user->nick+" :"+RegexEngine.GetProvider()+":"+i->freeform+" "+i->flags+" "+i->action+" "+ConvToStr(i->gline_time)+" :"+i->reason);
}
- }
-
- virtual ModResult OnStats(char symbol, User* user, string_list &results)
- {
- if (symbol == 's')
+ for (std::vector<std::string>::iterator i = exemptfromfilter.begin(); i != exemptfromfilter.end(); ++i)
{
- std::string sn = ServerInstance->Config->ServerName;
- for (std::vector<ImplFilter>::iterator i = filters.begin(); i != filters.end(); i++)
- {
- results.push_back(sn+" 223 "+user->nick+" :"+RegexEngine+":"+i->freeform+" "+i->flags+" "+i->action+" "+ConvToStr(i->gline_time)+" :"+i->reason);
- }
- for (std::vector<std::string>::iterator i = exemptfromfilter.begin(); i != exemptfromfilter.end(); ++i)
- {
- results.push_back(sn+" 223 "+user->nick+" :EXEMPT "+(*i));
- }
+ results.push_back(sn+" 223 "+user->nick+" :EXEMPT "+(*i));
}
- return MOD_RES_PASSTHRU;
}
-};
+ return MOD_RES_PASSTHRU;
+}
MODULE_INIT(ModuleFilter)
diff --git a/src/modules/m_hash.h b/src/modules/m_hash.h
index 08a24eb85..385fff95e 100644
--- a/src/modules/m_hash.h
+++ b/src/modules/m_hash.h
@@ -19,75 +19,31 @@
#define SHA256_DIGEST_SIZE (256 / 8)
#define SHA256_BLOCK_SIZE (512 / 8)
-/** Query a hash algorithm's name
- *
- * Example:
- * \code
- * cout << "Using hash algorithm: " << HashNameRequest(this, HashModule).response;
- * \endcode
- */
-struct HashNameRequest : public Request
+class HashProvider : public DataProvider
{
- std::string response;
- HashNameRequest(Module* Me, Module* Target) : Request(Me, Target, "NAME")
+ public:
+ HashProvider(Module* mod, const std::string& Name) : DataProvider(mod, Name) {}
+ virtual std::string sum(const std::string& data) = 0;
+ inline std::string hexsum(const std::string& data)
{
- Send();
+ return BinToHex(sum(data));
}
-};
-/** Send this class to the hashing module to HashSUM a std::string.
- *
- * Example:
- * \code
- * // Get the Hash sum of the string 'doodads'.
- * std::string result = HashRequest(this, HashModule, "doodads").result;
- * \endcode
- */
-struct HashRequest : public Request
-{
- const std::string data;
- std::string binresult;
- /** Initialize HashSumRequest for sending.
- * @param Me A pointer to the sending module
- * @param Target A pointer to the hashing module
- * @param data The data to be hashed
+ /** Allows the IVs for the hash to be specified. As the choice of initial IV is
+ * important for the security of a hash, this should not be used except to
+ * maintain backwards compatability. This also allows you to change the hex
+ * sequence from its default of "0123456789abcdef", which does not improve the
+ * strength of the output, but helps confuse those attempting to implement it.
+ *
+ * Only m_md5 implements this request; only m_cloaking should use it.
+ *
+ * Example:
+ * \code
+ * unsigned int iv[] = { 0xFFFFFFFF, 0x00000000, 0xAAAAAAAA, 0xCCCCCCCC };
+ * std::string result = Hash.sumIV(iv, "0123456789abcdef", "data");
+ * \endcode
*/
- HashRequest(Module* Me, Module* Target, const std::string &sdata)
- : Request(Me, Target, "HASH"), data(sdata)
- {
- Send();
- }
- inline std::string hex()
- {
- return BinToHex(binresult);
- }
-};
-
-/** Allows the IVs for the hash to be specified. As the choice of initial IV is
- * important for the security of a hash, this should not be used except to
- * maintain backwards compatability. This also allows you to change the hex
- * sequence from its default of "0123456789abcdef", which does not improve the
- * strength of the output, but helps confuse those attempting to implement it.
- *
- * Only m_md5 implements this request; only m_cloaking should use it.
- *
- * Example:
- * \code
- * unsigned int iv[] = { 0xFFFFFFFF, 0x00000000, 0xAAAAAAAA, 0xCCCCCCCC };
- * std::string result = HashRequestIV(this, HashModule, iv, "0123456789abcdef", "data").result;
- * \endcode
- */
-struct HashRequestIV : public Request
-{
- unsigned int* iv;
- const char* map;
- std::string result;
- const std::string data;
- HashRequestIV(Module* Me, Module* Target, unsigned int* IV, const char* HexMap, const std::string &sdata)
- : Request(Me, Target, "HASH-IV"), iv(IV), map(HexMap), data(sdata)
- {
- Send();
- }
+ virtual std::string sumIV(unsigned int* IV, const char* HexMap, const std::string &sdata) = 0;
};
#endif
diff --git a/src/modules/m_md5.cpp b/src/modules/m_md5.cpp
index 6ac9c3d87..6b74dae2e 100644
--- a/src/modules/m_md5.cpp
+++ b/src/modules/m_md5.cpp
@@ -47,7 +47,7 @@ class MD5Context
word32 in[16];
};
-class ModuleMD5 : public Module
+class MD5Provider : public HashProvider
{
void byteSwap(word32 *buf, unsigned words)
{
@@ -258,45 +258,36 @@ class ModuleMD5 : public Module
}
*dest++ = 0;
}
-
public:
-
- ModuleMD5()
+ std::string sum(const std::string& data)
{
- ServerInstance->Modules->PublishInterface("HashRequest", this);
+ char res[16];
+ MyMD5(res, (void*)data.data(), data.length(), NULL);
+ return std::string(res, 16);
}
- virtual ~ModuleMD5()
+ std::string sumIV(unsigned int* IV, const char* HexMap, const std::string &sdata)
{
- ServerInstance->Modules->UnpublishInterface("HashRequest", this);
+ char res[33];
+ GenHash(sdata.data(), res, HexMap, IV, sdata.length());
+ return res;
}
+ MD5Provider(Module* parent) : HashProvider(parent, "hash/md5") {}
+};
- void OnRequest(Request& request)
+class ModuleMD5 : public Module
+{
+ MD5Provider md5;
+ public:
+ ModuleMD5() : md5(this)
{
- if (strcmp("HASH", request.id) == 0)
- {
- char res[16];
- HashRequest& req = static_cast<HashRequest&>(request);
- MyMD5(res, (void*)req.data.data(), req.data.length(), NULL);
- req.binresult.assign(res, 16);
- }
- else if (strcmp("HASH-IV", request.id) == 0)
- {
- char res[33];
- HashRequestIV& req = static_cast<HashRequestIV&>(request);
- GenHash(req.data.data(), res, req.map, req.iv, req.data.length());
- req.result = res;
- }
- else if (strcmp("NAME", request.id) == 0)
- {
- static_cast<HashNameRequest&>(request).response = "md5";
- }
+ ServerInstance->Modules->AddService(md5);
}
Version GetVersion()
{
- return Version("Allows for MD5 encrypted oper passwords",VF_VENDOR);
+ return Version("Implements MD5 hashing",VF_VENDOR);
}
};
diff --git a/src/modules/m_password_hash.cpp b/src/modules/m_password_hash.cpp
index 617983ec4..f064e9cf0 100644
--- a/src/modules/m_password_hash.cpp
+++ b/src/modules/m_password_hash.cpp
@@ -16,47 +16,36 @@
#include "inspircd.h"
#include "m_hash.h"
-typedef std::map<irc::string, Module*> hashymodules;
-
/* Handle /MKPASSWD
*/
class CommandMkpasswd : public Command
{
- hashymodules &hashers;
- std::deque<std::string> &names;
public:
- CommandMkpasswd(Module* Creator, hashymodules &h, std::deque<std::string> &n) : Command(Creator, "MKPASSWD", 2), hashers(h), names(n)
+ CommandMkpasswd(Module* Creator) : Command(Creator, "MKPASSWD", 2)
{
syntax = "<hashtype> <any-text>";
Penalty = 5;
}
- void MakeHash(User* user, const char* algo, const char* stuff)
+ void MakeHash(User* user, const std::string& algo, const std::string& stuff)
{
- /* Lets see if they gave us an algorithm which has been implemented */
- hashymodules::iterator x = hashers.find(algo);
- if (x != hashers.end())
+ HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + algo);
+ if (hp)
{
- HashRequest hash(creator, x->second, stuff);
/* Now attempt to generate a hash */
user->WriteServ("NOTICE %s :%s hashed password for %s is %s",
- user->nick.c_str(), algo, stuff, hash.hex().c_str());
- }
- else if (names.empty())
- {
- /* same idea as bug #569 */
- user->WriteServ("NOTICE %s :No hash provider modules are loaded", user->nick.c_str());
+ user->nick.c_str(), algo.c_str(), stuff.c_str(), hp->hexsum(stuff).c_str());
}
else
{
/* I dont do flying, bob. */
- user->WriteServ("NOTICE %s :Unknown hash type, valid hash types are: %s", user->nick.c_str(), irc::stringjoiner(", ", names, 0, names.size() - 1).GetJoined().c_str() );
+ user->WriteServ("NOTICE %s :Unknown hash type", user->nick.c_str());
}
}
CmdResult Handle (const std::vector<std::string>& parameters, User *user)
{
- MakeHash(user, parameters[0].c_str(), parameters[1].c_str());
+ MakeHash(user, parameters[0], parameters[1]);
return CMD_SUCCESS;
}
@@ -64,84 +53,31 @@ class CommandMkpasswd : public Command
class ModuleOperHash : public Module
{
-
CommandMkpasswd cmd;
- hashymodules hashers; /* List of modules which implement HashRequest */
- std::deque<std::string> names; /* Module names which implement HashRequest */
-
- bool diduseiface; /* If we've called UseInterface yet. */
public:
- ModuleOperHash()
- : cmd(this, hashers, names)
+ ModuleOperHash() : cmd(this)
{
- diduseiface = false;
-
/* Read the config file first */
-// Conf = NULL;
OnRehash(NULL);
- /* Find all modules which implement the interface 'HashRequest' */
- modulelist* ml = ServerInstance->Modules->FindInterface("HashRequest");
-
- /* Did we find any modules? */
- if (ml)
- {
- /* Yes, enumerate them all to find out the hashing algorithm name */
- for (modulelist::iterator m = ml->begin(); m != ml->end(); m++)
- {
- /* Make a request to it for its name, its implementing
- * HashRequest so we know its safe to do this
- */
- std::string name = HashNameRequest(this, *m).response;
- /* Build a map of them */
- hashers[name.c_str()] = *m;
- names.push_back(name);
- }
- /* UseInterface doesn't do anything if there are no providers, so we'll have to call it later if a module gets loaded later on. */
- ServerInstance->Modules->UseInterface("HashRequest");
- diduseiface = true;
- }
-
ServerInstance->AddCommand(&cmd);
- Implementation eventlist[] = { I_OnPassCompare, I_OnLoadModule };
- ServerInstance->Modules->Attach(eventlist, this, 2);
- }
-
- virtual ~ModuleOperHash()
- {
- if (diduseiface) ServerInstance->Modules->DoneWithInterface("HashRequest");
- }
-
-
- virtual void OnLoadModule(Module* mod)
- {
- if (ServerInstance->Modules->ModuleHasInterface(mod, "HashRequest"))
- {
- std::string sname = HashNameRequest(this, mod).response;
- hashers[sname.c_str()] = mod;
- names.push_back(sname);
- if (!diduseiface)
- {
- ServerInstance->Modules->UseInterface("HashRequest");
- diduseiface = true;
- }
- }
+ Implementation eventlist[] = { I_OnPassCompare };
+ ServerInstance->Modules->Attach(eventlist, this, 1);
}
virtual ModResult OnPassCompare(Extensible* ex, const std::string &data, const std::string &input, const std::string &hashtype)
{
- /* First, lets see what hash theyre using on this oper */
- hashymodules::iterator x = hashers.find(hashtype.c_str());
+ HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + hashtype);
- /* Is this a valid hash name? (case insensitive) */
- if (x != hashers.end())
+ /* Is this a valid hash name? */
+ if (hp)
{
/* Compare the hash in the config to the generated hash */
- if (!strcasecmp(data.c_str(), HashRequest(this, x->second, input).hex().c_str()))
+ if (data == hp->hexsum(input))
return MOD_RES_ALLOW;
- /* No match, and must be hashed, forbid */
else
+ /* No match, and must be hashed, forbid */
return MOD_RES_DENY;
}
diff --git a/src/modules/m_regex.h b/src/modules/m_regex.h
index 969c4920b..613ec2700 100644
--- a/src/modules/m_regex.h
+++ b/src/modules/m_regex.h
@@ -40,38 +40,12 @@ public:
}
};
-class RegexFactoryRequest : public Request
+class RegexFactory : public DataProvider
{
-private:
- std::string regex;
+ public:
+ RegexFactory(Module* Creator, const std::string& Name) : DataProvider(Creator, Name) {}
-public:
- Regex* result;
-
- RegexFactoryRequest(Module* Me, Module* Target, const std::string& rx) : Request(Me, Target, "REGEX"), regex(rx), result(NULL)
- {
- }
-
- const std::string& GetRegex() const
- {
- return regex;
- }
-
- Regex* Create()
- {
- Send();
- return this->result;
- }
-};
-
-class RegexNameRequest : public Request
-{
-public:
- std::string result;
- RegexNameRequest(Module* Me, Module* Target) : Request(Me, Target, "REGEX-NAME")
- {
- Send();
- }
+ virtual Regex* Create(const std::string& expr) = 0;
};
#endif
diff --git a/src/modules/m_regex_glob.cpp b/src/modules/m_regex_glob.cpp
index 42cc0abd1..75d77a267 100644
--- a/src/modules/m_regex_glob.cpp
+++ b/src/modules/m_regex_glob.cpp
@@ -33,35 +33,28 @@ public:
}
};
-class ModuleRegexGlob : public Module
+class GlobFactory : public RegexFactory
{
-public:
- ModuleRegexGlob() {
- ServerInstance->Modules->PublishInterface("RegularExpression", this);
- }
-
- virtual Version GetVersion()
+ public:
+ Regex* Create(const std::string& expr)
{
- return Version("Regex module using plain wildcard matching.", VF_OPTCOMMON | VF_VENDOR);
+ return new GlobRegex(expr);
}
- virtual ~ModuleRegexGlob()
- {
- ServerInstance->Modules->UnpublishInterface("RegularExpression", this);
+ GlobFactory(Module* m) : RegexFactory(m, "regex/glob") {}
+};
+
+class ModuleRegexGlob : public Module
+{
+ GlobFactory gf;
+public:
+ ModuleRegexGlob() : gf(this) {
+ ServerInstance->Modules->AddService(gf);
}
- void OnRequest(Request& request)
+ Version GetVersion()
{
- if (strcmp("REGEX-NAME", request.id) == 0)
- {
- static_cast<RegexNameRequest&>(request).result = "glob";
- }
- else if (strcmp("REGEX", request.id) == 0)
- {
- RegexFactoryRequest& rfr = (RegexFactoryRequest&)request;
- std::string rx = rfr.GetRegex();
- rfr.result = new GlobRegex(rx);
- }
+ return Version("Regex module using plain wildcard matching.", VF_OPTCOMMON | VF_VENDOR);
}
};
diff --git a/src/modules/m_ripemd160.cpp b/src/modules/m_ripemd160.cpp
index 03a7f9895..6bd9a059a 100644
--- a/src/modules/m_ripemd160.cpp
+++ b/src/modules/m_ripemd160.cpp
@@ -149,7 +149,7 @@ typedef uint32_t dword;
}
-class ModuleRIPEMD160 : public Module
+class RIProv : public HashProvider
{
void MDinit(dword *MDbuf, unsigned int* key)
@@ -436,36 +436,33 @@ class ModuleRIPEMD160 : public Module
return (byte *)hashcode;
}
-
- public:
-
- ModuleRIPEMD160()
+public:
+ std::string sum(const std::string& data)
{
- ServerInstance->Modules->PublishInterface("HashRequest", this);
+ char* rv = (char*)RMD((byte*)data.data(), data.length(), NULL);
+ return std::string(rv, RMDsize / 8);
}
- virtual ~ModuleRIPEMD160()
+ std::string sumIV(unsigned int* IV, const char* HexMap, const std::string &sdata)
{
- ServerInstance->Modules->UnpublishInterface("HashRequest", this);
+ return "";
}
- void OnRequest(Request& request)
+ RIProv(Module* m) : HashProvider(m, "hash/ripemd160") {}
+};
+
+class ModuleRIPEMD160 : public Module
+{
+ public:
+ RIProv mr;
+ ModuleRIPEMD160() : mr(this)
{
- if (strcmp("HASH", request.id) == 0)
- {
- HashRequest& req = static_cast<HashRequest&>(request);
- char* data = (char*)RMD((byte*)req.data.data(), req.data.length(), NULL);
- req.binresult.assign(data, RMDsize / 8);
- }
- else if (strcmp("NAME", request.id) == 0)
- {
- static_cast<HashNameRequest&>(request).response = "ripemd160";
- }
+ ServerInstance->Modules->AddService(mr);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
- return Version("Allows for RIPEMD-160 encrypted oper passwords", VF_VENDOR);
+ return Version("Provides RIPEMD-160 hashing", VF_VENDOR);
}
};
diff --git a/src/modules/m_rline.cpp b/src/modules/m_rline.cpp
index 87a95a1ff..5d7415fb5 100644
--- a/src/modules/m_rline.cpp
+++ b/src/modules/m_rline.cpp
@@ -15,8 +15,6 @@
#include "m_regex.h"
#include "xline.h"
-static Module* rxengine = NULL;
-static Module* mymodule = NULL; /* Needed to let RLine send request! */
static bool ZlineOnMatch = false;
static std::vector<ZLine *> background_zlines;
@@ -34,21 +32,15 @@ class RLine : public XLine
* @param regex Pattern to match with
* @
*/
- RLine(time_t s_time, long d, std::string src, std::string re, std::string regexs)
+ RLine(time_t s_time, long d, std::string src, std::string re, std::string regexs, dynamic_reference<RegexFactory>& rxfactory)
: XLine(s_time, d, src, re, "R")
{
matchtext = regexs;
- if (!rxengine)
- {
- ServerInstance->SNO->WriteToSnoMask('a', "Cannot create regexes until engine is set to a loaded provider!");
- throw ModuleException("Regex engine not set or loaded!");
- }
-
/* This can throw on failure, but if it does we DONT catch it here, we catch it and display it
* where the object is created, we might not ALWAYS want it to output stuff to snomask x all the time
*/
- regex = RegexFactoryRequest(mymodule, rxengine, regexs).Create();
+ regex = rxfactory->Create(regexs);
}
/** Destructor
@@ -102,15 +94,22 @@ class RLine : public XLine
class RLineFactory : public XLineFactory
{
public:
- RLineFactory() : XLineFactory("R")
+ dynamic_reference<RegexFactory>& rxfactory;
+ RLineFactory(dynamic_reference<RegexFactory>& rx) : XLineFactory("R"), rxfactory(rx)
{
}
-
+
/** Generate a RLine
*/
XLine* Generate(time_t set_time, long duration, std::string source, std::string reason, std::string xline_specific_mask)
{
- return new RLine(set_time, duration, source, reason, xline_specific_mask);
+ if (!rxfactory)
+ {
+ ServerInstance->SNO->WriteToSnoMask('a', "Cannot create regexes until engine is set to a loaded provider!");
+ throw ModuleException("Regex engine not set or loaded!");
+ }
+
+ return new RLine(set_time, duration, source, reason, xline_specific_mask, rxfactory);
}
~RLineFactory()
@@ -124,9 +123,10 @@ class RLineFactory : public XLineFactory
class CommandRLine : public Command
{
std::string rxengine;
+ RLineFactory& factory;
public:
- CommandRLine(Module* Creator) : Command(Creator,"RLINE", 1, 3)
+ CommandRLine(Module* Creator, RLineFactory& rlf) : Command(Creator,"RLINE", 1, 3), factory(rlf)
{
flags_needed = 'o'; this->syntax = "<regex> [<rline-duration>] :<reason>";
}
@@ -139,11 +139,11 @@ class CommandRLine : public Command
// Adding - XXX todo make this respect <insane> tag perhaps..
long duration = ServerInstance->Duration(parameters[1]);
- RLine *r = NULL;
+ XLine *r = NULL;
try
{
- r = new RLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str());
+ r = factory.Generate(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str());
}
catch (ModuleException &e)
{
@@ -197,30 +197,26 @@ class CommandRLine : public Command
class ModuleRLine : public Module
{
private:
- CommandRLine r;
+ dynamic_reference<RegexFactory> rxfactory;
RLineFactory f;
+ CommandRLine r;
bool MatchOnNickChange;
std::string RegexEngine;
public:
- ModuleRLine() : r(this)
+ ModuleRLine() : rxfactory(this, "regex"), f(rxfactory), r(this, f)
{
- mymodule = this;
OnRehash(NULL);
- ServerInstance->Modules->UseInterface("RegularExpression");
-
ServerInstance->AddCommand(&r);
ServerInstance->XLines->RegisterFactory(&f);
- Implementation eventlist[] = { I_OnUserConnect, I_OnRehash, I_OnUserPostNick, I_OnLoadModule, I_OnStats, I_OnBackgroundTimer };
- ServerInstance->Modules->Attach(eventlist, this, 6);
-
+ Implementation eventlist[] = { I_OnUserConnect, I_OnRehash, I_OnUserPostNick, I_OnStats, I_OnBackgroundTimer };
+ ServerInstance->Modules->Attach(eventlist, this, 5);
}
virtual ~ModuleRLine()
{
- ServerInstance->Modules->DoneWithInterface("RegularExpression");
ServerInstance->XLines->DelAll("R");
ServerInstance->XLines->UnregisterFactory(&f);
}
@@ -253,29 +249,8 @@ class ModuleRLine : public Module
ZlineOnMatch = Conf.ReadFlag("rline", "zlineonmatch", 0);
std::string newrxengine = Conf.ReadValue("rline", "engine", 0);
- if (!RegexEngine.empty())
- {
- if (RegexEngine == newrxengine)
- return;
-
- ServerInstance->SNO->WriteToSnoMask('x', "Dumping all R-Lines due to regex engine change (was '%s', now '%s')", RegexEngine.c_str(), newrxengine.c_str());
- ServerInstance->XLines->DelAll("R");
- }
- rxengine = 0;
- RegexEngine = newrxengine;
- modulelist* ml = ServerInstance->Modules->FindInterface("RegularExpression");
- if (ml)
- {
- for (modulelist::iterator i = ml->begin(); i != ml->end(); ++i)
- {
- if (RegexNameRequest(this, *i).result == newrxengine)
- {
- ServerInstance->SNO->WriteToSnoMask('a', "R-Line now using engine '%s'", RegexEngine.c_str());
- rxengine = *i;
- }
- }
- }
- if (!rxengine)
+ rxfactory.SetProvider("regex/" + newrxengine);
+ if (!rxfactory)
{
ServerInstance->SNO->WriteToSnoMask('a', "WARNING: Regex engine '%s' is not loaded - R-Line functionality disabled until this is corrected.", RegexEngine.c_str());
}
@@ -290,19 +265,6 @@ class ModuleRLine : public Module
return MOD_RES_DENY;
}
- virtual void OnLoadModule(Module* mod)
- {
- if (ServerInstance->Modules->ModuleHasInterface(mod, "RegularExpression"))
- {
- std::string rxname = RegexNameRequest(this, mod).result;
- if (rxname == RegexEngine)
- {
- ServerInstance->SNO->WriteToSnoMask('a', "R-Line now using engine '%s'", RegexEngine.c_str());
- rxengine = mod;
- }
- }
- }
-
virtual void OnUserPostNick(User *user, const std::string &oldnick)
{
if (!IS_LOCAL(user))
diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp
index 298544edc..07f6bb0ed 100644
--- a/src/modules/m_sasl.cpp
+++ b/src/modules/m_sasl.cpp
@@ -229,8 +229,8 @@ class ModuleSASL : public Module
Implementation eventlist[] = { I_OnEvent, I_OnUserRegister };
ServerInstance->Modules->Attach(eventlist, this, 2);
- providerbase* providelist[] = { &auth, &sasl, &authExt };
- ServerInstance->AddServices(providelist, 3);
+ ServiceProvider* providelist[] = { &auth, &sasl, &authExt };
+ ServerInstance->Modules->AddServices(providelist, 3);
if (!ServerInstance->Modules->Find("m_services_account.so") || !ServerInstance->Modules->Find("m_cap.so"))
ServerInstance->Logs->Log("m_sasl", DEFAULT, "WARNING: m_services_account.so and m_cap.so are not loaded! m_sasl.so will NOT function correctly until these two modules are loaded!");
diff --git a/src/modules/m_sha256.cpp b/src/modules/m_sha256.cpp
index 7856b296b..8c2b00eea 100644
--- a/src/modules/m_sha256.cpp
+++ b/src/modules/m_sha256.cpp
@@ -132,7 +132,7 @@ uint32_t sha256_k[64] =
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
-class ModuleSHA256 : public Module
+class HashSHA256 : public HashProvider
{
void SHA256Init(SHA256Context *ctx, const unsigned int* ikey)
{
@@ -245,35 +245,33 @@ class ModuleSHA256 : public Module
}
public:
- ModuleSHA256()
+ std::string sum(const std::string& data)
{
- ServerInstance->Modules->PublishInterface("HashRequest", this);
+ unsigned char bytes[SHA256_DIGEST_SIZE];
+ SHA256(data.data(), bytes, data.length());
+ return std::string((char*)bytes, SHA256_DIGEST_SIZE);
}
- virtual ~ModuleSHA256()
+ std::string sumIV(unsigned int* IV, const char* HexMap, const std::string &sdata)
{
- ServerInstance->Modules->UnpublishInterface("HashRequest", this);
+ return "";
}
+ HashSHA256(Module* parent) : HashProvider(parent, "hash/sha256") {}
+};
- void OnRequest(Request& request)
+class ModuleSHA256 : public Module
+{
+ HashSHA256 sha;
+ public:
+ ModuleSHA256() : sha(this)
{
- if (strcmp("HASH", request.id) == 0)
- {
- unsigned char bytes[SHA256_DIGEST_SIZE];
- HashRequest& req = static_cast<HashRequest&>(request);
- SHA256(req.data.data(), bytes, req.data.length());
- req.binresult.assign((char*)bytes, SHA256_DIGEST_SIZE);
- }
- else if (strcmp("NAME", request.id) == 0)
- {
- static_cast<HashNameRequest&>(request).response = "sha256";
- }
+ ServerInstance->Modules->AddService(sha);
}
Version GetVersion()
{
- return Version("Allows for SHA-256 encrypted oper passwords", VF_VENDOR);
+ return Version("Implements SHA-256 hashing", VF_VENDOR);
}
};
diff --git a/src/modules/m_spanningtree/compat.cpp b/src/modules/m_spanningtree/compat.cpp
index b35879cd9..dd577fca7 100644
--- a/src/modules/m_spanningtree/compat.cpp
+++ b/src/modules/m_spanningtree/compat.cpp
@@ -26,6 +26,7 @@ static const char* const forge_common_1201[] = {
"m_saquit.so",
"m_setident.so",
"m_swhois.so",
+ "m_regex_pcre.so"
};
static std::string wide_newline("\r\n");
diff --git a/src/modules/m_spanningtree/hmac.cpp b/src/modules/m_spanningtree/hmac.cpp
index b5a5fa228..790358d36 100644
--- a/src/modules/m_spanningtree/hmac.cpp
+++ b/src/modules/m_spanningtree/hmac.cpp
@@ -55,16 +55,13 @@ std::string TreeSocket::MakePass(const std::string &password, const std::string
* Note: If m_sha256.so is not loaded, we MUST fall back to plaintext with no
* HMAC challenge/response.
*/
- Module* sha256 = ServerInstance->Modules->Find("m_sha256.so");
+ HashProvider* sha256 = ServerInstance->Modules->FindDataService<HashProvider>("hash/sha256");
if (Utils->ChallengeResponse && sha256 && !challenge.empty())
{
- /* XXX: This is how HMAC is supposed to be done:
+ /* This is how HMAC is supposed to be done:
*
* sha256( (pass xor 0x5c) + sha256((pass xor 0x36) + m) )
*
- * Note that we are encoding the hex hash, not the binary
- * output of the hash which is slightly different to standard.
- *
* 5c and 36 were chosen as part of the HMAC standard, because they
* flip the bits in a way likely to strengthen the function.
*/
@@ -72,17 +69,28 @@ std::string TreeSocket::MakePass(const std::string &password, const std::string
for (size_t n = 0; n < password.length(); n++)
{
- hmac1 += static_cast<char>(password[n] ^ 0x5C);
- hmac2 += static_cast<char>(password[n] ^ 0x36);
+ hmac1.push_back(static_cast<char>(password[n] ^ 0x5C));
+ hmac2.push_back(static_cast<char>(password[n] ^ 0x36));
}
- hmac2 += challenge;
- hmac2 = HashRequest(Utils->Creator, sha256, hmac2).hex();
+ if (proto_version >= 1202)
+ {
+ hmac2.append(challenge);
+ std::string hmac = sha256->hexsum(hmac1 + sha256->sum(hmac2));
+
+ return "AUTH:" + hmac;
+ }
+ else
+ {
+ // version 1.2 used a weaker HMAC, using hex output in the intermediate step
+ hmac2.append(challenge);
+ hmac2 = sha256->hexsum(hmac2);
- std::string hmac = hmac1 + hmac2;
- hmac = HashRequest(Utils->Creator, sha256, hmac).hex();
+ std::string hmac = hmac1 + hmac2;
+ hmac = sha256->hexsum(hmac);
- return "HMAC-SHA256:"+ hmac;
+ return "HMAC-SHA256:"+ hmac;
+ }
}
else if (!challenge.empty() && !sha256)
ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Not authenticating to server using SHA256/HMAC because we don't have m_sha256 loaded!");
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index fe2cfe9b6..0ed9b28ac 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -33,7 +33,6 @@
ModuleSpanningTree::ModuleSpanningTree()
: max_local(0), max_global(0)
{
- ServerInstance->Modules->UseInterface("BufferedSocketHook");
Utils = new SpanningTreeUtilities(this);
command_rconnect = new CommandRConnect(this, Utils);
ServerInstance->AddCommand(command_rconnect);
@@ -781,30 +780,16 @@ void ModuleSpanningTree::OnRehash(User* user)
void ModuleSpanningTree::OnLoadModule(Module* mod)
{
- this->RedoConfig(mod);
+ // TODO notify other servers?
}
void ModuleSpanningTree::OnUnloadModule(Module* mod)
{
- this->RedoConfig(mod);
+ // TODO notify other servers?
}
void ModuleSpanningTree::RedoConfig(Module* mod)
{
- /* If m_sha256.so is loaded (we use this for HMAC) or any module implementing a BufferedSocket interface is loaded,
- * then we need to re-read our config again taking this into account.
- */
- modulelist* ml = ServerInstance->Modules->FindInterface("BufferedSocketHook");
- bool IsBufferSocketModule = false;
-
- /* Did we find any modules? */
- if (ml && std::find(ml->begin(), ml->end(), mod) != ml->end())
- IsBufferSocketModule = true;
-
- if (mod->ModuleSourceFile == "m_sha256.so" || IsBufferSocketModule)
- {
- Utils->ReadConfiguration();
- }
}
// note: the protocol does not allow direct umode +o except
@@ -955,7 +940,6 @@ CullResult ModuleSpanningTree::cull()
{
Utils->cull();
ServerInstance->Timers->DelTimer(RefreshTimer);
- ServerInstance->Modules->DoneWithInterface("BufferedSocketHook");
return this->Module::cull();
}
diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp
index e41b53583..abed5fc25 100644
--- a/src/modules/m_spanningtree/treesocket1.cpp
+++ b/src/modules/m_spanningtree/treesocket1.cpp
@@ -40,26 +40,14 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, const std::string& shost, in
LinkState = CONNECTING;
if (!hook.empty())
{
- modulelist* ml = ServerInstance->Modules->FindInterface("BufferedSocketHook");
- if (ml)
+ ServiceProvider* prov = ServerInstance->Modules->FindService(SERVICE_IOHOOK, hook);
+ if (!prov)
{
- for(modulelist::iterator i = ml->begin(); i != ml->end(); ++i)
- {
- std::string name = (**i).ModuleSourceFile;
- int a = name.rfind('_');
- int b = name.rfind('.');
- name = name.substr(a+1, b-a-1);
- if (name == hook)
- {
- AddIOHook(*i);
- goto found;
- }
- }
+ SetError("Could not find hook '" + hook + "' for connection to " + ServerName);
+ return;
}
- SetError("Could not find hook '" + hook + "' for connection to " + ServerName);
- return;
+ AddIOHook(prov->creator);
}
-found:
DoConnect(shost, iport, maxtime, bindto);
Utils->timeoutlist[this] = std::pair<std::string, int>(ServerName, maxtime);
SendCapabilities(1);
diff --git a/src/modules/m_sqlauth.cpp b/src/modules/m_sqlauth.cpp
index 3a4461480..9b8a27ab7 100644
--- a/src/modules/m_sqlauth.cpp
+++ b/src/modules/m_sqlauth.cpp
@@ -35,16 +35,14 @@ class ModuleSQLAuth : public Module
public:
ModuleSQLAuth() : sqlAuthed("sqlauth", this)
{
- ServerInstance->Modules->UseInterface("SQLutils");
- ServerInstance->Modules->UseInterface("SQL");
-
SQLutils = ServerInstance->Modules->Find("m_sqlutils.so");
if (!SQLutils)
throw ModuleException("Can't find m_sqlutils.so. Please load m_sqlutils.so before m_sqlauth.so.");
- SQLprovider = ServerInstance->Modules->FindFeature("SQL");
- if (!SQLprovider)
+ ServiceProvider* prov = ServerInstance->Modules->FindService(SERVICE_DATA, "SQL");
+ if (!prov)
throw ModuleException("Can't find an SQL provider module. Please load one before attempting to load m_sqlauth.");
+ SQLprovider = prov->creator;
OnRehash(NULL);
Implementation eventlist[] = { I_OnUserDisconnect, I_OnCheckReady, I_OnRehash, I_OnUserRegister };
@@ -53,11 +51,8 @@ public:
virtual ~ModuleSQLAuth()
{
- ServerInstance->Modules->DoneWithInterface("SQL");
- ServerInstance->Modules->DoneWithInterface("SQLutils");
}
-
void OnRehash(User* user)
{
ConfigReader Conf;
@@ -105,19 +100,13 @@ public:
SearchAndReplace(thisquery, std::string("$server"), std::string(user->server));
SearchAndReplace(thisquery, std::string("$uuid"), user->uuid);
- Module* HashMod = ServerInstance->Modules->Find("m_md5.so");
-
- if (HashMod)
- {
- SearchAndReplace(thisquery, std::string("$md5pass"), HashRequest(this, HashMod, user->password).hex());
- }
-
- HashMod = ServerInstance->Modules->Find("m_sha256.so");
+ HashProvider* md5 = ServerInstance->Modules->FindDataService<HashProvider>("hash/md5");
+ if (md5)
+ SearchAndReplace(thisquery, std::string("$md5pass"), md5->hexsum(user->password));
- if (HashMod)
- {
- SearchAndReplace(thisquery, std::string("$sha256pass"), HashRequest(this, HashMod, user->password).hex());
- }
+ HashProvider* sha256 = ServerInstance->Modules->FindDataService<HashProvider>("hash/sha256");
+ if (sha256)
+ SearchAndReplace(thisquery, std::string("$sha256pass"), sha256->hexsum(user->password));
/* Build the query */
SQLrequest req = SQLrequest(this, SQLprovider, databaseid, SQLquery(thisquery));
diff --git a/src/modules/m_sqllog.cpp b/src/modules/m_sqllog.cpp
index 8ff12a8d9..29fa320db 100644
--- a/src/modules/m_sqllog.cpp
+++ b/src/modules/m_sqllog.cpp
@@ -156,15 +156,15 @@ class ModuleSQLLog : public Module
public:
ModuleSQLLog()
- {
- ServerInstance->Modules->UseInterface("SQLutils");
- ServerInstance->Modules->UseInterface("SQL");
-
+ {
Module* SQLutils = ServerInstance->Modules->Find("m_sqlutils.so");
if (!SQLutils)
throw ModuleException("Can't find m_sqlutils.so. Please load m_sqlutils.so before m_sqlauth.so.");
- SQLModule = ServerInstance->Modules->FindFeature("SQL");
+ ServiceProvider* prov = ServerInstance->Modules->FindService(SERVICE_DATA, "SQL");
+ if (!prov)
+ throw ModuleException("Can't find an SQL provider module. Please load one before attempting to load m_sqlauth.");
+ SQLModule = prov->creator;
OnRehash(NULL);
MyMod = this;
@@ -175,13 +175,6 @@ class ModuleSQLLog : public Module
ServerInstance->Modules->Attach(eventlist, this, 8);
}
- virtual ~ModuleSQLLog()
- {
- ServerInstance->Modules->DoneWithInterface("SQL");
- ServerInstance->Modules->DoneWithInterface("SQLutils");
- }
-
-
void ReadConfig()
{
ConfigReader Conf;
diff --git a/src/modules/m_sqloper.cpp b/src/modules/m_sqloper.cpp
index a6da1ddaa..3ee47953b 100644
--- a/src/modules/m_sqloper.cpp
+++ b/src/modules/m_sqloper.cpp
@@ -27,50 +27,22 @@ class ModuleSQLOper : public Module
LocalStringExt saved_pass;
Module* SQLutils;
std::string databaseid;
- irc::string hashtype;
- hashymodules hashers;
- bool diduseiface;
+ std::string hashtype;
parameterlist names;
public:
ModuleSQLOper() : saved_user("sqloper_user", this), saved_pass("sqloper_pass", this)
{
- ServerInstance->Modules->UseInterface("SQLutils");
- ServerInstance->Modules->UseInterface("SQL");
- ServerInstance->Modules->UseInterface("HashRequest");
-
OnRehash(NULL);
- diduseiface = false;
-
- /* Find all modules which implement the interface 'HashRequest' */
- modulelist* ml = ServerInstance->Modules->FindInterface("HashRequest");
-
- /* Did we find any modules? */
- if (ml)
- {
- /* Yes, enumerate them all to find out the hashing algorithm name */
- for (modulelist::iterator m = ml->begin(); m != ml->end(); m++)
- {
- /* Make a request to it for its name, its implementing
- * HashRequest so we know its safe to do this
- */
- std::string name = HashNameRequest(this, *m).response;
- /* Build a map of them */
- hashers[name.c_str()] = *m;
- names.push_back(name);
- }
- /* UseInterface doesn't do anything if there are no providers, so we'll have to call it later if a module gets loaded later on. */
- diduseiface = true;
- ServerInstance->Modules->UseInterface("HashRequest");
- }
-
SQLutils = ServerInstance->Modules->Find("m_sqlutils.so");
if (!SQLutils)
throw ModuleException("Can't find m_sqlutils.so. Please load m_sqlutils.so before m_sqloper.so.");
Implementation eventlist[] = { I_OnRehash, I_OnPreCommand, I_OnLoadModule };
- ServerInstance->Modules->Attach(eventlist, this, 4);
+ ServerInstance->Modules->Attach(eventlist, this, 3);
+ ServerInstance->Modules->AddService(saved_user);
+ ServerInstance->Modules->AddService(saved_pass);
}
bool OneOfMatches(const char* host, const char* ip, const char* hostlist)
@@ -87,36 +59,12 @@ public:
return false;
}
- virtual void OnLoadModule(Module* mod)
- {
- if (ServerInstance->Modules->ModuleHasInterface(mod, "HashRequest"))
- {
- std::string sname = HashNameRequest(this, mod).response;
- hashers[sname.c_str()] = mod;
- names.push_back(sname);
- if (!diduseiface)
- {
- ServerInstance->Modules->UseInterface("HashRequest");
- diduseiface = true;
- }
- }
- }
-
- virtual ~ModuleSQLOper()
- {
- ServerInstance->Modules->DoneWithInterface("SQL");
- ServerInstance->Modules->DoneWithInterface("SQLutils");
- if (diduseiface)
- ServerInstance->Modules->DoneWithInterface("HashRequest");
- }
-
-
virtual void OnRehash(User* user)
{
ConfigReader Conf;
databaseid = Conf.ReadValue("sqloper", "dbid", 0); /* Database ID of a database configured for the service provider module */
- hashtype = assign(Conf.ReadValue("sqloper", "hash", 0));
+ hashtype = Conf.ReadValue("sqloper", "hash", 0);
}
virtual ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
@@ -138,18 +86,14 @@ public:
bool LookupOper(User* user, const std::string &username, const std::string &password)
{
- Module* target;
-
- target = ServerInstance->Modules->FindFeature("SQL");
-
- if (target)
+ ServiceProvider* prov = ServerInstance->Modules->FindService(SERVICE_DATA, "SQL");
+ if (prov)
{
- hashymodules::iterator x = hashers.find(hashtype);
- if (x == hashers.end())
- return false;
+ Module* target = prov->creator;
+ HashProvider* hash = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + hashtype);
/* Make an MD5 hash of the password for using in the query */
- std::string md5_pass_hash = HashRequest(this, x->second, password).hex();
+ std::string md5_pass_hash = hash ? hash->hexsum(password) : password;
/* We generate our own sum here because some database providers (e.g. SQLite) dont have a builtin md5/sha256 function,
* also hashing it in the module and only passing a remote query containing a hash is more secure.
diff --git a/src/modules/m_sqlutils.cpp b/src/modules/m_sqlutils.cpp
index db5a990e1..a65f6c24a 100644
--- a/src/modules/m_sqlutils.cpp
+++ b/src/modules/m_sqlutils.cpp
@@ -33,14 +33,12 @@ private:
public:
ModuleSQLutils() : idExt("sqlutils_list", this)
{
- ServerInstance->Modules->PublishInterface("SQLutils", this);
Implementation eventlist[] = { I_OnChannelDelete, I_OnUnloadModule, I_OnUserDisconnect };
ServerInstance->Modules->Attach(eventlist, this, 3);
}
~ModuleSQLutils()
{
- ServerInstance->Modules->UnpublishInterface("SQLutils", this);
}
diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp
index 7457ce296..b028a6eb2 100644
--- a/src/modules/m_sslinfo.cpp
+++ b/src/modules/m_sslinfo.cpp
@@ -129,12 +129,6 @@ class ModuleSSLInfo : public Module
Implementation eventlist[] = { I_OnWhois, I_OnPreCommand };
ServerInstance->Modules->Attach(eventlist, this, 2);
- ServerInstance->Modules->PublishInterface("SSLCertInfo", this);
- }
-
- ~ModuleSSLInfo()
- {
- ServerInstance->Modules->UnpublishInterface("SSLCertInfo", this);
}
Version GetVersion()
diff --git a/src/modules/m_testclient.cpp b/src/modules/m_testclient.cpp
index c6abb0064..36027f41e 100644
--- a/src/modules/m_testclient.cpp
+++ b/src/modules/m_testclient.cpp
@@ -34,7 +34,10 @@ public:
virtual void OnBackgroundTimer(time_t)
{
- Module* target = ServerInstance->Modules->FindFeature("SQL");
+ ServiceProvider* prov = ServerInstance->Modules->FindService(SERVICE_DATA, "SQL");
+ if (!prov)
+ return;
+ Module* target = prov->creator;
if(target)
{