Permalink
Switch branches/tags
v7.2.9 v7.2.8 v7.2.7 atheme-services-7.1.0 atheme-services-7.1.0-rc1 atheme-services-7.1.0-alpha1 atheme-services-7.0.7 atheme-services-7.0.6 atheme-services-7.0.4 atheme-services-7.0.3 atheme-services-7.0.2 atheme-services-7.0.1 atheme-services-7.0.0-rc1 atheme-services-7.0.0-beta2 atheme-services-7.0.0-beta1 atheme-services-7.0.0-alpha14 atheme-services-7.0.0-alpha13.37 atheme-services-7.0.0-alpha13 atheme-services-7.0.0-alpha11 atheme-services-7.0.0-alpha10 atheme-services-7.0.0-alpha9 atheme-services-7.0.0-alpha8 atheme-services-7.0.0-alpha7 atheme-services-7.0.0-alpha6 atheme-services-7.0.0-alpha5 atheme-services-7.0.0-alpha4 atheme-services-7.0.0-alpha3 atheme-services-7.0.0-alpha2 atheme-services-7.0-alpha1 atheme-services-6.0.0 atheme-services-6.0.0-rc2 atheme-services-6.0.0-rc1 atheme-services-6.0.0-beta3 atheme-services-6.0.0-beta2 atheme-services-6.0.0-beta1 atheme-services-6.0.0-alpha7 atheme-services-6.0.0-alpha6 atheme-services-6.0.0-alpha5 atheme-services-6.0.0-alpha4 atheme-services-6.0.0-alpha3 atheme-services-6.0.0-alpha2 atheme-services-5.2.0 atheme-services-5.1.1 atheme-services-5.1.0 atheme-services-5.1-rc1 atheme-services-5.0.1 atheme-services-5.0 atheme-services-5.0-beta1 atheme-services-4.0.1 atheme-services-4.0.0 atheme-services-3.0.3 atheme-services-3.0.2 atheme-services-3.0.1 atheme-services-3.0.0 atheme-7.2.6 atheme-7.2.5 atheme-7.2.4 atheme-7.2.3 atheme-7.2.2 atheme-7.2.1 atheme-7.2.0 atheme-7.2.0-rc2 atheme-7.2.0-rc1 atheme-7.2.0-beta2 atheme-7.2.0-beta1 atheme-7.0.5 atheme-6.0.0-alpha1
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
233 lines (188 sloc) 6.72 KB
/*
* Copyright (c) 2005 Atheme Development Group
* Rights to this code are as documented in doc/LICENSE.
*
* This file contains code for the NickServ VERIFY function.
*/
#include "atheme.h"
static void ns_cmd_verify(sourceinfo_t *si, int parc, char *parv[]);
static void ns_cmd_fverify(sourceinfo_t *si, int parc, char *parv[]);
command_t ns_verify = { "VERIFY", N_("Verifies an account registration."), AC_NONE, 3, ns_cmd_verify, { .path = "nickserv/verify" } };
command_t ns_fverify = { "FVERIFY", N_("Forcefully verifies an account registration."), PRIV_USER_ADMIN, 2, ns_cmd_fverify, { .path = "nickserv/fverify" } };
static void
mod_init(module_t *const restrict m)
{
service_named_bind_command("nickserv", &ns_verify);
service_named_bind_command("nickserv", &ns_fverify);
}
static void
mod_deinit(const module_unload_intent_t intent)
{
service_named_unbind_command("nickserv", &ns_verify);
service_named_unbind_command("nickserv", &ns_fverify);
}
static void ns_cmd_verify(sourceinfo_t *si, int parc, char *parv[])
{
myuser_t *mu;
metadata_t *md;
mowgli_node_t *n;
char *op = parv[0];
char *nick = parv[1];
char *key = parv[2];
hook_user_req_t req;
if (!op || !nick || !key)
{
command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "VERIFY");
command_fail(si, fault_needmoreparams, _("Syntax: VERIFY <operation> <account> <key>"));
return;
}
if (!(mu = myuser_find(nick)))
{
command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), nick);
return;
}
/* forcing users to log in before we verify
* prevents some information leaks
*/
if (!(si->smu == mu))
{
command_fail(si, fault_badparams, _("Please log in before attempting to verify your registration."));
return;
}
if (!strcasecmp(op, "REGISTER"))
{
if (!(mu->flags & MU_WAITAUTH) || !(md = metadata_find(mu, "private:verify:register:key")))
{
command_fail(si, fault_badparams, _("\2%s\2 is not awaiting authorization."), nick);
return;
}
if (!strcasecmp(key, md->value))
{
mu->flags &= ~MU_WAITAUTH;
logcommand(si, CMDLOG_SET, "VERIFY:REGISTER: \2%s\2 (email: \2%s\2)", get_source_name(si), mu->email);
metadata_delete(mu, "private:verify:register:key");
metadata_delete(mu, "private:verify:register:timestamp");
command_success_nodata(si, _("\2%s\2 has now been verified."), entity(mu)->name);
command_success_nodata(si, _("Thank you for verifying your e-mail address! You have taken steps in ensuring that your registrations are not exploited."));
MOWGLI_ITER_FOREACH(n, mu->logins.head)
{
user_t *u = n->data;
ircd_on_login(u, mu, NULL);
}
/* XXX should this indeed be after ircd_on_login? */
req.si = si;
req.mu = mu;
req.mn = mynick_find(entity(mu)->name);
hook_call_user_verify_register(&req);
return;
}
logcommand(si, CMDLOG_SET, "failed VERIFY REGISTER \2%s\2, \2%s\2 (invalid key)", get_source_name(si), mu->email);
command_fail(si, fault_badparams, _("Verification failed. Invalid key for \2%s\2."),
entity(mu)->name);
return;
}
else if (!strcasecmp(op, "EMAILCHG"))
{
if (!(md = metadata_find(mu, "private:verify:emailchg:key")))
{
command_fail(si, fault_badparams, _("\2%s\2 is not awaiting authorization."), nick);
return;
}
if (!strcasecmp(key, md->value))
{
md = metadata_find(mu, "private:verify:emailchg:newemail");
/* Make sure we reject "set email same@address" for
* several accounts (without verifying the change)
* followed by verifying all of them.
*/
if (!email_within_limits(md->value)) {
command_fail(si, fault_toomany, _("\2%s\2 has too many accounts registered."), md->value);
return;
}
myuser_set_email(mu, md->value);
logcommand(si, CMDLOG_SET, "VERIFY:EMAILCHG: \2%s\2 (email: \2%s\2)", get_source_name(si), mu->email);
metadata_delete(mu, "private:verify:emailchg:key");
metadata_delete(mu, "private:verify:emailchg:newemail");
metadata_delete(mu, "private:verify:emailchg:timestamp");
command_success_nodata(si, _("\2%s\2 has now been verified."), mu->email);
return;
}
logcommand(si, CMDLOG_SET, "failed VERIFY EMAILCHG \2%s\2, \2%s\2 (invalid key)", get_source_name(si), mu->email);
command_fail(si, fault_badparams, _("Verification failed. Invalid key for \2%s\2."),
entity(mu)->name);
return;
}
else
{
command_fail(si, fault_badparams, _("Invalid operation specified for \2VERIFY\2."));
command_fail(si, fault_badparams, _("Please double-check your verification e-mail."));
return;
}
}
static void ns_cmd_fverify(sourceinfo_t *si, int parc, char *parv[])
{
myuser_t *mu;
metadata_t *md;
mowgli_node_t *n;
char *op = parv[0];
char *nick = parv[1];
hook_user_req_t req;
if (!op || !nick)
{
command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FVERIFY");
command_fail(si, fault_needmoreparams, _("Syntax: FVERIFY <operation> <account>"));
return;
}
if (!(mu = myuser_find_ext(nick)))
{
command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), nick);
return;
}
if (!strcasecmp(op, "REGISTER"))
{
if (!(mu->flags & MU_WAITAUTH) || !metadata_find(mu, "private:verify:register:key"))
{
command_fail(si, fault_badparams, _("\2%s\2 is not awaiting authorization."), nick);
return;
}
mu->flags &= ~MU_WAITAUTH;
logcommand(si, CMDLOG_REGISTER, "FVERIFY:REGISTER: \2%s\2 (email: \2%s\2)", entity(mu)->name, mu->email);
metadata_delete(mu, "private:verify:register:key");
metadata_delete(mu, "private:verify:register:timestamp");
command_success_nodata(si, _("\2%s\2 has now been verified."), entity(mu)->name);
MOWGLI_ITER_FOREACH(n, mu->logins.head)
{
user_t *u = n->data;
ircd_on_login(u, mu, NULL);
}
/* XXX should this indeed be after ircd_on_login? */
req.si = si;
req.mu = mu;
req.mn = mynick_find(entity(mu)->name);
hook_call_user_verify_register(&req);
return;
}
else if (!strcasecmp(op, "EMAILCHG"))
{
if (!metadata_find(mu, "private:verify:emailchg:key"))
{
command_fail(si, fault_badparams, _("\2%s\2 is not awaiting authorization."), nick);
return;
}
md = metadata_find(mu, "private:verify:emailchg:newemail");
myuser_set_email(mu, md->value);
logcommand(si, CMDLOG_REGISTER, "FVERIFY:EMAILCHG: \2%s\2 (email: \2%s\2)", entity(mu)->name, mu->email);
metadata_delete(mu, "private:verify:emailchg:key");
metadata_delete(mu, "private:verify:emailchg:newemail");
metadata_delete(mu, "private:verify:emailchg:timestamp");
command_success_nodata(si, _("\2%s\2 has now been verified."), mu->email);
return;
}
else
{
command_fail(si, fault_badparams, _("Invalid operation specified for \2FVERIFY\2."));
command_fail(si, fault_badparams, _("Valid operations are REGISTER and EMAILCHG."));
return;
}
}
SIMPLE_DECLARE_MODULE_V1("nickserv/verify", MODULE_UNLOAD_CAPABILITY_OK)