fixed: misc: ValidateEmail() buffer overflow
added: notifications for resetting a user's password (there is no a winix function for this yet) git-svn-id: svn://ttmath.org/publicrep/winix/trunk@817 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
@@ -848,6 +848,7 @@ pw.o: ../core/lastcontainer.h ../core/mounts.h ../core/mountparser.h
|
||||
pw.o: ../core/crypt.h ../core/users.h ../core/groups.h ../core/group.h
|
||||
pw.o: ../core/loadavg.h ../core/image.h ../core/basethread.h
|
||||
pw.o: ../core/threadmanager.h ../core/synchro.h ../core/log.h ../core/misc.h
|
||||
pw.o: ../functions/functions.h
|
||||
reload.o: reload.h functionbase.h ../core/item.h ../db/db.h ../db/dbbase.h
|
||||
reload.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h
|
||||
reload.o: ../core/misc.h ../core/item.h ../core/requesttypes.h
|
||||
|
@@ -12,7 +12,7 @@
|
||||
#include "core/slog.h"
|
||||
#include "core/plugin.h"
|
||||
#include "core/misc.h"
|
||||
|
||||
#include "functions/functions.h"
|
||||
|
||||
|
||||
namespace Fun
|
||||
@@ -113,44 +113,8 @@ bool AddUser::IsEmailCorrect(const std::wstring & email, bool use_ses_log)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AddUser::IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log)
|
||||
{
|
||||
if( pass != conf_pass )
|
||||
{
|
||||
log << log2 << "AddUser: passwords are different" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << logerror << T("adduser_err_passwords_different") << logend;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( pass.size() < config->pass_min_size )
|
||||
{
|
||||
log << log2 << "AddUser: password is too small" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << logerror << T("adduser_err_password_too_small") << " "
|
||||
<< config->pass_min_size << " " << T("adduser_err_password_too_small2") << logend;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( pass.size() > WINIX_ACCOUNT_MAX_PASSWORD_SIZE )
|
||||
{
|
||||
log << log2 << "AddUser: password can't be longer than: " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE << " characters" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << logerror << T("adduser_err_password_too_big") << " " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE
|
||||
<< " " << T("adduser_err_password_too_big2") << logend;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
// !! IMPROVE ME
|
||||
// may it should be moved to passwd winix function
|
||||
|
||||
|
||||
/*
|
||||
@@ -203,7 +167,8 @@ void AddUser::MakePost()
|
||||
const std::wstring & email = cur->request->PostVar(L"email");
|
||||
long code = 0;
|
||||
|
||||
if( !IsLoginCorrect(login, true) || !IsEmailCorrect(email, true) || !IsPasswordCorrect(pass, conf_pass, true) )
|
||||
if( !IsLoginCorrect(login, true) || !IsEmailCorrect(email, true) ||
|
||||
!functions->fun_passwd.IsPasswordCorrect(pass, conf_pass, true) )
|
||||
return;
|
||||
|
||||
user.name = login;
|
||||
|
@@ -27,7 +27,6 @@ public:
|
||||
void MakeGet();
|
||||
|
||||
bool IsLoginCorrect(const std::wstring & login, bool use_ses_log = false);
|
||||
bool IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log = false);
|
||||
bool IsEmailCorrect(const std::wstring & email, bool use_ses_log = false);
|
||||
|
||||
bool HasLoginCorrectChars(const std::wstring & login);
|
||||
|
@@ -30,13 +30,97 @@ bool Passwd::HasAccess()
|
||||
|
||||
|
||||
|
||||
bool Passwd::ChangePassword(const std::wstring & login, const std::wstring & new_password)
|
||||
bool Passwd::IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log)
|
||||
{
|
||||
up.pass = new_password;
|
||||
system->crypt.PassHashCrypt(up);
|
||||
Error res = db->ChangeUserPass(login, up);
|
||||
if( pass != conf_pass )
|
||||
{
|
||||
log << log2 << "Passwd: passwords are different" << logend;
|
||||
|
||||
return res == WINIX_ERR_OK;
|
||||
if( use_ses_log )
|
||||
slog << logerror << T("adduser_err_passwords_different") << logend;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( pass.size() < config->pass_min_size )
|
||||
{
|
||||
log << log2 << "Passwd: password is too small" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << logerror << T("adduser_err_password_too_small") << " "
|
||||
<< config->pass_min_size << " " << T("adduser_err_password_too_small2") << logend;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( pass.size() > WINIX_ACCOUNT_MAX_PASSWORD_SIZE )
|
||||
{
|
||||
log << log2 << "Passwd: password can't be longer than: " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE << " characters" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << logerror << T("adduser_err_password_too_big") << " " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE
|
||||
<< " " << T("adduser_err_password_too_big2") << logend;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Passwd::ChangePassword(long user_id, const std::wstring & new_password)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
User * puser = system->users.GetUser(user_id);
|
||||
|
||||
if( puser )
|
||||
{
|
||||
up.pass = new_password;
|
||||
system->crypt.PassHashCrypt(up);
|
||||
result = (db->ChangeUserPass(user_id, up) == WINIX_ERR_OK);
|
||||
|
||||
if( result )
|
||||
log << log2 << "Passwd: password for user " << puser->name << " has been changed" << logend;
|
||||
else
|
||||
log << log1 << "Passwd: I cannot change password -- database problem" << logend;
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Passwd: there is no a user with id: " << user_id << logend;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Passwd::ChangePassword(User * puser)
|
||||
{
|
||||
long user_id;
|
||||
|
||||
const std::wstring & pass_cur = cur->request->PostVar(L"passwordcur");
|
||||
const std::wstring & pass_new = cur->request->PostVar(L"passwordnew");
|
||||
const std::wstring & pass_conf = cur->request->PostVar(L"passwordconfirm");
|
||||
|
||||
if( !cur->session->puser->super_user && !functions->fun_login.CheckUserPass(puser->name, pass_cur, user_id) )
|
||||
{
|
||||
log << log3 << "Passwd: incorrect current password" << logend;
|
||||
slog << logerror << T("passwd_err_bad_current_password") << logend;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !IsPasswordCorrect(pass_new, pass_conf) )
|
||||
return;
|
||||
|
||||
if( ChangePassword(cur->session->puser->id, pass_new) )
|
||||
{
|
||||
slog << loginfo << T("passwd_password_changed") << logend;
|
||||
system->RedirectToLastItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,38 +133,21 @@ return res == WINIX_ERR_OK;
|
||||
*/
|
||||
void Passwd::MakePost()
|
||||
{
|
||||
long user_id;
|
||||
const std::wstring * plogin;
|
||||
|
||||
if( !cur->session->puser )
|
||||
return;
|
||||
|
||||
bool is_root = cur->session->puser->super_user;
|
||||
|
||||
if( is_root )
|
||||
plogin = &cur->request->PostVar(L"login");
|
||||
else
|
||||
plogin = &cur->session->puser->name;
|
||||
|
||||
const std::wstring & pass_cur = cur->request->PostVar(L"passwordcur");
|
||||
const std::wstring & pass_new = cur->request->PostVar(L"passwordnew");
|
||||
const std::wstring & pass_conf = cur->request->PostVar(L"passwordconfirm");
|
||||
|
||||
if( !is_root && !functions->fun_login.CheckUserPass(*plogin, pass_cur, user_id) )
|
||||
if( cur->session->puser )
|
||||
{
|
||||
log << log3 << "Passwd: incorrect current password" << logend;
|
||||
slog << logerror << T("passwd_err_bad_current_password") << logend;
|
||||
return;
|
||||
}
|
||||
if( cur->session->puser->super_user )
|
||||
plogin = &cur->request->PostVar(L"login");
|
||||
else
|
||||
plogin = &cur->session->puser->name;
|
||||
|
||||
if( !functions->fun_adduser.IsPasswordCorrect(pass_new, pass_conf) )
|
||||
return;
|
||||
User * puser = system->users.GetUser(*plogin);
|
||||
|
||||
if( ChangePassword(*plogin, pass_new) )
|
||||
{
|
||||
log << log2 << "Passwd: password for " << plogin << " has been changed" << logend;
|
||||
slog << loginfo << T("passwd_password_changed") << logend;
|
||||
system->RedirectToLastItem();
|
||||
if( puser )
|
||||
ChangePassword(puser);
|
||||
else
|
||||
log << log1 << "Passwd: there is no such a user: " << *plogin << logend;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -25,11 +25,16 @@ public:
|
||||
Passwd();
|
||||
bool HasAccess();
|
||||
void MakePost();
|
||||
bool ChangePassword(const std::wstring & login, const std::wstring & new_password);
|
||||
|
||||
bool IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log = false);
|
||||
bool ChangePassword(long user_id, const std::wstring & new_password);
|
||||
|
||||
private:
|
||||
|
||||
UserPass up;
|
||||
|
||||
void ChangePassword(User * puser);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
134
functions/pw.cpp
134
functions/pw.cpp
@@ -10,6 +10,7 @@
|
||||
#include "pw.h"
|
||||
#include "core/log.h"
|
||||
#include "core/misc.h"
|
||||
#include "functions/functions.h"
|
||||
|
||||
|
||||
namespace Fun
|
||||
@@ -38,9 +39,10 @@ bool Pw::ActivateAccount(User * puser, long code, bool use_ses_log)
|
||||
{
|
||||
if( db->ChangeUserStatus(puser->id, WINIX_ACCOUNT_READY) == WINIX_ERR_OK )
|
||||
{
|
||||
// !! IMPROVE ME
|
||||
// remove 'activation_code' value from admin environment for the user
|
||||
puser->aenv.Remove(L"activation_code");
|
||||
db->ChangeUserAdminEnv(puser->id, puser->aenv);
|
||||
puser->status = WINIX_ACCOUNT_READY;
|
||||
|
||||
log << log2 << "Pw: account: " << puser->name << " activated" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
@@ -113,10 +115,138 @@ void Pw::ActivateAccount()
|
||||
|
||||
|
||||
|
||||
bool Pw::SetNewPassword(User * puser, bool use_ses_log)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
const std::wstring & pass = cur->request->PostVar(L"passwordnew");
|
||||
const std::wstring & pass_conf = cur->request->PostVar(L"passwordconfirm");
|
||||
|
||||
if( functions->fun_passwd.IsPasswordCorrect(pass, pass_conf, use_ses_log) )
|
||||
{
|
||||
if( functions->fun_passwd.ChangePassword(puser->id, pass) )
|
||||
{
|
||||
result = true;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << loginfo << T("pw_password_changed") << logend;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( use_ses_log )
|
||||
slog << logerror << T("service_unavailable") << logend;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Pw::ResetPassword(User * puser, long code, bool use_ses_log, bool only_check_access)
|
||||
{
|
||||
std::wstring * user_code_str = puser->aenv.GetValue(L"password_change_code");
|
||||
|
||||
if( user_code_str )
|
||||
{
|
||||
if( Tol(*user_code_str) == code )
|
||||
{
|
||||
if( only_check_access )
|
||||
return true;
|
||||
else
|
||||
return SetNewPassword(puser, use_ses_log);
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log2 << "Pw: incorrect change password code" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << logerror << T(L"incorrect_change_password_code") << logend;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Pw: there is no change password code in admin environment" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << loginfo << T(L"password_cannot_be_changed") << logend;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Pw::ResetPassword(const std::wstring & login, long code, bool use_ses_log, bool only_check_access)
|
||||
{
|
||||
bool result = false;
|
||||
User * puser = system->users.GetUser(login);
|
||||
|
||||
if( puser )
|
||||
{
|
||||
long t = static_cast<long>(cur->request->start_time);
|
||||
|
||||
if( puser->aenv.Long(L"password_change_time") + config->reset_password_code_expiration_time > t )
|
||||
{
|
||||
result = ResetPassword(puser, code, use_ses_log, only_check_access);
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log2 << "Pw: the code has expired" << logend;
|
||||
|
||||
if( use_ses_log )
|
||||
slog << logerror << T(L"code_expired") << logend;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Pw: there is no a user: " << login << logend;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Pw::ResetPassword()
|
||||
{
|
||||
const std::wstring & login = cur->request->PostVar(L"login");
|
||||
long code = Tol(cur->request->PostVar(L"code"));
|
||||
|
||||
ResetPassword(login, code, true, false);
|
||||
system->RedirectToLastItem();
|
||||
}
|
||||
|
||||
|
||||
void Pw::ShowResetPasswordForm()
|
||||
{
|
||||
const std::wstring & login = cur->request->ParamValue(L"login");
|
||||
long code = Tol(cur->request->ParamValue(L"code"));
|
||||
|
||||
if( !login.empty() )
|
||||
{
|
||||
if( !ResetPassword(login, code, true, true) )
|
||||
system->RedirectToLastItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
system->RedirectToLastItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Pw::MakePost()
|
||||
{
|
||||
if( cur->request->IsParam(L"resetpassword") )
|
||||
ResetPassword();
|
||||
}
|
||||
|
||||
|
||||
void Pw::MakeGet()
|
||||
{
|
||||
if( cur->request->IsParam(L"activate") )
|
||||
ActivateAccount();
|
||||
else
|
||||
if( cur->request->IsParam(L"resetpassword") )
|
||||
ShowResetPasswordForm();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -24,14 +24,21 @@ public:
|
||||
Pw();
|
||||
|
||||
bool HasAccess();
|
||||
void MakePost();
|
||||
void MakeGet();
|
||||
|
||||
bool ActivateAccount(const std::wstring & login, long code, bool use_ses_log = false);
|
||||
bool ResetPassword(const std::wstring & login, long code, bool use_ses_log = false, bool only_check_access = false);
|
||||
|
||||
private:
|
||||
|
||||
bool ActivateAccount(User * puser, long code, bool use_ses_log);
|
||||
bool ResetPassword(User * puser, long code, bool use_ses_log);
|
||||
void ActivateAccount();
|
||||
bool SetNewPassword(User * puser, bool use_ses_log);
|
||||
bool ResetPassword(User * puser, long code, bool use_ses_log, bool only_check_access);
|
||||
void ResetPassword();
|
||||
void ShowResetPasswordForm();
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user