summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2022-12-07 15:59:46 +0000
committerSadie Powell <sadie@witchery.services>2022-12-07 15:59:46 +0000
commit1a2da821064f8d869b999fb8e32ffeddfc82967b (patch)
treeeff9bb4faac0fbbc6bd29fcf2f7f46845f4730d8
parent9d92de115785cb991a0d825a0b783594056ca1bb (diff)
parent4a2861ba3d4002b37d6e83312064245aeb407338 (diff)
Merge branch '2.0' into 2.1.
-rw-r--r--.github/workflows/ci-linux.yml3
-rw-r--r--.gitignore1
-rw-r--r--data/modules.example.conf10
-rw-r--r--modules/extra/m_regex_pcre2.cpp93
-rw-r--r--modules/protocol/hybrid.cpp102
-rw-r--r--modules/webcpanel/pages/nickserv/confirm.cpp26
-rw-r--r--modules/webcpanel/pages/nickserv/confirm.h24
-rw-r--r--modules/webcpanel/templates/default/nickserv/confirm.html29
-rw-r--r--modules/webcpanel/webcpanel.cpp9
-rw-r--r--modules/webcpanel/webcpanel.h1
10 files changed, 271 insertions, 27 deletions
diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml
index d53a83f2c..0a27f24b3 100644
--- a/.github/workflows/ci-linux.yml
+++ b/.github/workflows/ci-linux.yml
@@ -22,6 +22,7 @@ jobs:
libgnutls28-dev \
libldap2-dev \
libmysqlclient-dev \
+ libpcre2-dev \
libpcre3-dev \
libsqlite3-dev \
libssl-dev \
@@ -29,7 +30,7 @@ jobs:
ninja-build
- name: Enable extras
run: |
- for MODULE in m_ldap.cpp m_ldap_authentication.cpp m_ldap_oper.cpp m_mysql.cpp m_regex_pcre.cpp m_regex_posix.cpp m_regex_tre.cpp m_sql_authentication.cpp m_sql_log.cpp m_sql_oper.cpp m_sqlite.cpp m_ssl_gnutls.cpp m_ssl_openssl.cpp stats
+ for MODULE in m_ldap.cpp m_ldap_authentication.cpp m_ldap_oper.cpp m_mysql.cpp m_regex_pcre.cpp m_regex_pcre2.cpp m_regex_posix.cpp m_regex_tre.cpp m_sql_authentication.cpp m_sql_log.cpp m_sql_oper.cpp m_sqlite.cpp m_ssl_gnutls.cpp m_ssl_openssl.cpp stats
do
ln -s ${{ github.workspace }}/modules/extra/$MODULE ${{ github.workspace }}/modules
done
diff --git a/.gitignore b/.gitignore
index b2f62b5cd..03a3a02f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ modules/m_ldap_authentication.cpp
modules/m_ldap_oper.cpp
modules/m_mysql.cpp
modules/m_regex_pcre.cpp
+modules/m_regex_pcre2.cpp
modules/m_regex_posix.cpp
modules/m_regex_tre.cpp
modules/m_sql_authentication.cpp
diff --git a/data/modules.example.conf b/data/modules.example.conf
index 925bee8ad..f06789e41 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -403,11 +403,19 @@ module { name = "help" }
/*
* m_regex_pcre [EXTRA]
*
- * Provides the regex engine regex/pcre, which uses the Perl Compatible Regular Expressions library.
+ * Provides the regex engine regex/pcre, which uses version 1 of the Perl Compatible Regular
+ * Expressions library. This can not be loaded at the same time as the m_regex_pcre2 module.
*/
#module { name = "m_regex_pcre" }
/*
+ * m_regex_pcre2 [EXTRA]
+ *
+ * Provides the regex engine regex/pcre, which uses version 2 of the Perl Compatible Regular
+ * Expressions library. This can not be loaded at the same time as the m_regex_pcre module.
+#module { name = "m_regex_pcre2" }
+
+/*
* m_regex_posix [EXTRA]
*
* Provides the regex engine regex/posix, which uses the POSIX compliant regular expressions.
diff --git a/modules/extra/m_regex_pcre2.cpp b/modules/extra/m_regex_pcre2.cpp
new file mode 100644
index 000000000..a97f0aa73
--- /dev/null
+++ b/modules/extra/m_regex_pcre2.cpp
@@ -0,0 +1,93 @@
+/*
+ *
+ * (C) 2012-2022 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ */
+
+/* RequiredLibraries: pcre2-8 */
+/* RequiredWindowsLibraries: libpcre2-8 */
+
+#include "module.h"
+
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
+
+class PCRERegex : public Regex
+{
+ pcre2_code *regex;
+
+ public:
+ PCRERegex(const Anope::string &expr) : Regex(expr)
+ {
+ int errcode;
+ PCRE2_SIZE erroffset;
+ this->regex = pcre2_compile(reinterpret_cast<PCRE2_SPTR8>(expr.c_str()), expr.length(), PCRE2_CASELESS, &errcode, &erroffset, NULL);
+
+ if (!this->regex)
+ {
+ PCRE2_UCHAR error[128];
+ pcre2_get_error_message(errcode, error, sizeof error);
+ throw RegexException("Error in regex " + expr + " at offset " + stringify(erroffset) + ": " + reinterpret_cast<const char*>(error));
+ }
+ }
+
+ ~PCRERegex()
+ {
+ pcre2_code_free(this->regex);
+ }
+
+ bool Matches(const Anope::string &str)
+ {
+ pcre2_match_data *unused = pcre2_match_data_create_from_pattern(this->regex, NULL);
+ int result = pcre2_match(regex, reinterpret_cast<PCRE2_SPTR8>(str.c_str()), str.length(), 0, 0, unused, NULL);
+ pcre2_match_data_free(unused);
+ return result >= 0;
+ }
+};
+
+class PCRERegexProvider : public RegexProvider
+{
+ public:
+ PCRERegexProvider(Module *creator) : RegexProvider(creator, "regex/pcre") { }
+
+ Regex *Compile(const Anope::string &expression) override
+ {
+ return new PCRERegex(expression);
+ }
+};
+
+class ModuleRegexPCRE : public Module
+{
+ PCRERegexProvider pcre_regex_provider;
+
+ public:
+ ModuleRegexPCRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
+ pcre_regex_provider(this)
+ {
+ this->SetPermanent(true);
+ }
+
+ ~ModuleRegexPCRE()
+ {
+ for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(); it != XLineManager::XLineManagers.end(); ++it)
+ {
+ XLineManager *xlm = *it;
+ const std::vector<XLine *> &xlines = xlm->GetList();
+
+ for (unsigned int i = 0; i < xlines.size(); ++i)
+ {
+ XLine *x = xlines[i];
+
+ if (x->regex && dynamic_cast<PCRERegex *>(x->regex))
+ {
+ delete x->regex;
+ x->regex = NULL;
+ }
+ }
+ }
+ }
+};
+
+MODULE_INIT(ModuleRegexPCRE)
diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp
index 5046030ba..5fa0dcdc4 100644
--- a/modules/protocol/hybrid.cpp
+++ b/modules/protocol/hybrid.cpp
@@ -372,6 +372,21 @@ struct IRCDMessageCapab : Message::Capab
}
};
+struct IRCDMessageCertFP: IRCDMessage
+{
+ IRCDMessageCertFP(Module *creator) : IRCDMessage(creator, "CERTFP", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+
+ /* 0 */
+ /* :0MCAAAAAB CERTFP 4C62287BA6776A89CD4F8FF10A62FFB35E79319F51AF6C62C674984974FCCB1D */
+ void Run(MessageSource &source, const std::vector<Anope::string> &params, const Anope::map<Anope::string> &tags) override
+ {
+ User *u = source.GetUser();
+
+ u->fingerprint = params[0];
+ FOREACH_MOD(OnFingerprint, (u));
+ }
+};
+
struct IRCDMessageEOB : IRCDMessage
{
IRCDMessageEOB(Module *creator) : IRCDMessage(creator, "EOB", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
@@ -398,6 +413,32 @@ struct IRCDMessageJoin : Message::Join
}
};
+struct IRCDMessageMetadata : IRCDMessage
+{
+ IRCDMessageMetadata(Module *creator) : IRCDMessage(creator, "METADATA", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ /* 0 1 2 3 */
+ /* :0MC METADATA client 0MCAAAAAB certfp :4C62287BA6776A89CD4F8FF10A62FFB35E79319F51AF6C62C674984974FCCB1D */
+ void Run(MessageSource &source, const std::vector<Anope::string> &params, const Anope::map<Anope::string> &tags) override
+ {
+ if (params[0].equals_cs("client"))
+ {
+ User *u = User::Find(params[1]);
+ if (!u)
+ {
+ Log(LOG_DEBUG) << "METADATA for nonexistent user " << params[1];
+ return;
+ }
+
+ if (params[2].equals_cs("certfp"))
+ {
+ u->fingerprint = params[3];
+ FOREACH_MOD(OnFingerprint, (u));
+ }
+ }
+ }
+};
+
struct IRCDMessageMLock : IRCDMessage
{
IRCDMessageMLock(Module *creator) : IRCDMessage(creator, "MLOCK", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
@@ -629,21 +670,6 @@ struct IRCDMessageUID : IRCDMessage
}
};
-struct IRCDMessageCertFP: IRCDMessage
-{
- IRCDMessageCertFP(Module *creator) : IRCDMessage(creator, "CERTFP", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
-
- /* 0 */
- /* :0MCAAAAAB CERTFP 4C62287BA6776A89CD4F8FF10A62FFB35E79319F51AF6C62C674984974FCCB1D */
- void Run(MessageSource &source, const std::vector<Anope::string> &params, const Anope::map<Anope::string> &tags) override
- {
- User *u = source.GetUser();
-
- u->fingerprint = params[0];
- FOREACH_MOD(OnFingerprint, (u));
- }
-};
-
class ProtoHybrid : public Module
{
HybridProto ircd_proto;
@@ -671,8 +697,10 @@ class ProtoHybrid : public Module
/* Our message handlers */
IRCDMessageBMask message_bmask;
IRCDMessageCapab message_capab;
+ IRCDMessageCertFP message_certfp;
IRCDMessageEOB message_eob;
IRCDMessageJoin message_join;
+ IRCDMessageMetadata message_metadata;
IRCDMessageMLock message_mlock;
IRCDMessageNick message_nick;
IRCDMessagePass message_pass;
@@ -684,7 +712,6 @@ class ProtoHybrid : public Module
IRCDMessageTBurst message_tburst;
IRCDMessageTMode message_tmode;
IRCDMessageUID message_uid;
- IRCDMessageCertFP message_certfp;
bool use_server_side_mlock;
@@ -749,14 +776,41 @@ class ProtoHybrid : public Module
public:
ProtoHybrid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
ircd_proto(this),
- message_away(this), message_error(this), message_invite(this), message_kick(this),
- message_kill(this), message_mode(this), message_motd(this), message_notice(this), message_part(this),
- message_ping(this), message_privmsg(this), message_quit(this), message_squit(this), message_stats(this),
- message_time(this), message_topic(this), message_version(this), message_whois(this),
- message_bmask(this), message_capab(this), message_eob(this), message_join(this), message_mlock(this),
- message_nick(this), message_pass(this), message_pong(this), message_server(this), message_sid(this),
- message_sjoin(this), message_svsmode(this), message_tburst(this), message_tmode(this), message_uid(this),
- message_certfp(this)
+ message_away(this),
+ message_error(this),
+ message_invite(this),
+ message_kick(this),
+ message_kill(this),
+ message_mode(this),
+ message_motd(this),
+ message_notice(this),
+ message_part(this),
+ message_ping(this),
+ message_privmsg(this),
+ message_quit(this),
+ message_squit(this),
+ message_stats(this),
+ message_time(this),
+ message_topic(this),
+ message_version(this),
+ message_whois(this),
+ message_bmask(this),
+ message_capab(this),
+ message_certfp(this),
+ message_eob(this),
+ message_join(this),
+ message_metadata(this),
+ message_mlock(this),
+ message_nick(this),
+ message_pass(this),
+ message_pong(this),
+ message_server(this),
+ message_sid(this),
+ message_sjoin(this),
+ message_svsmode(this),
+ message_tburst(this),
+ message_tmode(this),
+ message_uid(this)
{
if (Config->GetModule(this))
this->AddModes();
diff --git a/modules/webcpanel/pages/nickserv/confirm.cpp b/modules/webcpanel/pages/nickserv/confirm.cpp
new file mode 100644
index 000000000..00d2196a4
--- /dev/null
+++ b/modules/webcpanel/pages/nickserv/confirm.cpp
@@ -0,0 +1,26 @@
+/*
+ * (C) 2003-2022 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ */
+
+#include "../../webcpanel.h"
+
+WebCPanel::NickServ::Confirm::Confirm(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u)
+{
+}
+
+bool WebCPanel::NickServ::Confirm::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements)
+{
+
+ std::vector<Anope::string> params;
+ params.push_back(message.post_data["code"]);
+
+ WebPanel::RunCommand(client, na->nc->display, na->nc, "NickServ", "nickserv/confirm", params, replacements);
+
+ TemplateFileServer page("nickserv/confirm.html");
+
+ page.Serve(server, page_name, client, message, reply, replacements);
+ return true;
+}
diff --git a/modules/webcpanel/pages/nickserv/confirm.h b/modules/webcpanel/pages/nickserv/confirm.h
new file mode 100644
index 000000000..09b286794
--- /dev/null
+++ b/modules/webcpanel/pages/nickserv/confirm.h
@@ -0,0 +1,24 @@
+/*
+ * (C) 2003-2022 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ */
+
+namespace WebCPanel
+{
+
+namespace NickServ
+{
+
+class Confirm : public WebPanelProtectedPage
+{
+ public:
+ Confirm(const Anope::string &cat, const Anope::string &u);
+
+ bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) override;
+};
+
+}
+
+}
diff --git a/modules/webcpanel/templates/default/nickserv/confirm.html b/modules/webcpanel/templates/default/nickserv/confirm.html
new file mode 100644
index 000000000..66dbe34df
--- /dev/null
+++ b/modules/webcpanel/templates/default/nickserv/confirm.html
@@ -0,0 +1,29 @@
+{INCLUDE header.html}
+ <div class="panel-heading">Confirm your Email</div>
+ <div class="panel-body">
+ {FOR M IN MESSAGES}
+ <div class="alert alert-info">
+ {M}<br>
+ </div>
+ {END FOR}
+
+ <em>You can <strong>CONFIRM</strong> your registration by entering your confirmation code below.</em>
+
+ <hr>
+
+ <h4>Confirm your account</h4>
+ <form class="form-horizontal" method="post" action="/nickserv/confirm">
+ <div class="form-group">
+ <label class="control-label col-lg-2" for="confirm">Confirmation Code:</label>
+ <div class="col-lg-5">
+ <input class="form-control" type="text" name="code" id="code" placeholder="Code from Email">
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="col-lg-offset-2 col-lg-5">
+ <button type="submit" class="btn btn-primary">Confirm Me!</button>
+ </div>
+ </div>
+ </form>
+ </div>
+{INCLUDE footer.html}
diff --git a/modules/webcpanel/webcpanel.cpp b/modules/webcpanel/webcpanel.cpp
index 0c608857d..b8fa12ca6 100644
--- a/modules/webcpanel/webcpanel.cpp
+++ b/modules/webcpanel/webcpanel.cpp
@@ -28,6 +28,7 @@ class ModuleWebCPanel : public Module
WebCPanel::NickServ::Cert nickserv_cert;
WebCPanel::NickServ::Access nickserv_access;
WebCPanel::NickServ::Alist nickserv_alist;
+ WebCPanel::NickServ::Confirm nickserv_confirm;
WebCPanel::ChanServ::Info chanserv_info;
WebCPanel::ChanServ::Set chanserv_set;
@@ -49,7 +50,7 @@ class ModuleWebCPanel : public Module
id(this, "webcpanel_id"), ip(this, "webcpanel_ip"), last_login(this, "webcpanel_last_login"),
style_css("style.css", "/static/style.css", "text/css"), logo_png("logo.png", "/static/logo.png", "image/png"), cubes_png("cubes.png", "/static/cubes.png", "image/png"), favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon"),
index("/"), logout("/logout"), _register("/register"), confirm("/confirm"),
- nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"),
+ nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"), nickserv_confirm("NickServ", "/nickserv/confirm"),
chanserv_info("ChanServ", "/chanserv/info"), chanserv_set("ChanServ", "/chanserv/set"), chanserv_access("ChanServ", "/chanserv/access"), chanserv_akick("ChanServ", "/chanserv/akick"),
chanserv_modes("ChanServ", "/chanserv/modes"), chanserv_drop("ChanServ", "/chanserv/drop"), memoserv_memos("MemoServ", "/memoserv/memos"), hostserv_request("HostServ", "/hostserv/request"),
operserv_akill("OperServ", "/operserv/akill")
@@ -107,6 +108,11 @@ class ModuleWebCPanel : public Module
s.subsections.push_back(ss);
provider->RegisterPage(&this->nickserv_alist);
+ ss.name = "Confirm";
+ ss.url = "/nickserv/confirm";
+ s.subsections.push_back(ss);
+ provider->RegisterPage(&this->nickserv_confirm);
+
panel.sections.push_back(s);
}
@@ -214,6 +220,7 @@ class ModuleWebCPanel : public Module
provider->UnregisterPage(&this->nickserv_cert);
provider->UnregisterPage(&this->nickserv_access);
provider->UnregisterPage(&this->nickserv_alist);
+ provider->UnregisterPage(&this->nickserv_confirm);
provider->UnregisterPage(&this->chanserv_info);
provider->UnregisterPage(&this->chanserv_set);
diff --git a/modules/webcpanel/webcpanel.h b/modules/webcpanel/webcpanel.h
index d1ae8317f..d9b8c5549 100644
--- a/modules/webcpanel/webcpanel.h
+++ b/modules/webcpanel/webcpanel.h
@@ -168,6 +168,7 @@ namespace WebPanel
#include "pages/nickserv/cert.h"
#include "pages/nickserv/access.h"
#include "pages/nickserv/alist.h"
+#include "pages/nickserv/confirm.h"
#include "pages/chanserv/info.h"
#include "pages/chanserv/set.h"