From 699381d21b4909bf2070776ac9418dda9e3ab24b Mon Sep 17 00:00:00 2001 From: NaNg Date: Sat, 30 Jan 2016 18:34:50 +0100 Subject: [PATCH] Replace requestpassword with lostpassword --- chanserv/authcmds/lostpassword.c | 76 ++++++++++++++++++++ chanserv/authcmds/newpass.c | 3 +- chanserv/authcmds/requestpassword.c | 70 ------------------ chanserv/authcmds/resetpassword.c | 107 ++++++++++++++++++++++++++++ chanserv/authcmds/sendpassword.c | 31 ++++---- chanserv/batcher/config.py.example | 1 + chanserv/batcher/templates.py | 17 +++-- chanserv/chanserv.h | 2 +- 8 files changed, 216 insertions(+), 91 deletions(-) create mode 100644 chanserv/authcmds/lostpassword.c delete mode 100644 chanserv/authcmds/requestpassword.c create mode 100644 chanserv/authcmds/resetpassword.c diff --git a/chanserv/authcmds/lostpassword.c b/chanserv/authcmds/lostpassword.c new file mode 100644 index 00000000..bcba593f --- /dev/null +++ b/chanserv/authcmds/lostpassword.c @@ -0,0 +1,76 @@ +/* CMDNAME: lostpassword + * CMDALIASES: lostpass + * CMDLEVEL: QCMD_NOTAUTHED + * CMDARGS: 2 + * CMDDESC: Sends a code to reset the password with. + * CMDFUNC: csa_dolostpw + * CMDPROTO: int csa_dolostpw(void *source, int cargc, char **cargv); + * CMDHELP: Usage: @UCOMMAND@ + * CMDHELP: Sends instructions for resetting your account to your registered email address, where: + * CMDHELP: email - your email address + */ + +#include "../chanserv.h" +#include "../authlib.h" +#include "../../lib/irc_string.h" +#include +#include + +int csa_dolostpw(void *source, int cargc, char **cargv) { + reguser *rup; + nick *sender=source; + time_t t; + int i, matched = 0; + + if (cargc<1) { + chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "lostpassword"); + return CMD_ERROR; + } + + t=time(NULL); + + for (i=0;inextbyname) { + if(!rup->email || strcasecmp(cargv[0],rup->email->content)) + continue; + + if(UHasStaffPriv(rup)) { + cs_log(sender,"LOSTPASSWORD FAIL privileged email %s",cargv[0]); + continue; + } + + matched = 1; + + if(rup->lockuntil && rup->lockuntil > t) { + chanservstdmessage(sender, QM_ACCOUNTLOCKED, rup->lockuntil); + continue; + } + + if(csa_checkthrottled(sender, rup, "LOSTPASSWORD")) + continue; + + rup->lockuntil=t; + rup->lastemailchange=t; + csdb_updateuser(rup); + + if(rup->lastauth) { + csdb_createmail(rup, QMAIL_LOSTPW); + } else { + csdb_createmail(rup, QMAIL_NEWACCOUNT); /* user hasn't authed yet and needs to do the captcha */ + } + + cs_log(sender,"LOSTPASSWORD OK username %s email %s", rup->username, rup->email->content); + chanservstdmessage(sender, QM_MAILQUEUED); + } + } + + if(!matched) { + cs_log(sender,"LOSTPASSWORD FAIL email %s",cargv[0]); + chanservstdmessage(sender, QM_BADEMAIL); + return CMD_ERROR; + } else { + chanservstdmessage(sender, QM_DONE); + } + + return CMD_OK; +} diff --git a/chanserv/authcmds/newpass.c b/chanserv/authcmds/newpass.c index b6be66aa..0052ba69 100644 --- a/chanserv/authcmds/newpass.c +++ b/chanserv/authcmds/newpass.c @@ -24,6 +24,7 @@ #include "../chanserv.h" #include "../authlib.h" #include "../../lib/irc_string.h" +#include "../../lib/hmac.h" #include "../../core/hooks.h" #include #include @@ -56,7 +57,7 @@ int csa_donewpw(void *source, int cargc, char **cargv) { return CMD_ERROR; } - if (!strcmp(cargv[0],cargv[1])) { + if (!hmac_strcmp(cargv[0],cargv[1])) { /* If they are the same then continue anyway but don't send the hook later. */ same=1; } diff --git a/chanserv/authcmds/requestpassword.c b/chanserv/authcmds/requestpassword.c deleted file mode 100644 index 887b3e6b..00000000 --- a/chanserv/authcmds/requestpassword.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Automatically generated by refactor.pl. - * - * - * CMDNAME: requestpassword - * CMDALIASES: requestpass - * CMDLEVEL: QCMD_NOTAUTHED - * CMDARGS: 2 - * CMDDESC: Requests the current password by email. - * CMDFUNC: csa_doreqpw - * CMDPROTO: int csa_doreqpw(void *source, int cargc, char **cargv); - * CMDHELP: Usage: @UCOMMAND@ - * CMDHELP: Sends your current password to your registered email address, where: - * CMDHELP: email - your registered email address - */ - -#include "../chanserv.h" -#include "../authlib.h" -#include "../../lib/irc_string.h" -#include -#include - -int csa_doreqpw(void *source, int cargc, char **cargv) { - reguser *rup; - nick *sender=source; - int i, matched = 0; - - if (cargc<1) { - chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "requestpassword"); - return CMD_ERROR; - } - - for (i=0;inextbyname) { - if(!rup->email || strcasecmp(cargv[0],rup->email->content)) - continue; - - if(UHasStaffPriv(rup)) { - cs_log(sender,"REQUESTPASSWORD FAIL privileged email %s",cargv[0]); - continue; - } - - matched = 1; - - if(csa_checkthrottled(sender, rup, "REQUESTPASSWORD")) - continue; - - rup->lastemailchange=time(NULL); - csdb_updateuser(rup); - - if(rup->lastauth) { - csdb_createmail(rup, QMAIL_REQPW); - } else { - csdb_createmail(rup, QMAIL_NEWACCOUNT); /* user hasn't authed yet and needs to do the captcha */ - } - - cs_log(sender,"REQUESTPASSWORD OK username %s email %s", rup->username,rup->email->content); - chanservstdmessage(sender, QM_MAILQUEUED); - } - } - - if(!matched) { - cs_log(sender,"REQUESTPASSWORD FAIL email %s",cargv[0]); - chanservstdmessage(sender, QM_BADEMAIL); - return CMD_ERROR; - } else { - chanservstdmessage(sender, QM_DONE); - } - - return CMD_OK; -} diff --git a/chanserv/authcmds/resetpassword.c b/chanserv/authcmds/resetpassword.c new file mode 100644 index 00000000..3f4eb66a --- /dev/null +++ b/chanserv/authcmds/resetpassword.c @@ -0,0 +1,107 @@ +/* CMDNAME: resetpassword + * CMDALIASES: resetpass + * CMDLEVEL: QCMD_SECURE | QCMD_NOTAUTHED + * CMDARGS: 4 + * CMDDESC: Resets the password. + * CMDFUNC: csa_dorespw + * CMDPROTO: int csa_dorespw(void *source, int cargc, char **cargv); + * CMDHELP: Usage: @UCOMMAND@ + * CMDHELP: Resets your password using the code received on your registered email address, where: + * CMDHELP: username - your username + * CMDHELP: newpass - your desired new password. Must be entered the same both times. + * CMDHELP: code - the code received in the RESET email. + */ + +#include "../chanserv.h" +#include "../authlib.h" +#include "../../lib/irc_string.h" +#include "../../lib/hmac.h" +#include +#include + +int csa_dorespw(void *source, int cargc, char **cargv) { + reguser *rup; + nick *sender=source; + unsigned int same=0; + int pq; + time_t t; + + if (cargc<4) { + chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "resetpassword"); + return CMD_ERROR; + } + + if (!(rup=findreguser(sender, cargv[0]))) + return CMD_ERROR; + + if (strcmp(cargv[1],cargv[2])) { + chanservstdmessage(sender, QM_PWDONTMATCH); /* Sorry, passwords do not match */ + cs_log(sender,"RESETPASS FAIL username %s new passwords don't match (%s vs %s)",rup->username,cargv[1],cargv[2]); + return CMD_ERROR; + } + + if (!hmac_strcmp(rup->password,cargv[1])) { + /* If they are the same then continue anyway but don't send the hook later. */ + same=1; + } + + pq = csa_checkpasswordquality(cargv[1]); + if(pq == QM_PWTOSHORT) { + chanservstdmessage(sender, QM_PWTOSHORT); /* new password too short */ + cs_log(sender,"RESETPASS FAIL username %s password too short %s (%zu characters)",rup->username,cargv[1],strlen(cargv[1])); + return CMD_ERROR; + } else if(pq == QM_PWTOWEAK) { + chanservstdmessage(sender, QM_PWTOWEAK); /* new password is weak */ + cs_log(sender,"RESETPASS FAIL username %s password too weak %s",rup->username,cargv[1]); + return CMD_ERROR; + } else if(pq == QM_PWTOLONG) { + chanservstdmessage(sender, QM_PWTOLONG); /* new password too long */ + cs_log(sender,"RESETPASS FAIL username %s password too long %s",rup->username,cargv[1]); + return CMD_ERROR; + } else if(pq == -1) { + /* all good */ + } else { + chanservsendmessage(sender, "unknown error in resetpass.c... contact #help"); + return CMD_ERROR; + } + + if(UHasStaffPriv(rup) || !rup->lockuntil || hmac_strcmp(cargv[3], csc_generateresetcode(rup->lockuntil, rup->username))) { + chanservstdmessage(sender, QM_BADRESETCODE); + return CMD_ERROR; + } + + t=time(NULL); + + if(rup->lockuntil > t) { + chanservstdmessage(sender, QM_ACCOUNTLOCKED, rup->lockuntil); + return CMD_ERROR; + } + + rup->lockuntil=t+7*24*3600; + + if(rup->lastemail) { + freesstring(rup->lastemail); + rup->lastemail=NULL; + } + + rup->lastpasschange=t; + csdb_accounthistory_insert(sender, rup->password, cargv[1], NULL, NULL); + setpassword(rup, cargv[1]); + + rup->lastauth=t; + chanservstdmessage(sender, QM_PWCHANGED); + cs_log(sender,"RESETPASS OK username %s", rup->username); + +#ifdef AUTHGATE_WARNINGS + if(UHasOperPriv(rup)) + chanservsendmessage(sender, "WARNING FOR PRIVILEGED USERS: you MUST go to https://auth.quakenet.org and login successfully to update the cache, if you do not your old password will still be usable in certain circumstances."); +#endif + + csdb_updateuser(rup); + csdb_createmail(rup, QMAIL_NEWPW); + + if (!same) + triggerhook(HOOK_CHANSERV_PWCHANGE, sender); + + return CMD_OK; +} diff --git a/chanserv/authcmds/sendpassword.c b/chanserv/authcmds/sendpassword.c index 033e2f15..bdeb31f1 100644 --- a/chanserv/authcmds/sendpassword.c +++ b/chanserv/authcmds/sendpassword.c @@ -1,15 +1,12 @@ -/* Automatically generated by refactor.pl. - * - * - * CMDNAME: sendpassword +/* CMDNAME: sendpassword * CMDALIASES: sendpass * CMDLEVEL: QCMD_HELPER * CMDARGS: 1 - * CMDDESC: Sends the users current password by email. + * CMDDESC: Sends the user a reset code to the email. * CMDFUNC: csa_dosendpw * CMDPROTO: int csa_dosendpw(void *source, int cargc, char **cargv); * CMDHELP: Usage: @UCOMMAND@ - * CMDHELP: Sends the password for the specified account to the specified users email address. + * CMDHELP: Sends the password for the specified account to the user's email address. */ #include "../chanserv.h" @@ -21,6 +18,7 @@ int csa_dosendpw(void *source, int cargc, char **cargv) { reguser *rup; nick *sender=source; + time_t t; if (cargc<1) { chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "sendpassword"); @@ -36,16 +34,23 @@ int csa_dosendpw(void *source, int cargc, char **cargv) { return CMD_ERROR; } - /* we don't reset the throttling timer - rup->lastemailchange=time(NULL); - csdb_updateuser(rup); - */ + t = time(NULL); - if(rup->lastauth) { - csdb_createmail(rup, QMAIL_REQPW); + if(rup->lockuntil && rup->lockuntil > t) { + // Send same reset code. + csdb_createmail(rup, QMAIL_NEWPW); } else { - csdb_createmail(rup, QMAIL_NEWACCOUNT); /* user hasn't authed yet and needs to do the captcha */ + rup->lockuntil=t; + rup->lastemailchange=t; + csdb_updateuser(rup); + + if(rup->lastauth) { + csdb_createmail(rup, QMAIL_LOSTPW); + } else { + csdb_createmail(rup, QMAIL_NEWACCOUNT); /* user hasn't authed yet and needs to do the captcha */ + } } + chanservstdmessage(sender, QM_MAILQUEUED); cs_log(sender,"SENDPASSWORD username %s", rup->username); diff --git a/chanserv/batcher/config.py.example b/chanserv/batcher/config.py.example index 9a210c1c..00613c91 100644 --- a/chanserv/batcher/config.py.example +++ b/chanserv/batcher/config.py.example @@ -4,6 +4,7 @@ CONFIG = { "smtpauth": None, "templateoptions": { "bot": "Q9", + "botsecure": "Q9@CServe.test.quakenet.org", "cleanup": 80, "securityurl": "http://www.quakenet.org/faq/faq.php?c=160", "siteurl": "http://www.quakenet.org/", diff --git a/chanserv/batcher/templates.py b/chanserv/batcher/templates.py index 648f39cd..fda7ddd9 100644 --- a/chanserv/batcher/templates.py +++ b/chanserv/batcher/templates.py @@ -46,9 +46,14 @@ def generate_resetcode(config, obj): obj["lockuntil"] = time.ctime(obj["user.lockuntil"]) obj["resetline"] = "/MSG %(config.bot)s RESET #%(user.username)s %(resetcode)s" % obj +def generate_resetpassword(config, obj): + generate_resetcode(config, obj) + obj["resetline"] = "/MSG %(config.botsecure)s RESETPASSWORD #%(user.username)s %(resetcode)s" %obj + MAILTEMPLATES = { "mutators": { 1: generate_url, + 2: generate_resetpassword, 3: generate_resetcode, 5: generate_resetcode, 6: generate_activation_url, @@ -85,15 +90,15 @@ def generate_resetcode(config, obj): NB: Save this email for future reference. """, }, - 2: { "subject": "%(config.bot)s password request", "body": """ -Your username/password is: + 2: { "subject": "%(config.bot)s reset password", "body": """ +A password reset was requested for your account, to reset your password please use: +%(resetline)s -Username: %(user.username)s -Password: %(user.password)s +Where should be replaced with your desired password. -To auth yourself to %(config.bot)s, type the following command +For more information please visit the resetpassword help link at http://www.quakenet.org/help/q-commands/resetpassword - /MSG %(config.bot)s@%(config.server)s AUTH %(user.username)s %(user.password)s +If it was not you who issued this command, please disregard this mail. """, }, 3: { "subject": "%(config.bot)s password change", "body": """ Your password has recently changed. If this was not requested by you, diff --git a/chanserv/chanserv.h b/chanserv/chanserv.h index e636e3fc..bc72a509 100644 --- a/chanserv/chanserv.h +++ b/chanserv/chanserv.h @@ -258,7 +258,7 @@ #define VALID_ACCOUNT_NAME "\\A[a-z][a-z0-9\\-]+\\Z" #define QMAIL_NEWACCOUNT 1 /* new account */ -#define QMAIL_REQPW 2 /* requestpassword */ +#define QMAIL_LOSTPW 2 /* lostpassword */ #define QMAIL_NEWPW 3 /* new password */ #define QMAIL_RESET 4 /* reset account */ #define QMAIL_NEWEMAIL 5 /* new email address */