From 6a0d930eb01440966a46521105b561b504a45782 Mon Sep 17 00:00:00 2001 From: multiOTP Date: Sat, 23 Sep 2023 00:21:18 +0200 Subject: [PATCH] New release 5.9.6.7 ENH: Documentation updated for "Configuring multiOTP with FreeRADIUS 3.x under Linux" ENH: Without2FA tokens cannot be used for multi_account connection ENH: Added documentation for SSH login with multiOTP --- Dockerfile | 6 +- README.md | 264 +++++++++++++----- check.multiotp.class.php | 4 +- checkmultiotp.cmd | 4 +- launcher/ReadMe.txt | 4 +- launcher/launcher.cpp | 8 +- multiotp.class.php | 84 ++++-- multiotp.cli.header.php | 4 +- multiotp.cli.proxy.php | 4 +- multiotp.php | 88 ++++-- multiotp.server.php | 4 +- radius_debug.cmd | 4 +- radius_install.cmd | 4 +- radius_uninstall.cmd | 4 +- raspberry/boot-part/install.sh | 6 +- .../usr/local/bin/multiotp/index.php | 88 ++++-- .../usr/local/bin/multiotp/multiotp.class.php | 84 ++++-- .../usr/local/bin/multiotp/multiotp.php | 4 +- .../usr/local/bin/multiotp/multiotp.proxy.php | 88 ++++-- ...{readme_5.9.6.5.txt => readme_5.9.6.7.txt} | 256 +++++++++++++---- .../bin/multiotp/scripts/multiotp-service.sh | 4 +- .../local/bin/multiotp/scripts/multiotp.pl | 4 +- raspberry/boot-part/newvm.sh | 6 +- ...raspberry-strong-authentication-server.txt | 2 +- .../multiotp-open-source-raspberry-img.txt | 2 +- scripts/multiotp-service.sh | 4 +- scripts/multiotp.pl | 4 +- webservice_install.cmd | 4 +- webservice_uninstall.cmd | 4 +- 29 files changed, 744 insertions(+), 302 deletions(-) rename raspberry/boot-part/multiotp-tree/usr/local/bin/multiotp/{readme_5.9.6.5.txt => readme_5.9.6.7.txt} (91%) diff --git a/Dockerfile b/Dockerfile index 40a76f7..ac41a71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,8 +15,8 @@ # Please check https://www\.multiOTP.net/ and you will find the magic button ;-) # # @author Andre Liechti, SysCo systemes de communication sa, -# @version 5.9.6.5 -# @date 2023-07-07 +# @version 5.9.6.7 +# @date 2023-09-22 # @since 2013-11-29 # @copyright (c) 2013-2023 SysCo systemes de communication sa # @copyright GNU Lesser General Public License @@ -46,7 +46,7 @@ MAINTAINER Andre Liechti LABEL Description="multiOTP open source, running on Debian ${DEBIAN} with PHP${PHPVERSION}." \ License="LGPL-3.0" \ Usage="docker run -v [PATH/TO/MULTIOTP/DATA/VOLUME]:/etc/multiotp -v [PATH/TO/FREERADIUS/CONFIG/VOLUME]:/etc/freeradius -v [PATH/TO/MULTIOTP/LOG/VOLUME]:/var/log/multiotp -v [PATH/TO/FREERADIUS/LOG/VOLUME]:/var/log/freeradius -p [HOST WWW PORT NUMBER]:80 -p [HOST SSL PORT NUMBER]:443 -p [HOST RADIUS-AUTH PORT NUMBER]:1812/udp -p [HOST RADIUS-ACCNT PORT NUMBER]:1813/udp -d multiotp-open-source" \ - Version="5.9.6.5" + Version="5.9.6.7" ARG DEBIAN_FRONTEND=noninteractive diff --git a/README.md b/README.md index 091f845..910cd7d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ multiOTP open source is OATH certified for HOTP/TOTP (c) 2010-2023 SysCo systemes de communication sa https://www.multiotp.net/ -Current build: 5.9.6.5 (2023-07-07) +Current build: 5.9.6.7 (2023-09-22) Binary download: https://download.multiotp.net/ (including virtual appliance image) @@ -99,8 +99,9 @@ TABLE OF CONTENTS * How to configure multiOTP to use the client/server feature ? * How to build a Raspberry Pi strong authentication server ? * How to install a local only strong authentication on a Windows machine ? - * How to install a centralized strong authentication server - for strong authentication on Windows desktops or RDP ? + * How to install a centralized 2FA server for Windows desktops or RDP login ? + * Same Windows generic account with multiple two-factor authentication accounts + * Using multiOTP on Linux for SSH login * LDAP filter customization * OpenSSL options for LDAPS * Compatible clients applications and devices @@ -154,6 +155,11 @@ WHAT'S NEW IN THIS 5.9.x RELEASE CHANGE LOG OF RELEASED VERSIONS =============================== ``` +2023-09-22 5.9.6.7 ENH: Documentation updated for "Configuring multiOTP with FreeRADIUS 3.x under Linux" + ENH: Without2FA tokens cannot be used for multi_account connection + ENH: Added documentation for SSH login with multiOTP +2023-08-09 5.9.6.6 FIX: Prefix PIN information was sometimes missing on the provisioning info + ENH: New Raspberry Pi distribution binary 2023-07-07 5.9.6.5 FIX: Better Raspberry Pi support FIX: ShowLog() method (used by -showlog option) was buggy 2023-05-10 5.9.6.1 FIX: Automated concurrent access for the same user with "Without2FA" token could corrupt the user file @@ -410,7 +416,8 @@ CHANGE LOG OF RELEASED VERSIONS For _user_data, default values are now extracted from the definition array QRcode generation for mOTP (motp://[SITENAME]:[USERNAME]?secret=[SECRET-KEY]) 2015-07-15 4.3.2.5 Calling multiotp CLI without parameter returns now error code 30 (instead of 19) -2015-06-24 4.3.2.4 multi_account automatic support +2015-06-24 4.3.2.4 multi_account automatic support (multi_account is activated when + "multi_account" is set as description of the account (also with AD/LDAP sync) Scratch password generation (UTF) 2015-06-10 4.3.2.3 Enhancements for the Dev(Talks): demo 2015-06-09 4.3.2.2 Empty users are refused @@ -1109,7 +1116,7 @@ Before starting or asking for help - Make sure the otp script is executable chmod +x /path/to/multiotp.php - Verify multiotp is setup correctly by calling the script from the commandline with the appropriate arguments -1) Create 'raddb/modules/multiotp' and add the following, this will create a new instance of the exec module: +1) Create '/etc/freeradius/3.0/mods-available/multiotp' and add the following, this will create a new instance of the exec module: ``` # Exec module instance for multiOTP # Replace '/path/to' with the actual path to the multiotp.php file @@ -1117,12 +1124,17 @@ exec multiotp { wait = yes input_pairs = request output_pairs = reply - program = "/path/to/multiotp.php %{User-Name} %{User-Password} -src=%{Packet-Src-IP-Address} -chap-challenge=%{CHAP-Challenge} -chap-password=%{CHAP-Password} -ms-chap-challenge=%{MS-CHAP-Challenge} -ms-chap-response=%{MS-CHAP-Response} -ms-chap2-response=%{MS-CHAP2-Response}" + program = "/path/to/multiotp.php -base-dir='/path/to/multiotp/' '%{User-Name}' '%{User-Password}' -src='%{Packet-Src-IP-Address}' -tag='%{Client-Shortname}' -mac='%{Called-Station-Id}' -calling-ip='%{Framed-IP-Address}' -calling-mac='%{Calling-Station-Id}' -chap-challenge='%{CHAP-Challenge}' -chap-password='%{CHAP-Password}' -ms-chap-challenge='%{MS-CHAP-Challenge}' -ms-chap-response='%{MS-CHAP-Response}' -ms-chap2-response='%{MS-CHAP2-Response}' -state='%{State}'" shell_escape = yes } ``` -2) Copy module/mschap to module/multiotpmschap. Change the following line in multiotpmschap: +2) Enable multiotp module by creating a symbolic link +``` +ln -s /etc/freeradius/3.0/mods-available/multiotp /etc/freeradius/3.0/mods-enabled/multiotp +``` + +3) Copy /etc/freeradius/3.0/mods-available/mschap to /etc/freeradius/3.0/mods-available/multiotpmschap. Change the following line in multiotpmschap: ``` "mschap {" ``` @@ -1133,77 +1145,142 @@ to Also change ntlm_auth variable: ``` -ntlm_auth = "/path/to/multiotp.php %{User-Name} %{User-Password} -nt-key-only -src=%{Packet-Src-IP-Address} -chap-challenge=%{CHAP-Challenge} -chap-password=%{CHAP-Password} -ms-chap-challenge=%{MS-CHAP-Challenge} -ms-chap-response=%{MS-CHAP-Response} -ms-chap2-response=%{MS-CHAP2-Response}" +ntlm_auth = "/path/to/multiotp.php -base-dir='/path/to/multiotp/' '%{User-Name}' '%{User-Password}' -nt-key-only -src='%{Packet-Src-IP-Address}' -tag='%{Client-Shortname}' -mac='%{Called-Station-Id}' -calling-ip='%{Framed-IP-Address}' -calling-mac='%{Calling-Station-Id}' -chap-challenge='%{CHAP-Challenge}' -chap-password='%{CHAP-Password}' -ms-chap-challenge='%{MS-CHAP-Challenge}' -ms-chap-response='%{MS-CHAP-Response}' -ms-chap2-response='%{MS-CHAP2-Response}' -state='%{State}'" ``` -3) Edit 'raddb/policy.conf' and add the following to override the authorize method of the exec module: (or add a new multiotp file in the policy.d folder) -policy { +4) Enable multiotpmschap module by creating a symbolic link ``` - # Change to a specific prefix if you want to deal with normal PAP authentication as well as OTP - # e.g. "multiotp_prefix = 'otp:'" - multiotp_prefix = '' - multiotp.authorize { - # This test force multiOTP for any MS-CHAP(v2) attempt - if (control:Auth-Type == MS-CHAP) { - update control { - Auth-Type := multiotpmschap - } - } - # This test force multiOTP for any MS-CHAP(v2) attempt - elsif (control:Auth-Type == mschap) { - update control { - Auth-Type := multiotpmschap - } - } - # This test force multiOTP for any CHAP attempt - elsif (control:Auth-Type == chap) { - update control { - Auth-Type := multiotp - } - } - # This test is for decimal OTP code only, otherwise you will have to change it - # elsif (!control:Auth-Type && User-Password =~ /^${policy.multiotp_prefix}([0-9]{10})$/) { - # - # Use this simple test for non decimal only OTP code: elsif (!control:Auth-Type) { - # - # This test force multiOTP for any other attempt like PAP - elsif (!control:Auth-Type) { - update control { - Auth-Type := multiotp - } +ln -s /etc/freeradius/3.0/mods-available/multiotpmschap /etc/freeradius/3.0/mods-enabled/multiotpmschap +``` + +5) Edit /etc/freeradius/3.0/mods-available/perl file. Change the following line : +``` +filename = +``` +to +``` +filename = /path/to/multiotp/scripts/multiotp.pl +``` + +Since 5.8.3.0 and FreeRADIUS 3.0.18, set the perl flags to -U +``` +perl_flags = "-U" +``` + +6) Enable perl module by creating a symbolic link +``` +ln -s /etc/freeradius/3.0/mods-available/perl /etc/freeradius/3.0/mods-enabled/perl +``` + +7)If necessary change multiOTP path in the multiOTP perl file scripts/multiotp.pl +``` +my $output=`/usr/local/bin/multiotp/multiotp.php -base-dir='/usr/local/bin/multiotp/' "$multiotp_ +``` +to + +``` +my $output=`/path/to/multiotp.php -base-dir='/path/to/multiotp/' "$multiotp_ +``` + + +7) Create /etc/freeradius/3.0/policy.d/multiotp file and add the following to override the authorize method of the exec module: +``` +# Change to a specific prefix if you want to deal with normal PAP authentication as well as OTP +# e.g. "multiotp_prefix = 'otp:'" +multiotp_prefix = '' +multiotp.authorize { + # This test force multiOTP for any MS-CHAP(v2),CHAP and PAP attempt + if (control:Auth-Type == mschap) { + update control { + Auth-Type := multiotpmschap + } + } + elsif (control:Auth-Type == chap) { + update control { + Auth-Type := multiotp + } + } + elsif (!control:Auth-Type) { + update control { + Auth-Type := multiotp } } } ``` -4) Edit your virtual server file, the default for the outer server is 'raddb/sites-available/default' +8) Enable files and add perl just after files, in the authorize section of /etc/freeradius/3.0/sites-available/default. Add the following lines: +... + files +``` + perl #multiotp + if (ok || updated) { #multiotp + update control { #multiotp + Auth-Type := Perl #multiotp + Client-Shortname = "%{Client-Shortname}" #multiotp + Packet-Src-IP-Address = "%{Packet-Src-IP-Address}" #multiotp + } #multiotp + } #multiotp +``` -5) Add a call to multiotp before the pap module in authorize: +After logintime add the following line : +... + expiration + logintime ``` -authorize { - ... # Handle multiotp authentication multiotp +``` - # Handle other PAP authentication - pap - ... -} +9) Add a call to multiotp before the pap module in authenticate section of /etc/freeradius/3.0/sites-available/default. Add the following lines: +... +authenticate { +``` +Auth-Type multiotp { + multiotp +} #multiotp +Auth-Type multiotpmschap { + multiotpmschap +} #multiotpmschap +Auth-Type Perl { #multiotp + perl #multiotp +} #multiotp ``` -6) Create the multiotp sub-section in authenticate: +10) Add a call to perl in accounting section of /etc/freeradius/3.0/sites-available/default. Add the following lines: +... +accounting { ``` + perl #multiotp +``` + +11) Enable multiotp, in the authorize section of /etc/freeradius/3.0/sites-available/inner-tunnel. Add the following lines: + +After logintime add the following line : +... + expiration + logintime +``` + # Handle multiotp authentication + multiotp +``` + +... authenticate { +``` Auth-Type multiotp { multiotp - } + } #multiotp Auth-Type multiotpmschap { multiotpmschap - } -} + } #multiotpmschap + Auth-Type Perl { #multiotp + perl #multiotp + } #multiotp + ``` -7) Start the server up in debug mode radiusd -X and test authentication + +12) Start the server up in debug mode radiusd -X and test authentication HOW TO CONFIGURE MULTIOTP TO SYNCHRONIZED THE USERS FROM AN ACTIVE DIRECTORY ? @@ -1395,9 +1472,8 @@ HOW TO INSTALL A LOCAL ONLY STRONG AUTHENTICATION ON A WINDOWS MACHINE ? 7) To disable the Credential Provider, uninstall it from Windows, or execute multiOTPCredentialProvider-unregister.reg -HOW TO INSTALL A CENTRALIZED STRONG AUTHENTICATION SERVER -FOR STRONG AUTHENTICATION ON WINDOWS DESKTOPS OR RDP ? -========================================================= +HOW TO INSTALL A CENTRALIZED 2FA SERVER FOR WINDOWS DESKTOPS OR RDP LOGIN ? +=========================================================================== 1) Install a client/server multiOTP environment like explained above. 2) On each client, install multiOTPCredentialProvider . It works with Windows 7/8/8.1/10/11/2012(R2)/2016/2019/2022 in 64 bits. @@ -1412,6 +1488,63 @@ FOR STRONG AUTHENTICATION ON WINDOWS DESKTOPS OR RDP ? or execute multiOTPCredentialProvider-unregister.reg +SAME WINDOWS GENERIC ACCOUNT WITH MULTIPLE TWO-FACTOR AUTHENTICATION ACCOUNTS +============================================================================= +If you have to share the same generic Windows account, but you still need +2FA authentication for each user (like for a specific industrial computer in a +24/7/365 process), you can do the following configuration: +1) Create (or sync with AD/LDAP) a multiOTP account for the generic account +2) In multiOTP, set the description of the generic account to "multi_account" + (if the account is synced by AD/LDAP, put the description in the AD/LDAP) +3) Create (or sync with AD/LDAP) the accounts of each users +4) On the login screen of the computer, use the following credentials: + - Account : generic Windows account + - Password : password of the generic Windows account + - OTP : [username of the specific user][space][OTP code of the specific user] + + +USING MULTIOTP ON LINUX FOR SSH LOGIN +===================================== +0) Configure OpenSSH and PAM + Configure your OpenSSH server to request the PassCode (PinCode+OTP) + to the radius server. For this purpose we will use a radius PAM agent. + +1) PAM configuration for OpenSSH server: + Edit the file /etc/pam.d/sshd with this configuration. + Comment the username/password line and add the PAM library. + Be sure you have the PAM radius library. +``` + #auth required pam_stack.so service=system-auth + auth required /lib/security/pam_radius_auth.so +``` + +2) Specify the Radius Server. + Create and edit a file called server in /etc/raddb + with the Radius IP,port and the shared secret key. +``` + #Server[:port] shared_secret timeout (s) + 127.0.0.1 secret 1 + 10.1.23.1:1812 myfirstpass 6 +``` + +3) OpenSSH server (radiusd daemon) configuration: + Edit /etc/sshd/sshd_config and be sure PAM is + enabled and keyboard-interactive AuthN support. +``` + UsePAM yes + PasswordAuthentication no + ChallengeResponseAuthentication yes +``` + +4) Stop and start the OpenSSH server +``` + /etc/init.d/sshd stop + /etc/init.d/sshd start +``` + +5) You are now ready to test your login SSH with an software OTP :-) + + HOW TO BUILD A RASPBERRY PI STRONG AUTHENTICATION SERVER ? ========================================================== 0) If you want to download a multiOTP Raspberry Pi image ready to use, follow this URL: @@ -1484,7 +1617,9 @@ HOW TO BUILD A RASPBERRY PI STRONG AUTHENTICATION SERVER ? LDAP FILTER CUSTOMIZATION ========================= -You can customize your own LDAP filter. By default, the LDAP filter is the following: +You can customize your own LDAP filter. By default, the LDAP filter is empty. +In the LDAP filter, you can use the following placeholders: + {cn_identifier}, {username}, {groups_filtering} OPENSSL OPTIONS FOR LDAPS @@ -1595,7 +1730,7 @@ MULTIOTP COMMAND LINE TOOL ========================== ``` -multiOTP 5.9.6.5 (2023-07-07) +multiOTP 5.9.6.7 (2023-09-22) (c) 2010-2023 SysCo systemes de communication sa http://www.multiOTP.net (you can try the [Donate] button ;-) @@ -1693,6 +1828,7 @@ Return codes: 82 ERROR: User not allowed for this device 88 ERROR: Device is not defined as a HA slave 89 ERROR: Device is not defined as a HA master +91 ERROR: Authentication failed (without2fa token not authorized here) 92 ERROR: Authentication failed (bad password) 93 ERROR: Authentication failed (time based token probably out of sync) 94 ERROR: API request error @@ -2111,8 +2247,8 @@ Visit https://forum.multiotp.net/ for additional support ``` ``` -Hash verification for multiotp_5.9.6.5.zip -SHA256:c17f48e035340f33055d2d786f9a9ed44cea1ba8dbc81dbc3788d46501c51465 -SHA1:1d1d7550198b9d480d646e2c1c29f2e67ac64d69 -MD5:a51547307b18456dd971a8deab303dfe +Hash verification for multiotp_5.9.6.7.zip +SHA256:4902e1bff912878cfe1cb14876b3c2775ca450cef412139137d414a932130c6a +SHA1:3cbc8b7d4d85eb53e53bccf54c535d375ad1d532 +MD5:a89b73d238194f08c179141d55f761c3 ``` diff --git a/check.multiotp.class.php b/check.multiotp.class.php index 0cef6b9..92e7274 100644 --- a/check.multiotp.class.php +++ b/check.multiotp.class.php @@ -22,8 +22,8 @@ * PHP 5.4.0 or higher is supported. * * @author Andre Liechti, SysCo systemes de communication sa, - * @version 5.9.6.5 - * @date 2023-07-07 + * @version 5.9.6.7 + * @date 2023-09-22 * @since 2013-07-10 * @copyright (c) 2013-2023 SysCo systemes de communication sa * @copyright GNU Lesser General Public License diff --git a/checkmultiotp.cmd b/checkmultiotp.cmd index a1065e6..7646b89 100644 --- a/checkmultiotp.cmd +++ b/checkmultiotp.cmd @@ -11,8 +11,8 @@ REM REM Windows batch file for Windows 2K/XP/2003/7/2008/8/2012/10/2019 REM REM @author Andre Liechti, SysCo systemes de communication sa, -REM @version 5.9.6.5 -REM @date 2023-07-07 +REM @version 5.9.6.7 +REM @date 2023-09-22 REM @since 2010-07-10 REM @copyright (c) 2010-2023 SysCo systemes de communication sa REM @copyright GNU Lesser General Public License diff --git a/launcher/ReadMe.txt b/launcher/ReadMe.txt index d7f42bb..9a88189 100644 --- a/launcher/ReadMe.txt +++ b/launcher/ReadMe.txt @@ -15,8 +15,8 @@ The multiOTP C++ launcher is simply used to launch PHP and run multiotp.windows.php with the provided arguments. @author Andre Liechti, SysCo systemes de communication sa, -@version 5.9.6.5 -@date 2023-07-07 +@version 5.9.6.7 +@date 2023-09-22 @since 2016-12-08 @copyright (c) 2010-2023 SysCo systemes de communication sa @copyright GNU Lesser General Public License diff --git a/launcher/launcher.cpp b/launcher/launcher.cpp index 8b2390f..769262d 100644 --- a/launcher/launcher.cpp +++ b/launcher/launcher.cpp @@ -14,8 +14,8 @@ * and run multiotp.windows.php with the provided arguments. * * @author Andre Liechti, SysCo systemes de communication sa, - * @version 5.9.6.5 - * @date 2023-07-07 + * @version 5.9.6.7 + * @date 2023-09-22 * @since 2016-12-08 * @copyright (c) 2010-2023 SysCo systemes de communication sa * @copyright GNU Lesser General Public License @@ -68,8 +68,8 @@ #include #define SOFTWARE "LAUNCHPHPMULTIOTP" -#define VER_NUMBER "5.9.6.5" -#define VER_DATE "2023-07-07" +#define VER_NUMBER "5.9.6.7" +#define VER_DATE "2023-09-22" void replaceAll(std::string& str, const std::string& from, const std::string& to) { if (from.empty()) diff --git a/multiotp.class.php b/multiotp.class.php index be663fd..61d50a4 100644 --- a/multiotp.class.php +++ b/multiotp.class.php @@ -72,8 +72,8 @@ * PHP 5.4.0 or higher is supported. * * @author Andre Liechti, SysCo systemes de communication sa, - * @version 5.9.6.5 - * @date 2023-07-07 + * @version 5.9.6.7 + * @date 2023-09-22 * @since 2010-06-08 * @copyright (c) 2010-2023 SysCo systemes de communication sa * @copyright GNU Lesser General Public License @@ -277,8 +277,8 @@ class Multiotp * @brief Main class definition of the multiOTP project. * * @author Andre Liechti, SysCo systemes de communication sa, - * @version 5.9.6.5 - * @date 2023-07-07 + * @version 5.9.6.7 + * @date 2023-09-22 * @since 2010-07-18 */ { @@ -393,8 +393,8 @@ class Multiotp * @retval void * * @author Andre Liechti, SysCo systemes de communication sa, - * @version 5.9.6.5 - * @date 2023-07-07 + * @version 5.9.6.7 + * @date 2023-09-22 * @since 2010-07-18 */ function __construct( @@ -418,11 +418,11 @@ function __construct( if (!isset($this->_class)) { $this->_class = base64_decode('bXVsdGlPVFA='); } if (!isset($this->_version)) { - $temp_version = '@version 5.9.6.5'; // You should add a suffix for your changes (for example 5.0.3.2-andy-2016-10-XX) + $temp_version = '@version 5.9.6.7'; // You should add a suffix for your changes (for example 5.0.3.2-andy-2016-10-XX) $this->_version = nullable_trim(mb_substr($temp_version, 8)); } if (!isset($this->_date)) { - $temp_date = '@date 2023-07-07'; // You should update the date with the date of your changes + $temp_date = '@date 2023-09-22'; // You should update the date with the date of your changes $this->_date = nullable_trim(mb_substr($temp_date, 8)); } if (!isset($this->_copyright)) { $this->_copyright = base64_decode('KGMpIDIwMTAtMjAyMyBTeXNDbyBzeXN0ZW1lcyBkZSBjb21tdW5pY2F0aW9uIHNh'); } @@ -1740,6 +1740,7 @@ function ResetErrorsArray() $this->_errors_text[88] = "ERROR: Device is not defined as a HA slave"; $this->_errors_text[89] = "ERROR: Device is not defined as a HA master"; + $this->_errors_text[91] = "ERROR: Authentication failed (without2fa token not authorized here)"; $this->_errors_text[92] = "ERROR: Authentication failed (bad password)"; $this->_errors_text[93] = "ERROR: Authentication failed (time based token probably out of sync)"; $this->_errors_text[94] = "ERROR: API request error"; @@ -8932,13 +8933,13 @@ function GenerateHtmlQrCode( } // Simplify current algorithm info - $html = preg_replace('/IfMultiotpUserAlgorithm="[BCHIMOPTUY,]*'.mb_strtoupper($this->GetUserAlgorithm(),'UTF-8').'[BCHIMOPTUY,]*"}/i', 'IfMultiotpUserAlgorithm="'.mb_strtoupper($this->GetUserAlgorithm(),'UTF-8').'"}', $html); + $html = preg_replace('/IfMultiotpUserAlgorithm="[2ABCFHIMOPTUWY,]*'.mb_strtoupper($this->GetUserAlgorithm(),'UTF-8').'[2ABCFHIMOPTUWY,]*"}/i', 'IfMultiotpUserAlgorithm="'.mb_strtoupper($this->GetUserAlgorithm(),'UTF-8').'"}', $html); // Clean other algorithms info foreach (explode("\t",$this->GetAlgorithmsList()) as $algorithm_one) { if (mb_strtoupper($algorithm_one,'UTF-8') != mb_strtoupper($this->GetUserAlgorithm(),'UTF-8')) { - $html = preg_replace('//i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); - $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); + $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); - $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); + $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); - $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); + $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); - $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); + $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); - $html = preg_replace('//i', '/i', ' -- {/IfMultiotpUserAlgorithm="DELETE"} -->', $html); + $html = preg_replace('//i', '