Skip to content

Commit 45fdfb5

Browse files
author
André Liechti
committed
Release 5.10.2.1
FIX: Changing notification options (SMTP server and SysLog options) was not always possible FIX: SMSEagle v2 implementation was not always able to send to international countries FIX: websocketCore.php was missing in the sources ENH: Template updated to propose the free "multiOTP token app" by default for Android and iOS ENH: Embedded Windows PHP edition updated to version 8.4.16 x64 (from 8.4.14 x86) ENH: Embedded Windows nginx edition updated to version 1.29.6 ENH: Updated environment detection, like docker detection ENH: Updated Linux helper, for the future new web interface ENH: For Windows, WMIC dependencies has been removed and replaced by Powershell commands
1 parent ac9fe6f commit 45fdfb5

37 files changed

Lines changed: 6033 additions & 5353 deletions

Dockerfile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
# Please check https://www\.multiOTP.net/ and you will find the magic button ;-)
1616
#
1717
# @author Andre Liechti, SysCo systemes de communication sa, <[email protected]>
18-
# @version 5.10.1.2
19-
# @date 2026-01-05
18+
# @version 5.10.2.1
19+
# @date 2026-03-23
2020
# @since 2013-11-29
2121
# @copyright (c) 2013-2026 SysCo systemes de communication sa
2222
# @copyright GNU Lesser General Public License
@@ -43,8 +43,8 @@ LABEL org.opencontainers.image.title="multiOTP open source"
4343
LABEL org.opencontainers.image.description="multiOTP open source, running on Debian ${DEBIAN} with PHP${PHPVERSION}." \
4444
License="LGPL-3.0" \
4545
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" \
46-
Version="5.10.1.2"
47-
LABEL org.opencontainers.image.Version="5.10.1.2"
46+
Version="5.10.2.1"
47+
LABEL org.opencontainers.image.Version="5.10.2.1"
4848
LABEL org.opencontainers.image.authors="Andre Liechti <[email protected]>"
4949
LABEL org.opencontainers.image.url="https://www.multiotp.net"
5050
LABEL org.opencontainers.image.source="https://github.com/multiOTP/multiotp"
@@ -120,7 +120,7 @@ COPY raspberry/boot-part/multiotp-tree /boot/multiotp-tree/
120120
WORKDIR /
121121

122122
RUN chmod 777 /boot/*.sh && \
123-
/boot/install.sh
123+
/boot/install.sh RUNDOCKER
124124

125125
EXPOSE 80/tcp 443/tcp 1812/udp 1813/udp
126126

README.md

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ multiOTP open source is OATH certified for HOTP/TOTP
66
(c) 2010-2026 SysCo systemes de communication sa
77
https://www.multiotp.net/
88

9-
Current build: 5.10.1.2 (2026-01-05)
9+
Current build: 5.10.2.1 (2026-03-23)
1010

1111
Binary download: https://download.multiotp.net/ (including virtual appliance image, docker and full release notes)
1212

@@ -22,7 +22,10 @@ PATH/TO/FREERADIUS/LOG/VOLUME:/var/log/freeradius
2222

2323
The **multiotp/multiotp-open-source** docker is working on Synology devices !
2424

25-
Binary download of the multiOTP open source Credential Provider for Windows 7/8/8.1/10/11/2012(R2)/2016/2019/2022 : https://download.multiotp.net/credential-provider/
25+
It's strongly recommended to read the whole README file.
26+
That said, if you're in a hurry: the default RADIUS secret for subnet 0.0.0.0/0 is `myfirstpass`.
27+
28+
Binary download of the multiOTP open source Credential Provider for Windows 7/8/8.1/10/11/2012(R2)/2016/2019/2022/2025 : https://download.multiotp.net/credential-provider/
2629

2730
[![Donate via PayPal](https://img.shields.io/badge/donate-paypal-87ceeb.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=USD&[email protected]&item_name=Donation%20for%20multiOTP%20project)
2831
*Please consider supporting this project by making a donation via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=USD&[email protected]&item_name=Donation%20for%20multiOTP%20project)*
@@ -47,13 +50,21 @@ appliances including more features like:
4750
- Full Web GUI interface
4851
- Automated provisioning of new account (based on Active Directory)
4952
- High Availability master-slave support (Enterprise Edition)
53+
- Push token using free multiOTP token App (Enterprise Edition)
5054
- Web API support (Enterprise Edition)
5155
- free virtual appliances available, including a free lifetime one user licence
5256
- online demo of the full Web GUI interface
5357
- ...
5458

5559

5660
The multiOTP class supports currently the following algorithms and RFC's:
61+
- OATH/HOTP or OATH/TOTP, base32/hex/raw seed, QRcode provisioning
62+
(multiOTP token App, FreeOTP, Google Authenticator, ...)
63+
- Yubico OTP (http://yubico.com/yubikey)
64+
- mOTP (http://motp.sourceforge.net)
65+
- SMS tokens (using Afilnet, aspsms, Clickatell, eCall, IntelliSMS, Nexmo, NowSMS,
66+
SMSEagle, SMSGateway, Spryng, Swisscom, Telnyx, any custom provider, your own script)
67+
- TAN (emergency scratch passwords)
5768
- RFC1994 CHAP (Challenge Handshake Authentication Protocol)
5869
- RFC2433 MS-CHAP (Microsoft PPP CHAP Extensions)
5970
- RFC2487 SMTP Service Extension for Secure SMTP over TLS
@@ -63,13 +74,6 @@ The multiOTP class supports currently the following algorithms and RFC's:
6374
- RFC5424 Syslog Protocol (client)
6475
- RFC6030 PSKC (Additional Portable Symmetric Key Container Algorithm Profiles)
6576
- RFC6238 OATH/TOTP (TOTP: Time-Based One-Time Password Algorithm)
66-
- Yubico OTP (http://yubico.com/yubikey)
67-
- mOTP (http://motp.sourceforge.net)
68-
- OATH/HOTP or OATH/TOTP, base32/hex/raw seed, QRcode provisioning
69-
(FreeOTP, Google Authenticator, ...)
70-
- SMS tokens (using Afilnet, aspsms, Clickatell, eCall, IntelliSMS, Nexmo, NowSMS,
71-
SMSEagle, SMSGateway, Spryng, Swisscom, Telnyx, any custom provider, your own script)
72-
- TAN (emergency scratch passwords)
7377

7478
This package was initially published here : http://syscoal.users.phpclasses.org/package/6373.html
7579
For more PHP classes, have a look on [PHPclasses.org](http://syscoal.users.phpclasses.org/browse/), where a lot of authors are sharing their classes for free.
@@ -155,6 +159,16 @@ WHAT'S NEW IN THIS 5.10.x RELEASE
155159
CHANGE LOG OF RELEASED VERSIONS
156160
===============================
157161
```
162+
2026-03-23 5.10.2.1 FIX: Changing notification options (SMTP server and SysLog options) was not always possible
163+
FIX: SMSEagle v2 implementation was not always able to send to international countries
164+
FIX: websocketCore.php was missing in the sources
165+
ENH: Template updated to propose the free "multiOTP token app" by default for Android and iOS
166+
ENH: Embedded Windows PHP edition updated to version 8.4.16 x64 (from 8.4.14 x86)
167+
ENH: Embedded Windows nginx edition updated to version 1.29.6
168+
ENH: Updated environment detection, like docker detection
169+
ENH: Updated Linux helper, for the future new web interface
170+
ENH: For Windows, WMIC dependencies has been removed and replaced by Powershell commands
171+
2026-01-23 5.10.1.5 ENH: For Docker installation, configuration files are copied automatically in the external volumes if missing
158172
2026-01-05 5.10.1.2 FIX: Locked and delayed status handled before push status
159173
2025-12-23 5.10.1.1 ENH: New SendEmail implementation with internal smtp stack (using smtp parameters)
160174
ENH: Better Docker integration
@@ -932,6 +946,13 @@ Provisioning will be done simply by flashing a QRcode.
932946
- YubiKey Nano
933947
- YubiKey Neo
934948
- YubiKey Neo-N
949+
950+
The YubiKey CSV import is based on the .CSV created by the legacy Yubikey Personalization Tools, which is, the following lines in a file called for example **yubico_log.csv**:
951+
952+
```
953+
LOGGING START,2025-05-04T03:02:01
954+
Yubico OTP,2025-05-04T03:02:01,1,vvcccdjkllvd,sde2c13f6a65,c6d293cbf190e4eb13f45b3913edea7b,,,0,0,0,0,0,0,0,0,0,0
955+
```
935956

936957
If you want to use software tokens with Apps like Google Authenticator, you can
937958
create a QRcode provisioning in two EASY steps with the command line tool:
@@ -1969,7 +1990,7 @@ MULTIOTP COMMAND LINE TOOL
19691990
==========================
19701991

19711992
```
1972-
multiOTP 5.10.1.2 (2026-01-05)
1993+
multiOTP 5.10.2.1 (2026-03-23)
19731994
(c) 2010-2026 SysCo systemes de communication sa
19741995
http://www.multiOTP.net (you can try the [Donate] button ;-)
19751996
@@ -2504,8 +2525,8 @@ Visit https://forum.multiotp.net/ for additional support
25042525
```
25052526

25062527
```
2507-
Hash verification for multiotp_5.10.1.2.zip
2508-
SHA256:3e2cf1e4704695b30b823df1b3952614342c203a1260350a21bce699c79431fc
2509-
SHA1:b67317fd8bc32ba8e8f0d6cbae9005b673cc2ad2
2510-
MD5:c0e70540ccf2b8c6d48d822ba201840c
2528+
Hash verification for multiotp_5.10.2.1.zip
2529+
SHA256:61f69686dd814dcca83fbe03629f7db2979be89136ef4d26a714051fa24a99df
2530+
SHA1:755072a5aa8a909564a32ec184fbfd51427f5696
2531+
MD5:c1a63cd5d8ec69771c0854acf4301dd3
25112532
```

check.multiotp.class.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
* PHP 5.4.0 or higher is supported.
2323
*
2424
* @author Andre Liechti, SysCo systemes de communication sa, <[email protected]>
25-
* @version 5.10.1.2
26-
* @date 2026-01-05
25+
* @version 5.10.2.1
26+
* @date 2026-03-23
2727
* @since 2013-07-10
2828
* @copyright (c) 2013-2026 SysCo systemes de communication sa
2929
* @copyright GNU Lesser General Public License

checkmultiotp.cmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ REM
1111
REM Windows batch file for Windows 2K/XP/2003/7/2008/8/2012/10/2019
1212
REM
1313
REM @author Andre Liechti, SysCo systemes de communication sa, <[email protected]>
14-
REM @version 5.10.1.2
15-
REM @date 2026-01-05
14+
REM @version 5.10.2.1
15+
REM @date 2026-03-23
1616
REM @since 2010-07-10
1717
REM @copyright (c) 2010-2026 SysCo systemes de communication sa
1818
REM @copyright GNU Lesser General Public License

contrib/MultiotpSms.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,8 @@ function setProvider(
513513
$this->encoding = "UTF";
514514
$this->status_success = "20";
515515
$this->content_success = "OK";
516-
$this->no_double_zero = FALSE;
517-
$this->international_format = FALSE;
516+
$this->no_double_zero = TRUE;
517+
$this->international_format = TRUE;
518518
$this->basic_auth = FALSE;
519519
$this->content_encoding = "";
520520
$this->header = "Content-Type: text/plain\r\n";
@@ -1029,6 +1029,11 @@ function sendSMS(
10291029
$fp = @fsockopen($protocol.$host, $server_port, $errno, $errdesc, $this->timeout);
10301030
}
10311031

1032+
// DEBUG
1033+
file_put_contents('sms_debug.log', "$url\n", FILE_APPEND);
1034+
file_put_contents('sms_debug.log', "$payload\n", FILE_APPEND);
1035+
1036+
10321037
if (FALSE !== $fp) {
10331038
$info['timed_out'] = FALSE;
10341039
$output = "";

contrib/MultiotpTools.php

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
* Check PHP version and define version constant if needed
55
* (PHP_VERSION_ID is natively available only for PHP >= 5.2.7)
66
****************************************************************/
7-
if (!function_exists('constant_defined')) {
8-
function constant_defined(
7+
if (!function_exists('defined')) {
8+
function defined(
99
$constant_name
1010
) {
1111
$result = false;
@@ -20,17 +20,15 @@ function constant_defined(
2020
}
2121

2222

23-
if (!constant_defined('PHP_VERSION_ID'))
24-
{
25-
$version = explode('.', PHP_VERSION);
26-
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
23+
if (!defined('PHP_VERSION_ID')) {
24+
$version = explode('.', PHP_VERSION);
25+
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
2726
}
2827

29-
if (PHP_VERSION_ID < 50207)
30-
{
31-
define('PHP_MAJOR_VERSION', $version[0]);
32-
define('PHP_MINOR_VERSION', $version[1]);
33-
define('PHP_RELEASE_VERSION', $version[2]);
28+
if (PHP_VERSION_ID < 50207) {
29+
define('PHP_MAJOR_VERSION', $version[0]);
30+
define('PHP_MINOR_VERSION', $version[1]);
31+
define('PHP_RELEASE_VERSION', $version[2]);
3432
}
3533

3634

@@ -130,26 +128,23 @@ function is64bitPHP() {
130128
***********************************************************************/
131129
if (!function_exists('ram_total_space')) {
132130
function ram_total_space() {
133-
$size = 0;
134-
if (mb_strtolower(mb_substr(PHP_OS, 0, 3),'UTF-8') === 'win') {
135-
$lines = null;
136-
$matches = null;
137-
exec('wmic ComputerSystem get TotalPhysicalMemory /Value', $lines);
138-
if (preg_match('/^TotalPhysicalMemory\=(\d+)$/', $lines[2], $matches)) {
139-
$size = $matches[1];
140-
}
141-
} else {
142-
$meminfo_file = fopen('/proc/meminfo', 'r');
143-
while ($line = fgets($meminfo_file)) {
144-
$elements = array();
145-
if (preg_match('/^MemTotal:\s+(\d+)\skB$/', $line, $elements)) {
146-
$size = $elements[1] * 1024;
147-
break;
148-
}
149-
}
150-
fclose($meminfo_file);
131+
$size = 0;
132+
if (mb_strtolower(mb_substr(PHP_OS, 0, 3),'UTF-8') === 'win') {
133+
$lines = null;
134+
exec('powershell -Command "(Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory"', $lines);
135+
$size = intval(trim($lines[0] ?? 0));
136+
} else {
137+
$meminfo_file = fopen('/proc/meminfo', 'r');
138+
while ($line = fgets($meminfo_file)) {
139+
$elements = array();
140+
if (preg_match('/^MemTotal:\s+(\d+)\skB$/', $line, $elements)) {
141+
$size = $elements[1] * 1024;
142+
break;
143+
}
151144
}
152-
return (double) $size;
145+
fclose($meminfo_file);
146+
}
147+
return (double) $size;
153148
}
154149
}
155150

@@ -162,27 +157,24 @@ function ram_total_space() {
162157
***********************************************************************/
163158
if (!function_exists('ram_free_space')) {
164159
function ram_free_space() {
165-
$size = 0;
166-
if (mb_strtolower(mb_substr(PHP_OS, 0, 3),'UTF-8') === 'win') {
167-
$lines = null;
168-
$matches = null;
169-
exec('wmic OS get FreePhysicalMemory /Value', $lines);
170-
if (preg_match('/^FreePhysicalMemory\=(\d+)$/', $lines[2], $matches)) {
171-
$size = $matches[1] * 1024;
172-
}
173-
} else {
174-
$meminfo_file = fopen('/proc/meminfo', 'r');
175-
while ($line = fgets($meminfo_file)) {
176-
$elements = array();
177-
if (preg_match('/^MemFree:\s+(\d+)\skB$/', $line, $elements)) {
178-
// KB to Bytes
179-
$size = $elements[1] * 1024;
180-
break;
181-
}
182-
}
183-
fclose($meminfo_file);
160+
$size = 0;
161+
if (mb_strtolower(mb_substr(PHP_OS, 0, 3),'UTF-8') === 'win') {
162+
$lines = null;
163+
exec('powershell -Command "(Get-CimInstance -ClassName Win32_OperatingSystem).FreePhysicalMemory"', $lines);
164+
$size = intval(trim($lines[0] ?? 0)) * 1024;
165+
} else {
166+
$meminfo_file = fopen('/proc/meminfo', 'r');
167+
while ($line = fgets($meminfo_file)) {
168+
$elements = array();
169+
if (preg_match('/^MemFree:\s+(\d+)\skB$/', $line, $elements)) {
170+
// KB to Bytes
171+
$size = $elements[1] * 1024;
172+
break;
173+
}
184174
}
185-
return (double) $size;
175+
fclose($meminfo_file);
176+
}
177+
return (double) $size;
186178
}
187179
}
188180

@@ -1199,6 +1191,33 @@ function mask2cidr($mask) {
11991191
}
12001192

12011193

1194+
if (!function_exists('cidr2mask'))
1195+
{
1196+
// https://gist.github.com/linickx/1309388
1197+
function cidr2mask($netmask) {
1198+
$netmask_result="";
1199+
for($i=1; $i <= $netmask; $i++) {
1200+
$netmask_result .= "1";
1201+
}
1202+
1203+
for($i=$netmask+1; $i <= 32; $i++) {
1204+
$netmask_result .= "0";
1205+
}
1206+
1207+
$netmask_ip_binary_array = str_split( $netmask_result, 8 );
1208+
1209+
$netmask_ip_decimal_array = array();
1210+
foreach( $netmask_ip_binary_array as $k => $v ){
1211+
$netmask_ip_decimal_array[$k] = bindec( $v ); // "100" => 4
1212+
}
1213+
1214+
$subnet = join( ".", $netmask_ip_decimal_array );
1215+
1216+
return $subnet;
1217+
}
1218+
}
1219+
1220+
12021221
if (!function_exists('protect_file'))
12031222
{
12041223
function protect_file(

0 commit comments

Comments
 (0)