diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c99596926b399b22291c617dc1479211de493ea7 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -0,0 +1 @@ +ALTER TABLE `sys_user` ADD `otp_type` SET('none', 'email') NOT NULL DEFAULT 'none' AFTER `lost_password_reqtime`, ADD `otp_data` VARCHAR(255) NULL AFTER `otp_type`, ADD `otp_recovery` VARCHAR(64) NULL AFTER `otp_data`, ADD `otp_attempts` TINYINT NOT NULL DEFAULT '0' AFTER `otp_recovery`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index ec6596bc779e4274d5612273e5f9fa96fd9a27cd..cf340bda0170cb77039941455303d76ee28066ca 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1842,6 +1842,10 @@ CREATE TABLE `sys_user` ( `lost_password_function` tinyint(1) NOT NULL default '1', `lost_password_hash` VARCHAR(50) NOT NULL default '', `lost_password_reqtime` DATETIME NULL default NULL, + `otp_type` set('none', 'email') NOT NULL DEFAULT 'none', + `otp_data` varchar(255) DEFAULT NULL, + `otp_recovery` varchar(64) DEFAULT NULL, + `otp_attempts` tinyint(4) NOT NULL DEFAULT 0, PRIMARY KEY (`userid`) ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; diff --git a/interface/lib/app.inc.php b/interface/lib/app.inc.php old mode 100755 new mode 100644 index 96e8a1ddef0892b1ca35186ea08d263af75b21be..6a8e563d80fade4e9ccb9482004017b8e6149c5e --- a/interface/lib/app.inc.php +++ b/interface/lib/app.inc.php @@ -212,6 +212,12 @@ class app { } } + public function auth_log($msg) { + $authlog_handle = fopen($this->_conf['ispconfig_log_dir'].'/auth.log', 'a'); + fwrite($authlog_handle, $msg . PHP_EOL); + fclose($authlog_handle); + } + /** Priority values are: 0 = DEBUG, 1 = WARNING, 2 = ERROR */ public function error($msg, $next_link = '', $stop = true, $priority = 1) { //$this->uses("error"); diff --git a/interface/web/admin/form/users.tform.php b/interface/web/admin/form/users.tform.php index 1aab0a42985bb8b28932393366e4de14d67f8aa2..bc77087e2852c71d10f416e559b23291ab86b243 100644 --- a/interface/web/admin/form/users.tform.php +++ b/interface/web/admin/form/users.tform.php @@ -94,6 +94,11 @@ while ($file = @readdir($handle)) { } } +$otp_method_list = array( + 'none' => 'none', + 'email' => 'email', +); + //* Load themes $themes_list = array(); $handle = @opendir(ISPC_THEMES_PATH); @@ -254,6 +259,25 @@ $form['tabs']['users'] = array ( 'rows' => '', 'cols' => '' ), + 'otp_type' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', + 'errmsg'=> 'otp_auth_empty'), + 1 => array ( 'type' => 'REGEX', + 'regex' => '/^[a-z0-9\_]{0,64}$/', + 'errmsg'=> 'otp_auth_regex'), + ), + 'regex' => '', + 'errmsg' => '', + 'default' => '', + 'value' => $otp_method_list, + 'separator' => '', + 'width' => '30', + 'maxlength' => '255', + 'rows' => '', + 'cols' => '' + ), 'language' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', diff --git a/interface/web/admin/lib/lang/ar_users.lng b/interface/web/admin/lib/lang/ar_users.lng index 369d56559510f445a96d40969035f4cbfde07ca5..d4acbf4e807d1a9ad740c14e6c5bfbdd12d1d594 100644 --- a/interface/web/admin/lib/lang/ar_users.lng +++ b/interface/web/admin/lib/lang/ar_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/bg_users.lng b/interface/web/admin/lib/lang/bg_users.lng index a7d669bd2284be54fffb0e9c9f7be1989db24aac..3bd134b40ba3fd2b52502329e1e409dac4f5f4fe 100644 --- a/interface/web/admin/lib/lang/bg_users.lng +++ b/interface/web/admin/lib/lang/bg_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/br_users.lng b/interface/web/admin/lib/lang/br_users.lng index 2e60a744c0c0ed605b0bfed34cd159495d57d490..022d723c97720740209c2897b0b80ab0854440be 100644 --- a/interface/web/admin/lib/lang/br_users.lng +++ b/interface/web/admin/lib/lang/br_users.lng @@ -38,3 +38,4 @@ $wb['startmodule_empty'] = 'O módulo inicial está vazio.'; $wb['startmodule_regex'] = 'Caracteres inválidos no módulo inicial.'; $wb['app_theme_empty'] = 'Tema está vazio.'; $wb['app_theme_regex'] = 'Caracteres inválidos no tema.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; diff --git a/interface/web/admin/lib/lang/ca_users.lng b/interface/web/admin/lib/lang/ca_users.lng index 369d56559510f445a96d40969035f4cbfde07ca5..d4acbf4e807d1a9ad740c14e6c5bfbdd12d1d594 100644 --- a/interface/web/admin/lib/lang/ca_users.lng +++ b/interface/web/admin/lib/lang/ca_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/cz_users.lng b/interface/web/admin/lib/lang/cz_users.lng index c973ea2f8044ee67504a22e3c6d8ca6422d32883..6ad957242a28ffa42c4929c4ada7b55f542949bd 100644 --- a/interface/web/admin/lib/lang/cz_users.lng +++ b/interface/web/admin/lib/lang/cz_users.lng @@ -38,3 +38,4 @@ $wb['startmodule_empty'] = 'Startmodule empty.'; $wb['startmodule_regex'] = 'Invalid chars in Startmodule.'; $wb['app_theme_empty'] = 'App theme empty.'; $wb['app_theme_regex'] = 'Invalid chars in App theme.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; diff --git a/interface/web/admin/lib/lang/de_users.lng b/interface/web/admin/lib/lang/de_users.lng index e52090dceaef804ea83f49f7deac564978dc7405..2747595da72aaf30b5f8beffa0bb233d8bb9bfbc 100644 --- a/interface/web/admin/lib/lang/de_users.lng +++ b/interface/web/admin/lib/lang/de_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Der Benutzername darf nicht web oder diff --git a/interface/web/admin/lib/lang/dk_users.lng b/interface/web/admin/lib/lang/dk_users.lng index fa595ed18415832f257a8bcab11a6bdd0bfae91c..351cd091afce3513693700c8d09a8a704b9d65fb 100644 --- a/interface/web/admin/lib/lang/dk_users.lng +++ b/interface/web/admin/lib/lang/dk_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Brugernavn må ikke være web eller web plus $wb['client_not_admin_err'] = 'En bruger der hører til en klient kan ikke indstilles til typen: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/el_users.lng b/interface/web/admin/lib/lang/el_users.lng index 6d07d6632457fc5dc1d854d7243669fffbadfeb6..0b46b3a52247913458c777f15ec09637d11db65b 100644 --- a/interface/web/admin/lib/lang/el_users.lng +++ b/interface/web/admin/lib/lang/el_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/en_users.lng b/interface/web/admin/lib/lang/en_users.lng index 88fa9430d3837b06fff7ee78535e1cd227e3f44f..855146d171063b86d81b3b2835090e266d9f5a1a 100644 --- a/interface/web/admin/lib/lang/en_users.lng +++ b/interface/web/admin/lib/lang/en_users.lng @@ -38,4 +38,5 @@ $wb['startmodule_empty'] = 'Startmodule empty.'; $wb['startmodule_regex'] = 'Invalid chars in Startmodule.'; $wb['app_theme_empty'] = 'App theme empty.'; $wb['app_theme_regex'] = 'Invalid chars in App theme.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/es_users.lng b/interface/web/admin/lib/lang/es_users.lng index 5a06c7ed3e3a3319245b7f031391bed4879c2fa5..44c67b1832cc45f978d257efaa64eb49c26eaf09 100644 --- a/interface/web/admin/lib/lang/es_users.lng +++ b/interface/web/admin/lib/lang/es_users.lng @@ -34,4 +34,5 @@ $wb['username_txt'] = 'Nombre de usuario'; $wb['username_unique'] = 'Ya existe un usuario con ese nombre de usuario.'; $wb['vorname_txt'] = 'Primer nombre'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/fi_users.lng b/interface/web/admin/lib/lang/fi_users.lng index 1e5bb588559e0eb4577bc05a9eb65decd3a572ab..02bc863bb7f49e178a8645b39f53b2c5e4564e36 100644 --- a/interface/web/admin/lib/lang/fi_users.lng +++ b/interface/web/admin/lib/lang/fi_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/fr_users.lng b/interface/web/admin/lib/lang/fr_users.lng index 0f50d10d67c97698be1a92ad9b7b49854c1f3736..5013698f16b97b52e29cb3dc21e6ce8592149c64 100644 --- a/interface/web/admin/lib/lang/fr_users.lng +++ b/interface/web/admin/lib/lang/fr_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Le nom d\'utilisateur ne peut pas commencer p $wb['client_not_admin_err'] = 'Un utilisateur affilié à un client ne peut pas être changé en type admin'; $wb['lost_password_function_txt'] = 'La fonction mot de passe oublié est disponible'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/hr_users.lng b/interface/web/admin/lib/lang/hr_users.lng index 3a7da2a422baea63b92c33b16d33c341b932117d..e317aa923a6fc456bc6380bb85bb9ae6e898e951 100644 --- a/interface/web/admin/lib/lang/hr_users.lng +++ b/interface/web/admin/lib/lang/hr_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Korisničko ime ne može biti web ili web sa $wb['client_not_admin_err'] = 'Korisnik koji je u grupi klijenti ne može biti admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/hu_users.lng b/interface/web/admin/lib/lang/hu_users.lng index 6f1ded0b70b1a36c0744badc8fc6af0643ca78f1..dc1089b76fdb295707d737c7c973cbf7aa1812dd 100644 --- a/interface/web/admin/lib/lang/hu_users.lng +++ b/interface/web/admin/lib/lang/hu_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/id_users.lng b/interface/web/admin/lib/lang/id_users.lng index bc546d4df4e050b30ee5aeec15926a76e288139e..032613d1e543049aad7ffedd6ac1d4ee61c1a4d3 100644 --- a/interface/web/admin/lib/lang/id_users.lng +++ b/interface/web/admin/lib/lang/id_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/it_users.lng b/interface/web/admin/lib/lang/it_users.lng index 2c5dbeda480b1c84f05caf7237c37e95edfda014..57a462394aa55abfe9f5c0e8c32c04a4b6b51d26 100644 --- a/interface/web/admin/lib/lang/it_users.lng +++ b/interface/web/admin/lib/lang/it_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Il nome utente non può essere web o web+un n $wb['client_not_admin_err'] = 'Un utente che appartiene ad un cliente non può essere del tipo: admin'; $wb['lost_password_function_txt'] = 'La funzione password dimenticata è disponibile'; $wb['no_user_insert'] = 'CP-Utente di tipo -utente- viene aggiunto automaticamente quando aggiungi un cliente o un rivenditore.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/ja_users.lng b/interface/web/admin/lib/lang/ja_users.lng index 45b1faec67c05eadb93286c6826aa7153608c4b0..9786f8b57647670f316bd266fbc365923d480bde 100644 --- a/interface/web/admin/lib/lang/ja_users.lng +++ b/interface/web/admin/lib/lang/ja_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/nl_users.lng b/interface/web/admin/lib/lang/nl_users.lng index e1e6609c27d5e998244b8db740709464d7c18ffe..9013af5901e530ef3654c209092a1086d343b780 100644 --- a/interface/web/admin/lib/lang/nl_users.lng +++ b/interface/web/admin/lib/lang/nl_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = 'Twee-factor authenticatie'; ?> diff --git a/interface/web/admin/lib/lang/pl_users.lng b/interface/web/admin/lib/lang/pl_users.lng index f5439f4f5f5fe86dee7e7e7161be928071d6b4de..b879f671e298d52c7eb0b12136a074d5293fe35f 100644 --- a/interface/web/admin/lib/lang/pl_users.lng +++ b/interface/web/admin/lib/lang/pl_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Nazwa użytkownika nie może być web lub web $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/pt_users.lng b/interface/web/admin/lib/lang/pt_users.lng index 7522fb0270d615bcbe2e3d6197ab16baffce1d08..f1cf858176002e2589ad2ead532bbe05a6574ea9 100644 --- a/interface/web/admin/lib/lang/pt_users.lng +++ b/interface/web/admin/lib/lang/pt_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/ro_users.lng b/interface/web/admin/lib/lang/ro_users.lng index 369d56559510f445a96d40969035f4cbfde07ca5..d4acbf4e807d1a9ad740c14e6c5bfbdd12d1d594 100644 --- a/interface/web/admin/lib/lang/ro_users.lng +++ b/interface/web/admin/lib/lang/ro_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/ru_users.lng b/interface/web/admin/lib/lang/ru_users.lng index d805b939116e50996d59f9ef73103b98476a69c0..5d67479d701ba0f83803f00a81a8e1a3c2bb0d7f 100644 --- a/interface/web/admin/lib/lang/ru_users.lng +++ b/interface/web/admin/lib/lang/ru_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Имя пользователя не може $wb['client_not_admin_err'] = 'Пользователь, который принадлежит к клиенту не может быть установлен тип: admin'; $wb['lost_password_function_txt'] = 'Функция восстановления пароля доступна'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/se_users.lng b/interface/web/admin/lib/lang/se_users.lng index 60f3829adc9237e5453a4bbe9029e58f2bada62f..a8baa7ee79886fdcd1cb201adef121b9637e42c0 100644 --- a/interface/web/admin/lib/lang/se_users.lng +++ b/interface/web/admin/lib/lang/se_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Användarnamnet får inte vara web eller web $wb['client_not_admin_err'] = 'En användare som tillhör en kund kan inte sättas som admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/sk_users.lng b/interface/web/admin/lib/lang/sk_users.lng index 9cc7f87e0d23dc6feb43ad2d26664c3b336e7918..f0c863d749ed2190a06956dd65b6c7f2c6a99c5b 100644 --- a/interface/web/admin/lib/lang/sk_users.lng +++ b/interface/web/admin/lib/lang/sk_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'The username may not be web or web plus a num $wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin'; $wb['lost_password_function_txt'] = 'Forgot password function is available'; $wb['no_user_insert'] = 'CP-Users of type -user- get added and updated automatically when you add a client or reseller.'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/lib/lang/tr_users.lng b/interface/web/admin/lib/lang/tr_users.lng index 84826357b7a91726f0e2120f36c4489ac5b6d210..3483c48fb984f665d575428e3a766bb528753424 100644 --- a/interface/web/admin/lib/lang/tr_users.lng +++ b/interface/web/admin/lib/lang/tr_users.lng @@ -34,4 +34,5 @@ $wb['username_error_collision'] = 'Kullanıcı adı -web- ya da -web- sözcüğ $wb['client_not_admin_err'] = 'Bir müşteriye ait bir kullanıcının türü admin olarak atanamaz'; $wb['lost_password_function_txt'] = 'Parolamı unuttum özelliği kullanılabilir'; $wb['no_user_insert'] = 'Bir müşteri ya da bayi eklediğinizde -user- türündeki kontrol panosu kullanıcıları otomatik olarak eklenir ve güncellenir .'; +$wb['otp_auth_txt'] = '2-Factor Authentication'; ?> diff --git a/interface/web/admin/templates/users_user_edit.htm b/interface/web/admin/templates/users_user_edit.htm index 234f40f25ef0a11cac4d20389061ad388bd71efa..4e8e3da496fb368a6c90017e669519ff92ccdc7b 100644 --- a/interface/web/admin/templates/users_user_edit.htm +++ b/interface/web/admin/templates/users_user_edit.htm @@ -28,6 +28,15 @@ +
+ +
+ +
+
+
diff --git a/interface/web/login/index.php b/interface/web/login/index.php index d59d24efc8273dc6ab5781f117a5f640a667daa8..c4643f4ed2f9f7c076df06a15106b40c1ba93cb8 100644 --- a/interface/web/login/index.php +++ b/interface/web/login/index.php @@ -126,13 +126,6 @@ function process_login_request(app $app, &$error, $conf, $module) } } - $app->plugin->raiseEvent('login', $username); - - //* Save successful login message to var - $authlog = 'Successful login for user \''.$username.'\' from '.$_SERVER['REMOTE_ADDR'].' at '.date('Y-m-d H:i:s').' with session ID '.session_id(); - $authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a'); - fwrite($authlog_handle, $authlog."\n"); - fclose($authlog_handle); /* * We need LOGIN_REDIRECT instead of HEADER_REDIRECT to load the @@ -141,10 +134,33 @@ function process_login_request(app $app, &$error, $conf, $module) if ($loginAs) { echo 'LOGIN_REDIRECT:'.$_SESSION['s']['module']['startpage']; + $app->plugin->raiseEvent('login', $username); + $app->auth_log('Successful login for user \''. $username .'\' ' . $msg . ' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id()); exit; } else { - header('Location: ../index.php'); - die(); + + //* Do 2FA authentication + if($user['otp_type'] != 'none') { + + //* Save session in pending state and destroy original session + $_SESSION['s_pending'] = $_SESSION['s']; + unset($_SESSION['s']); + + //* Create OTP session + $_SESSION['otp']['session_attempts'] = 0; + $_SESSION['otp']['type'] = $user['otp_type']; + $_SESSION['otp']['data'] = $user['otp_data']; + //$_SESSION['otp']['recovery_debug'] = $user['otp_recovery']; // For DEBUG only. + + //* Redirect to otp script + header('Location: otp.php'); + die(); + } else { + $app->plugin->raiseEvent('login', $username); + $app->auth_log('Successful login for user \''. $username .'\' ' . $msg . ' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id()); + header('Location: ../index.php'); + die(); + } } } else { if (!$alreadyfailed['times']) { @@ -161,11 +177,7 @@ function process_login_request(app $app, &$error, $conf, $module) if ($app->db->errorMessage != '') $error .= '
'.$app->db->errorMessage != ''; $app->plugin->raiseEvent('login_failed', $username); - //* Save failed login message to var - $authlog = 'Failed login for user \''.$username.'\' from '.$_SERVER['REMOTE_ADDR'].' at '.date('Y-m-d H:i:s'); - $authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a'); - fwrite($authlog_handle, $authlog."\n"); - fclose($authlog_handle); + $app->auth_log('Failed login for user \''. $username .'\ from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s')); } } diff --git a/interface/web/login/lib/lang/ar.lng b/interface/web/login/lib/lang/ar.lng index a50df19db41051fb421ffe9dc5673ba273bda9c9..79ff8def0bfad10129e96da146ec9a7629d29b32 100644 --- a/interface/web/login/lib/lang/ar.lng +++ b/interface/web/login/lib/lang/ar.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/bg.lng b/interface/web/login/lib/lang/bg.lng index 8081ec8097f2efe56bed1d001c7365be9b46e29a..18f46d6df8f5be5e44473db554981d8c28b95807 100644 --- a/interface/web/login/lib/lang/bg.lng +++ b/interface/web/login/lib/lang/bg.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/br.lng b/interface/web/login/lib/lang/br.lng index 382bd1b8ac14962c3ffd4104fed43758ffc4612e..1f5b41c369389027fae7cb32be3a66c392895a39 100644 --- a/interface/web/login/lib/lang/br.lng +++ b/interface/web/login/lib/lang/br.lng @@ -32,3 +32,12 @@ $wb['pw_reset_act_mail_msg'] = 'Por favor, confirme se você deseja reiniciar su $wb['lost_password_function_wait_txt'] = 'Você não pode requisitar uma nova senha ainda. Por favor, aguarde alguns minutos.'; $wb['lost_password_function_expired_txt'] = 'Este link de ativação expirou. Por favor, faça uma nova requisição.'; $wb['lost_password_function_denied_txt'] = 'Este link de ativação não é válido.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; diff --git a/interface/web/login/lib/lang/ca.lng b/interface/web/login/lib/lang/ca.lng index 8c672b59c5caac8bbef310f796b5e283799f5f40..f4aa11776a941d8b506392f45007d051efa6700f 100644 --- a/interface/web/login/lib/lang/ca.lng +++ b/interface/web/login/lib/lang/ca.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/cz.lng b/interface/web/login/lib/lang/cz.lng index 9b22d7d3c776076375eef06dcfc64f313d871c32..a57ff3f7044885f0acae16a68495376c7e63e0bf 100644 --- a/interface/web/login/lib/lang/cz.lng +++ b/interface/web/login/lib/lang/cz.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/de.lng b/interface/web/login/lib/lang/de.lng index 446f04edc87eb44b17263d5b4754f1966679f848..dcb94af7168cafcdd4af58137fd246fe8933bb1f 100644 --- a/interface/web/login/lib/lang/de.lng +++ b/interface/web/login/lib/lang/de.lng @@ -32,4 +32,13 @@ $wb['lost_password_function_disabled_txt'] = 'Die Passwort vergessen Funktion st $wb['lost_password_function_wait_txt'] = 'Sie können im Moment kein neues Passwort anfordern. Bitte warten Sie einige Minuten.'; $wb['lost_password_function_expired_txt'] = 'Der Passwortlink ist abgelaufen. Bitte fordern Sie einen neuen an.'; $wb['lost_password_function_denied_txt'] = 'Dieser Passwortlink ist ungültig.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/dk.lng b/interface/web/login/lib/lang/dk.lng index 8a104c45be9fdd0a364f519870d20134cd926b2e..37d41ddea1581710d1a24d512d35803ab79e27cc 100644 --- a/interface/web/login/lib/lang/dk.lng +++ b/interface/web/login/lib/lang/dk.lng @@ -32,4 +32,13 @@ $wb['lost_password_function_disabled_txt'] = 'The lost password function is not $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/el.lng b/interface/web/login/lib/lang/el.lng index 8a6ed3387f8bb72829facb4051345e2197db9aa2..64a03b36f63e3bc1ec1856d7ac6aa87ce6397788 100644 --- a/interface/web/login/lib/lang/el.lng +++ b/interface/web/login/lib/lang/el.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/en.lng b/interface/web/login/lib/lang/en.lng index a99d0d3d092c47d3aa334bdef4de4c0d96cdf184..8dd94c6294f3c996fac2b331b7431323b0d7d1c3 100644 --- a/interface/web/login/lib/lang/en.lng +++ b/interface/web/login/lib/lang/en.lng @@ -32,4 +32,13 @@ $wb['lost_password_function_disabled_txt'] = 'The lost password function is not $wb['lost_password_function_wait_txt'] = 'You cannot request a new password yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/es.lng b/interface/web/login/lib/lang/es.lng index 273f69aabea71918947c92a351114595f2f3ae2c..dd8bd12bc4910604569c1d6576d2bf4aa54234ea 100644 --- a/interface/web/login/lib/lang/es.lng +++ b/interface/web/login/lib/lang/es.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Por favor confirme que desea restablecer la cont $wb['lost_password_function_wait_txt'] = 'No puede solicitar una nueva contraseña todavía. Por favor, espere unos minutos.'; $wb['lost_password_function_expired_txt'] = 'Este enlace de activación ha caducado. Por favor, solicite uno nuevo.'; $wb['lost_password_function_denied_txt'] = 'Este enlace de activación no es válido.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/fi.lng b/interface/web/login/lib/lang/fi.lng index 8198dd4822ae84dd7a2202b9e0b9ec726316148f..9bbcbdddabdd7cf09d666de995cf91194d15abe0 100644 --- a/interface/web/login/lib/lang/fi.lng +++ b/interface/web/login/lib/lang/fi.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/fr.lng b/interface/web/login/lib/lang/fr.lng index f067751aa9bc1499665c7126c494f4e78c51f48e..dfc04fd184601ab61b2bf3abe8648b5819bd07ea 100644 --- a/interface/web/login/lib/lang/fr.lng +++ b/interface/web/login/lib/lang/fr.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/hr.lng b/interface/web/login/lib/lang/hr.lng index 193123557a4b6931d20ef32de6c01ee782f3596b..1980c4292dcda9cbe5eef922e48e1c540b1e29d3 100644 --- a/interface/web/login/lib/lang/hr.lng +++ b/interface/web/login/lib/lang/hr.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/hu.lng b/interface/web/login/lib/lang/hu.lng index b6adb6b19d2dd3fb3ba25d24508061c972954ca1..99e2ca769bcc07b6de8534090e36af5feac6003b 100644 --- a/interface/web/login/lib/lang/hu.lng +++ b/interface/web/login/lib/lang/hu.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/id.lng b/interface/web/login/lib/lang/id.lng index 35e3675a9d9f630a024d13ca03b6e097b70b9331..615357f654f6b47fe4dc61eda6c32c2c0f88d1db 100644 --- a/interface/web/login/lib/lang/id.lng +++ b/interface/web/login/lib/lang/id.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/it.lng b/interface/web/login/lib/lang/it.lng index 7d83e22108a67d4d0a812dc76c3a551ddb5b7604..df498e978acc76c0f12db9149b0ab5891925a867 100644 --- a/interface/web/login/lib/lang/it.lng +++ b/interface/web/login/lib/lang/it.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Per confermare il reset della password si prega $wb['lost_password_function_wait_txt'] = 'Non puoi richiedere una nuova password in questo momento. Riprova tra qualche minuto.'; $wb['lost_password_function_expired_txt'] = 'Link di attivazione scaduto. Si prega di richiedere un nuovo link di attivazione.'; $wb['lost_password_function_denied_txt'] = 'Link di attivazione non valido.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/ja.lng b/interface/web/login/lib/lang/ja.lng index 4b9e2c62363720530033eee88a65e4639edd08be..bff26e9d83826f74edf744190f3a2737c0a72885 100644 --- a/interface/web/login/lib/lang/ja.lng +++ b/interface/web/login/lib/lang/ja.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/nl.lng b/interface/web/login/lib/lang/nl.lng index cd5f3b713df85fc5354847b9ec6a19d5a7d0bbfe..453aae6fac9bdc7ef6646a2fcd9e6db23c2f67f7 100644 --- a/interface/web/login/lib/lang/nl.lng +++ b/interface/web/login/lib/lang/nl.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Twee-factor authenticatie'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'Een email is verstuurd aan'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authenticatie'; +$wb['otp_code_email_template_txt'] = 'Uw eenmalige login code is %s' . PHP_EOL . 'Deze code is geldig voor 10 minuten.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Aanvragen nieuwe code'; +$wb['otp_code_email_sent_failed_txt'] = 'Verzenden van email naar %s is mislukt.'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/pl.lng b/interface/web/login/lib/lang/pl.lng index 9b2359b3eb7610481b194ff4aef087a835393804..f6937205425592ecc92a2903e5ca38fffc674404 100644 --- a/interface/web/login/lib/lang/pl.lng +++ b/interface/web/login/lib/lang/pl.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'Nie możesz jeszcze zażądać nowego hasła. Poczekaj kilka minut.'; $wb['lost_password_function_expired_txt'] = 'Link aktywacyjny wygasł. Poproś o nowy.'; $wb['lost_password_function_denied_txt'] = 'Ten link aktywacyjny jest nieprawidłowy.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/pt.lng b/interface/web/login/lib/lang/pt.lng index 4be018a50c72b54a1f4007b73e1a60b80b1a054a..fd453844ea22bee3cf366331f3135564623bbc38 100644 --- a/interface/web/login/lib/lang/pt.lng +++ b/interface/web/login/lib/lang/pt.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/ro.lng b/interface/web/login/lib/lang/ro.lng index 7676d928d57fbe6a18e2eb7182d9a80e7f6c714d..94950d6c069ab7652e9f75d7529d0d0bfa74cb33 100644 --- a/interface/web/login/lib/lang/ro.lng +++ b/interface/web/login/lib/lang/ro.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/ru.lng b/interface/web/login/lib/lang/ru.lng index 4f1b4e86fc8d4cd099161dd6d8f5fc5d7d31ad47..999723c2d6b378f775a7435d19fb2f1a7616f4a8 100644 --- a/interface/web/login/lib/lang/ru.lng +++ b/interface/web/login/lib/lang/ru.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Для подтверждения сброса $wb['lost_password_function_wait_txt'] = 'Вы не можете запросить новый пароль, пока нет. Пожалуйста, подождите несколько минут.'; $wb['lost_password_function_expired_txt'] = 'Срок активации этой ссылки истек. Пожалуйста, запросите новую.'; $wb['lost_password_function_denied_txt'] = 'Эта ссылка активации недействительна.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/se.lng b/interface/web/login/lib/lang/se.lng index 4f8a8a44431c6787484fd280173fdd4b6e2c3b7b..db0aeba05ecba8c39d72a3858dd2981a5a0489e7 100644 --- a/interface/web/login/lib/lang/se.lng +++ b/interface/web/login/lib/lang/se.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/sk.lng b/interface/web/login/lib/lang/sk.lng index 8c211b19beab44a010faa95f82f731c0988b04ef..20ed8f74a79446c9e33e8f834276685dabbd3e09 100644 --- a/interface/web/login/lib/lang/sk.lng +++ b/interface/web/login/lib/lang/sk.lng @@ -32,4 +32,13 @@ $wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPC $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/lib/lang/tr.lng b/interface/web/login/lib/lang/tr.lng index 7bcc75f6942b52238d1c80546c0397d3c29d908d..f30f1fb35440cb52be0ab93803ccd10239acb32e 100644 --- a/interface/web/login/lib/lang/tr.lng +++ b/interface/web/login/lib/lang/tr.lng @@ -32,4 +32,13 @@ $wb['lost_password_function_disabled_txt'] = 'Bu kullanıcı parolamı unuttum $wb['lost_password_function_wait_txt'] = 'Henüz yeni parola isteğinde bulunamazsınız. Lütfen bir kaç dakika bekleyin.'; $wb['lost_password_function_expired_txt'] = 'Bu etkinleştirme bağlantısının süresi geçmiş. Lütfen yeni bir parola sıfırlama isteğinde bulunun.'; $wb['lost_password_function_denied_txt'] = 'Bu etkinleştirme bağlantısı geçersiz.'; +$wb['otp_code_txt'] = 'Two Factor Authentication'; +$wb['otp_code_desc_txt'] = 'Enter the code you got from your authenticator app or via email.'; +$wb['otp_code_placeholder_txt'] = 'OTP code'; +$wb['otp_code_email_sent_txt'] = 'An email was sent to'; +$wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication'; +$wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL; +$wb['otp_code_resend_txt'] = 'Request new code'; +$wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s'; +$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.'; ?> diff --git a/interface/web/login/otp.php b/interface/web/login/otp.php new file mode 100644 index 0000000000000000000000000000000000000000..8b80691da6f20a626c518db9a89d12c8cc335d9e --- /dev/null +++ b/interface/web/login/otp.php @@ -0,0 +1,231 @@ += 1) { + $app->auth->csrf_token_check(); +} + +require ISPC_ROOT_PATH.'/web/login/lib/lang/'.$app->functions->check_language($conf['language']).'.lng'; + +function finish_2fa_success($msg = '') { + global $app; + $_SESSION['s'] = $_SESSION['s_pending']; + unset($_SESSION['s_pending']); + unset($_SESSION['otp']); + $username = $_SESSION['s']['user']['username']; + if (!empty($msg)) { + $msg = ' ' . $msg; + } + $app->auth_log('Successful login for user \''. $username .'\'' . $msg . ' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id()); + $app->db->query('UPDATE `sys_user` SET otp_attempts=0 WHERE userid = ?', $_SESSION['s']['user']['userid']); + session_write_close(); + header('Location: ../index.php'); + die(); +} + +// Handle recovery code +if(isset($_POST['code']) && strlen($_POST['code']) == $otp_recovery_code_length) { + //* TODO Recovery code handling + + $user = $app->db->queryOneRecord('SELECT otp_attempts, otp_recovery FROM sys_user WHERE userid = ?', $_SESSION['s_pending']['user']['userid']); + + //* We allow one more try to enter recovery code + if($user['otp_attempts'] > $max_global_code_retry + 1) { + die("Sorry, contact your administrator."); + } + + if (password_verify($_POST['code'], $user['otp_recovery'])) { + finish_2fa_success('via 2fa recovery code'); + } + else { + $app->db->query('UPDATE `sys_user` SET otp_attempts=otp_attempts + 1 WHERE userid = ?', $_SESSION['s_pending']['user']['userid']); + } +} + + +// Begin 2fa via Email. +if($_SESSION['otp']['type'] == 'email') { + + //* Email 2fa handler settings + $max_code_resend = 3; + $max_time = 600; // time in seconds until the code gets invalidated + $code_length = 6; + + if(isset($_POST['code']) && strlen($_POST['code']) == $code_length && isset($_SESSION['otp']['code_hash'])) { + + $user = $app->db->queryOneRecord('SELECT otp_attempts FROM sys_user WHERE userid = ?', $_SESSION['s_pending']['user']['userid']); + + //* Check if we reached limits + if($_SESSION['otp']['sent'] > $max_code_resend + || $_SESSION['otp']['session_attempts'] > $max_session_code_retry + || $user['otp_attempts'] > $max_global_code_retry + || time() > $_SESSION['otp']['starttime'] + $max_time + ) { + unset($_SESSION['otp']); + unset($_SESSION['s_pending']); + $app->error('2FA failed','index.php'); + } + + //* 2fa success + if(password_verify($_POST['code'], $_SESSION['otp']['code_hash'])) { + finish_2fa_success('with 2fa'); + } else { + //* 2fa wrong code + $_SESSION['otp']['session_attempts']++; + $app->db->query('UPDATE `sys_user` SET otp_attempts=otp_attempts + 1 WHERE userid = ?', $_SESSION['s_pending']['user']['userid']); + } + } + + // Send code via email. + if (!isset($_SESSION['otp']['sent']) || $_GET['action'] == 'resend') { + + $mail_otp_code_retry_timeout = 30; + if (isset($_SESSION['otp']['starttime']) && $_SESSION['otp']['starttime'] > time() - $mail_otp_code_retry_timeout) { + $token_sent_message = sprintf($wb['otp_code_email_sent_wait_txt'], $mail_otp_code_retry_timeout); + } + else { + + // Generate new code + $new_otp_code = random_int(100000, 999999); + $_SESSION['otp']['code_hash'] = password_hash($new_otp_code, PASSWORD_DEFAULT); + //$_SESSION['otp']['code_debug'] = $new_otp_code; # for DEBUG only. + $_SESSION['otp']['starttime'] = time(); + + // Ensure that code is not sent too often + if(isset($_SESSION['otp']['sent']) && $_SESSION['otp']['sent'] > $max_code_resend) { + $app->error('Code resend limit reached', 'index.php'); + } + + $app->uses('functions'); + $app->uses('getconf'); + $server_config_array = $app->getconf->get_global_config(); + + $app->uses('getconf,ispcmail'); + $mail_config = $server_config_array['mail']; + if($mail_config['smtp_enabled'] == 'y') { + $mail_config['use_smtp'] = true; + $app->ispcmail->setOptions($mail_config); + } + + $clientuser = $app->db->queryOneRecord('SELECT email FROM sys_user u LEFT JOIN client c ON (u.client_id=c.client_id) WHERE u.userid = ?', $_SESSION['s_pending']['user']['userid']); + if (!empty($clientuser['email'])) { + $email_to = $clientuser['email']; + } + else { + // Admin users are not related to a client, thus use the globally configured email address. + $email_to = $mail_config['admin_mail']; + } + + $app->ispcmail->setSender($mail_config['admin_mail'], $mail_config['admin_name']); + $app->ispcmail->setSubject($wb['otp_code_email_subject_txt']); + $app->ispcmail->setMailText(sprintf($wb['otp_code_email_template_txt'], $new_otp_code)); + $send_result = $app->ispcmail->send($email_to); + $app->ispcmail->finish(); + + if ($send_result) { + + // Increase sent counter. + if(!isset($_SESSION['otp']['sent'])) { + $_SESSION['otp']['sent'] = 1; + } else { + $_SESSION['otp']['sent']++; + } + + $token_sent_message = $wb['otp_code_email_sent_txt'] . ' ' . $email_to; + } + else { + $token_sent_message = sprintf($wb['otp_code_email_sent_failed_txt'], $email_to); + } + } + } + + // Show form to enter email code + // ... below + +} else { + $app->error('Otp method unknown', 'index.php'); +} + + +$logo = $app->db->queryOneRecord("SELECT * FROM sys_ini WHERE sysini_id = 1"); +if($logo['custom_logo'] != ''){ + $base64_logo_txt = $logo['custom_logo']; +} else { + $base64_logo_txt = $logo['default_logo']; +} +$app->tpl->setVar('base64_logo_txt', $base64_logo_txt); + +$app->tpl->setVar('current_theme', isset($_SESSION['s']['theme']) ? $_SESSION['s']['theme'] : 'default', true); +if (!empty($token_sent_message)) { + $app->tpl->setVar('token_sent_message', $token_sent_message); +} + +// Load templating system and lang file. +$app->uses('tpl'); +$app->tpl->newTemplate('main_login.tpl.htm'); +$app->tpl->setInclude('content_tpl', 'templates/otp.htm'); + + +// SET csrf token. +$csrf_token = $app->auth->csrf_token_get('otp'); +$app->tpl->setVar('_csrf_id',$csrf_token['csrf_id']); +$app->tpl->setVar('_csrf_key',$csrf_token['csrf_key']); +//$app->tpl->setVar('msg', print_r($_SESSION['otp'], 1)); // For DEBUG only. + +$app->tpl->setVar($wb); + +$app->tpl_defaults(); +$app->tpl->pparse(); + + +?> diff --git a/interface/web/login/templates/otp.htm b/interface/web/login/templates/otp.htm new file mode 100644 index 0000000000000000000000000000000000000000..cf49ba8108d6c7157c0458104d79c5098a40868d --- /dev/null +++ b/interface/web/login/templates/otp.htm @@ -0,0 +1,25 @@ + + + + + + +

+

+
+
+
+ +
+
+ +
+ {tmpl_var name='token_sent_message'}
+ {tmpl_var name='otp_code_resend_txt'} + + + + + +
+
diff --git a/interface/web/tools/form/user_settings.tform.php b/interface/web/tools/form/user_settings.tform.php index f063634b0ccf96ed6222acb33274c81b7dbd9ea2..85cdda08471d49d45f34e096cdb4119d3227f5ff 100644 --- a/interface/web/tools/form/user_settings.tform.php +++ b/interface/web/tools/form/user_settings.tform.php @@ -119,6 +119,10 @@ if($_SESSION["s"]["user"]["typ"] == 'admin') { } } +$otp_method_list = array( + 'none' => 'none', + 'email' => 'email', +); //* Load themes $themes_list = array(); $handle = @opendir(ISPC_THEMES_PATH); @@ -163,6 +167,25 @@ $form['tabs']['users'] = array ( 'rows' => '', 'cols' => '' ), + 'otp_type' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', + 'errmsg'=> 'otp_auth_empty'), + 1 => array ( 'type' => 'REGEX', + 'regex' => '/^[a-z0-9\_]{0,64}$/', + 'errmsg'=> 'otp_auth_regex'), + ), + 'regex' => '', + 'errmsg' => '', + 'default' => '', + 'value' => $otp_method_list, + 'separator' => '', + 'width' => '30', + 'maxlength' => '255', + 'rows' => '', + 'cols' => '' + ), 'language' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', diff --git a/interface/web/tools/lib/lang/ar_usersettings.lng b/interface/web/tools/lib/lang/ar_usersettings.lng index c05b94e76e77b6f2c2548b8f3dc9607ba91d228f..ac3339f448b0f861f7701f03aeb01af081ec6a2a 100644 --- a/interface/web/tools/lib/lang/ar_usersettings.lng +++ b/interface/web/tools/lib/lang/ar_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/bg_usersettings.lng b/interface/web/tools/lib/lang/bg_usersettings.lng index c30dcf37019f205569a250bd4addd21cf6961e6a..93cbf9441728149843566af79f2053dc0f7f507c 100644 --- a/interface/web/tools/lib/lang/bg_usersettings.lng +++ b/interface/web/tools/lib/lang/bg_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/br_usersettings.lng b/interface/web/tools/lib/lang/br_usersettings.lng index 8e6829a8c027b923b5d700d4f5144b039bbcf5af..a8bb10a34372a2a919e9cfb9e5bbf8b8ae541bd6 100644 --- a/interface/web/tools/lib/lang/br_usersettings.lng +++ b/interface/web/tools/lib/lang/br_usersettings.lng @@ -15,3 +15,4 @@ $wb['startmodule_empty'] = 'Módulo inicial está vazio.'; $wb['startmodule_regex'] = 'Caracteres inválidos no módulo inicial.'; $wb['app_theme_empty'] = 'Tema está vazio.'; $wb['app_theme_regex'] = 'Caracteres inválidos no tema.'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; diff --git a/interface/web/tools/lib/lang/ca_usersettings.lng b/interface/web/tools/lib/lang/ca_usersettings.lng index 4705660b9e1489cdd8fdcdaadd22561a4892d410..74dfb3281d8b0446ed32b29d3fc0da2091f8cb32 100644 --- a/interface/web/tools/lib/lang/ca_usersettings.lng +++ b/interface/web/tools/lib/lang/ca_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Les mots de passe correspondent.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Page d\'accueil'; $wb['app_theme_txt'] = 'Interface'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/cz_usersettings.lng b/interface/web/tools/lib/lang/cz_usersettings.lng index 3805d25b3a6a144835d8a7d499717729bf8ab0ba..c3ded6184d09917be0a99248b45bf722652595e2 100644 --- a/interface/web/tools/lib/lang/cz_usersettings.lng +++ b/interface/web/tools/lib/lang/cz_usersettings.lng @@ -15,3 +15,4 @@ $wb['startmodule_empty'] = 'Startmodule empty.'; $wb['startmodule_regex'] = 'Invalid chars in Startmodule.'; $wb['app_theme_empty'] = 'App theme empty.'; $wb['app_theme_regex'] = 'Invalid chars in App theme.'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; diff --git a/interface/web/tools/lib/lang/de_usersettings.lng b/interface/web/tools/lib/lang/de_usersettings.lng index dd5fefffae16a756fc596ae7566cedefe27d495f..e66f2db650f617d2eabd537f70bc02afd8b32e65 100644 --- a/interface/web/tools/lib/lang/de_usersettings.lng +++ b/interface/web/tools/lib/lang/de_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Die Passwörter stimmen überein.'; $wb['language_txt'] = 'Sprache'; $wb['startmodule_txt'] = 'Startmodul'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/dk_usersettings.lng b/interface/web/tools/lib/lang/dk_usersettings.lng index 341d9db757b08e847b3d0aa5b7ece8781959764a..e413c61f1b360a3e2efe9757ddc0d172792edf89 100644 --- a/interface/web/tools/lib/lang/dk_usersettings.lng +++ b/interface/web/tools/lib/lang/dk_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_txt'] = 'Password'; $wb['language_txt'] = 'Sprog'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/el_usersettings.lng b/interface/web/tools/lib/lang/el_usersettings.lng index 68ddcd657c44dac297d32edcc570ceb6bd06b10c..4158c9fc0ee1b6fe7f66eb8d85032265a302ffcd 100644 --- a/interface/web/tools/lib/lang/el_usersettings.lng +++ b/interface/web/tools/lib/lang/el_usersettings.lng @@ -11,4 +11,5 @@ $wb['password_mismatch_txt'] = 'The passwords do not match.'; $wb['password_match_txt'] = 'The passwords do match.'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/en.lng b/interface/web/tools/lib/lang/en.lng index 7794543497984f911d29364e2b6497c39ab5940d..eff8a133231bfd8974da242398f0470b45fc5dbf 100644 --- a/interface/web/tools/lib/lang/en.lng +++ b/interface/web/tools/lib/lang/en.lng @@ -10,4 +10,4 @@ $wb['Resync'] = 'Resync'; $wb['Import'] = 'Import'; $wb['ISPConfig 3 mail'] = 'ISPConfig 3 mail'; $wb['PDNS Tupa'] = 'PowerDNS Tupa'; -?> \ No newline at end of file +?> diff --git a/interface/web/tools/lib/lang/en_usersettings.lng b/interface/web/tools/lib/lang/en_usersettings.lng index 421805e7896ebe54e961752415dd7cfa46244179..458eef7606042fe4019e35292cdfbb75d056a529 100644 --- a/interface/web/tools/lib/lang/en_usersettings.lng +++ b/interface/web/tools/lib/lang/en_usersettings.lng @@ -16,4 +16,5 @@ $wb['startmodule_empty'] = 'Startmodule empty.'; $wb['startmodule_regex'] = 'Invalid chars in Startmodule.'; $wb['app_theme_empty'] = 'App theme empty.'; $wb['app_theme_regex'] = 'Invalid chars in App theme.'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/es_usersettings.lng b/interface/web/tools/lib/lang/es_usersettings.lng index 43a181a11c7337042c0faada5357b30b53aae228..b3a6390948a432c9d6023b85f9f75854e4f31d80 100644 --- a/interface/web/tools/lib/lang/es_usersettings.lng +++ b/interface/web/tools/lib/lang/es_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Las contraseñas coinciden.'; $wb['language_txt'] = 'Idioma'; $wb['startmodule_txt'] = 'Módulo de inicio'; $wb['app_theme_txt'] = 'Diseño'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/fi_usersettings.lng b/interface/web/tools/lib/lang/fi_usersettings.lng index 91d71739537e6d663f4a6e9fc043ab5f73af5fed..888b1c7eb64d46a4dc3e961ee38378bda61eda77 100644 --- a/interface/web/tools/lib/lang/fi_usersettings.lng +++ b/interface/web/tools/lib/lang/fi_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/fr_usersettings.lng b/interface/web/tools/lib/lang/fr_usersettings.lng index b398e76e352ccb6b168473b29f74bcbf6c5b932f..57f47dc9fbb82bc1c211dc4fb92cf16c1b670d19 100644 --- a/interface/web/tools/lib/lang/fr_usersettings.lng +++ b/interface/web/tools/lib/lang/fr_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Les mots de passe correspondent.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/hr_usersettings.lng b/interface/web/tools/lib/lang/hr_usersettings.lng index b707cce4da55bf35f0c771408c92f95fd0464457..cf206223395f8b6c4016cbc14a8e1101b0efcec2 100644 --- a/interface/web/tools/lib/lang/hr_usersettings.lng +++ b/interface/web/tools/lib/lang/hr_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Šifre su identične.'; $wb['language_txt'] = 'Jezik'; $wb['startmodule_txt'] = 'Početna stranica'; $wb['app_theme_txt'] = 'Tema'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/hu_usersettings.lng b/interface/web/tools/lib/lang/hu_usersettings.lng index 2a89acf5b5f926929859300cc3e573566b55fc1c..35bb4a60dee5ebb226d8b75c1e02d341119e66be 100644 --- a/interface/web/tools/lib/lang/hu_usersettings.lng +++ b/interface/web/tools/lib/lang/hu_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/id_usersettings.lng b/interface/web/tools/lib/lang/id_usersettings.lng index 760cfe75f244d893433fc863f683093816a11c00..1a63a8b41c399aefdd28cc5c193df9a711a34278 100644 --- a/interface/web/tools/lib/lang/id_usersettings.lng +++ b/interface/web/tools/lib/lang/id_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/it_usersettings.lng b/interface/web/tools/lib/lang/it_usersettings.lng index 0f1cefe1bf3411eeb539324b6927dd3ac96dfe26..e291041b1c61cbaea57ccf2c7f049f7dc6fef266 100644 --- a/interface/web/tools/lib/lang/it_usersettings.lng +++ b/interface/web/tools/lib/lang/it_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Le password coincidono.'; $wb['language_txt'] = 'Lingua pannello'; $wb['startmodule_txt'] = 'Modulo di avvio'; $wb['app_theme_txt'] = 'Apparenza'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/ja_usersettings.lng b/interface/web/tools/lib/lang/ja_usersettings.lng index 291aa94537208f694c4b6e49eabe059d7ac8f085..d5ba174fde29f7690d6e6c3a8c842822d5bc07fa 100644 --- a/interface/web/tools/lib/lang/ja_usersettings.lng +++ b/interface/web/tools/lib/lang/ja_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/nl_usersettings.lng b/interface/web/tools/lib/lang/nl_usersettings.lng index 909df9dbecf4bcadca6266477ec37b276581f1ee..cb31a68d209977df2ee0ab01c6ae354562738ebe 100644 --- a/interface/web/tools/lib/lang/nl_usersettings.lng +++ b/interface/web/tools/lib/lang/nl_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Taal'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Twee-factor Authenticatie'; ?> diff --git a/interface/web/tools/lib/lang/pl_usersettings.lng b/interface/web/tools/lib/lang/pl_usersettings.lng index 64396df2409dbb08ea741cd5d7ea7551ce5769c1..1bb9a69ae7525a61a7bea81e02c91331cc0551dc 100644 --- a/interface/web/tools/lib/lang/pl_usersettings.lng +++ b/interface/web/tools/lib/lang/pl_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Hasła się zgadzają'; $wb['language_txt'] = 'Język'; $wb['startmodule_txt'] = 'Moduł startowy'; $wb['app_theme_txt'] = 'Temat'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/pt_usersettings.lng b/interface/web/tools/lib/lang/pt_usersettings.lng index 4925a3f7286da3e7a1fc9c74205d7dcd4217ccfe..b5ca31359e3cfc3e9b6443be984572b68973855e 100644 --- a/interface/web/tools/lib/lang/pt_usersettings.lng +++ b/interface/web/tools/lib/lang/pt_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/ro_usersettings.lng b/interface/web/tools/lib/lang/ro_usersettings.lng index 8c43550f33cc56729cd5902089e60d21b5732e25..7c826d923b62e6958ee82b9cb178561dfcff642f 100644 --- a/interface/web/tools/lib/lang/ro_usersettings.lng +++ b/interface/web/tools/lib/lang/ro_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/ru_usersettings.lng b/interface/web/tools/lib/lang/ru_usersettings.lng index ffa3f3bf03116cf1d8b3cd4b97c38114e4762b28..d8e091e55364e47b9e2528a231f34855f41d8bcb 100644 --- a/interface/web/tools/lib/lang/ru_usersettings.lng +++ b/interface/web/tools/lib/lang/ru_usersettings.lng @@ -14,4 +14,5 @@ $wb['interface_desc_txt'] = 'Измените свой интерфейс'; $wb['language_txt'] = 'Язык'; $wb['startmodule_txt'] = 'Стартовый модуль'; $wb['app_theme_txt'] = 'Тема'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/se_usersettings.lng b/interface/web/tools/lib/lang/se_usersettings.lng index f6de2dc4eebe227af1be4cfe0e5de3bd5ee7eff1..9680936d7bee1af79c3f846b9d90b66a7156e368 100644 --- a/interface/web/tools/lib/lang/se_usersettings.lng +++ b/interface/web/tools/lib/lang/se_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Lösenorden matchar'; $wb['language_txt'] = 'Språk'; $wb['startmodule_txt'] = 'Startmodul'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/sk_usersettings.lng b/interface/web/tools/lib/lang/sk_usersettings.lng index e00f5e664b1bb4bcb71a6614446dec2530c1aa21..ee1ff41888281bcecd049c124a68679526cced82 100644 --- a/interface/web/tools/lib/lang/sk_usersettings.lng +++ b/interface/web/tools/lib/lang/sk_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'The passwords do match.'; $wb['language_txt'] = 'Language'; $wb['startmodule_txt'] = 'Startmodule'; $wb['app_theme_txt'] = 'Design'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/lib/lang/tr_usersettings.lng b/interface/web/tools/lib/lang/tr_usersettings.lng index a1fd7c56d4cddc2fd47065819f46c37917369bfb..81ea3ed5f6ed1a851a34b1449c395a3fa96a3a25 100644 --- a/interface/web/tools/lib/lang/tr_usersettings.lng +++ b/interface/web/tools/lib/lang/tr_usersettings.lng @@ -12,4 +12,5 @@ $wb['password_match_txt'] = 'Parola ile onayı aynı.'; $wb['language_txt'] = 'Dil'; $wb['startmodule_txt'] = 'Başlangıç modülü'; $wb['app_theme_txt'] = 'Tasarım'; +$wb['otp_auth_txt'] = 'Two Factor Authentication'; ?> diff --git a/interface/web/tools/templates/user_settings.htm b/interface/web/tools/templates/user_settings.htm index a620f419c54d58ed5ad4e3b044c8410b10d46160..f430b64195d29cb56cb3a52e74355101b0db64c5 100644 --- a/interface/web/tools/templates/user_settings.htm +++ b/interface/web/tools/templates/user_settings.htm @@ -26,6 +26,14 @@
+
+ +
+ +
+