From 4eaefa0d62bed6726031e4641748696e2faef925 Mon Sep 17 00:00:00 2001 From: Alessandro Briosi Date: Wed, 13 Nov 2024 09:03:13 +0100 Subject: [PATCH] Handle Authentication with TOTP in reverse --- .../mvc/app/library/OPNsense/Auth/TOTP.php | 2 +- .../scripts/openvpn/user_pass_verify.php | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/TOTP.php b/src/opnsense/mvc/app/library/OPNsense/Auth/TOTP.php index 96cb993a205..c7ca679cf94 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/TOTP.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/TOTP.php @@ -54,7 +54,7 @@ trait TOTP /** * @var bool token after password */ - private $passwordFirst = false; + public $passwordFirst = false; /** * use graceperiod and timeWindow to calculate which moments in time we should check diff --git a/src/opnsense/scripts/openvpn/user_pass_verify.php b/src/opnsense/scripts/openvpn/user_pass_verify.php index dfd7314013e..9ccd93cc848 100755 --- a/src/opnsense/scripts/openvpn/user_pass_verify.php +++ b/src/opnsense/scripts/openvpn/user_pass_verify.php @@ -80,16 +80,15 @@ function do_auth($common_name, $serverid, $method, $auth_file) if (empty($username) || empty($password)) { return "username or password missing ({$method} - {$auth_file})"; } + $pinpassword = false; + $pin = false; if (strpos($password, 'SCRV1:') === 0) { // static-challenge https://github.com/OpenVPN/openvpn/blob/v2.4.7/doc/management-notes.txt#L1146 - // validate and concat password into our default pin+password + // validate and split password into pin and password (used below based on authenticato settings) $tmp = explode(':', $password); if (count($tmp) == 3) { - $pass = base64_decode($tmp[1]); + $pinpassword = base64_decode($tmp[1]); $pin = base64_decode($tmp[2]); - if ($pass !== false && $pin !== false) { - $password = $pin . $pass; - } } } $a_server = $serverid !== null ? (new OPNsense\OpenVPN\OpenVPN())->getInstanceById($serverid, 'server') : null; @@ -121,7 +120,15 @@ function do_auth($common_name, $serverid, $method, $auth_file) foreach (explode(',', $a_server['authmode']) as $authName) { $authenticator = $authFactory->get($authName); if ($authenticator) { - if ($authenticator->authenticate($username, $password)) { + $checkpassword = $password; + if ($pin!=false) { + if (property_exists($authenticator,'passwordFirst') && $authenticator->passwordFirst) { + $checkpassword = $pinpassword . $pin; + } else { + $checkpassword = $pin . $pinpassword; + } + } + if ($authenticator->authenticate($username, $checkpassword)) { // fetch or create client specific override $common_name = empty($a_server['cso_login_matching']) ? $common_name : $username; syslog(