Added password recovery facility
SVN revision: 478
This commit is contained in:
+308
-109
@@ -6,6 +6,9 @@
|
||||
Contents: Web server program for Electronic Logbook ELOG
|
||||
|
||||
$Log$
|
||||
Revision 1.69 2003/04/07 15:26:58 midas
|
||||
Added password recovery facility
|
||||
|
||||
Revision 1.68 2003/04/07 09:25:57 midas
|
||||
Added button 'remember me'
|
||||
|
||||
@@ -1468,9 +1471,12 @@ char list[1024][NAME_LENGTH];
|
||||
send(s, str, strlen(str), 0);
|
||||
if (verbose) puts(str);
|
||||
|
||||
snprintf(str, strsize - 1, "X-Elog-URL: %s\r\n", url);
|
||||
send(s, str, strlen(str), 0);
|
||||
if (verbose) puts(str);
|
||||
if (url)
|
||||
{
|
||||
snprintf(str, strsize - 1, "X-Elog-URL: %s\r\n", url);
|
||||
send(s, str, strlen(str), 0);
|
||||
if (verbose) puts(str);
|
||||
}
|
||||
|
||||
snprintf(str, strsize - 1, "X-Elog-submit-type: web|elog\r\n");
|
||||
send(s, str, strlen(str), 0);
|
||||
@@ -4703,20 +4709,11 @@ struct tm *ts;
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
|
||||
void show_change_pwd_page(LOGBOOK *lbs)
|
||||
BOOL change_pwd(LOGBOOK *lbs, char *user, char *pwd)
|
||||
{
|
||||
char str[256], str2[256], file_name[256], line[256], *p, *pl, old_pwd[32],
|
||||
new_pwd[32], new_pwd2[32], user[80];
|
||||
char str[256], file_name[256], line[256], *p, *pl;
|
||||
char *buf;
|
||||
int i, fh, wrong_pwd, size;
|
||||
|
||||
do_crypt(getparam("oldpwd"), old_pwd);
|
||||
do_crypt(getparam("newpwd"), new_pwd);
|
||||
do_crypt(getparam("newpwd2"), new_pwd2);
|
||||
|
||||
strcpy(user, getparam("unm"));
|
||||
if (isparam("config"))
|
||||
strcpy(user, getparam("config"));
|
||||
int i, fh, size;
|
||||
|
||||
getcfg(lbs->name, "Password file", str);
|
||||
|
||||
@@ -4728,108 +4725,134 @@ int i, fh, wrong_pwd, size;
|
||||
strlcat(file_name, str, sizeof(file_name));
|
||||
}
|
||||
|
||||
fh = open(file_name, O_RDWR | O_BINARY, 644);
|
||||
if (fh > 0)
|
||||
{
|
||||
lseek(fh, 0, SEEK_END);
|
||||
size = TELL(fh);
|
||||
lseek(fh, 0, SEEK_SET);
|
||||
|
||||
buf = malloc(size+1);
|
||||
read(fh, buf, size);
|
||||
buf[size] = 0;
|
||||
pl = buf;
|
||||
|
||||
while (pl < buf+size)
|
||||
{
|
||||
for (i=0 ; pl[i] && pl[i] != '\r' && pl[i] != '\n' ; i++)
|
||||
line[i] = pl[i];
|
||||
line[i] = 0;
|
||||
|
||||
if (line[0] == ';' || line[0] == '#' || line[0] == 0)
|
||||
{
|
||||
pl += strlen(line);
|
||||
while (*pl && (*pl == '\r' || *pl == '\n'))
|
||||
pl++;
|
||||
continue;
|
||||
}
|
||||
|
||||
strcpy(str, line);
|
||||
if (strchr(str, ':'))
|
||||
*strchr(str, ':') = 0;
|
||||
if (strcmp(str, user) == 0)
|
||||
break;
|
||||
|
||||
pl += strlen(line);
|
||||
while (*pl && (*pl == '\r' || *pl == '\n'))
|
||||
pl++;
|
||||
}
|
||||
|
||||
/* return if not found */
|
||||
if (pl >= buf+size)
|
||||
{
|
||||
free(buf);
|
||||
close(fh);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
p = strchr(line, ':');
|
||||
if (p)
|
||||
p = strchr(p+1, ':');
|
||||
if (p == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* replace password */
|
||||
lseek(fh, 0, SEEK_SET);
|
||||
write(fh, buf, pl-buf);
|
||||
|
||||
sprintf(str, "%s:%s%s\n", user, pwd, p);
|
||||
write(fh, str, strlen(str));
|
||||
|
||||
pl += strlen(line);
|
||||
while (*pl && (*pl == '\r' || *pl == '\n'))
|
||||
pl++;
|
||||
|
||||
write(fh, pl, strlen(pl));
|
||||
|
||||
#ifdef _MSC_VER
|
||||
chsize(fh, TELL(fh));
|
||||
#else
|
||||
ftruncate(fh, TELL(fh));
|
||||
#endif
|
||||
|
||||
free(buf);
|
||||
close(fh);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
|
||||
void show_change_pwd_page(LOGBOOK *lbs)
|
||||
{
|
||||
char str[256], old_pwd[32],
|
||||
new_pwd[32], new_pwd2[32], act_pwd[32], user[80];
|
||||
int wrong_pwd;
|
||||
|
||||
do_crypt(getparam("oldpwd"), old_pwd);
|
||||
do_crypt(getparam("newpwd"), new_pwd);
|
||||
do_crypt(getparam("newpwd2"), new_pwd2);
|
||||
|
||||
strcpy(user, getparam("unm"));
|
||||
if (isparam("config"))
|
||||
strcpy(user, getparam("config"));
|
||||
|
||||
wrong_pwd = FALSE;
|
||||
|
||||
if (old_pwd[0] || new_pwd[0])
|
||||
{
|
||||
fh = open(file_name, O_RDWR | O_BINARY, 644);
|
||||
if (fh > 0)
|
||||
if (user[0] && get_user_line(lbs->name, user, act_pwd, NULL, NULL, NULL))
|
||||
{
|
||||
lseek(fh, 0, SEEK_END);
|
||||
size = TELL(fh);
|
||||
lseek(fh, 0, SEEK_SET);
|
||||
|
||||
buf = malloc(size+1);
|
||||
read(fh, buf, size);
|
||||
buf[size] = 0;
|
||||
pl = buf;
|
||||
|
||||
while (pl < buf+size)
|
||||
if (getcfg(lbs->name, "Admin user", str) &&
|
||||
strstr(str, user) != 0)
|
||||
wrong_pwd = 0;
|
||||
else
|
||||
{
|
||||
for (i=0 ; pl[i] && pl[i] != '\r' && pl[i] != '\n' ; i++)
|
||||
line[i] = pl[i];
|
||||
line[i] = 0;
|
||||
|
||||
if (line[0] == ';' || line[0] == '#' || line[0] == 0)
|
||||
{
|
||||
pl += strlen(line);
|
||||
while (*pl && (*pl == '\r' || *pl == '\n'))
|
||||
pl++;
|
||||
continue;
|
||||
}
|
||||
|
||||
strcpy(str, line);
|
||||
if (strchr(str, ':'))
|
||||
*strchr(str, ':') = 0;
|
||||
if (strcmp(str, user) == 0)
|
||||
break;
|
||||
|
||||
pl += strlen(line);
|
||||
while (*pl && (*pl == '\r' || *pl == '\n'))
|
||||
pl++;
|
||||
if (strcmp(old_pwd, act_pwd) != 0)
|
||||
wrong_pwd = 1;
|
||||
}
|
||||
|
||||
/* if user found, check old password */
|
||||
if (user[0] && (strcmp(str, user) == 0))
|
||||
{
|
||||
p = line+strlen(str);
|
||||
if (*p)
|
||||
p++;
|
||||
if (strcmp(new_pwd, new_pwd2) != 0)
|
||||
wrong_pwd = 2;
|
||||
}
|
||||
|
||||
strcpy(str2, p);
|
||||
if (strchr(str2, ':'))
|
||||
*strchr(str2, ':') = 0;
|
||||
/* replace password */
|
||||
if (!wrong_pwd)
|
||||
change_pwd(lbs, user, new_pwd);
|
||||
|
||||
if (getcfg(lbs->name, "Admin user", str) &&
|
||||
strstr(str, getparam("unm")) != 0)
|
||||
wrong_pwd = 0;
|
||||
else
|
||||
{
|
||||
if (strcmp(old_pwd, str2) != 0)
|
||||
wrong_pwd = 1;
|
||||
}
|
||||
if (!wrong_pwd && strcmp(user, getparam("unm")) == 0)
|
||||
{
|
||||
set_login_cookies(lbs, user, new_pwd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(new_pwd, new_pwd2) != 0)
|
||||
wrong_pwd = 2;
|
||||
}
|
||||
|
||||
/* replace password */
|
||||
if (!wrong_pwd)
|
||||
{
|
||||
lseek(fh, 0, SEEK_SET);
|
||||
write(fh, buf, pl-buf);
|
||||
|
||||
sprintf(str, "%s:%s:%s:%s\n", user, new_pwd,
|
||||
getparam("full_name"), getparam("user_email"));
|
||||
write(fh, str, strlen(str));
|
||||
|
||||
pl += strlen(line);
|
||||
while (*pl && (*pl == '\r' || *pl == '\n'))
|
||||
pl++;
|
||||
|
||||
write(fh, pl, strlen(pl));
|
||||
|
||||
#ifdef _MSC_VER
|
||||
chsize(fh, TELL(fh));
|
||||
#else
|
||||
ftruncate(fh, TELL(fh));
|
||||
#endif
|
||||
}
|
||||
|
||||
free(buf);
|
||||
close(fh);
|
||||
|
||||
if (!wrong_pwd && strcmp(user, getparam("unm")) == 0)
|
||||
{
|
||||
set_login_cookies(lbs, user, new_pwd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wrong_pwd)
|
||||
{
|
||||
redirect(lbs, ".");
|
||||
return;
|
||||
}
|
||||
if (!wrong_pwd)
|
||||
{
|
||||
redirect(lbs, ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4852,8 +4875,14 @@ int i, fh, wrong_pwd, size;
|
||||
if (!getcfg(lbs->name, "Admin user", str) ||
|
||||
!strstr(str, getparam("unm")) != 0)
|
||||
{
|
||||
rsprintf("<tr><td align=right class=\"dlgform\">%s:\n", loc("Old password"));
|
||||
rsprintf("<td align=left class=\"dlgform\"><input type=password name=oldpwd></td></tr>\n");
|
||||
if (isparam("old_pwd"))
|
||||
rsprintf("<input type=hidden name=oldpwd value=\"%s\"", getparam("old_pwd"));
|
||||
else
|
||||
{
|
||||
rsprintf("<tr><td align=right class=\"dlgform\">%s:\n", loc("Old password"));
|
||||
rsprintf("<td align=left class=\"dlgform\"><input type=password name=oldpwd>\n");
|
||||
rsprintf("</td></tr>\n");
|
||||
}
|
||||
}
|
||||
|
||||
rsprintf("<tr><td align=right class=\"dlgform\">%s:</td>\n", loc("New password"));
|
||||
@@ -4903,6 +4932,10 @@ BOOL is_author(LOGBOOK *lbs, char attrib[MAX_N_ATTR][NAME_LENGTH], char *owner)
|
||||
char str[1000], preset[1000];
|
||||
int i;
|
||||
|
||||
/* check if current user is admin */
|
||||
if (getcfg(lbs->name, "Admin user", str) && strstr(str, getparam("unm")) != 0)
|
||||
return TRUE;
|
||||
|
||||
/* search attribute which contains short_name of author */
|
||||
for (i=0 ; i<lbs->n_attr ; i++)
|
||||
{
|
||||
@@ -6413,6 +6446,149 @@ int i;
|
||||
rsprintf("</body></html>\r\n");
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
|
||||
void show_forgot_pwd_page(LOGBOOK *lbs)
|
||||
{
|
||||
int i;
|
||||
char str[1000], login_name[256], full_name[256], user_email[256], name[256], pwd[256], redir[256],
|
||||
pwd_encrypted[256], smtp_host[256], mail_from[256], subject[256], mail_text[1000], url[1000];
|
||||
|
||||
if (isparam("login_name"))
|
||||
{
|
||||
/* seach in pwd file */
|
||||
|
||||
strcpy(name, getparam("login_name"));
|
||||
|
||||
for (i=0 ; ; i++)
|
||||
{
|
||||
if (!enum_user_line(lbs, i, login_name))
|
||||
break;
|
||||
|
||||
get_user_line(lbs->name, login_name, NULL, full_name, user_email, NULL);
|
||||
|
||||
if (equal_ustring(name, login_name) || equal_ustring(name, full_name) || equal_ustring(name, user_email))
|
||||
{
|
||||
if (user_email[0] == 0)
|
||||
{
|
||||
sprintf(str, loc("No Email address registered with user name <i>\"%s\"</i>"), name);
|
||||
show_error(str);
|
||||
return;
|
||||
}
|
||||
|
||||
/* create random password */
|
||||
srand((unsigned int)time(NULL));
|
||||
for (i=0 ; i<6 ; i++)
|
||||
str[i] = rand() & 0x7F;
|
||||
str[i] = 0;
|
||||
base64_encode(str, pwd);
|
||||
do_crypt(pwd, pwd_encrypted);
|
||||
|
||||
/* send email with new password */
|
||||
if (!getcfg("global", "SMTP host", smtp_host))
|
||||
{
|
||||
show_error(loc("No SMTP host defined in [global] section of configuration file"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to get URL from referer */
|
||||
if (!getcfg("global", "URL", url))
|
||||
{
|
||||
if (referer[0])
|
||||
strcpy(url, referer);
|
||||
else
|
||||
{
|
||||
if (tcp_port == 80)
|
||||
sprintf(url, "http://%s/", host_name);
|
||||
else
|
||||
sprintf(url, "http://%s:%d/", host_name, tcp_port);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (url[strlen(url)-1] != '/')
|
||||
strlcat(url, "/", sizeof(url));
|
||||
strlcat(url, lbs->name, sizeof(url));
|
||||
strlcat(url, "/", sizeof(url));
|
||||
}
|
||||
|
||||
sprintf(redir, "?cmd=Change password&old_pwd=%s", pwd);
|
||||
url_encode(redir, sizeof(redir));
|
||||
sprintf(str, "?redir=%s&uname=%s&upassword=%s", redir, login_name, pwd);
|
||||
strlcat(url, str, sizeof(url));
|
||||
|
||||
if (!getcfg(lbs->name, "Use Email from", mail_from))
|
||||
sprintf(mail_from, "ELog@%s", host_name);
|
||||
|
||||
if (lbs)
|
||||
sprintf(subject, loc("Password recovery for ELOG %s"), lbs->name);
|
||||
else
|
||||
sprintf(subject, loc("Password recovery for ELOG %s"), host_name);
|
||||
|
||||
sprintf(mail_text, loc("A new password has been created for you on host %s"), host_name);
|
||||
strlcat(mail_text, ".\r\n", sizeof(mail_text));
|
||||
strlcat(mail_text, loc("Plese log on by clicking on following link and change your password"), sizeof(mail_text));
|
||||
strlcat(mail_text, ":\r\n\r\n", sizeof(mail_text));
|
||||
strlcat(mail_text, url, sizeof(mail_text));
|
||||
strlcat(mail_text, "\r\n\r\n", sizeof(mail_text));
|
||||
sprintf(mail_text+strlen(mail_text), "ELOG Version %s\r\n", VERSION);
|
||||
|
||||
if (sendmail(smtp_host, mail_from, user_email, subject, mail_text, TRUE, url) != -1)
|
||||
{
|
||||
/* save new password */
|
||||
change_pwd(lbs, login_name, pwd_encrypted);
|
||||
|
||||
/* show notification web page */
|
||||
show_standard_header(lbs, FALSE, loc("ELOG password recovery"), "");
|
||||
|
||||
rsprintf("<table class=\"dlgframe\" cellspacing=0 align=center>");
|
||||
rsprintf("<tr><td colspan=2 class=\"dlgtitle\">\n");
|
||||
|
||||
rsprintf(loc("A new password for user <i>\"%s\"</i> has been sent to %s"), full_name, user_email);
|
||||
|
||||
rsprintf("</td></tr></table>\n");
|
||||
rsprintf("</body></html>\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
show_error(loc("Error sending Email"));
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr(name, '@'))
|
||||
sprintf(str, loc("Email address <i>\"%s\"</i> not registered"), name);
|
||||
else
|
||||
sprintf(str, loc("User name <i>\"%s\"</i> not registered"), name);
|
||||
|
||||
show_error(str);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---- header ----*/
|
||||
|
||||
show_standard_header(lbs, TRUE, loc("ELOG password recovery"), NULL);
|
||||
|
||||
rsprintf("<table class=\"dlgframe\" cellspacing=0 align=center>");
|
||||
|
||||
/*---- entry form ----*/
|
||||
|
||||
rsprintf("<tr><td class=\"dlgtitle\">%s</td></tr>\n", loc("Enter your user name or email address"));
|
||||
|
||||
|
||||
rsprintf("<tr><td align=center class=\"dlgform\">\n");
|
||||
rsprintf("<input type=hidden name=cmd value=forgot>\n");
|
||||
rsprintf("<input type=text size=40 name=login_name></td></tr>\n");
|
||||
|
||||
rsprintf("<tr><td align=center class=\"dlgform\"><input type=submit value=\"%s\">\n", loc("Submit"));
|
||||
|
||||
rsprintf("</td></tr></table>\n\n");
|
||||
rsprintf("</body></html>\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
|
||||
void show_new_user_page(LOGBOOK *lbs)
|
||||
@@ -10576,6 +10752,13 @@ int i, n;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check for "forgot password" */
|
||||
if (isparam("cmd") && strcmp(getparam("cmd"), "forgot") == 0)
|
||||
{
|
||||
show_forgot_pwd_page(lbs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* display error message for invalid user */
|
||||
if (isparam("iusr"))
|
||||
{
|
||||
@@ -10909,12 +11092,23 @@ FILE *f;
|
||||
/* if password file is given in global section, protect also logbook selection page */
|
||||
if (getcfg("global", "password file", str))
|
||||
{
|
||||
/* check for self register */
|
||||
if (getcfg("global", "Self register", str) && atoi(str) > 0)
|
||||
{
|
||||
if (!do_self_register(NULL, command))
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for password recovery */
|
||||
if (isparam("cmd") || isparam("newpwd"))
|
||||
{
|
||||
if (equal_ustring(getparam("cmd"), "Change password") || isparam("newpwd"))
|
||||
{
|
||||
show_change_pwd_page(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* if data from login screen, evaluate it and set cookies */
|
||||
if (*getparam("uname") && getparam("upassword"))
|
||||
{
|
||||
@@ -10940,7 +11134,6 @@ FILE *f;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!check_user_password(NULL, getparam("unm"), getparam("upwd"), ""))
|
||||
return;
|
||||
}
|
||||
@@ -11486,6 +11679,12 @@ FILE *f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (equal_ustring(command, loc("Forgot")))
|
||||
{
|
||||
show_forgot_pwd_page(lbs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (equal_ustring(command, loc("Config")))
|
||||
{
|
||||
if (!getcfg(lbs->name, "Password file", str))
|
||||
|
||||
Reference in New Issue
Block a user