swad-core/swad_password.c

843 lines
30 KiB
C
Raw Permalink Normal View History

2014-12-01 23:55:08 +01:00
// swad_password.c: Users' passwords
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2024 Antonio Ca<EFBFBD>as Vargas
2014-12-01 23:55:08 +01:00
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
2018-10-24 09:25:09 +02:00
#define _GNU_SOURCE // For asprintf
#include <stdio.h> // For asprintf
2014-12-01 23:55:08 +01:00
#include <stdlib.h> // For system, getenv, etc.
#include <string.h> // For string functions
#include <sys/wait.h> // For the macro WEXITSTATUS
#include <unistd.h> // For unlink
#include "swad_action_list.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2014-12-01 23:55:08 +01:00
#include "swad_database.h"
2017-03-30 11:20:06 +02:00
#include "swad_enrolment.h"
#include "swad_error.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-01 23:55:08 +01:00
#include "swad_global.h"
2019-10-23 19:05:05 +02:00
#include "swad_HTML.h"
2014-12-01 23:55:08 +01:00
#include "swad_ID.h"
#include "swad_ID_database.h"
#include "swad_mail_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_password.h"
#include "swad_password_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_parameter.h"
#include "swad_session_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_user.h"
#include "swad_user_database.h"
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
// If there are X users with the same password,
// it means than the password is trivial
// and another user can not change his/her password to this
#define Pwd_MAX_OTHER_USERS_USING_THE_SAME_PASSWORD 2
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
2018-10-16 01:36:13 +02:00
const char *Pwd_PASSWORD_SECTION_ID = "password_section";
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Pwd_CheckAndUpdateNewPwd (struct Usr_Data *UsrDat);
2018-10-16 09:01:02 +02:00
static void Pwd_PutLinkToSendNewPasswdPars (void *UsrIdLogin);
2015-04-02 18:39:49 +02:00
2017-03-07 01:56:41 +01:00
static void Pwd_CreateANewPassword (char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1]);
2014-12-01 23:55:08 +01:00
static bool Pwd_CheckIfPasswdIsUsrIDorName (const char *PlainPassword);
/*****************************************************************************/
/************* Get parameter with my plain password from a form **************/
/*****************************************************************************/
void Pwd_GetParUsrPwdLogin (void)
2014-12-01 23:55:08 +01:00
{
/***** Get plain password from form *****/
Par_GetParText ("UsrPwd",Gbl.Usrs.Me.LoginPlainPassword,
2017-03-07 01:56:41 +01:00
Pwd_MAX_BYTES_PLAIN_PASSWORD);
2014-12-01 23:55:08 +01:00
/***** Encrypt password *****/
Cry_EncryptSHA512Base64 (Gbl.Usrs.Me.LoginPlainPassword,Gbl.Usrs.Me.LoginEncryptedPassword);
}
/*****************************************************************************/
/**** Check if login password is the same as current password in database ****/
/*****************************************************************************/
// Returns true if there's no current password in database, or if login password is the same
// Returns false if there's a current password in database and is not the same as the login password
bool Pwd_CheckCurrentPassword (void)
{
return (Gbl.Usrs.Me.UsrDat.Password[0] ?
!strcmp (Gbl.Usrs.Me.LoginEncryptedPassword,Gbl.Usrs.Me.UsrDat.Password) :
true);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**** Check if login password is the same as current password in database ****/
/*****************************************************************************/
// Returns true if there's pending password in database and login password is the same
// Returns false if there's no a pending password in database, or if pending password is not the same as the login password
bool Pwd_CheckPendingPassword (void)
{
/***** Get pending password from database *****/
Pwd_DB_GetPendingPassword ();
2014-12-01 23:55:08 +01:00
return (Gbl.Usrs.Me.PendingPassword[0] ?
!strcmp (Gbl.Usrs.Me.LoginEncryptedPassword,Gbl.Usrs.Me.PendingPassword) :
false);
}
/*****************************************************************************/
/************ Assign my pending password to my current password **************/
/*****************************************************************************/
void Pwd_AssignMyPendingPasswordToMyCurrentPassword (void)
{
/***** Update my current password in database *****/
Pwd_DB_AssignMyPendingPasswordToMyCurrentPassword ();
2014-12-01 23:55:08 +01:00
/***** Update my current password *****/
2017-01-15 22:58:26 +01:00
Str_Copy (Gbl.Usrs.Me.UsrDat.Password,Gbl.Usrs.Me.PendingPassword,
sizeof (Gbl.Usrs.Me.UsrDat.Password) - 1);
2021-02-02 13:29:19 +01:00
/***** Remove my pending password from database
since it is not longer necessary *****/
Pwd_DB_RemoveMyPendingPassword ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2018-10-16 08:48:51 +02:00
/*********************** Update my password in database **********************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2018-10-16 08:48:51 +02:00
void Pwd_UpdateMyPwd (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_You_have_not_entered_your_password_correctly;
2017-03-07 01:56:41 +01:00
char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1];
2014-12-01 23:55:08 +01:00
/***** Get plain password from form *****/
Par_GetParText ("UsrPwd",PlainPassword,Pwd_MAX_BYTES_PLAIN_PASSWORD);
2014-12-01 23:55:08 +01:00
/***** Encrypt password *****/
Cry_EncryptSHA512Base64 (PlainPassword,Gbl.Usrs.Me.LoginEncryptedPassword);
2018-10-16 09:01:02 +02:00
/***** Check current password *****/
2014-12-01 23:55:08 +01:00
if (Pwd_CheckCurrentPassword ())
2018-10-16 09:01:02 +02:00
/***** Check and update new password *****/
2018-10-25 13:05:36 +02:00
Pwd_CheckAndUpdateNewPwd (&Gbl.Usrs.Me.UsrDat);
2014-12-01 23:55:08 +01:00
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID,
Txt_You_have_not_entered_your_password_correctly);
2014-12-01 23:55:08 +01:00
}
2018-10-16 08:48:51 +02:00
/*****************************************************************************/
/********************* Update another user's password ************************/
/*****************************************************************************/
void Pwd_UpdateOtherUsrPwd (void)
{
/***** Get other user's code from form and get user's data *****/
if (Usr_GetParOtherUsrCodEncryptedAndGetUsrData ())
switch (Usr_CheckIfICanEditOtherUsr (&Gbl.Usrs.Other.UsrDat))
{
case Usr_CAN:
/***** Check and update password *****/
Pwd_CheckAndUpdateNewPwd (&Gbl.Usrs.Other.UsrDat);
break;
case Usr_CAN_NOT:
default:
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
break;
}
2018-10-16 08:48:51 +02:00
else // User not found
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2018-10-16 08:48:51 +02:00
}
2018-10-16 09:01:02 +02:00
/*****************************************************************************/
/********************* Check and update new password *************************/
/*****************************************************************************/
static void Pwd_CheckAndUpdateNewPwd (struct Usr_Data *UsrDat)
2018-10-16 09:01:02 +02:00
{
extern const char *Txt_You_have_not_written_twice_the_same_new_password;
extern const char *Txt_The_password_has_been_changed_successfully;
char NewPlainPassword[2][Pwd_MAX_BYTES_PLAIN_PASSWORD + 1];
char NewEncryptedPassword[Pwd_BYTES_ENCRYPTED_PASSWORD + 1];
Par_GetParText ("Paswd1",NewPlainPassword[0],Pwd_MAX_BYTES_PLAIN_PASSWORD);
Par_GetParText ("Paswd2",NewPlainPassword[1],Pwd_MAX_BYTES_PLAIN_PASSWORD);
2018-10-16 09:01:02 +02:00
/***** Check if I have written twice the same password *****/
if (strcmp (NewPlainPassword[0],
NewPlainPassword[1]))
2018-10-16 09:01:02 +02:00
// Passwords don't match
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID,
Txt_You_have_not_written_twice_the_same_new_password);
2018-10-16 09:01:02 +02:00
else
{
Cry_EncryptSHA512Base64 (NewPlainPassword[0],NewEncryptedPassword);
if (Pwd_SlowCheckIfPasswordIsGood (NewPlainPassword[0],
NewEncryptedPassword,
UsrDat->UsrCod)) // New password is good?
{
2019-02-15 21:09:18 +01:00
/* Update user's data */
2018-10-16 09:01:02 +02:00
Str_Copy (UsrDat->Password,NewEncryptedPassword,
sizeof (UsrDat->Password) - 1);
Ses_DB_UpdateSession ();
2018-10-16 09:01:02 +02:00
Enr_UpdateUsrData (UsrDat);
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_SUCCESS,Pwd_PASSWORD_SECTION_ID,
Txt_The_password_has_been_changed_successfully);
2018-10-16 09:01:02 +02:00
}
}
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-11-16 23:19:52 +01:00
/*************** Show form to send a new password by email *******************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2015-04-02 18:39:49 +02:00
void Pwd_PutLinkToSendNewPasswd (void)
{
2015-12-08 12:09:18 +01:00
extern const char *Txt_Forgotten_password;
2015-04-02 18:39:49 +02:00
2019-01-12 03:00:59 +01:00
Lay_PutContextualLinkIconText (ActReqSndNewPwd,NULL,
Pwd_PutLinkToSendNewPasswdPars,Gbl.Usrs.Me.UsrIdLogin,
"key.svg",Ico_BLACK,
Txt_Forgotten_password,NULL);
2015-04-02 18:39:49 +02:00
}
static void Pwd_PutLinkToSendNewPasswdPars (void *UsrIdLogin)
2015-04-02 18:39:49 +02:00
{
2020-04-08 22:09:35 +02:00
if (UsrIdLogin)
Par_PutParString (NULL,"UsrId",(char *) Gbl.Usrs.Me.UsrIdLogin);
2015-04-02 18:39:49 +02:00
}
/*****************************************************************************/
2016-11-16 23:19:52 +01:00
/*************** Show form to send a new password by email *******************/
2015-04-02 18:39:49 +02:00
/*****************************************************************************/
2014-12-01 23:55:08 +01:00
void Pwd_ShowFormSendNewPwd (void)
{
2016-11-13 11:46:04 +01:00
extern const char *Hlp_PROFILE_Password;
2014-12-01 23:55:08 +01:00
extern const char *Txt_If_you_have_forgotten_your_password_;
2015-12-08 12:09:18 +01:00
extern const char *Txt_Forgotten_password;
2014-12-01 23:55:08 +01:00
extern const char *Txt_nick_email_or_ID;
2015-12-08 12:09:18 +01:00
extern const char *Txt_Get_a_new_password;
2014-12-01 23:55:08 +01:00
2019-10-20 22:00:28 +02:00
/***** Begin form *****/
Frm_BeginForm (ActSndNewPwd);
2014-12-01 23:55:08 +01:00
/***** Begin box *****/
Box_BoxBegin (Txt_Forgotten_password,NULL,NULL,
Hlp_PROFILE_Password,Box_NOT_CLOSABLE);
2015-04-11 23:46:21 +02:00
/***** Help text *****/
Ale_ShowAlert (Ale_INFO,Txt_If_you_have_forgotten_your_password_);
2015-04-11 23:46:21 +02:00
/***** User's ID/nickname *****/
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
HTM_TxtColonNBSP (Txt_nick_email_or_ID);
HTM_INPUT_TEXT ("UsrId",Cns_MAX_CHARS_EMAIL_ADDRESS,Gbl.Usrs.Me.UsrIdLogin,
HTM_DONT_SUBMIT_ON_CHANGE,
"size=\"8\" class=\"INPUT_%s\" required=\"required\"",
The_GetSuffix ());
HTM_LABEL_End ();
2014-12-01 23:55:08 +01:00
/***** Send button and end box *****/
Box_BoxWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Get_a_new_password);
2015-04-11 23:46:21 +02:00
2014-12-01 23:55:08 +01:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-11-16 23:19:52 +01:00
/*********************** Send a new password by email ************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
void Pwd_ChkIdLoginAndSendNewPwd (void)
{
2015-03-27 21:41:53 +01:00
extern const char *Txt_You_must_enter_your_nick_email_or_ID;
2014-12-01 23:55:08 +01:00
extern const char *Txt_There_was_a_problem_sending_an_email_automatically;
extern const char *Txt_If_you_have_written_your_ID_nickname_or_email_correctly_;
struct Usr_ListUsrCods ListUsrCods;
2019-02-14 20:51:08 +01:00
unsigned NumUsr;
2017-03-07 01:56:41 +01:00
char NewRandomPlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1];
2014-12-01 23:55:08 +01:00
int ReturnCode;
2019-02-17 01:14:55 +01:00
char ErrorTxt[256];
2014-12-01 23:55:08 +01:00
/***** Check if user's ID or nickname is not empty *****/
if (!Gbl.Usrs.Me.UsrIdLogin[0])
{
2019-02-16 18:11:52 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_You_must_enter_your_nick_email_or_ID);
2014-12-01 23:55:08 +01:00
Pwd_ShowFormSendNewPwd ();
return;
}
/***** Reset default list of users' codes *****/
ListUsrCods.NumUsrs = 0;
ListUsrCods.Lst = NULL;
/***** Check if user exists *****/
/* Check if user has typed his user's ID or his nickname */
if (Nck_CheckIfNickWithArrIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 1: It's a nickname
2014-12-01 23:55:08 +01:00
{
if ((Gbl.Usrs.Me.UsrDat.UsrCod = Nck_GetUsrCodFromNickname (Gbl.Usrs.Me.UsrIdLogin)) > 0)
{
/* Get user's data */
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
2019-03-06 14:31:21 +01:00
ListUsrCods.Lst[0] = Gbl.Usrs.Me.UsrDat.UsrCod;
2014-12-01 23:55:08 +01:00
}
}
2016-11-16 23:19:52 +01:00
else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 2: It's an email
2014-12-01 23:55:08 +01:00
{
if ((Gbl.Usrs.Me.UsrDat.UsrCod = Mai_DB_GetUsrCodFromEmail (Gbl.Usrs.Me.UsrIdLogin)) > 0)
2014-12-01 23:55:08 +01:00
{
/* Get user's data */
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
2019-03-06 14:31:21 +01:00
ListUsrCods.Lst[0] = Gbl.Usrs.Me.UsrDat.UsrCod;
2014-12-01 23:55:08 +01:00
}
}
2016-11-16 23:19:52 +01:00
else // 3: It's not a nickname nor email
2014-12-01 23:55:08 +01:00
{
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (Gbl.Usrs.Me.UsrIdLogin);
if (ID_CheckIfUsrIDIsValid (Gbl.Usrs.Me.UsrIdLogin))
{
/***** Allocate space for the list *****/
ID_ReallocateListIDs (&Gbl.Usrs.Me.UsrDat,1);
// User has typed a user's ID
2017-01-15 22:58:26 +01:00
Str_Copy (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID,Gbl.Usrs.Me.UsrIdLogin,
sizeof (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID) - 1);
2016-03-21 19:52:40 +01:00
Str_ConvertToUpperText (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID);
2014-12-01 23:55:08 +01:00
/* Get users' codes for this ID */
if (!ID_GetListUsrCodsFromUsrID (&Gbl.Usrs.Me.UsrDat,NULL,&ListUsrCods,true)) // Only confirmed IDs
// If no users found with confirmed IDs, try to get all users (confirmed or not)
ID_GetListUsrCodsFromUsrID (&Gbl.Usrs.Me.UsrDat,NULL,&ListUsrCods,false); // All users (confirmed or not)
}
}
2016-11-16 23:19:52 +01:00
/***** Send a new password via email when user exists *****/
2019-02-14 20:51:08 +01:00
for (NumUsr = 0;
NumUsr < ListUsrCods.NumUsrs;
NumUsr++)
2014-12-01 23:55:08 +01:00
{
2019-02-14 20:51:08 +01:00
Gbl.Usrs.Me.UsrDat.UsrCod = ListUsrCods.Lst[NumUsr];
Usr_GetUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat, // Get my data
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CRS);
2019-02-14 20:51:08 +01:00
if (Gbl.Usrs.Me.UsrDat.Email[0])
switch ((ReturnCode = Pwd_SendNewPasswordByEmail (NewRandomPlainPassword)))
{
case 0: // Message sent successfully
Pwd_SetMyPendingPassword (NewRandomPlainPassword);
break;
case 1:
Err_ShowErrorAndExit (Txt_There_was_a_problem_sending_an_email_automatically);
2019-02-14 20:51:08 +01:00
break;
default:
2019-02-17 01:14:55 +01:00
snprintf (ErrorTxt,sizeof (ErrorTxt),
2019-02-14 20:51:08 +01:00
"Internal error: an email message has not been sent successfully."
" Error code returned by the script: %d",
ReturnCode);
Err_ShowErrorAndExit (ErrorTxt);
2019-02-14 20:51:08 +01:00
break;
}
2014-12-01 23:55:08 +01:00
}
2019-02-14 20:51:08 +01:00
/***** Free list of users' codes *****/
Usr_FreeListUsrCods (&ListUsrCods);
/***** Help message *****/
2019-02-16 18:11:52 +01:00
Ale_ShowAlert (Ale_INFO,Txt_If_you_have_written_your_ID_nickname_or_email_correctly_);
2019-02-14 20:51:08 +01:00
/**** Show forms to login / create account again *****/
Usr_WriteLandingPage ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-11-16 23:19:52 +01:00
/*********************** Send a new password by email ************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
// Gbl.Usrs.Me.UsrDat must be filled
// Return code returned by command
2017-03-07 01:56:41 +01:00
int Pwd_SendNewPasswordByEmail (char NewRandomPlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1])
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_The_following_password_has_been_assigned_to_you_to_log_in_X_NO_HTML;
2018-12-08 16:43:13 +01:00
extern const char *Txt_New_password_NO_HTML[1 + Lan_NUM_LANGUAGES];
2020-04-11 15:21:30 +02:00
char FileNameMail[PATH_MAX + 1];
FILE *FileMail;
Lan_Language_t ToUsrLanguage;
2014-12-01 23:55:08 +01:00
int ReturnCode;
/***** Create temporary file for mail content *****/
2020-04-11 15:21:30 +02:00
Mai_CreateFileNameMail (FileNameMail,&FileMail);
2014-12-01 23:55:08 +01:00
/***** Create a new random password *****/
Pwd_CreateANewPassword (NewRandomPlainPassword);
/***** If I have no language, set language to current language *****/
ToUsrLanguage = Gbl.Usrs.Me.UsrDat.Prefs.Language;
if (ToUsrLanguage == Lan_LANGUAGE_UNKNOWN)
ToUsrLanguage = Gbl.Prefs.Language;
2014-12-01 23:55:08 +01:00
/***** Write mail content into file and close file *****/
/* Welcome note */
Mai_WriteWelcomeNoteEMail (FileMail,&Gbl.Usrs.Me.UsrDat,ToUsrLanguage);
2014-12-01 23:55:08 +01:00
/* Message body */
2020-04-11 15:21:30 +02:00
fprintf (FileMail,Txt_The_following_password_has_been_assigned_to_you_to_log_in_X_NO_HTML,
2017-01-28 15:58:46 +01:00
Cfg_PLATFORM_SHORT_NAME,NewRandomPlainPassword,Cfg_URL_SWAD_CGI,
(unsigned) (Cfg_TIME_TO_DELETE_OLD_PENDING_PASSWORDS / (24L * 60L * 60L)),
2014-12-01 23:55:08 +01:00
Gbl.Usrs.Me.UsrDat.Email);
/* Footer note */
Mai_WriteFootNoteEMail (FileMail,ToUsrLanguage);
2014-12-01 23:55:08 +01:00
2020-04-11 15:21:30 +02:00
fclose (FileMail);
2014-12-01 23:55:08 +01:00
2016-11-16 23:19:52 +01:00
/***** Call the script to send an email *****/
ReturnCode = Mai_SendMailMsg (FileNameMail,
Txt_New_password_NO_HTML[ToUsrLanguage],
Gbl.Usrs.Me.UsrDat.Email);
2014-12-01 23:55:08 +01:00
/***** Remove temporary file *****/
2020-04-11 15:21:30 +02:00
unlink (FileNameMail);
2014-12-01 23:55:08 +01:00
/***** Write message depending on return code *****/
return ReturnCode;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*********************** Create a new random password ************************/
/*****************************************************************************/
2017-03-07 01:56:41 +01:00
static void Pwd_CreateANewPassword (char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1])
2014-12-01 23:55:08 +01:00
{
2017-03-07 01:56:41 +01:00
Str_CreateRandomAlphanumStr (PlainPassword,Pwd_MIN_CHARS_PLAIN_PASSWORD);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************************** Set my pending password *************************/
/*****************************************************************************/
2017-03-07 01:56:41 +01:00
void Pwd_SetMyPendingPassword (char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1])
2014-12-01 23:55:08 +01:00
{
/***** Encrypt my pending password *****/
Cry_EncryptSHA512Base64 (PlainPassword,Gbl.Usrs.Me.PendingPassword);
/***** Remove expired pending passwords from database *****/
Pwd_DB_RemoveExpiredPendingPassword ();
2014-12-01 23:55:08 +01:00
/***** Update my current pending password in database *****/
Pwd_DB_UpdateMyPendingPassword ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************ Check if a password is good ************************/
/*****************************************************************************/
bool Pwd_SlowCheckIfPasswordIsGood (const char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1],
const char EncryptedPassword[Pwd_BYTES_ENCRYPTED_PASSWORD + 1],
2014-12-01 23:55:08 +01:00
long UsrCod)
{
2015-11-02 18:55:24 +01:00
extern const char *Txt_The_password_is_too_trivial_;
2014-12-01 23:55:08 +01:00
/***** Check if password seems good by making fast checks *****/
if (!Pwd_FastCheckIfPasswordSeemsGood (PlainPassword))
return false;
/***** Check if password is found in user's ID, first name or surnames of anybody *****/
if (Pwd_CheckIfPasswdIsUsrIDorName (PlainPassword)) // PlainPassword is a user's ID, name or surname
{
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID,
Txt_The_password_is_too_trivial_);
2014-12-01 23:55:08 +01:00
return false;
}
/***** Check if password is used by too many other users *****/
if (Pwd_DB_GetNumOtherUsrsWhoUseThisPassword (EncryptedPassword,UsrCod) >
2014-12-01 23:55:08 +01:00
Pwd_MAX_OTHER_USERS_USING_THE_SAME_PASSWORD)
{
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID,
Txt_The_password_is_too_trivial_);
2014-12-01 23:55:08 +01:00
return false;
}
return true;
}
/*****************************************************************************/
/***** Check if a password is a user's ID, a first name or a surname *********/
/*****************************************************************************/
static bool Pwd_CheckIfPasswdIsUsrIDorName (const char *PlainPassword)
{
/***** Check if password is found in user's ID *****/
if (ID_DB_FindStrInUsrsIDs (PlainPassword))
return true; // Found
2018-11-03 20:52:00 +01:00
/***** Check if password is found in first name or surnames of anybody *****/
return Usr_DB_FindStrInUsrsNames (PlainPassword);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************** Check if a password seems good ***********************/
/*****************************************************************************/
bool Pwd_FastCheckIfPasswordSeemsGood (const char *PlainPassword)
{
2015-11-02 18:55:24 +01:00
extern const char *Txt_The_password_must_be_at_least_X_characters;
extern const char *Txt_The_password_can_not_contain_spaces;
extern const char *Txt_The_password_can_not_consist_only_of_digits;
2014-12-01 23:55:08 +01:00
unsigned LengthPassword = strlen (PlainPassword),i;
bool ItsANumber;
/***** Check length of password *****/
2017-03-07 01:56:41 +01:00
if (LengthPassword < Pwd_MIN_BYTES_PLAIN_PASSWORD) // PlainPassword too short
2014-12-01 23:55:08 +01:00
{
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID,
Txt_The_password_must_be_at_least_X_characters,
Pwd_MIN_CHARS_PLAIN_PASSWORD);
2014-12-01 23:55:08 +01:00
return false;
}
/***** Check spaces in password *****/
if (strchr (PlainPassword,(int) ' ') != NULL) // PlainPassword with spaces
{
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID,
Txt_The_password_can_not_contain_spaces);
2014-12-01 23:55:08 +01:00
return false;
}
/***** Check if password is a number *****/
for (i = 0, ItsANumber = true;
i < LengthPassword && ItsANumber;
i++)
if (PlainPassword[i] < '0' || PlainPassword[i] > '9')
ItsANumber = false;
if (ItsANumber)
{
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID,
Txt_The_password_can_not_consist_only_of_digits);
2014-12-01 23:55:08 +01:00
return false;
}
return true;
}
/*****************************************************************************/
/********************** Show form for changing my password *******************/
/*****************************************************************************/
2018-10-09 20:32:01 +02:00
void Pwd_ShowFormChgMyPwd (void)
2014-12-01 23:55:08 +01:00
{
2016-11-13 11:46:04 +01:00
extern const char *Hlp_PROFILE_Password;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Before_going_to_any_other_option_you_must_create_your_password;
extern const char *Txt_Your_password_is_not_secure_enough;
extern const char *Txt_Your_password_must_be_at_least_X_characters_and_can_not_contain_spaces_;
extern const char *Txt_Password;
extern const char *Txt_Current_password;
2015-04-03 01:19:45 +02:00
extern const char *Txt_Change_password;
extern const char *Txt_Set_password;
2014-12-01 23:55:08 +01:00
bool IHaveAPasswordInDB = (bool) Gbl.Usrs.Me.UsrDat.Password[0];
/***** Begin section *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_Begin (Pwd_PASSWORD_SECTION_ID);
2014-12-01 23:55:08 +01:00
/***** Begin form *****/
Frm_BeginFormAnchor (ActChgMyPwd,Pwd_PASSWORD_SECTION_ID);
/***** Begin box *****/
Box_BoxBegin (Txt_Password,NULL,NULL,
Hlp_PROFILE_Password,Box_NOT_CLOSABLE);
/***** Show possible alerts *****/
Ale_ShowAlerts (Pwd_PASSWORD_SECTION_ID);
/***** Help message *****/
if (!IHaveAPasswordInDB) // If I don't have a password in database...
Ale_ShowAlert (Ale_WARNING,Txt_Before_going_to_any_other_option_you_must_create_your_password);
else if (Gbl.Usrs.Me.LoginPlainPassword[0])
{
if (!Pwd_FastCheckIfPasswordSeemsGood (Gbl.Usrs.Me.LoginPlainPassword))
Ale_ShowAlert (Ale_WARNING,Txt_Your_password_is_not_secure_enough);
}
/***** Begin table *****/
HTM_TABLE_BeginWidePadding (2);
/***** Current password *****/
if (IHaveAPasswordInDB) // If I have a password in database...
{
HTM_TR_Begin (NULL);
/* Label */
Frm_LabelColumn ("Frm_C1 RM","UsrPwd",Txt_Current_password);
/* Data */
HTM_TD_Begin ("class=\"Frm_C2 LM\"");
HTM_INPUT_PASSWORD ("UsrPwd",NULL,"off",
HTM_REQUIRED,
"id=\"UsrPwd\""
" class=\"Frm_C2_INPUT INPUT_%s\"",
The_GetSuffix ());
HTM_TD_End ();
HTM_TR_End ();
}
/***** Help message *****/
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"2\"");
Ale_ShowAlert (Ale_INFO,Txt_Your_password_must_be_at_least_X_characters_and_can_not_contain_spaces_,
Pwd_MIN_CHARS_PLAIN_PASSWORD);
HTM_TD_End ();
HTM_TR_End ();
/***** New password *****/
Pwd_PutFormToGetNewPasswordTwice ();
/***** End table, send button and end box *****/
Box_BoxTableWithButtonEnd (Btn_CONFIRM_BUTTON,
IHaveAPasswordInDB ? Txt_Change_password :
Txt_Set_password);
/***** End form *****/
Frm_EndForm ();
2015-04-11 23:46:21 +02:00
2018-10-09 20:32:01 +02:00
/***** End section *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_End ();
2014-12-01 23:55:08 +01:00
}
2015-11-20 21:11:33 +01:00
/*****************************************************************************/
/**************** Put form to request the new password once ******************/
/*****************************************************************************/
void Pwd_PutFormToGetNewPasswordOnce (void)
{
extern const char *Txt_Password;
extern const char *Txt_HELP_password;
2019-12-27 21:10:39 +01:00
/***** Password *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 17:36:41 +02:00
/* Label */
Frm_LabelColumn ("Frm_C1 RM","Paswd",Txt_Password);
2019-10-07 17:36:41 +02:00
/* Data */
HTM_TD_Begin ("class=\"Frm_C2 LM\"");
HTM_INPUT_PASSWORD ("Paswd",Txt_HELP_password,NULL,
HTM_REQUIRED,
"id=\"Paswd\" class=\"REC_C2_BOT_INPUT INPUT_%s\"",
The_GetSuffix ());
HTM_TD_End ();
2019-10-07 17:36:41 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2015-11-20 21:11:33 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/**************** Put form to request the new password twice *****************/
/*****************************************************************************/
void Pwd_PutFormToGetNewPasswordTwice (void)
{
extern const char *Txt_New_password;
extern const char *Txt_Retype_new_password;
2019-11-04 13:40:33 +01:00
extern const char *Txt_HELP_password;
2014-12-01 23:55:08 +01:00
2019-02-15 21:09:18 +01:00
/***** 1st password *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 17:36:41 +02:00
/* Label */
Frm_LabelColumn ("Frm_C1 RM","Paswd1",Txt_New_password);
2019-10-07 17:36:41 +02:00
/* Data */
HTM_TD_Begin ("class=\"Frm_C2 LM\"");
HTM_INPUT_PASSWORD ("Paswd1",Txt_HELP_password,NULL,
HTM_REQUIRED,
"id=\"Paswd1\" class=\"Frm_C2_INPUT INPUT_%s\"",
The_GetSuffix ());
HTM_TD_End ();
2019-10-07 17:36:41 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2019-02-15 21:09:18 +01:00
/***** 2nd password *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 17:36:41 +02:00
/* Label */
Frm_LabelColumn ("Frm_C1 RM","Paswd2",Txt_Retype_new_password);
2019-10-07 17:36:41 +02:00
/* Data */
HTM_TD_Begin ("class=\"Frm_C2 LM\"");
HTM_INPUT_PASSWORD ("Paswd2",Txt_HELP_password,NULL,
HTM_REQUIRED,
"id=\"Paswd2\" class=\"Frm_C2_INPUT INPUT_%s\"",
The_GetSuffix ());
HTM_TD_End ();
2019-10-07 17:36:41 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********** Show form to the change of password of another user **************/
/*****************************************************************************/
2018-10-16 01:36:13 +02:00
void Pwd_ShowFormChgOtherUsrPwd (void)
2014-12-01 23:55:08 +01:00
{
2015-09-18 18:08:43 +02:00
extern const char *Txt_Password;
extern const char *Txt_Change_password;
static Act_Action_t NextAction[Rol_NUM_ROLES] =
{
[Rol_UNK ] = ActChgPwdOth,
[Rol_GST ] = ActChgPwdOth,
[Rol_USR ] = ActChgPwdOth,
[Rol_STD ] = ActChgPwdStd,
[Rol_NET ] = ActChgPwdTch,
[Rol_TCH ] = ActChgPwdTch,
[Rol_DEG_ADM] = ActChgPwdOth,
[Rol_CTR_ADM] = ActChgPwdOth,
[Rol_INS_ADM] = ActChgPwdOth,
[Rol_SYS_ADM] = ActChgPwdOth,
};
2014-12-01 23:55:08 +01:00
/***** Begin section *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_Begin (Pwd_PASSWORD_SECTION_ID);
2018-10-15 14:07:12 +02:00
/***** Begin box *****/
Box_BoxBegin (Txt_Password,NULL,NULL,NULL,Box_NOT_CLOSABLE);
2018-10-15 14:07:12 +02:00
/***** Show possible alerts *****/
Ale_ShowAlerts (Pwd_PASSWORD_SECTION_ID);
2014-12-01 23:55:08 +01:00
/***** Form to change password *****/
/* Begin form */
Frm_BeginFormAnchor (NextAction[Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs],Pwd_PASSWORD_SECTION_ID);
Usr_PutParOtherUsrCodEncrypted (Gbl.Usrs.Other.UsrDat.EnUsrCod);
2014-12-31 02:46:20 +01:00
/* New password */
HTM_TABLE_BeginPadding (2);
Pwd_PutFormToGetNewPasswordTwice ();
HTM_TABLE_End ();
Btn_PutConfirmButton (Txt_Change_password);
/* End form */
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
/***** End box *****/
Box_BoxEnd ();
2015-09-18 02:15:35 +02:00
2018-10-16 08:48:51 +02:00
/***** End section *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************** Ask for confirmation on dangerous actions *****************/
/*****************************************************************************/
void Pwd_AskForConfirmationOnDangerousAction (void)
{
2015-11-20 14:44:54 +01:00
extern const char *Txt_I_understand_that_this_action_can_not_be_undone;
2014-12-01 23:55:08 +01:00
extern const char *Txt_For_security_enter_your_password;
2019-10-24 00:04:40 +02:00
HTM_DIV_Begin ("class=\"CM\" style=\"margin:12px;\"");
2019-11-03 11:20:14 +01:00
/***** Checkbox *****/
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
HTM_INPUT_CHECKBOX ("Consent",Cns_UNCHECKED,HTM_DONT_SUBMIT_ON_CHANGE,
"value=\"Y\"");
HTM_Txt (Txt_I_understand_that_this_action_can_not_be_undone);
HTM_LABEL_End ();
HTM_BR ();
/***** Password *****/
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
HTM_TxtColonNBSP (Txt_For_security_enter_your_password);
HTM_INPUT_PASSWORD ("OthUsrPwd",NULL,"off",HTM_REQUIRED,
"class=\"INPUT_%s\"",The_GetSuffix ());
HTM_LABEL_End ();
2019-11-03 11:20:14 +01:00
2019-10-23 20:07:56 +02:00
HTM_DIV_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************** Get confirmation on dangerous actions ******************/
/*****************************************************************************/
// Returns true if consent have been checked and my password is correct
bool Pwd_GetConfirmationOnDangerousAction (void)
{
extern const char *Txt_You_have_not_confirmed_the_action;
extern const char *Txt_You_have_not_entered_your_password_correctly;
2017-03-07 01:56:41 +01:00
char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1];
2017-03-13 14:22:36 +01:00
char EncryptedPassword[Pwd_BYTES_ENCRYPTED_PASSWORD + 1];
2014-12-01 23:55:08 +01:00
/***** Get if consent has been done *****/
if (!Par_GetParBool ("Consent"))
2014-12-01 23:55:08 +01:00
{
2019-02-16 18:11:52 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_You_have_not_confirmed_the_action);
2014-12-01 23:55:08 +01:00
return false;
}
/***** Get my password *****/
/* Get plain password from form */
Par_GetParText ("OthUsrPwd",PlainPassword,Pwd_MAX_BYTES_PLAIN_PASSWORD);
2014-12-01 23:55:08 +01:00
/* Encrypt password */
Cry_EncryptSHA512Base64 (PlainPassword,EncryptedPassword);
/* Compare passwords */
if (strcmp (Gbl.Usrs.Me.LoginEncryptedPassword,EncryptedPassword))
{
2019-02-16 18:11:52 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_You_have_not_entered_your_password_correctly);
2014-12-01 23:55:08 +01:00
return false;
}
return true;
}