Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace requestpassword with lostpassword: second attempt #68

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions chanserv/authcmds/lostpassword.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* CMDNAME: lostpassword
* CMDALIASES: lostpass
* CMDLEVEL: QCMD_NOTAUTHED
* CMDARGS: 1
* CMDDESC: Sends instructions for resetting your account to your registered email address.
* CMDFUNC: csa_dolostpw
* CMDPROTO: int csa_dolostpw(void *source, int cargc, char **cargv);
* CMDHELP: Usage: @UCOMMAND@ <email>
* 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 <stdio.h>
#include <string.h>

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;i<REGUSERHASHSIZE;i++) {
for (rup=regusernicktable[i];rup;rup=rup->nextbyname) {
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;
}
3 changes: 2 additions & 1 deletion chanserv/authcmds/newpass.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "../chanserv.h"
#include "../authlib.h"
#include "../../lib/irc_string.h"
#include "../../lib/hmac.h"
#include "../../core/hooks.h"
#include <stdio.h>
#include <string.h>
Expand Down Expand Up @@ -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;
}
Expand Down
48 changes: 3 additions & 45 deletions chanserv/authcmds/requestpassword.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
*
* CMDNAME: requestpassword
* CMDALIASES: requestpass
* CMDLEVEL: QCMD_NOTAUTHED
* CMDARGS: 2
* CMDLEVEL: QCMD_HIDDEN
* CMDARGS: 1
* CMDDESC: Requests the current password by email.
* CMDFUNC: csa_doreqpw
* CMDPROTO: int csa_doreqpw(void *source, int cargc, char **cargv);
Expand All @@ -20,51 +20,9 @@
#include <string.h>

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;i<REGUSERHASHSIZE;i++) {
for (rup=regusernicktable[i];rup;rup=rup->nextbyname) {
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);
}
chanservstdmessage(sender, QM_CMDDEPRECATEDPREFER, "LOSTPASSWORD");

return CMD_OK;
}
114 changes: 114 additions & 0 deletions chanserv/authcmds/resetpassword.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/* CMDNAME: resetpassword
* CMDALIASES: resetpass
* CMDLEVEL: QCMD_SECURE | QCMD_NOTAUTHED
* CMDARGS: 4
* CMDDESC: Change your password using a code that was sent to your email address.
* CMDFUNC: csa_dorespw
* CMDPROTO: int csa_dorespw(void *source, int cargc, char **cargv);
* CMDHELP: Usage: @UCOMMAND@ <username> <code> <newpassword> <newpassword>
* CMDHELP: Changes your account password using a code that was sent to your email address.
* CMDHELP: Your new password must be at least 6 characters long, contain at least one number
* CMDHELP: and one letter, and may not contain sequences of letters or numbers. Also note
* CMDHELP: that your password will be truncated to 10 characters.
* CMDHELP: Your new password will be sent to your registered email address.
* CMDHELP: Where:
* CMDHELP: username - your username
* CMDHELP: code - code you received in an email sent to your registered address
* CMDHELP: newpassword - your desired new password. Must be entered the same both times.
* CMDHELP: Note: due to the sensitive nature of this command, you must send the message to
* CMDHELP: [email protected] when using it.
*/

#include "../chanserv.h"
#include "../authlib.h"
#include "../../lib/irc_string.h"
#include "../../lib/hmac.h"
#include <stdio.h>
#include <string.h>

int csa_dorespw(void *source, int cargc, char **cargv) {
reguser *rup;
nick *sender=source;
char *username, *code, *newpass, *newpassconfirm;
unsigned int same=0;
int pq;
time_t t;

if (cargc<4) {
chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "resetpassword");
return CMD_ERROR;
}

username=cargv[0];
code=cargv[1];
newpass=cargv[2];
newpassconfirm=cargv[3];

if (!(rup=findreguser(sender, username)))
return CMD_ERROR;

if (strcmp(newpass,newpassconfirm)) {
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,newpass,newpassconfirm);
return CMD_ERROR;
}

if (!hmac_strcmp(rup->password,newpass)) {
/* If they are the same then continue anyway but don't send the hook later. */
same=1;
}

pq = csa_checkpasswordquality(newpass);
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,newpass,strlen(newpass));
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,newpass);
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,newpass);
return CMD_ERROR;
} else if(pq == -1) {
/* all good */
} else {
chanservsendmessage(sender, "Encountered an unknown error; please contact #help.");
return CMD_ERROR;
}

if(UHasStaffPriv(rup) || !rup->lockuntil || hmac_strcmp(code, 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, newpass, NULL, NULL);
setpassword(rup, newpass);

rup->lastauth=t;
chanservstdmessage(sender, QM_PWCHANGED);
cs_log(sender,"RESETPASS OK username %s", rup->username);

csdb_updateuser(rup);

if (!same)
triggerhook(HOOK_CHANSERV_PWCHANGE, sender);

return CMD_OK;
}
33 changes: 19 additions & 14 deletions chanserv/authcmds/sendpassword.c
Original file line number Diff line number Diff line change
@@ -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 their email address.
* CMDFUNC: csa_dosendpw
* CMDPROTO: int csa_dosendpw(void *source, int cargc, char **cargv);
* CMDHELP: Usage: @UCOMMAND@ <username>
* CMDHELP: Sends the password for the specified account to the specified users email address.
* CMDHELP: Sends the password for the specified account to the specified user's email address.
*/

#include "../chanserv.h"
Expand All @@ -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");
Expand All @@ -32,20 +30,27 @@ int csa_dosendpw(void *source, int cargc, char **cargv) {

if(UHasStaffPriv(rup)) {
chanservstdmessage(sender, QM_REQUESTPASSPRIVUSER);
cs_log(sender,"SENDPASSWORD FAIL privilidged user %s",rup->username);
cs_log(sender,"SENDPASSWORD FAIL privileged user %s",rup->username);
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 + 30 * 60 > 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);

Expand Down
19 changes: 12 additions & 7 deletions chanserv/batcher/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.bot)s@%(config.server)s RESETPASSWORD #%(user.username)s %(resetcode)s <newpassword> <newpassword>" %obj

MAILTEMPLATES = {
"mutators": {
1: generate_url,
2: generate_resetpassword,
3: generate_resetcode,
5: generate_resetcode,
6: generate_activation_url,
Expand Down Expand Up @@ -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:

Username: %(user.username)s
Password: %(user.password)s
2: { "subject": "%(config.bot)s password reset request", "body": """
A password reset has been requested for your account. To reset your password,
please use:
%(resetline)s

To auth yourself to %(config.bot)s, type the following command
Where <newpass> should be replaced with your desired password.

/MSG %(config.bot)s@%(config.server)s AUTH %(user.username)s %(user.password)s
If you did not issue this command, you can ignore this email and no changes will
be made to your account.
""", },
3: { "subject": "%(config.bot)s password change", "body": """
Your password has recently changed. If this was not requested by you,
Expand Down
2 changes: 1 addition & 1 deletion chanserv/chanserv.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,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 */
Expand Down
1 change: 1 addition & 0 deletions chanserv/chanserv_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ BeginMessages() {
msg(QM_TOOMANYCHANNELS, "User is known on too many channels.", ""),
msg(QM_PWINVALID, "Password contains invalid characters.", ""),
msg(QM_TOOMANYAUTHATTEMPTS, "Too many auth attempts -- reconnect to QuakeNet to try again.", ""),
msg(QM_CMDDEPRECATEDPREFER, "This command has been removed -- please use $0 instead.", "s"),
}
EndMessages()
#endif