ソースを参照

Auto create TOTP secret (#6670)

* Auto create TOTP secret

Auto create TOTP secret after successful database authentication when the TOTP secret has not been set.
FusionPBX 2 年 前
コミット
eaf3b45025

+ 26 - 0
core/authentication/app_languages.php

@@ -78,4 +78,30 @@ $text['label-email_description']['zh-cn'] = "查阅您的核查文件。";
 $text['label-email_description']['ja-jp'] = "認証コードのメールをご確認ください。";
 $text['label-email_description']['ko-kr'] = "인증 코드의 이메일 확인.";
 
+$text['description-totp']['en-us'] = "Scan the code with an authentication application or password manager. Then use it to generate the token for the login.";
+$text['description-totp']['en-gb'] = "Scan the code with an authentication application or password manager. Then use it to generate the token for the login.";
+$text['description-totp']['ar-eg'] = "مسح الرمز مع تطبيق التوثيق أو مدير كلمة السر ثم استخدامه لتوليد الضباب لقطع الخشب.";
+$text['description-totp']['de-at'] = "Scannen Sie den Code mit einer Authentifizierungs-Anwendung oder einem Passwort-Manager. Dann verwenden Sie es, um das Token für den Login zu generieren.";
+$text['description-totp']['de-ch'] = "Scannen Sie den Code mit einer Authentifizierungs-Anwendung oder einem Passwort-Manager. Dann verwenden Sie es, um das Token für den Login zu generieren.";
+$text['description-totp']['de-de'] = "Scannen Sie den Code mit einer Authentifizierungs-Anwendung oder einem Passwort-Manager. Dann verwenden Sie es, um das Token für den Login zu generieren.";
+$text['description-totp']['el-gr'] = "Βάλτε τον κωδικό με μια εφαρμογή πιστοποίησης ή password manager. Στη συνέχεια χρησιμοποιήστε το για να δημιουργήσετε το token για τη σύνδεση.";
+$text['description-totp']['es-cl'] = "Analice el código con una aplicación de autenticación o gestor de contraseñas. A continuación, utilizarlo para generar la ficha para el login.";
+$text['description-totp']['es-mx'] = "Analice el código con una aplicación de autenticación o gestor de contraseñas. A continuación, utilizarlo para generar la ficha para el login.";
+$text['description-totp']['fr-ca'] = "Scannez le code avec une application d'authentification ou un gestionnaire de mot de passe. Ensuite, utilisez-le pour générer le jeton pour le login.";
+$text['description-totp']['fr-fr'] = "Scannez le code avec une application d'authentification ou un gestionnaire de mot de passe. Ensuite, utilisez-le pour générer le jeton pour le login.";
+$text['description-totp']['he-il'] = "לסרוק את הקוד עם יישום אימות או מנהל סיסמאות. לאחר מכן השתמש בו כדי ליצור את האסימון עבור הכניסה.";
+$text['description-totp']['it-it'] = "Scansiona il codice con un'applicazione di autenticazione o un gestore di password. Quindi utilizzare per generare il token per il login.";
+$text['description-totp']['nl-nl'] = "Scan de code met een authenticatie aanvraag of wachtwoordmanager. Gebruik het dan om het teken voor het login te genereren.";
+$text['description-totp']['pl-pl'] = "Skanowanie kodu z zastosowaniem uwierzytelnia lub menedżerem haseł. Zastosowanie go do generowania tokenu dla loginu.";
+$text['description-totp']['pt-br'] = "Digitalize o código com um aplicativo de autenticação ou gerenciador de senha. Em seguida, use-o para gerar o token para o login.";
+$text['description-totp']['pt-pt'] = "Digitalize o código com um aplicativo de autenticação ou gerenciador de senha. Em seguida, use-o para gerar o token para o login.";
+$text['description-totp']['ro-ro'] = "Scanați codul cu o aplicație de autentificare sau un manager de parole. Apoi utilizați-l pentru a genera simbolul pentru autentificare.";
+$text['description-totp']['ru-ru'] = "Сканировать код с приложением аутентификации или менеджером паролей. Затем используйте его для создания токена для входа.";
+$text['description-totp']['sv-se'] = "Skanna koden med en autentiseringsapplikation eller lösenordshanterare. Använd sedan den för att generera token för inloggningen.";
+$text['description-totp']['uk-ua'] = "Сканування коду за допомогою програми автентифікації або пароля. Потім використовуйте його для створення токени для входу.";
+$text['description-totp']['tr-tr'] = "Kodu bir doğrulama uygulama veya şifre yöneticisi ile tarayın. Sonra giriş için token oluşturmak için kullanın.";
+$text['description-totp']['zh-cn'] = "载有认证申请或密码管理员的编码。 然后使用该标识生成标识。";
+$text['description-totp']['ja-jp'] = "認証アプリケーションまたはパスワードマネージャでコードをスキャンします。 ログイン時にトークンを生成します。";
+$text['description-totp']['ko-kr'] = "인증 신청서 또는 비밀번호 관리자로 코드를 스캔합니다. 그런 다음 로그인 토큰을 생성합니다.";
+
 ?>

+ 77 - 6
core/authentication/resources/classes/plugins/totp.php

@@ -25,8 +25,16 @@ class plugin_totp {
 	 */
 	function totp() {
 
+		//get the username
+			if (isset($_SESSION["username"])) {
+				$this->username = $_SESSION["username"];
+			}
+			if (isset($_POST['username'])) {
+				$this->username = $_POST['username'];
+			}
+
 		//request the username
-			if (!isset($_POST['username']) && !isset($_POST['authentication_code'])) {
+			if (!$this->username && !isset($_POST['authentication_code'])) {
 
 				//set a default template
 				$_SESSION['domain']['template']['name'] = 'default';
@@ -62,7 +70,7 @@ class plugin_totp {
 				$view->assign("login_logo_height", $login_logo_height);
 				$view->assign("login_logo_source", $login_logo_source);
 				$view->assign("button_login", $text['button-login']);
-					
+
 				//show the views
 				$content = $view->render('username.htm');
 				echo $content;
@@ -130,16 +138,80 @@ class plugin_totp {
 				$view->cache_dir = $_SESSION['server']['temp']['dir'];
 				$view->init();
 
-				//assign default values to the template
+				//assign values to the template
 				$view->assign("login_title", $text['label-verify']);
 				$view->assign("login_authentication_code", $text['label-authentication_code']);
 				$view->assign("login_logo_width", $login_logo_width);
 				$view->assign("login_logo_height", $login_logo_height);
 				$view->assign("login_logo_source", $login_logo_source);
-				$view->assign("button_verify", $text['label-verify']);
 
 				//show the views
-				$content = $view->render('totp.htm');
+				if ($_SESSION['authentication']['plugin']['database']['authorized'] && empty($this->user_totp_secret)) {
+
+					//create the totp secret
+					$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
+					$user_totp_secret = $base32->encode(generate_password(20,3));
+					$this->user_totp_secret = $user_totp_secret;
+
+					//add user setting to array for update
+					$x = 0;
+					$array['users'][$x]['user_uuid'] = $this->user_uuid;
+					$array['users'][$x]['domain_uuid'] = $this->domain_uuid;
+					$array['users'][$x]['user_totp_secret'] = $this->user_totp_secret;
+
+					//add the user_edit permission
+					$p = new permissions;
+					$p->add("user_edit", "temp");
+
+					//save the data
+					$database = new database;
+					$database->app_name = 'users';
+					$database->app_uuid = '112124b3-95c2-5352-7e9d-d14c0b88f207';
+					$database->save($array);
+
+					//remove the temporary permission
+					$p->delete("user_edit", "temp");
+
+					//qr code includes
+					require_once 'resources/qr_code/QRErrorCorrectLevel.php';
+					require_once 'resources/qr_code/QRCode.php';
+					require_once 'resources/qr_code/QRCodeImage.php';
+
+					//build the otp authentication url
+					$otpauth = "otpauth://totp/".$this->username;
+					$otpauth .= "?secret=".$this->user_totp_secret;
+					$otpauth .= "&issuer=".$_SESSION['domain_name'];
+
+					//build the qr code image
+					try {
+						$code = new QRCode (- 1, QRErrorCorrectLevel::H);
+						$code->addData($otpauth);
+						$code->make();
+						$img = new QRCodeImage ($code, $width=210, $height=210, $quality=50);
+						$img->draw();
+						$image = $img->getImage();
+						$img->finish();
+					}
+					catch (Exception $error) {
+						echo $error;
+					}
+
+					//assign values to the template
+					$view->assign("totp_secret", $this->user_totp_secret);
+					$view->assign("totp_image", base64_encode($image));
+					$view->assign("totp_description", $text['description-totp']);
+					$view->assign("button_next", $text['button-next']);
+
+					//render the template
+					$content = $view->render('totp_secret.htm');
+				}
+				else {
+					//assign values to the template
+					$view->assign("button_verify", $text['label-verify']);
+
+					//render the template
+					$content = $view->render('totp.htm');
+				}
 				echo $content;
 				exit;
 			}
@@ -245,7 +317,6 @@ class plugin_totp {
 				//retun the array
 				return $result;
 
-
 				//$_SESSION['authentication']['plugin']['totp']['plugin'] = "totp";
 				//$_SESSION['authentication']['plugin']['totp']['domain_name'] = $_SESSION["domain_name"];
 				//$_SESSION['authentication']['plugin']['totp']['username'] = $row['username'];

+ 25 - 33
core/authentication/resources/views/email.htm

@@ -1,36 +1,28 @@
 <!DOCTYPE html>
 <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
-<head>
-<meta charset='utf-8'>
-<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
-<meta http-equiv='X-UA-Compatible' content='IE=edge'>
-<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
-<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php'>
-<title>{$login_title}</title>
-<body>
-	<div id='page' align='center'>
-		<div id='default_login'>
-			<!--
-			<a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}'/></a><br />
-			-->
-			<form method='post' name='frm' action=''>
-				<div>
-					{$login_email_description}
-					<br /><br />
-					<input class='formfld' type='text' name='authentication_code' maxlength='255' placeholder="{$login_authentication_code}" value="{$authentication_code}">
-					<br /><br />
-				</div>
-				<div>
-					<input type='hidden' name='{$token_name}' value='{$token_hash}'>
-					<input type='submit' name='' class='btn' value='{$button_verify}'>
-				</div>
-			</form>
+	<head>
+		<meta charset='utf-8' />
+		<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
+		<meta http-equiv='X-UA-Compatible' content='IE=edge' />
+		<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
+		<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php' />
+		<title>{$login_title}</title>
+	</head>
+	<body>
+		<div id='page' align='center'>
+			<div id='default_login'>
+				<form method='post' name='frm' action=''>
+					<div>
+						{$login_email_description}
+						<br /><br />
+						<input class='formfld' type='text' style='text-align: center; min-width: 200px; width: 200px; margin-bottom: 8px;' name='authentication_code' maxlength='255' placeholder="{$login_authentication_code}" value="{$authentication_code}" />
+						<br /><br />
+					</div>
+					<div>
+						<input type='submit' name='' class='btn' value='{$button_verify}' />
+					</div>
+				</form>
+			</div>
 		</div>
-	</div>
-	<!--
-	<div id='footer_login'>
-		<span class='footer'>{$settings.theme.footer}</span>
-	</div>
-	-->
-</body>
-</html>
+	</body>
+</html>

+ 23 - 28
core/authentication/resources/views/login.htm

@@ -1,32 +1,27 @@
 <!DOCTYPE html>
 <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
-<head>
-<meta charset='utf-8'>
-<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
-<meta http-equiv='X-UA-Compatible' content='IE=edge'>
-<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
-<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php'>
-<title>{$login_title}</title>
-<body>
-	<div id='page' align='center'>
-		<div id='default_login'>
-			<a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}'></a><br />
-			<form method='post' name='frm' action='{$login_destination_url}'>
-				<div>
-					<input type='text' class='txt login' style='text-align: center; min-width: 200px; width: 200px; margin-bottom: 8px;' name='username' id='username' placeholder="{$label_username}"><br />
-					<input type='password' class='txt login' style='text-align: center; min-width: 200px; width: 200px; margin-bottom: 8px;' name='password' placeholder="{$label_password}"><br />
-				</div>
-				<div>
-					<!--<input type='hidden' name='{$token_name}' value='{$token_hash}'>-->
-					<input type='submit' id='btn_login' class='btn' style='width: 100px; margin-top: 15px;' value='{$button_login}'>
-				</div>
-			</form>
+	<head>
+		<meta charset='utf-8' />
+		<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
+		<meta http-equiv='X-UA-Compatible' content='IE=edge' />
+		<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
+		<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php' />
+		<title>{$login_title}</title>
+	</head>
+	<body>
+		<div id='page' align='center'>
+			<div id='default_login'>
+				<a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}' /></a><br />
+				<form method='post' name='frm' action='{$login_destination_url}'>
+					<div>
+						<input type='text' class='txt login' style='text-align: center; min-width: 200px; width: 200px; margin-bottom: 8px;' name='username' id='username' placeholder="{$label_username}" /><br />
+						<input type='password' class='txt login' style='text-align: center; min-width: 200px; width: 200px; margin-bottom: 8px;' name='password' placeholder="{$label_password}" /><br />
+					</div>
+					<div>
+						<input type='submit' id='btn_login' class='btn' style='width: 100px; margin-top: 15px;' value='{$button_login}' />
+					</div>
+				</form>
+			</div>
 		</div>
-	</div>
-	<!--
-	<div id='footer_login'>
-		<span class='footer'>{$settings.theme.footer}</span>
-	</div>
-	-->
-</body>
+	</body>
 </html>

+ 23 - 40
core/authentication/resources/views/totp.htm

@@ -1,44 +1,27 @@
 <!DOCTYPE html>
 <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
-<head>
-<meta charset='utf-8'>
-<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
-<meta http-equiv='X-UA-Compatible' content='IE=edge'>
-<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
-<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php'>
-<title>{$login_title}</title>
-<body>
-	<!--
-	<div class='action_bar' id='action_bar'>
-		<div class='heading'><b>{$title_authentication_code}</b></div>
-		<div class='actions'>\n";
+	<head>
+		<meta charset='utf-8' />
+		<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
+		<meta http-equiv='X-UA-Compatible' content='IE=edge' />
+		<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
+		<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php' />
+		<title>{$login_title}</title>
+	</head>
+	<body>
+		<div id='page' align='center'>
+			<div id='default_login'>
+				<a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}' /></a><br />
+				<form method='post' name='frm' action=''>
+					<div>
+						<input class='formfld' type='text' style='text-align: center;' name='authentication_code' maxlength='255' placeholder="{$login_authentication_code}" value="{$authentication_code}" />
+						<br /><br />
+					</div>
+					<div>
+						<input type='submit' name='' class='btn' value='{$button_verify}' />
+					</div>
+				</form>
+			</div>
 		</div>
-		<div style='clear: both;'></div>
-	</div>
-	-->
-	<div id='page' align='center'>
-		<div id='default_login'>
-			<a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}'/></a><br />
-			<form method='post' name='frm' action=''>
-				<div>
-					<input class='formfld' type='text' style='text-align: center; min-width: 200px; width: 200px; margin-bottom: 8px;' name='authentication_code' maxlength='255' placeholder="{$login_authentication_code}" value="{$authentication_code}">
-					<br /><br />
-					<!--
-					{$description_authentication_code}
-					<br /><br />
-					-->
-				</div>
-				<div>
-					<input type='hidden' name='{$token_name}' value='{$token_hash}'>
-					<input type='submit' name='' class='btn' value='{$button_verify}'>
-				</div>
-			</form>
-		</div>
-	</div>
-	<!--
-	<div id='footer_login'>
-		<span class='footer'>{$settings.theme.footer}</span>
-	</div>
-	-->
-</body>
+	</body>
 </html>

+ 28 - 0
core/authentication/resources/views/totp_secret.htm

@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
+	<head>
+		<meta charset='utf-8' />
+		<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
+		<meta http-equiv='X-UA-Compatible' content='IE=edge' />
+		<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
+		<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php' />
+		<title>{$login_title}</title>
+	</head>
+	<body>
+		<div id='page' align='center'>
+			<div id='default_login' style='max-width: 400px;'>
+				<a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}'/></a><br />
+				<form method='post' name='frm' action=''>
+					<div id='totp_qr'>
+						{$totp_secret}<br /><br />
+						<img src="data:image/jpeg;base64,{$totp_image}" style='margin-top: 0px; padding: 5px; background: white; max-width: 100%;' /><br /><br />
+						{$totp_description}<br /><br />
+					</div>
+					<div>
+						<input type='submit' name='' class='btn' value='{$button_next}' />
+					</div>
+				</form>
+			</div>
+		</div>
+	</body>
+</html>

+ 22 - 27
core/authentication/resources/views/username.htm

@@ -1,31 +1,26 @@
 <!DOCTYPE html>
 <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
-<head>
-<meta charset='utf-8'>
-<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
-<meta http-equiv='X-UA-Compatible' content='IE=edge'>
-<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
-<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php'>
-<title>{$login_title}</title>
-<body>
-	<div id='page' align='center'>
-		<div id='default_login'>
-			<a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}'></a><br />
-			<form method='post' name='frm' action='{$login_destination_url}'>
-				<div>
-					<input type='text' class='txt login' style='text-align: center; min-width: 200px; width: 200px; margin-bottom: 8px;' name='username' id='username' placeholder="{$login_username}"><br />
-				</div>
-				<div>
-					<input type='hidden' name='{$token_name}' value='{$token_hash}'>
-					<input type='submit' id='btn_login' class='btn' style='width: 100px; margin-top: 15px;' value='{$button_login}'>
-				</div>
-			</form>
+	<head>
+		<meta charset='utf-8' />
+		<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
+		<meta http-equiv='X-UA-Compatible' content='IE=edge' />
+		<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
+		<link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php' />
+		<title>{$login_title}</title>
+	</head>
+	<body>
+		<div id='page' align='center'>
+			<div id='default_login'>
+				<a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}' /></a><br />
+				<form method='post' name='frm' action='{$login_destination_url}'>
+					<div>
+						<input type='text' class='txt login' style='text-align: center; min-width: 200px; width: 200px; margin-bottom: 8px;' name='username' id='username' placeholder="{$login_username}" /><br />
+					</div>
+					<div>
+						<input type='submit' id='btn_login' class='btn' style='width: 100px; margin-top: 15px;' value='{$button_login}' />
+					</div>
+				</form>
+			</div>
 		</div>
-	</div>
-	<!--
-	<div id='footer_login'>
-		<span class='footer'>{$settings.theme.footer}</span>
-	</div>
-	-->
-</body>
+	</body>
 </html>