{"id":35640612,"url":"https://github.com/multiotp/multiotp","last_synced_at":"2026-04-05T19:01:11.675Z","repository":{"id":25113775,"uuid":"28535249","full_name":"multiOTP/multiotp","owner":"multiOTP","description":"multiOTP open source strong two factor authentication PHP library, OATH certified, with TOTP, HOTP, Mobile-OTP, YubiKey, SMS, QRcode provisioning, etc.","archived":false,"fork":false,"pushed_at":"2026-03-23T12:03:50.000Z","size":11573,"stargazers_count":433,"open_issues_count":7,"forks_count":90,"subscribers_count":25,"default_branch":"master","last_synced_at":"2026-03-24T09:36:12.337Z","etag":null,"topics":["2fa","active-directory","authentication","credential-provider","hotp","ldap","motp","offline","otp","php","sms","synchronization","totp","yubico","yubico-otp","yubikey","yubikey-authenticators"],"latest_commit_sha":null,"homepage":"http://www.multiOTP.net/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/multiOTP.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2014-12-27T11:30:44.000Z","updated_at":"2026-03-23T12:01:50.000Z","dependencies_parsed_at":"2023-11-24T10:45:58.640Z","dependency_job_id":"627164e2-0b3f-4170-83bb-b901bbe3e693","html_url":"https://github.com/multiOTP/multiotp","commit_stats":null,"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/multiOTP/multiotp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiOTP%2Fmultiotp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiOTP%2Fmultiotp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiOTP%2Fmultiotp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiOTP%2Fmultiotp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/multiOTP","download_url":"https://codeload.github.com/multiOTP/multiotp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiOTP%2Fmultiotp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31446531,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T15:22:31.103Z","status":"ssl_error","status_checked_at":"2026-04-05T15:22:00.205Z","response_time":75,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2fa","active-directory","authentication","credential-provider","hotp","ldap","motp","offline","otp","php","sms","synchronization","totp","yubico","yubico-otp","yubikey","yubikey-authenticators"],"created_at":"2026-01-05T11:13:35.865Z","updated_at":"2026-04-05T19:01:11.664Z","avatar_url":"https://github.com/multiOTP.png","language":"PHP","readme":"multiOTP open source\r\n====================\r\nmultiOTP open source is a GNU LGPL implementation of a strong two-factor authentication PHP class  \r\nmultiOTP open source is OATH certified for HOTP/TOTP\r\n\r\n(c) 2010-2026 SysCo systemes de communication sa  \r\nhttps://www.multiotp.net/\r\n\r\nCurrent build: 5.10.2.2 (2026-04-03)\r\n\r\nBinary download: https://download.multiotp.net/ (including virtual appliance image, docker and full release notes)\r\n\r\nDocker container available: **docker run -v path/to/multiotp/data:/etc/multiotp -v path/to/freeradius/config:/etc/freeradius -v path/to/multiotp/log:/var/log/multiotp -v path/to/freeradius/log:/var/log/freeradius -p 80:80 -p 443:443 -p 1812:1812/udp -p 1813:1813/udp -d multiotp/multiotp-open-source**\r\n\r\n**Docker volumes**  \r\nPATH/TO/MULTIOTP/DATA/VOLUME:/etc/multiotp  \r\nPATH/TO/FREERADIUS/CONFIG/VOLUME:/etc/freeradius  \r\nPATH/TO/MULTIOTP/LOG/VOLUME:/var/log/multiotp  \r\nPATH/TO/FREERADIUS/LOG/VOLUME:/var/log/freeradius  \r\n\r\n**A Dockerfile is included in the distribution ZIP file**\r\n\r\nThe **multiotp/multiotp-open-source** docker is working on Synology devices !  \r\n\r\nIt's strongly recommended to read the whole README file.  \r\nThat said, if you're in a hurry: the default RADIUS secret for subnet 0.0.0.0/0 is `myfirstpass`.\r\n\r\nBinary 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/\r\n\r\n[![Donate via PayPal](https://img.shields.io/badge/donate-paypal-87ceeb.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026currency_code=USD\u0026business=paypal@sysco.ch\u0026item_name=Donation%20for%20multiOTP%20project)\r\n*Please consider supporting this project by making a donation via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026currency_code=USD\u0026business=paypal@sysco.ch\u0026item_name=Donation%20for%20multiOTP%20project)*\r\n\r\nVisit http://forum.multiotp.net/ for additional support.\r\n\r\nThe multiOTP package is the lightest package available that provides so many\r\nstrong authentication functionalities and goodies, and best of all, for anyone\r\nthat is interested about security issues, it's a fully open source solution!\r\n\r\nThis package is the result of a *bunch* of work. If you are happy using this\r\npackage, [Donation] are always welcome to support this project.\r\nPlease check https://www.multiotp.net/ and you will find the magic button ;-)\r\n\r\nIf you need some specific features in the open source edition of multiOTP,\r\nplease contact us in order to discuss about a sponsorship in order to\r\nprioritize your needs.\r\n\r\nYou can also have a look on on https://www.multiOTP.com for multiOTP Pro and\r\nmultiOTP Enterprise, which are commercial editions of ready to use virtual\r\nappliances including more features like:\r\n - Full Web GUI interface\r\n - Automated provisioning of new account (based on Active Directory)\r\n - High Availability master-slave support (Enterprise Edition)\r\n - Push token using free multiOTP token App (Enterprise Edition)\r\n - Web API support (Enterprise Edition)\r\n - free virtual appliances available, including a free lifetime one user licence\r\n - online demo of the full Web GUI interface\r\n - ...\r\n\r\n\r\nThe multiOTP class supports currently the following algorithms and RFC's:\r\n- OATH/HOTP or OATH/TOTP, base32/hex/raw seed, QRcode provisioning\r\n  (multiOTP token App, FreeOTP, Google Authenticator, ...)\r\n- Yubico OTP (http://yubico.com/yubikey)\r\n- mOTP (http://motp.sourceforge.net)\r\n- SMS tokens (using Afilnet, aspsms, Clickatell, eCall, IntelliSMS, Nexmo, NowSMS,\r\n  SMSEagle, SMSGateway, Spryng, Swisscom, Telnyx, any custom provider, your own script)\r\n- TAN (emergency scratch passwords)\r\n- RFC1994 CHAP (Challenge Handshake Authentication Protocol)\r\n- RFC2433 MS-CHAP (Microsoft PPP CHAP Extensions)\r\n- RFC2487 SMTP Service Extension for Secure SMTP over TLS\r\n- RFC2759 MS-CHAPv2 (Microsoft PPP CHAP Extensions, Version 2)\r\n- RFC2821 SMTP (Simple Mail Transfer Protocol)\r\n- RFC4226 OATH/HOTP (HOTP: An HMAC-Based One-Time Password Algorithm)\r\n- RFC5424 Syslog Protocol (client)\r\n- RFC6030 PSKC (Additional Portable Symmetric Key Container Algorithm Profiles)\r\n- RFC6238 OATH/TOTP (TOTP: Time-Based One-Time Password Algorithm)\r\n\r\nThis package was initially published here : http://syscoal.users.phpclasses.org/package/6373.html\r\nFor 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.\r\n\r\nTABLE OF CONTENTS\r\n=================\r\n * Donations and sponsoring\r\n * Wishlist for future releases\r\n * How can I upgrade from a previous version ?\r\n * What's new in the releases\r\n * Change Log of released version\r\n * Content of the package\r\n * Typical tree of a working Linux installation\r\n * How can I create myself the different versions ?\r\n * When and how can I use this package ?\r\n * What is the prefix PIN option ?\r\n * How the lockout of an account is working ?\r\n * How to self-unlock an account ?\r\n * How to debug ?\r\n * How to install the multiOTP web service under Windows ?\r\n * How to install the multiOTP radius server under Windows ?\r\n * Configuring multiOTP with TekRADIUS or TekRADIUS LT under Windows\r\n * Email configuration\r\n * How to install the multiOTP web service under Linux ?\r\n * Configuring multiOTP with FreeRADIUS 2.x under Linux\r\n * Configuring multiOTP with FreeRADIUS 3.x under Linux\r\n * How to configure multiOTP to synchronized the users from an Active Directory ?\r\n * How to configure multiOTP to synchronized the users from a standard LDAP ?\r\n * How to configure multiOTP to use the client/server feature ?\r\n * How to build a Raspberry Pi strong authentication server ?\r\n * How to install a local only strong authentication on a Windows machine ?\r\n * How to install a centralized 2FA server for Windows desktops or RDP login ?\r\n * Adding 2FA with multiOTP to the Remote Desktop Web Access (RDWeb) on Windows\r\n * Same Windows generic account with multiple two-factor authentication accounts\r\n * Using multiOTP on Linux for SSH login\r\n * LDAP filter customization\r\n * OpenSSL options for LDAPS\r\n * Compatible clients applications and devices\r\n * External packages used\r\n * multiOTP PHP class documentation\r\n * multiOTP command line tool\r\n\r\n\r\nDONATIONS AND SPONSORING\r\n========================\r\nYou can support our multiOTP open source project with donations and sponsoring.\r\nSponsorships are crucial for ongoing and future development of the project! \r\nIf you'd like to support our work, then consider making a donation, any support\r\nis always welcome even if it's as low as $1!\r\nYou can also sponsor the development of a specific feature. Please contact\r\nus in order to discuss the detail of the implementation.\r\n\r\n\r\nHOW CAN I UPGRADE FROM A PREVIOUS VERSION ?\r\n===========================================\r\n!!! Be careful when you upgrade your multiOTP open source Virtual Appliance !!!\r\nThe multiOTP open source Virtual Appliance is using the files in\r\nraspberry/boot-part/multiotp-tree/usr/local/bin/multiotp, with\r\nconfig and backend folders defined to be located in /etc/multiotp/\r\n\r\nIf you are currently using the multiOTP open source Virtual Appliance, you can upgrade\r\nthe multiOTP version by copying the extracted content of the folder and subfolders from\r\nraspberry/boot-part/multiotp-tree/usr/local/bin/multiotp to /usr/local/bin/multiotp  \r\nAn update through the web interface should be available in the future\r\n\r\nIf you are currently using the multiOTP open source linux files, you can\r\nupgrade your installation by copying the extracted content of the folder and\r\nsubfolders from linux to your current multiOTP folder\r\n\r\n!!! since 5.0.4.6 under Linux, the config, devices, groups, tokens and users folders are now\r\nalways located in /etc/multiotp/. Please be sure to make the move when you are upgrading !!!\r\n(before 5.0.4.6, theses subfolders where located just below the main multiOTP folder)\r\n\r\nIf you are currently using the multiOTP open source windows files, you can\r\nupgrade your installation by copying the extracted content of the folder and\r\nsubfolders from windows to your current multiOTP folder\r\n\r\n\r\nWHAT'S NEW IN THIS 5.10.x RELEASE\r\n- New 2FA opt-in option, to migrate smoothly from Without2FA accounts to 2FA\r\n- New Proxmox, OVA and Hyper-V appliances available (version 013, based on Debian 13)\r\n- Free (and open source) multiOTP token App companion, proposed by default in the provisioning template\r\n- Push support with the multiOTP token App, available for free with Enterprise subscription\r\n\r\n\r\nCHANGE LOG OF RELEASED VERSIONS\r\n===============================\r\n```\r\n2026-04-03 5.10.2.2 FIX: Hardware token import was not always working correctly for 013 appliances\r\n                    FIX: PHP 8.x incompatibility issue in SMTP library (Thanks to @dexkuz)\r\n                    ENH: PHP 8.x deprecated code cleaned\r\n                    ENH: Yubikey import now also accept \"Yubico CSV\" format\r\n                    ENH: New 2FA opt-in option, to migrate smoothly from Without2FA accounts to 2FA\r\n                    ENH: Better rights handling in the Docker version\r\n                    ENH: Embedded Windows PHP edition updated to version 8.5.4 x64\r\n                    ENH: Embedded Windows nginx edition updated to version 1.29.7\r\n                    ENH: Documentation enhancement\r\n2026-03-23 5.10.2.1 FIX: Changing notification options (SMTP server and SysLog options) was not always possible\r\n                    FIX: SMSEagle v2 implementation was not always able to send to international countries\r\n                    FIX: websocketCore.php was missing in the sources\r\n                    ENH: Template updated to propose the free \"multiOTP token app\" by default for Android and iOS\r\n                    ENH: Embedded Windows PHP edition updated to version 8.4.16 x64\r\n                    ENH: Embedded Windows nginx edition updated to version 1.29.6\r\n                    ENH: Updated environment detection, like docker detection\r\n                    ENH: Updated Linux helper, for the future new web interface\r\n                    ENH: For Windows, WMIC dependencies has been removed and replaced by Powershell commands\r\n2026-01-23 5.10.1.5 ENH: For Docker installation, configuration files are copied automatically in the external volumes if missing\r\n2026-01-05 5.10.1.2 FIX: Locked and delayed status handled before push status\r\n2025-12-23 5.10.1.1 ENH: New SendEmail implementation with internal smtp stack (using smtp parameters)\r\n                    ENH: Better Docker integration\r\n2025-12-18 5.10.0.7 FIX: PostgreSQL fix for the fields in the log table\r\n                    FIX: Warning issue when using the docker version (old temp folder removed)\r\n                    ENH: New options: \"don't auto disable\" and \"don't auto enable\" LDAP accounts\r\n                    ENH: New SMS library integration and new SMSEagle v2 API support\r\n                    ENH: New API functions for the forthcoming VueJS 3.x interface (Q1 2026)\r\n                    ENH: New QRcode enrollment for mOTP, compatible with the free multiOTP token App\r\n                    ENH: Updated log functions to enhance the log information in the next releases\r\n                    ENH: Cleaned logs for unnecessary information\r\n                    ENH: New download page for the multiOTP family\r\n                    ENH: New multiOTP token App\r\n                    ENH: Additional constants in the library\r\n2025-11-04 5.10.0.4 ENH: Option to disable automatic activation/deactivation of user during LDAP synchronisation\r\n2025-11-04 5.10.0.3 FIX: MultiotpXmlParser class adapted to be 100% compatible with the legacy version\r\n                    ENH: Embedded Windows PHP edition updated to version 8.4.14\r\n                    ENH: The default radius secret is now set to myfirstpass for every device (0.0.0.0/0)\r\n2025-10-31 5.10.0.2 FIX: /boot/newvm.sh INIT no more called by RUN in the Dockerfile\r\n                    ENH: Updated Docker format\r\n2025-10-31 5.10.0.1 FIX: Warning was displayed in some cases when using GetSysLogServer() method\r\n                    FIX: Notice was displayed in some cases when using the sms library (MultiotpSms)\r\n                    FIX: Implementation check URI no more enabled by default in Windows source\r\n                    FIX: Syslog server handling was sometimes generating warnings\r\n                    FIX: Better initialization of the config_data array for FreeBSD\r\n                    ENH: New rewritten MultiotpXmlParser class\r\n                    ENH: New Proxmox, OVA and Hyper-V appliances available (version 013, based on Debian 13)\r\n                    ENH: Initial Push support with the multiOTP token App, needs multiOTP-gateway-service\r\n                    ENH: multiOTP Credential Provider enhanced support\r\n                    ENH: URI only reacting on / to avoid intensive hits\r\n                    ENH: Embedded Windows PHP edition updated to version 8.4.13\r\n                    ENH: Embedded Windows nginx edition updated to version 1.29.2\r\n2025-10-16 5.9.9.3 ENH: Debian Trixie 13 support\r\n2025-01-20 5.9.9.1 FIX: Windows backup temp folder is now the default system temp folder\r\n                   FIX: Adding -sync-delete-retention-days parameter doesn't return missing parameters error\r\n                   FIX: Case sensitive issue has been fixed with MSCHAPv2 authentication (thanks Alexey)\r\n                   FIX: Case sensitive issue has been fixed during FastCreateUser process\r\n                   ENH: Created users are trimmed to avoid bad space prefix/suffix during copy/paste\r\n                   ENH: multiOTP Credential Provider enhanced support\r\n                   ENH: New default-2fa-digits command line option to set the default amount of OTP digits \r\n                   ENH: PHP 8.4.x deprecated code cleaned (xml_set_object removed)\r\n2025-01-10 5.9.8.3 FIX: {MultiotpUserDisplayName} tag usage in templates (was not replaced in the QRcode)\r\n                   ENH: New Message-Authenticator requirement support for FortiGate v7.2.10+, v7.4.5+ and v7.6.1+\r\n                   ENH: New SetCurrentUserSid function for new Credential Provider -usersid option\r\n                   ENH: Embedded Windows PHP edition updated to version 8.3.15\r\n                   ENH: Embedded Windows nginx edition updated to version 1.27.3\r\n2024-08-26 5.9.8.0 FIX: Database backend setup and initialization was not working well with some PHP version\r\n                   ENH: New option to force writing logs only in file (even if the backend is a database)\r\n                   ENH: Spryng SMS provider support\r\n                   ENH: PHP 8.2.x deprecated code cleaned (null for string parameters)\r\n2024-05-03 5.9.7.2 FIX: without2fa token can be now correctly converted to TOTP with default 30 seconds time interval\r\n                   FIX: Without2fa tokens with prefix pin where not working with CHAP/MSCHAP/MSCHAPv2\r\n                   FIX: Windows: radiusd.conf and clients.conf files removed from the distribution\r\n                        (they are created automatically when installing the services using radius_install.cmd)\r\n                   ENH: Windows: -debug option removed from the radius module launcher\r\n                   ENH: By design, Credential Provider check request don't wait any prefix. This behavior can now be overwrited.\r\n2023-12-03 5.9.7.1 FIX: Command line number of parameters detection corrected\r\n                   ENH: It's now possible to define the number of digits for new created PIN\r\n                        (multiotp -config default-pin-digits=n)\r\n                   ENH: It's now possible to generate the HTML provisioning file by command line\r\n                        (multiotp -htmlinfo username /full/path/to/username.html or\r\n                         multiotp -htmlinfo /full/path/to/folder/ to generate files for all users)\r\n                   ENH: Embedded Windows nginx edition updated to version 1.25.3\r\n                   ENH: Embedded Windows internal tools updated (wget 1.21.4 and fart 1.99d)\r\n                   ENH: Embedded Windows freeradius is now launched using NSSM (instead of SRVANY)\r\n2023-11-23 5.9.7.0 FIX: Better Windows nginx configuration support (path backslashes replaced by slashes)\r\n                   ENH: Embedded Windows nginx edition updated to version 1.24.0\r\n                   ENH: Embedded Windows PHP edition updated to version 8.2.13\r\n                   ENH: Better hardware/model detection\r\n                   ENH: Documentation enhanced with instructions for RDWeb on Windows\r\n                   ENH: Upgrade of some internal tools\r\n2023-10-12 5.9.6.9 ENH: Better internal configuration organization\r\n2023-10-11 5.9.6.8 ENH: Debian Bookworm 12 support\r\n2023-09-22 5.9.6.7 ENH: Documentation updated for \"Configuring multiOTP with FreeRADIUS 3.x under Linux\"\r\n                   ENH: Without2FA tokens cannot be used for multi_account connection\r\n                   ENH: Added documentation for Linux SSH login with multiOTP using PAM\r\n2023-08-09 5.9.6.6 FIX: Prefix PIN information was sometimes missing on the provisioning info\r\n                   ENH: New Raspberry Pi distribution binary\r\n2023-07-07 5.9.6.5 FIX: Better Raspberry Pi support\r\n                   FIX: ShowLog() method (used by -showlog option) was buggy\r\n2023-05-10 5.9.6.1 FIX: Automated concurrent access for the same user with \"Without2FA\" token could corrupt the user file\r\n                   FIX: Any files backend operation is now secured with explicit lock mechanism\r\n                   ENH: Template updated to print bigger QRcode for \"MOTP-XML\" tokens\r\n2023-05-04 5.9.5.7 FIX: Weekly anonymized stats date was not always updated\r\n                   FIX: Adding -tokenslist command in CLI mode (was in the documentation, but was missing)\r\n                   FIX: Remove a debug line displaying sometimes \"COMMDN:$command\\n\";\r\n                   FIX: Some minor PHP notice corrections\r\n                   FIX: Template updated to display correct information for \"Without2FA\" tokens\r\n                   FIX: Enhanced backup process, some configuration may be missing in the backup depending the initial firmware version\r\n                   ENH: Adding on-premises smsgateway (https://github.com/multiOTP/SMSGateway) as a new SMS provider\r\n                   ENH: Better warning messages when CheckUserLdapPassword failed\r\n                   ENH: Embedded documentation enhanced\r\n2023-01-19 5.9.5.5 ENH: LDAP filter can be customized using SetLdapFilter() method\r\n                        ({cn_identifier}, {username}, and {groups_filtering} placeholders are supported)\r\n                   ENH: Full PHP 8.x support (tested with 8.2.1 and 8.1.14),\r\n                        with backward compatibility support (7.x, \u003e=5.4.x)\r\n                   ENH: Enhanced AD/LDAP paging support\r\n2022-12-31 5.9.5.3 ENH: Embedded Windows nginx edition updated to version 1.22.1\r\n                   ENH: Embedded Windows PHP edition updated to version 8.2.0\r\n                   ENH: PHP 8.2.x deprecated code cleaned (nullable trim, dynamic properties, PostgreSQL command without connection argument)\r\n                   ENH: Enhanced sms library (MultiotpSms), new eCall API implementation, new ASPSMS API implementation\r\n                   ENH: Better MySQL error handling\r\n                   ENH: Better PostgreSQL error handling\r\n2022-11-11 5.9.5.1 FIX: Windows nginx subfolders are now protected\r\n                   ENH: It's now possible to define a special AD/LDAP group to attribute \"Without2FA\" token to specific users\r\n                   ENH: Default username and password are not displayed anymore if default password has been changed\r\n2022-11-04 5.9.4.0 ENH: Enhanced multiOTP Credential Provider\r\n2022-10-21 5.9.3.1 FIX: Better special characters support in username and password\r\n                   ENH: The locked accounts list now also list the temporary delayed accounts\r\n                   ENH: Accounts with Without2FA tokens can now also be stored in cache\r\n2022-08-10 5.9.2.1 ENH: Enhanced Without2FA support, bypassing the 2FA in Credential Provider\r\n                   ENH: Command -iswithout2fa added as a CLI option (to check if a token is needed)\r\n2022-06-17 5.9.1.0 ENH: Enhanced multiOTP Credential Provider\r\n                   ENH: Additional CLI option -nt-key-only added\r\n2022-05-26 5.9.0.3 FIX: Issue with /run/php when a Docker container is restarted\r\n                   FIX: {MultiOtpVersion} is now correctly replaced in scratchtemplate.html\r\n                   ENH: {MultiotpUserDisplayName} tag (AD/LDAP DisplayName) can be used in templates\r\n2022-05-20 5.9.0.2 FIX: User account containing octal encoded ISO characters are now also converted to UTF\r\n2022-05-18 5.9.0.1 FIX: Set specific flags to run Perl scripts from FreeRADIUS\r\n2022-05-18 5.9.0.0 FIX: User account containing special ISO characters are now also converted to UTF\r\n                   ENH: New Hyper-V and OVA appliances available (version 011, based on Debian 11)\r\n                   ENH: Scratchlist can be generated from the Web GUI\r\n2022-05-08 5.8.8.4 ENH: Better docker support (also for Synology)\r\n2022-05-08 5.8.8.1 ENH: Add Raspberry Pi Bullseye 11.0 support\r\n2022-04-28 5.8.7.0 ENH: PHP 7.4 deprecated code cleaned\r\n                   ENH: Embedded Windows nginx edition updated to version 1.21.6\r\n                   ENH: Embedded Windows PHP edition updated to version 7.4.29\r\n                   ENH: New MariaDB/MySQL indexes handling during schema creation and schema updates\r\n                   ENH: Enhanced internal tests\r\n2022-04-14 5.8.6.1 FIX: Token \"Without2FA\" where not working all time with LDAP users\r\n                   ENH: Telnyx SMS provider support\r\n                   ENH: PHP 7.4 deprecated code cleaned\r\n                   ENH: Email token is now supported for Credential Provider\r\n                   ENH: In CLI check, if username doesn't exist, it try automatically a shorter domain name step by step\r\n2022-01-14 5.8.5.1 ENH: Embedded Windows nginx edition updated to version 1.21.4\r\n2021-11-18 5.8.3.2 ENH: Enhanced multiOTP Credential Provider support\r\n2021-09-14 5.8.3.0 ENH: New VM support (Debian Bullseye 11.0, PHP 7.4, FreeRADIUS 3.0.21, Nginx 1.18.0)\r\n                   ENH: Removed multicast support on the network card\r\n2021-08-19 5.8.2.9 ENH: Added compatibility with new multiOTP Credential Provider (5.8.2 and further)\r\n2021-06-04 5.8.2.4 ENH: Detect Credential Provider Request and force the no prefix option\r\n2021-05-19 5.8.2.3 FIX: Dockerfile updated (php-bcmath added)\r\n2021-04-08 5.8.2.1 ENH: eDirectory LDAP server support\r\n2021-03-25 5.8.1.9 FIX: Cookie privacy (httponly and secure) backported to previous virtual appliances\r\n                   ENH: Cookie privacy (httponly and secure) are now handled in the application directly\r\n                   ENH: Weak SSL ciphers disabled\r\n                   ENH: Better Docker support\r\n                   ENH: Better log handling\r\n2021-03-21 5.8.1.2 ENH: Test (1 == GetUserPrefixPin()) replaced by IsUserPrefixPin()\r\n2021-03-14 5.8.1.1 FIX: In some cases, the HOTP/TOTP was not well computed\r\n2021-03-21 5.8.1.2 FIX: Dockerfile corrected, apt-offline removed\r\n                   ENH: Enhanced log file handling\r\n2021-03-14 5.8.1.1 FIX: In some cases, the HOTP/TOTP was not well computed\r\n2021-02-12 5.8.1.0 ENH: Enhanced Web GUI accounts list (green=AD/LDAP synced, orange = delayed, red=locked)\r\n2020-12-11 5.8.0.7 ENH: -sync-delete-retention-days= option is set by default to 30 days\r\n2020-12-11 5.8.0.6 ENH: VM version 010 support  (Debian Buster 10.5, PHP 7.3, FreeRADIUS 3.0.17)\r\n                   ENH: MySQL optimization\r\n                   ENH: Enhanced windows command line scripts (automatic administrator level)\r\n2020-09-20 5.8.0.2 ENH: New -sync-delete-retention-days= option in order to purge inexistent AD/LDAP users\r\n                        (SetSyncDeleteRetentionDays and GetSyncDeleteRetentionDays method)\r\n2020-08-31 5.8.0.0 FIX: Too many ReadConfigData loop during initialization\r\n                   FIX: Better unicode handling, multibyte fonctions also for mb_substr()\r\n                   FIX: A device file was searched with the name of the FreeRADIUS Client-Shortname\r\n                   ENH: Raspberry Pi 4B support\r\n                   ENH: New unified distribution\r\n                   ENH: Debian Buster 10.5 support\r\n                   ENH: Enhanced PHP 7.3 support\r\n                   ENH: Better mysqli support for alternate connection port\r\n2019-10-23 5.6.1.5 FIX: Separated configuration/statistics storage handling\r\n                   ENH: Generic web based SMS provider support\r\n2019-10-22 5.6.1.3 ENH: Better PHP 7.3 support\r\n                   ENH: Base32 encoder/decoder new implementation\r\n                   ENH: During WriteConfigData, loop on the current values, and check with the old values\r\n                   ENH: Enhanced internal tests\r\n                   ENH: Debian Buster 10 support\r\n2019-09-02 5.5.0.3 ENH: Give an info if time based token is probably out of sync (in a window 10 time bigger)\r\n                        (for example for hardware tokens not used for a long time)\r\n                   ENH: Modifications for Debian 10.x (buster) binary images support (64 bits)\r\n2019-03-29 5.4.1.8 ENH: Enhanced error messages, more log information\r\n                   ENH: In debug mode, display an error if logfile cannot be written\r\n                   ENH: Global Access-Challenge support\r\n2019-01-30 5.4.1.7 FIX: IsTemporaryBadServer function (thanks to brownowski on GitHub)\r\n                   ENH: New QRcode library used (without external files dependency)\r\n                   ENH: New Raspberry images support for Raspberry Pi 1B/1B+/2B/3B/3B+\r\n2019-01-25 5.4.1.6 FIX: If any, clean specific NTP DHCP option at every reboot\r\n2019-01-18 5.4.1.4 ENH: Modifications for Debian 9.x (stretch) binary images support\r\n2019-01-07 5.4.1.1 ENH: Raspberry Pi 3B+ support\r\n                   ENH: Debian Strech 9 support\r\n2018-11-13 5.4.0.2 ENH: Import of PSKC definition files with binary decoding key file\r\n                   ENH: Added Swisscom LA REST, Afilnet, Clickatell2, eCall, Nexmo, NowSMS, SMSEagle and custom SMS provider support\r\n2018-09-14 5.4.0.1 FIX: Values of SetUserCacheLevel(), GetUserCacheLevel(), SetUserCacheLifetime()\r\n                        and GetUserCacheLifetime() are not correctly initialized\r\n                   ENH: Enigma Virtual Box updated to version 9.10 (to create the special all-in-one-file)\r\n                   ENH: PHP 7.1.22 used in the one single file (only PHP \u003c 7.2 is still compatible with Windows 7/2008)\r\n                   ENH: Compatibility mode to Windows 7 automatically added for radiusd.exe during radius service installation\r\n                   ENH: PHP display error flag is now set to off by default in the webservice under Windows\r\n2018-08-26 5.3.0.3 FIX: Better without2FA algorithm support\r\n                   FIX: Restore configuration has been fixed in the command line edition\r\n                   ENH: Cache-level and cache-lifetime can be set separately for each user\r\n                   ENH: In client/server mode, only unencrypted user attributes are sent back to a successful client request\r\n                   ENH: Enhanced monitoring\r\n2018-08-22 5.3.0.1 ENH: Monitoring fields added (create_host, create_time, last_update_host)\r\n2018-08-21 5.3.0.0 FIX: stream_timeout is no more pushed to 20 seconds in PostHttpDataXmlRequest if we are in Credential Provider mode\r\n                   FIX: RemoveTokenFromUser() method corrected. Token administrative information corrected,\r\n                        new software token created for the user\r\n                   ENH: Multiple semicolon separated \"Users DN\" supported for AD/LDAP synchronization\r\n                   ENH: Additional debug messages for disabled users during synchronization\r\n                   ENH: Enigma Virtual Box updated to version 9.00 (to create the special all-in-one-file)\r\n                   ENH: PHP 7.2.8 used in the one single file\r\n                   ENH: without2FA algorithm now available (useful to do 2FA only for some accounts and not for others)\r\n2018-07-16 5.2.0.2 ENH: Active Directory nested groups support\r\n                        (user1 in groupA, groupA in groupB, setting the OTP groups to \"groupB\" will add user1)\r\n                   ENH: Enhanced AD/LDAP support for huge Microsoft Active Directory\r\n                   ENH: \"Base DN\" and \"Users DN\" are now two different parameters (\"Users DN\" optional)\r\n2018-03-20 5.1.1.2 FIX: typo in the source code of the command line option for ldap-pwd and prefix-pin\r\n                   ENH: Initial public Dockerfile release\r\n2018-03-05 5.1.0.8 FIX: Enigma Virtual Box updated to version 8.10 (to create the special all-in-one-file)\r\n2018-02-27 5.1.0.7 FIX: [Receive an OTP by SMS] link is now fixed for Windows 10\r\n2018-02-26 5.1.0.6 ENH: Credential Provider registry entries are now always used when calling multiOTP.exe\r\n2018-02-21 5.1.0.5 FIX: To avoid virus false positive alert, multiOTP.exe is NO more packaged in one single file\r\n                        using Enigma, a php folder is now included in the multiOTP folder\r\n                   FIX: multiOTPOptions registry entry is now useless\r\n2018-02-21 5.1.0.4 ENH: Credential Provider registry entries are used if available\r\n2018-02-19 5.1.0.3 FIX: Better unicode handling, multibyte fonctions used when needed (mb_strtolower(), ...)\r\n                   ENH: Expired AD/LDAP password support\r\n                   ENH: multiOTP Credential Provider (for Windows) improvements\r\n                         (user@domain.name UPN support, default domain name supported and displayed, SMS request link)\r\n                   ENH: \"force_no_prefix_pin\" option for devices (for example if the device is a\r\n                        computer with multiOTP credential Provider and AD/LDAP synced password)\r\n2017-11-04 5.0.5.6 Better FreeRADIUS 3.x documentation\r\n                   New radius tag prefix configuration option\r\n                   New multiple groups device option\r\n                   Some notice corrections (if the array element doesn't exist)\r\n                   A user cannot be created with a leading backslash (fixed in FastCreateUser and CreateUserFromToken)\r\n2017-09-29 5.0.5.2 The proposed mOTP generator for Android/iOS is now OTP Authenticator\r\n                   New QRCode provisioning format for mOTP (compatible with OTP Authenticator)\r\n2017-09-08 5.0.5.0 NirSoft nircmd.exe tool removed from the distribution (false virus detection)\r\n                   Multiple URLs separator for client/server config is still \";\", but [space] and \",\" are accepted\r\n                   New developer mode for some specific detailed logs during development process only\r\n2017-07-07 5.0.4.9 New methods: SetLdapTlsReqcert, GetLdapTlsReqcert, SetLdapTlsCipherSuite, GetLdapTlsCipherSuite\r\n                    to change config parameters, instead of hard coded parameters (for SSL/TLS LDAP connection)\r\n                   Fixed too much detailed information in the log when trying\r\n                    to detect a token serial number for self-registration\r\n2017-06-06 5.0.4.8 Fixed SSL/TLS LDAP failed connection for PHP 7.x (GnuTLS TLS1.2 restriction removed for PHP 7.x)\r\n2017-06-02 5.0.4.6 Fixed a typo in the ReadCacheData method for PostgreSQL support (thanks Frank for the feedback)\r\n                   Fixed default folder detection for the multiotp.exe file\r\n                   Important, under Linux, the config, devices, groups, tokens and users folders are now always\r\n                    located in /etc/multiotp/. Please be sure to make the move when you are upgrading\r\n                   Cleaned some ugly PHP warnings when the backend is not initialized\r\n2017-05-29 5.0.4.5 Restore configuration added in Web GUI\r\n                   Fixed configuration file directory under Windows in Web GUI\r\n                   Fixed path with spaces handling for the command line edition (thanks Scott for the feedback)\r\n                   PostgreSQL support, based on source code provided by Frank van der Aa\r\n2017-05-16 5.0.4.4 GetList() is now sorted with files backend\r\n                   A replay during a defined delay (default 60 seconds) of the previous refused password is rejected,\r\n                    but the error counter is not incremented (SetLastFailedWhiteDelay and GetLastFailedWhiteDelay)\r\n                   A user cannot be created with a leading backslash\r\n2017-02-23 5.0.3.7 Group names are now always trimed to avoid blank spaces\r\n                   SetLinuxFolderMode() and GetLinuxFolderMode() methods added\r\n2017-02-21 5.0.3.6 GetDelayedUsersList() method added\r\n                   GetList() return now a sorted list\r\n                   RestoreConfiguration() method updated, system configuration data can be ignored\r\n                   SetUserTokenSeed() and SetTokenSeed() methods accept now also base32 and raw binary\r\n                   The full windows package has been fixed and cleaned\r\n2017-02-03 5.0.3.5 GetUserInfo method added\r\n                   ImportTokensFromCsv fixed when the file is not readable\r\n                   Fix possible endless loop when opening a file that exists but without the right to read it\r\n2017-01-26 5.0.3.4 It's now possible to do several commands at once with the CLI edition\r\n                   New overwrite_request_ldap_pwd option (enabled by default).\r\n                    If overwrite is enabled, default_request_ldap_pwd value is forced during synchronization\r\n                   Multiple groups per user is now supported (not all devices support multiple groups).\r\n                    (radius reply attributor has been changed to += by default)\r\n                   multiotp -delete-token command has been added in the CLI\r\n                   -lock and -unlock command return now 19 (instead of 99) in the CLI\r\n                   Better support of DialinIp functions in command line usage\r\n                   New LDAP cache management to support huge AD/LDAP, with cache on disk (system temporary folder)\r\n                   New PurgeLockFolder() and PurgeLdapCacheFolder() method\r\n                   The default proposed TOTP/HOTP generator for Android/iOS is now FreeOTP Authenticator\r\n                   Better Eastern European languages support\r\n                   Multiple purpose tokens provisioning format PSKCV10,\r\n                    like Gemalto e3050cL and t1050 tokens, is now supported.\r\n                   Various bug fixes and enhancements when using the proxy mode.\r\n2016-11-14 5.0.3.0 Log messages are better categorized\r\n                   The user dialin IP address is synchronized from the\r\n                    Active Directory msRADIUSFramedIPAddress attribute\r\n                   New IP dialin methods : SetUserDialinIpAddress(), SetUserDialinIpMask(),\r\n                    SetDefaultDialinIpMask(), GetUserDialinIpAddress(), GetUserDialinIpMask(),\r\n                    GetDefaultDialinIpMask()\r\n                   If the user dialin IP address is defined, Framed-IP-Address\r\n                    and Framed-IP-Mask are delivered in the RADIUS answer\r\n                   Enhanced token importation process (to support binary encryption key\r\n                    in hexadecimal 0xAABBCC format)\r\n2016-11-04 5.0.2.6 Better log message for automatically or manually created objects\r\n                   External packages update\r\n                   New GetUserLastLogin() and SetUserLastLogin() methods\r\n                   Backup configuration file can now be restored in commercial\r\n                    version without any changes\r\n2016-10-16 5.0.2.5 Better SSL support using context if available (for PHP \u003e= 5.3)\r\n                   New methods SetTouchFolder(), GetTouchFolder(), TouchFolder(),\r\n                    FolderTouched() to offer asynchronous implementation capabilities\r\n                   New methods added for SOAP service\r\n                   Weekly anonymized stats added (can be disabled).\r\n                    Anonymized stats include the following information:\r\n                     backend type, AD/LDAP used or not, OS version, PHP version,\r\n                     library version, number of accounts defined, number of tokens defined.\r\n                     They are sent on the stats.multiotp.net FQDN which is hosted in Switzerland.\r\n                   It's possible to select a specific LDAP/AD attribute used as the synchronised\r\n                    account name: SetLdapSyncedUserAttribute(), GetLdapSyncedUserAttribute()\r\n                   An account can be tested from the dashboard\r\n                   Unified configuration backup and restore format (BackupConfiguration)\r\n                   Better support of MS-CHAPv2 in the provided appliances\r\n                   Cached requests supported (cached during a specific amount of time,\r\n                    useful for WebDAV authentication) (device option cache_result_enabled)\r\n                   A try on the previous password is rejected,\r\n                    but the error counter is not incremented\r\n                   ForceNoDisplayLog() method added to disable log on display in server mode\r\n                   XML parsing error are more verbose\r\n                   XmlServer is now sending XML response with the specific Content-type: text/xml\r\n                   YubicoOTP private id check is now implemented\r\n                   SSL AD/LDAP also supported with Windows 2012 server\r\n                   SyncLdapUsers is now using a semaphore file to avoid\r\n                    concurrent process for large AD/LDAP sync\r\n                    (tested with 1'000 groups, 100'000 users, 1'000 users in the LDAP sync group)\r\n                   AD/LDAP additional log information\r\n                   New GetNetworkInfo and SetNetworkInfo methods\r\n                   Special chars support enhanced in LDAP class (as described in RFC4515)\r\n                   The default ldap_group_cn_identifier is now cn instead of sAMAccountName\r\n                   The first matching group defined in AD/LDAP group(s) filtering is now\r\n                    defined for the user (this group is returned as the Filter-Id (11) option\r\n                    in a successful RADIUS answer)\r\n                   Enhanced SMS support for Clickatell, SSL is now also working\r\n                   Bug fix concerning QRcode generation for mOTP\r\n                   Code fixes\r\n                   New AssignTokenToUser() and RemoveTokenFromUser() methods\r\n2015-07-18 4.3.2.6 New ResetTempUserArray method (as we want to move away from global array in the near future)\r\n                   For _user_data, default values are now extracted from the definition array\r\n                   QRcode generation for mOTP (motp://[SITENAME]:[USERNAME]?secret=[SECRET-KEY])\r\n2015-07-15 4.3.2.5 Calling multiotp CLI without parameter returns now error code 30 (instead of 19)\r\n2015-06-24 4.3.2.4 multi_account automatic support (multi_account is activated when\r\n                    \"multi_account\" is set as description of the account (also with AD/LDAP sync)\r\n                   Scratch password generation (UTF)\r\n2015-06-10 4.3.2.3 Enhancements for the Dev(Talks): demo\r\n2015-06-09 4.3.2.2 Empty users are refused\r\n                   TOTP time interval of imported tokens is set by default to 30s\r\n                   More accuracy in the logged information\r\n                   Refactoring backend methods, sharing code\r\n                   Refactoring some ugly parts (!)\r\n                   Documentation update concerning lockout functions and prefix PIN prefix\r\n                   Special token entry 'Sms' is now also accepted, like 'SMS' or 'sms', to send an SMS token\r\n                   The minus (-) in the prefix password is now supported (it was filtered to fix some rare user issues)\r\n                   The autoresync option is now enabled by default\r\n                   Resync during authentication (autoresync) is now better handled in the class directly\r\n                   The server_cache_level is now set to 1 by default (instead of 0)\r\n                   If the token length is not correct, it's now written in the log\r\n                   Some LDAP messages are now only logged in debug mode\r\n2014-12-15 4.3.1.1 Better generic LDAP support\r\n                     - description sync done in the following order: description, gecos, displayName\r\n                     - memberOf is not always implemented, alternative method to sync users based on group names.\r\n                     - disabled account synchronization using shadowExpire or sambaAcctFlags\r\n                   Better Active Directory support\r\n                     - accountExpires is now supported for synchronization\r\n                     - ms-DS-User-Account-Control-Computed (to handle locked out accounts, available since Windows 2003)\r\n2014-12-09 4.3.1.0 MULTIOTP_PATH environment variable support\r\n                   CLI proxy added to speed up the command line\r\n                   Scratch password need also the prefix PIN if it's activated\r\n                   OTP with integrated serial numbers better supported (in PAP)\r\n                   Generic LDAP support (instead of Microsoft AD support only)\r\n                   Raspberry Pi edition has now a special proxy to speed up the command line\r\n2014-11-04 4.3.0.0 It's now possible to use the AD/LDAP password instead of the PIN code\r\n                   Yubico OTP support, including keys import using the log file in Traditional format\r\n                   qrcode() stub enhanced to check if the required folders are available\r\n                   SyncLdapUsers completely redesigned\r\n                     - no more complete array in memory\r\n                     - MultiotpAdLdap class also enhanced accordingly\r\n                       - cached group_cn requests\r\n                       - cached recursive_groups requests\r\n                       - new \"by element\" functions\r\n                   Demo mode support\r\n                   Bug fix concerning the NT_KEY generation with enabled prefix PIN (thanks Adam)\r\n                   ResyncToken() method added (instead of using CheckToken() method for synchronization)\r\n2014-06-12 4.2.4.3 Bug fix concerning aspsms provider\r\n2014-04-13 4.2.4.2 XML parsing consolidation, one library for the whole project\r\n                   Fixed bug concerning tokens CSV import\r\n2014-04-06 4.2.4.1 Fixed bug concerning LDAP handling\r\n                   NT_KEY support added (for FreeRADIUS further handling)\r\n                   Tokens CSV import (serial_number;manufacturer;algorithm;seed;digits;interval_or_event)\r\n                   When a user is deleted, the token(s) attributed to this user is/are unassigned\r\n                   New option -user-info added\r\n2014-03-30 4.2.4   Fixed bug concerning MySQL handling and mysqli support added\r\n                   Enhanced SetAttributesToEncrypt function\r\n                   New implementation fo some external classes\r\n                   Generated QRcode are better\r\n                   LOT of new QA tests, more than 60 different tests (including PHP class and command line versions)\r\n                   Enhanced documentation\r\n2014-03-13 4.2.3   Fixed bug for clear text password going back to TekRADIUS (PIN was always prefixed for mOTP)\r\n                   Fixed bug when client/server mode is activated, but not working well\r\n2014-03-03 4.2.2   Better AD/LDAP integration\r\n                   Web GUI is now complete for a simple usage, including hardware tokens import\r\n                   Better template for provisioning information\r\n                   Some values can now go back to TekRADIUS\r\n                   If activated, prefix PIN is now also requested for SMS authentication\r\n                   More information in the logs\r\n                   Better list of the external packages used\r\n2014-02-14 4.2.1   AD/LDAP is now fully supported in order to create users based on AD/LDAP content\r\n                    (with groups filtering)\r\n2014-02-07 4.2.0   MS-CHAP and MS-CHAPv2 are now supported\r\n                    (md4 implementation added for PHP backward compatibility)\r\n                   Enhanced LDAP configuration structure\r\n                   Fixed bug during token attribution to users\r\n                    (a \"no name\" token appeared sometimes)\r\n2014-01-20 4.1.1   md5.js was missing in the public distribution\r\n                   Alternate json_encode function is defined if the JSON extension is not loaded\r\n                   Fixed possible image functions incompatibilities with some PHP versions\r\n                    during QRcode generation\r\n                   As suggested by Sylvain, token resync doesn't need prefix PIN anymore\r\n                    (but still accepted)\r\n                   More verbosity in the logs in debug mode\r\n                   Specific parameters order in QRCode for Microsoft Authenticator support\r\n                    (thanks to Erik Nylund)\r\n2013-12-23 4.1.0   The open source edition of multiOTP is OATH certified ;-)\r\n                    (that means full compatibility with any OATH tokens and encrypted PSKC import support)\r\n                   Raspberry Pi nanocomputer is now fully supported\r\n                   Basic web interface\r\n                   Self-registration of hardware tokens is now possible\r\n                    PAP mode: if self-registration is enabled, a user can register a non-attributed token by typing\r\n                    [serial number][OTP] instead of [OTP]. If user has a prefix PIN, type [serial number][PIN][OTP])\r\n                    PAP/CHAP mode: if self-registration is enabled, a user can register a non-attributed token by typing\r\n                    [username:serialnumber] as the username and the [OTP] in the password field.\r\n                    If user has a prefix PIN, [PIN][OTP] must be typed in the password field\r\n                   Automatic resync/unlock option during authentication (PAP only). When the autoresync option\r\n                    is enabled, any user can resync his token by typing [OTP1] [OTP2] in the password field. \r\n                    If user has a prefix PIN, he must type [PIN][OTP1] [PIN][OTP2].\r\n                   Tokens with less than 3 characters are not accepted anymore in CheckToken()\r\n                   Default Linux file mode is now set by default (0666 for created and changed files)\r\n                   Error 28 is returned if the file is not writable, even after a successful login\r\n                   Added GetUsersCount() function\r\n                   Added GenerateSmsToken() function\r\n                   Added Groups management functions\r\n                   Added Tokens assignation functions\r\n                   Added SetUserActivated(1|0) and GetUserActivated() function\r\n                   Added SetUserSynchronized(1|0) and GetUserSynchronized() function\r\n                   scratch_passwords is now a text field in the database\r\n                   The third parameter of the Decrypt method is now mandatory\r\n                   Some modifications in order to correctly handle the class methods\r\n2013-09-22 4.0.9   Fixed a bug in GetUserScratchPasswordsArray. If a user had no scratch password\r\n                    and the implementation accepted blank password, it was accepted\r\n                   Fixed a bug where scratch passwords generation used odd numbers of characters for hex2bin()\r\n2013-08-30 4.0.7   GetScriptFolder() was still buggy sometimes, thanks Frank for the feedback\r\n                   File mode of the created QRcode file is also changed based on GetLinuxFileMode()\r\n                   'sms' as the password to request an SMS token can now be sent in lower or uppercase\r\n                   Added a description attribute for the tokens\r\n2013-08-25 4.0.6   base32_encode() is now RFC compliant with uppercases\r\n                   GetUserTokenQrCode() and GetTokenQrCode() where buggy\r\n                   GetScriptFolder() use now __FILE__ if the full path is included\r\n                   When doing a check in the CLI header, @... is automatically removed from the\r\n                    username if the user doesn't exist, and the check is done on the clean name\r\n                   Added a lot of tests to enhance release quality\r\n2013-08-21 4.0.5   Fixed the check of the cache lifetime\r\n                   Added a temporary server blacklist during the same instances\r\n                   Default server timeout is now set to 1 second\r\n2013-08-20 4.0.4   Added an optional group attribute for the user\r\n                    (which will be send with the Radius Filter-Id option)\r\n                   Added scratch passwords generation (if the token is lost)\r\n                   Automatic database schema upgrade using method UpgradeSchemaIfNeeded()\r\n                   Added client/server support with local cache\r\n                   Added CHAP authentication support (PAP is of course still supported)\r\n                   The encryption key is now a parameter of the class constructor\r\n                   The method SetEncryptionKey('MyPersonalEncryptionKey') is DEPRECATED\r\n                   The method DefineMySqlConnection is DEPRECATED\r\n                   Full MySQL support, including tables creation (see example and SetSqlXXXX methods)\r\n                   Added email, sms and seed_password to users attributes\r\n                   Added sms support (aspsms, clickatell, intellisms, exec)\r\n                   Added prefix support for debug mode (in order to send Reply-Message := to Radius)\r\n                   Added a lot of new methods to handle easier the users and the tokens\r\n                   General speedup by using available native functions for hash_hmac and others\r\n                   Default max_time_window has been lowered to 600 seconds (thanks Stefan for suggestion)\r\n                   Integrated Google Authenticator support with integrated base 32 seed handling\r\n                   Integrated QRcode generator library (from Y. Swetake)\r\n                   General options in an external configuration file\r\n                   Comments have been reformatted and enhanced for automatic documentation\r\n                   Development process enhanced, source code reorganized, external contributions are\r\n                    added automatically at the end of the library after an internal build release\r\n2011-10-25 3.9.2   Some quick fixes after intensive check\r\n                   Improved get_script_dir() in CLI for Linux/Windows compatibility\r\n2011-09-15 3.9.1   Some quick fixes concerning multiple users\r\n2011-09-13 3.9.0   Added support for account with multiple users\r\n2011-07-06 3.2.0   Encryption hash handling with additional error message 33\r\n                    (if the key has changed)\r\n                   Added more examples\r\n                   Added generic user with multiple account\r\n                    (Real account name is combined: \"user\" and \"account password\")\r\n                   Added log options, now default doesn't log token value anymore\r\n                   Debugging MySQL backend support for the token handling\r\n                   Fixed automatic detection of \\ or / for script path detection\r\n2010-12-19 3.1.1   Better MySQL backend support, including in CLI version\r\n2010-09-15 3.1.0   Removed bad extra spaces in the multiotp.php file for Linux\r\n                   MySQL backend support\r\n2010-09-02 3.0.0   Added tokens handling support\r\n                    including importing XML tokens definition file\r\n                    (http://tools.ietf.org/html/draft-hoyer-keyprov-pskc-algorithm-profiles-00)\r\n                   Enhanced flat database file format (multiotp is still compatible with old versions)\r\n                   Internal method SetDataReadFlag renamed to SetUserDataReadFlag\r\n                   Internal method GetDataReadFlag renamed to GetUserDataReadFlag\r\n2010-08-21 2.0.4   Enhancement in order to use an alternate php \"compiler\" for Windows command line\r\n                   Documentation enhancement\r\n2010-08-18 2.0.3   Minor notice fix\r\n2010-07-21 2.0.2   Fix to create correctly the folders \"users\" and \"log\" if needed\r\n2010-07-19 2.0.1   Foreach was not working well in PHP4, replaced at some places\r\n2010-07-19 2.0.0   New design using a class, mOTP support, cleaning of the code\r\n2010-06-15 1.1.5   Added OATH/TOTP support\r\n2010-06-15 1.1.4   Project renamed to multiotp to avoid overlapping\r\n2010-06-08 1.1.3   Typo in script folder detection\r\n2010-06-08 1.1.2   Typo in variable name\r\n2010-06-08 1.1.1   Status bar during resynchronization\r\n2010-06-08 1.1.0   Fix in the example, distribution not compressed\r\n2010-06-07 1.0.0   Initial implementation\r\n```\r\n\r\nCONTENT OF THE PACKAGE\r\n======================\r\n- the MSI installer of multiOTP Credential Provider for Windows 7/8/8.1/10/2012(R2)/2016\r\n  must be downloaded separately on https://download.multiotp.net/credential-provider/\r\n\r\n```\r\nIn the linux folder:\r\n- multiotp.php             : command line tool (merge of the header and the class, external files also included)\r\n- multiotp.class.php       : the main file, it is the class itself, external files are already included\r\n- multiotp.server.php      : the web service file (the class is already merged in the file, external files also included)\r\n- check.multiotp.class.php : PHP script to validate some multiOTP functionalities\r\n- md5.js                   : encryption JS library used by multiotp.server.php\r\n- test-tokens.csv          : provisioning file of test tokens\r\n+ oath subfolder           : contains provisioning files for oath test tokens\r\n+ templates folder         : all templates files needed to generate the provisioning pages from the web GUI\r\n\r\n*******************************************************************************\r\n***  FOR THESE PHP FILES, THE BACKEND IS FILE BASED AND THE CONFIG AND      ***\r\n***  BACKEND FOLDERS ARE RELATIVE AND JUST BELOW THE MAIN MULTIOTP FOLDER   ***\r\n*******************************************************************************\r\n```\r\n\r\n```\r\nIn the raspberry folder:\r\n- all necessary files to be able to create your own strong authentication device using a Raspberry Pi\r\n\r\n*******************************************************************************\r\n***  FOR THESE PHP FILES, THE BACKEND IS SET BY DEFAULT AS FILE BASED AND   ***\r\n***  THE CONFIG AND BACKEND FOLDERS DEFINED TO BE LOCATED IN /etc/multiotp/ ***\r\n***  FURTHERMORE, THIS VERSION USES THE ADVANCED WEB PROXY IMPLEMENTATION   ***\r\n*******************************************************************************\r\n*** !!! Be careful when you update your open source virtual appliance !!!   ***\r\n*** The multiOTP open source Virtual Appliance is also using the            ***\r\n*** files in raspberry/boot-part/multiotp-tree/usr/local/bin/multiotp,      ***\r\n*** with config and backend folders defined to be located in /etc/multiotp/ ***\r\n*******************************************************************************\r\n```\r\n\r\n```\r\nIn the sources folder:\r\n- multiotp.class.php       : the main file, it is the class itself, which requires external files\r\n- multiotp.cli.header.php  : header file to be merged with the class for a single file command line tool\r\n- multiotp.server.php      : the web service file, which requires the class as external file\r\n- check.multiotp.class.php : PHP script to validate some multiOTP functionalities\r\n+ contrib subfolder        : contains all external files required by the multiotp.class.php file\r\n\r\n*******************************************************************************\r\n***  FOR THESE PHP FILES, THE BACKEND IS FILE BASED AND THE CONFIG AND      ***\r\n***  BACKEND FOLDERS ARE RELATIVE AND JUST BELOW THE MAIN MULTIOTP FOLDER   ***\r\n*******************************************************************************\r\n```\r\n\r\n```\r\nIn the windows folder:\r\n- multiotp.exe             : command line tool for Windows (digitally signed) with embedded PHP 7.x\r\n- multiotp.class.php       : the main file, it is the class itself, external files are already included\r\n- multiotp.server.php      : the web service file (the class is already merged in the file, external files also included)\r\n- check.multiotp.class.php : PHP script to validate some multiOTP functionalities\r\n- md5.js                   : encryption JS library used by multiotp.server.php\r\n- checkmultiotp.cmd        : Windows script to validate some multiOTP functionalities\r\n- radius_debug.cmd         : Windows script to run the multiOTP radius web server in debug mode\r\n- radius_install.cmd       : Windows script to install and start the multiOTP radius web server\r\n- radius_uninstall.cmd     : Windows script to stop and uninstall the multiOTP radius web server\r\n- webservice_install.cmd   : Windows script to install and start the multiOTP web service\r\n- webservice_uninstall.cmd : Windows script to stop and uninstall the multiOTP web service\r\n- test-tokens.csv          : provisioning file of test tokens\r\n+ legacy subfolder         : contains a windows command line version with all needed files\r\n                             (not embedded in a mini VM). This version is used by the multiOTP web service.\r\n+ oath subfolder           : contains provisioning files for oath test tokens\r\n+ radius subfolder         : all necessary files to be able to install a Windows radius server already\r\n                             configured with multiOTP support (using FreeRADIUS implementation for Windows)\r\n+ templates subfolder      : all templates files needed to generate the provisioning pages from the web GUI\r\n+ tools subfolder          : command line tools needed by some cmd scripts\r\n+ webservice subfolder     : all necessary files to be able to install a Windows multiOTP web service\r\n                             (using Nginx as the light web server on port 8112,\r\n                              or as a secured SSL connection (https) on port 8113)\r\n\r\n*******************************************************************************\r\n***  FOR THESE PHP FILES, THE BACKEND IS FILE BASED AND THE CONFIG AND      ***\r\n***  BACKEND FOLDERS ARE RELATIVE AND JUST BELOW THE MAIN MULTIOTP FOLDER   ***\r\n*******************************************************************************\r\n```\r\n\r\n\r\nTYPICAL TREE OF A WORKING LINUX INSTALLATION\r\n============================================\r\nA typical installation has the following tree organization:\r\n\r\n**Software files**\r\n```\r\n/usr/local/bin/\r\n/usr/local/bin/multiotp (contains multiotp.php)\r\n/usr/local/bin/multiotp/templates\r\n```\r\n\r\n**Data files**\r\n```\r\n/etc/multiotp/\r\n/etc/multiotp/config (contains multiotp.ini)\r\n/etc/multiotp/devices\r\n/etc/multiotp/groups\r\n/etc/multiotp/tokens\r\n/etc/multiotp/users (contains my_user1.db, my_user2.db, ...)\r\n```\r\n\r\n\r\nHOW CAN I CREATE MYSELF THE DIFFERENT VERSIONS ?\r\n================================================\r\nThe multiotp.php file is a copy of the multiotp.cli.header.php including\r\nthe copy of all files that are included in the PHP code, which are\r\nmultiotp.class.php and the whole contrib subfolder content.\r\n\r\nFor the virtual appliance and the Raspberry Pi edition, the multiotp.php file\r\nis a copy of the multiotp.cli.proxy.php file.\r\n(the proxy version calls the multiotp.proxy.php using the web server,\r\nand the web server has a PHP cache to improve the speed of the whole process).\r\n\r\nFor the virtual appliance and the Raspberry Pi edition, the multiotp.proxy.php file is\r\na copy of the multiotp.cli.header.php including the copy of all files that are included\r\nin the PHP code, which are multiotp.class.php and the whole contrib subfolder content.\r\n\r\nFor the virtual appliance and the Raspberry Pi edition, the following line in multiotp.class.php\r\n```\r\n$multiotp = new Multiotp('DefaultCliEncryptionKey', $initialize_backend, $folder_path);\r\n```\r\nis replaced by\r\n```\r\n$multiotp = new Multiotp('DefaultCliEncryptionKey', $initialize_backend, $folder_path);\r\nif (false !== strpos(getcwd(), '/')) {\r\n  $multiotp-\u003eSetConfigFolder('/etc/multiotp/config/');\r\n  $multiotp-\u003eSetCacheFolder('/tmp/cache/');\r\n  $multiotp-\u003eSetDevicesFolder('/etc/multiotp/devices/');\r\n  $multiotp-\u003eSetGroupsFolder('/etc/multiotp/groups/');\r\n  $multiotp-\u003eSetTokensFolder('/etc/multiotp/tokens/');\r\n  $multiotp-\u003eSetUsersFolder('/etc/multiotp/users/');\r\n  $multiotp-\u003eSetLogFolder('/var/log/multiotp/');\r\n  $multiotp-\u003eReadConfigData();\r\n}\r\n$multiotp-\u003eSetLinuxFileMode('0666');\r\n```\r\n\r\nThe multiotp.exe is a stub launcher running a PHP interpreter.\r\nThe necessary files of the PHP distribution are included in the php subfolder.  \r\nPHP download : http://php.net/downloads.php\r\n\r\nThe source files of the Credential provider are available on GitHub and needs\r\nthe free Visual Studio Community to be compiled.  \r\nSource files : https://github.com/multiOTP/multiOTPCredentialProvider  \r\nVisual Studio Community : https://www.visualstudio.com/vs/community/\r\n\r\n\r\nWHEN AND HOW CAN I USE THIS PACKAGE ? \r\n=====================================\r\nIf you decide to have strong two factor authentication inside your company,\r\nthis is definitely the package you need! You will be able to have strong\r\nauthentication for your VPN accesses, your SSL gateway, your private websites\r\nand even your Windows login for desktops AND laptops!\r\n\r\nThe multiOTP class can be used alone (for example to have strong \r\nauthentication for your PHP based web application), as a command line tool\r\n(to handle users and have strong authentication using command line), as a web\r\nservice (to provide centralized authentication for a client/server installation)\r\nor finally coupled with a radius server like TekRADIUS or FreeRADIUS to be able\r\nto have a strong two factor authentication through the RADIUS protocol for\r\nexternal devices like for example firewalls or captive portals.\r\n\r\nThe default backend storage is done in flat files, but you can also defined a\r\nMySQL server as the backend server. To use MySQL, you will only have to provide\r\nthe server, the username, the password and the database name. Tables will be\r\ncreated/updated automatically by multiOTP. The schema is also upgraded\r\nautomatically if you install a new release of multiOTP.\r\n\r\nStarting with version 4.x, you can also install a multiOTP web service\r\non a server, and this way some other multiOTP slave clients (like laptops)\r\ncan connect to the web service and caching the tokens information (if allowed).\r\n\r\nInside a company, you will probably use multiOTP with a radius server or as\r\na web service (see below on how to install these services).\r\n\r\nIf you are running under Windows, TekRADIUS or TekRADIUS LT will do the job \r\n(http:/www.tekradius.com/).\r\nThe difference is that TekRADIUS needs an MS-SQL SERVER (or MS-SQL Express) \r\nand TekRADIUS LT uses only an embedded SQLite database.\r\n\r\nmultiOTP is working fine under Windows with WinRADIUS, a port of FreeRADIUS\r\n(http://winradius.eu/)\r\n\r\nmultiOTP is also working fine with another port of FreeRADIUS\r\nfor Windows (http://sourceforge.net/projects/freeradius/)\r\n\r\nIf you are running under Linux, FreeRADIUS will do the job.\r\n(http://freeradius.org/)\r\n\r\nNow, you can register your different devices like firewalls, SSL, etc.\r\nin the radius server and provide the IP address(es) of the device(s)\r\n(often called NAS) and their shared Secret.\r\n\r\nIf you want to have strong authentication on Windows logon, have a look at the\r\nopen source project multiOTPCredentialProvider which is based on MultiotpCPV2RDP\r\nfrom arcadejust and MultiOneTimePassword Credential Provider from Last Squirrel IT.\r\nIt works with Windows 7/8/8.1/10/11/2012(R2)/2016/2019/2022 in 64 bits.  \r\nThe Credential Provider does not need any RADIUS connection! It uses instead a\r\nlocal version of multiOTP which can be configured as a client of a\r\ncentralized server (with caching support).\r\n(https://download.multiotp.net/credential-provider/)\r\n\r\nWhen the backend is set, it's time to create/define the tokens. You will have\r\nto select hardware or software token generators for your users. Currently, the\r\nlibrary supports mOTP, TOTP, HOTP, SMS or scratch passwords (printed on paper).\r\n\r\nmOTP is a free implementation of strong tokens that asks a PIN to generate a\r\ncode. This code depends of the time and the PIN typed by the user.\r\n\r\nA special without2FA token type is also available. It could be useful to do 2FA\r\nonly for some accounts and not for others.\r\n\r\nThe easiest tokens to use are TOTP, they are time based and well supported by\r\na lot of implementations like Google Authenticator.\r\nProvisioning will be done simply by flashing a QRcode.\r\n\r\n# Software tokens with mOTP (Mobile-OTP) support\r\n  - Swiss SafeLab OTP authenticator (iOS and Android)\r\n  - iPhone:    iOTP from PDTS (type iOTP in the Apple AppStore)\r\n  - Android:   Mobile-OTP (http://motp.sf.net/Mobile-OTP.apk)\r\n  - PalmOS:    Mobile-OTP (http://motp.sf.net/mobileotp_palm.zip)\r\n  - Java J2ME (Nokia and other Java capable phones): MobileOTP\r\n              (http://motp.sf.net/MobileOTP.jad)\r\n  - WinPhone:  Token2 (https://token2.com/?content=mobileapp)\r\n  \r\n# Software tokens with OATH compliant HOTP or TOTP support\r\n  Check the various markets of your devices, for examples:\r\n  - FreeOTP (open source): https://freeotp.github.io/\r\n  - oathtoken for iPhone/iPad: https://github.com/archiecobbs/oathtoken\r\n  - androidtoken for Android: https://github.com/markmcavoy/androidtoken\r\n  - Google Authenticator (Android/iPhone/iPad/BlackBerry)\r\n\r\n# Hardware tokens\r\n  - Any tokens that are OATH certified\r\n    - Feitian provides OATH compliant HOTP and TOTP tokens\r\n       (seed is provided in a standardized token definition PSKC xml file)\r\n      - OTP c100: OATH/HOTP, 6 digits\r\n      - OTP c200: OATH/TOTP, 6 digits, 60 seconds time interval\r\n        (seed is provided in a standardized token definition PSKC xml file)\r\n    - Gemalto provides OATH compliant HOTP and TOTP tokens\r\n      - Gemalto Ezio Token\r\n    - Seamoon provides OATH compliant TOTP tokens\r\n      - Seamoon KingKey: OATH/TOTP, 6 digits, 60 seconds time interval\r\n        (seed is provided in a specific smd file)\r\n    - ZyXEL OTP provides HOTP OATH compliant tokens (v2 and old v1 tokens)\r\n      - ZyWALL OTPv2 (rebranded SafeNet/Aladdin eToken PASS) : OATH/HOTP, 6 digits\r\n        (seed is extracted from the importAlpine.dat downloaded file,\r\n         the seed is the sccKey attribute)\r\n      - ZyWALL OTPv1 (rebranded Authenex A-Key 3600): OATH/HOTP, 6 digits\r\n        (seed is extracted from the OTP_data01_upgrade.sql SQL file,\r\n         SEED field at the end of the file)\r\n  - YubiKeys from Yubico (both in Yubico OTP or in OATH-HOTP format)\r\n    - YubiKey standard\r\n    - YubiKey Nano\r\n    - YubiKey Neo\r\n    - YubiKey Neo-N\r\n    \r\nThe YubiKey CSV import is based on the .CSV created by :\r\n- the legacy Yubikey Personalization Tools (YubiKey traditional format log file)\r\n  which is the following lines in a file called for example **yubico_log.csv**:\r\n\r\n  ```\r\n  LOGGING START,01.01.2015 04:03\r\n  Yubico OTP,01.01.2015 04:03,1,vvccccdtvkiu,40e661b3ce2b,7b01896b5ef79d8092fd04556b4f4403,,,0,0,0,0,0,0,0,0,0,0\r\n  Yubico OTP,01.01.2015 04:03,2,vvgdctvftcrt,f23f0218e3bb,64d66d0d758090bc6ef159866e63fea6,,,0,0,0,0,0,0,0,0,0,0\r\n  ```\r\n\r\n- the Yubico Authenticator (YubiKey Yubico format)\r\n  which is the following lines in a file called for example **yubico_token.csv**:\r\n\r\n  ```\r\n  2604031,vvccccdtvkiu,40e661b3ce2b,7b01896b5ef79d8092fd04556b4f4403,,2026-04-03T05:10:02,\r\n  2604032,vvgdctvftcrt,f23f0218e3bb,64d66d0d758090bc6ef159866e63fea6,,2026-04-03T05:10:02,\r\n  ```\r\n\r\nIf you want to use software tokens with Apps like Google Authenticator, you can\r\ncreate a QRcode provisioning in two EASY steps with the command line tool:\r\n - create the token for the user (without prefix PIN request):\r\n   multiotp -fastcreatenopin my_user\r\n - generate the provisioning QRcode: multiotp -qrcode my_user my_qrcode.png  \r\n \r\nYou can also create a user quickly with the prefix PIN request option based on\r\nthe default option set in your configuration: multiotp -fastcreate my_user  \r\n\r\nAnd of course, you can also force to create a user quickly with a requested\r\nprefix PIN: multiotp -fastcreatewithpin my_user\r\n\r\n\r\nWHAT IS THE PREFIX PIN OPTION ?\r\n===============================\r\nThe prefix PIN option is activated by default. Users will have to type their\r\nPIN + the displayed token. The prefix PIN option has no effect for mOTP tokens,\r\nand the users MUST NOT type their prefix PIN before the displayed token for\r\nmOTP tokens, as the prefix PIN is already used by the algorithm in order to\r\ngenerate the token.  \r\n\r\nStarting with version 4.3, it's now possible to use the synchronized AD/LDAP\r\npassword as a prefix instead of the static PIN. Please note that even with the\r\nAD/LDAP password as a prefix activated, the PIN used for mOTP tokens is still\r\nthe static PIN.  \r\n\r\nTo create a user quickly with the prefix PIN request option based on\r\nthe default option set in your configuration: multiotp -fastcreate my_user  \r\n\r\nTo create a user quickly without a prefix PIN request:\r\nmultiotp -fastcreatenopin my_user  \r\n \r\nTo create a user quickly with a requested prefix PIN:\r\nmultiotp -fastcreatewithpin my_user\r\n\r\n\r\nHOW THE LOCKOUT OF AN ACCOUNT IS WORKING ?\r\n==========================================\r\nTo prevent brute-force attack, an account is temporary locked for 300 seconds\r\nafter 3 unsuccessful trials.  \r\nAfter 6 unsuccessful trials, the account is definitely locked.  \r\n\r\nA user is unlocked by typing the following command line: \r\nmultiotp -unlock user\r\n\r\nA user can also unlock his account by typing two consecutive codes, \r\nseparated by a space (don't forget the prefix PIN/password if enabled).  \r\nIf prefix PIN is enabled, your PIN is 1234 and the two consecutive tokens are\r\n984501 and 348202, you will have to type \"1234984501 1234348202\" as the\r\npassword in order to unlock the account during authentication.  \r\n\r\nThe lockout parameters can be modified using these command lines:  \r\nmultiotp -config failure-delayed-time=60  \r\nmultiotp -config max-block-failures=12  \r\nmultiotp -config max-delayed-failures=10  \r\n\r\n\r\nHOW TO SELF-UNLOCK AN ACCOUNT ?\r\n===============================\r\nThe user can help itself by auto-deblocking its account like this:\r\nUsername: USERNAME\r\nPassword: [PREFIX PASSWORD] + [OTP] + [space] + [THE NEXT OTP]\r\n\r\n\r\nHOW TO DEBUG ?\r\n==============\r\nIn order to have debug information, you can use the -debug option. With this\r\noption, the debug information are saved in the file log/multiotp.log.  \r\nIf you want to see directly the debug information on screen, add the\r\n-display-log and an output of the debug information will be done on screen too.\r\n\r\nIn order to enable the debug mode permanently without using the option, you can\r\ndo that like this: multiotp -config debug=1\r\n\r\nThe same thing can be done for a permanent display of the debug information on\r\nthe screen without using the option: multiotp -config display-log=1\r\n\r\n\r\nHOW TO INSTALL THE MULTIOTP WEB SERVICE UNDER WINDOWS ?\r\n=======================================================\r\nInstalling the multiOTP web service is VERY easy. Simply run the\r\nwebservice_install script. Nginx configuration file will be created,\r\nfirewall rules will be adapted and the service will be installed and started.\r\nThe service is called multiOTPservice and is listening on port 8112 (http)\r\nand on port 8113 (https).\r\n\r\n\r\nHOW TO INSTALL THE MULTIOTP RADIUS SERVER UNDER WINDOWS ?\r\n=========================================================\r\nInstalling the multiOTP radius service is VERY easy too. Simply run the\r\nradius_install script. The etc/raddb/modules/multiotp file will be created,\r\nfirewall rules will be adapted and the service will be installed and started.\r\nThe service is called multiOTPradius and the secret is multiotpsecret for any\r\nclient including 127.0.0.1.\r\n\r\n\r\nCONFIGURING MULTIOTP WITH TEKRADIUS OR TEKRADIUS LT UNDER WINDOWS\r\n=================================================================\r\nTekRADIUS supports a Default Username to be used when a matching user\r\nprofile cannot be found for an incoming RADIUS authentication request.\r\nSo a quick and easy way is to create in the TekRADIUS Manager a User\r\nnamed 'Default' that belongs to the existing 'Default' Group.\r\nThen add to this Default user the following attribute :\r\nCheck  External-Executable  C:\\multitop\\multiotp.exe %ietf|1% %ietf|2% -chap-challenge=%ietf|60% -chap-password=%ietf|3% -ms-chap-challenge=%msoft|11% -ms-chap-response=%msoft|1% -ms-chap2-response=%msoft|25%\r\n\r\nSome values can go back to TekRADIUS:\r\n\r\na) Set the right format options for TekRADIUS:\r\n   multiotp -config radius-reply-attributor=\"=\" radius-reply-separator=\"crlf\"\r\n   \r\nb) Set multiOTP to send back to TekRADIUS the clear (non encrypted) authentication:\r\n   multiotp -config clear-otp-attribute=\"ietf|2\"\r\n\r\nc) Set multiOTP to send back to TekRADIUS the group of the authenticated user:\r\n   multiotp -config group-attribute=\"ietf|11\"\r\n\r\n\r\nEMAIL CONFIGURATION\r\n=========================================================\r\nIf you want to be able to send OTP by email, you will have to activate it:\r\nmultiotp -config email-code-allowed=1\r\n\r\nInstalling the multiOTP radius service is VERY easy too. Simply run the\r\nradius_install script. The etc/raddb/modules/multiotp file will be created,\r\nfirewall rules will be adapted and the service will be installed and started.\r\nThe service is called multiOTPradius and the secret is multiotpsecret for any\r\nclient including 127.0.0.1.\r\n\r\n\r\nHOW TO INSTALL THE MULTIOTP WEB SERVICE UNDER LINUX ?\r\n=====================================================\r\nThe multiOTP web service is a simple web site. If you are under Linux and you\r\nare reading this document, you have for sure the necessary skill to configure\r\nyour favorite web server in order to have an URL that will launch the page\r\nmultiotp.server.php which is in the main folder of the multiOTP distribution.\r\n\r\nPlease check carefully the rights of the folders, as the multiOTP web service\r\nhas to write in the various subfolders.\r\n\r\n\r\nCONFIGURING MULTIOTP WITH FREERADIUS 2.X UNDER LINUX\r\n====================================================\r\nUsing the -request-nt-key option, NT_KEY: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX can\r\nnow be displayed (like with the same option used with ntlm_auth).\r\n\r\n1) Create a new module file called \"multiotp\" in etc/raddb/modules/ containing:  \r\n```\r\n    # Exec module instance for multiOTP (https://www.multiotp.net/).  \r\n    # for Linux  : replace '/path/to/multiotp' with the actual path to the multiotp.php file, including the full file name.\r\n    # for Windows: replace '/path/to' with the actual path to the multiotp.exe file (also with /), including the fulle file name.\r\n    exec multiotp {  \r\n        wait = yes  \r\n        input_pairs = request  \r\n        output_pairs = reply  \r\n        program = \"/path/to/multiotp '%{User-Name}' '%{User-Password}' -request-nt-key -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}\"  \r\n        shell_escape = yes  \r\n    }\r\n```\r\n\r\n2) In the configuration file called \"default\" in etc/raddb/sites-enabled/  \r\n```\r\n    a) Add the multiOTP handling  \r\n    #  \r\n    # Handle multiOTP (https://www.multiotp.net/) authentication.  \r\n    # This must be added BEFORE the first \"pap\" entry found in the file.  \r\n    multiotp  \r\n```\r\n\r\n```\r\n    b) Add the multiOTP authentication handling  \r\n    #  \r\n    # Handle multiOTP (https://www.multiotp.net/) authentication.  \r\n    # This must be added BEFORE the first \"Auth-Type PAP\" entry found in the file.  \r\n    Auth-Type multiotp {  \r\n        multiotp  \r\n    }  \r\n```\r\n\r\n```\r\n    c) Comment the first line containing only \"chap\"  \r\n    #chap is now handled by multiOTP  \r\n```\r\n\r\n```\r\n    d) Comment the first line containing only \"mschap\"  \r\n    #mschap is now handled by multiOTP  \r\n```\r\n\r\n3) In the configuration file called \"inner-tunnel\" in etc/raddb/sites-enabled/  \r\n    \r\n```\r\n    a) Add the multiOTP handling  \r\n    #  \r\n    # Handle multiOTP (https://www.multiotp.net/) authentication.  \r\n    # This must be added BEFORE the first \"pap\" entry found in the file.  \r\n    multiotp  \r\n```\r\n\r\n```\r\n    b) Add the multiOTP authentication handling  \r\n    #  \r\n    # Handle multiOTP (https://www.multiotp.net/) authentication.  \r\n    # This must be added BEFORE the first \"Auth-Type PAP\" entry found in the file.  \r\n    Auth-Type multiotp {  \r\n        multiotp  \r\n    }  \r\n```\r\n\r\n```\r\n    c) Comment the first line containing only \"chap\"  \r\n    #chap is now handled by multiOTP  \r\n```\r\n\r\n```\r\n    d) Comment the first line containing only \"mschap\"  \r\n    #mschap is now handled by multiOTP  \r\n```\r\n\r\n4) In the configuration file called \"policy.conf\" in etc/raddb/  \r\n   Add the multiOTP authorization policy  \r\n```\r\n    #  \r\n    # Handle multiOTP (https://www.multiotp.net/) authorization policy.  \r\n    # This must be added just before the last \"}\"  \r\n    multiotp.authorize {  \r\n        if (!control:Auth-Type) {  \r\n            update control {  \r\n                Auth-Type := multiotp  \r\n            }  \r\n        }  \r\n    }  \r\n```\r\n\r\n5) In the configuration file called \"radiusd.conf\" in etc/raddb/  \r\n   Depending which port(s) and/or ip address(es) you want to listen, change\r\n   the corresponding ipaddr and port parameters  \r\n\r\n6) In the configuration file called \"clients.conf\" in etc/raddb/  \r\n   Add the clients IP, mask and secret that you want to authorize.  \r\n```\r\n    #  \r\n    # Handle multiOTP (https://www.multiotp.net/) for some clients.  \r\n    client 0.0.0.0 {  \r\n        netmask = 0  \r\n        secret = multiotpsecret  \r\n    }  \r\n```\r\n   \r\n7) Now, to see what's going on, you can:\r\n   - stop the service : /etc/init.d/freeradius stop\r\n   - launch the FreeRADIUS server in debug mode : /usr/sbin/freeradius -X\r\n   - try to make some authentication requests\r\n\r\n8) When you have checked that everything works well:\r\n   - stop the debug mode (CTRL + C)\r\n   - restart the service /etc/init.d/freeradius restart\r\n\r\nSome values can go back to FreeRADIUS:\r\n\r\n * Set the right format options for FreeRADIUS:  \r\n   multiotp -config radius-reply-attributor=\" += \" radius-reply-separator=\",\"\r\n   \r\n * Set multiOTP to send back to FreeRADIUS the group of the authenticated user:  \r\n   multiotp -config group-attribute=\"Filter-Id\"  \r\n\r\n\r\nCONFIGURING MULTIOTP WITH FREERADIUS 3.X UNDER LINUX\r\n====================================================\r\nSource: https://wiki.freeradius.org/guide/multiOTP-HOWTO\r\n\r\nmultiOTP tokens will work with any type of PAP/CHAP/MS-CHAP/MS-CHAPv2 based authentication, including EAP-TTLS-PAP. With the correct OS/Supplicant software tokens can be used for 802.1X authentication and well as for standard PAP/CHAP/MS-CHAP/MS-CHAPv2 authentication (just make the changes described in the inner server). This guide closely follows the NTLM Auth with PAP HOWTO but with a little extra validation.\r\n\r\nNT_KEY generation is also supported using the -request-nt-key option (like for ntlm_auth --request-nt-key option), which is needed in order to enable VPN (PPTP + MPPE) with MS-CHAP/MS-CHAPv2.\r\n\r\nBefore starting or asking for help\r\n- Make sure the otp script is executable chmod +x /path/to/multiotp.php\r\n- Verify multiotp is setup correctly by calling the script from the commandline with the appropriate arguments\r\n\r\n1) Create '/etc/freeradius/3.0/mods-available/multiotp' and add the following, this will create a new instance of the exec module:\r\n```\r\n# Exec module instance for multiOTP\r\n# Replace '/path/to' with the actual path to the multiotp.php file\r\nexec multiotp {\r\n        wait = yes\r\n        input_pairs = request\r\n        output_pairs = reply\r\n\t\tprogram = \"/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}'\"\t\t\r\n        shell_escape = yes\r\n}\r\n```\r\n\r\n2) Enable multiotp module by creating a symbolic link\r\n```\r\nln -s /etc/freeradius/3.0/mods-available/multiotp /etc/freeradius/3.0/mods-enabled/multiotp\r\n```\r\n\r\n3) Copy /etc/freeradius/3.0/mods-available/mschap to /etc/freeradius/3.0/mods-available/multiotpmschap. Change the following line in multiotpmschap:\r\n```\r\n\"mschap {\"\r\n```\r\nto\r\n```\r\n\"mschap multiotpmschap {\"\r\n```\r\n\r\nAlso change ntlm_auth variable:\r\n```\r\nntlm_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}'\"\r\n```\r\n\r\n4) Enable multiotpmschap module by creating a symbolic link\r\n```\r\nln -s /etc/freeradius/3.0/mods-available/multiotpmschap /etc/freeradius/3.0/mods-enabled/multiotpmschap\r\n```\r\n\r\n5) Edit /etc/freeradius/3.0/mods-available/perl file. Change the following line :\r\n```\r\nfilename =\r\n```\r\nto\r\n```\r\nfilename = /path/to/multiotp/scripts/multiotp.pl\r\n```\r\n\r\nSince 5.8.3.0 and FreeRADIUS 3.0.18, set the perl flags to -U\r\n```\r\nperl_flags = \"-U\"\r\n```\r\n\r\n6) Enable perl module by creating a symbolic link\r\n```\r\nln -s /etc/freeradius/3.0/mods-available/perl /etc/freeradius/3.0/mods-enabled/perl\r\n```\r\n\r\n7)If necessary change multiOTP path in the multiOTP perl file scripts/multiotp.pl\r\n```\r\nmy $output=`/usr/local/bin/multiotp/multiotp.php -base-dir='/usr/local/bin/multiotp/' \"$multiotp_\r\n```\r\nto\r\n\r\n```\r\nmy $output=`/path/to/multiotp.php -base-dir='/path/to/multiotp/' \"$multiotp_\r\n```\r\n\r\n\r\n7) Create /etc/freeradius/3.0/policy.d/multiotp file and add the following to override the authorize method of the exec module:\r\n```\r\n# Change to a specific prefix if you want to deal with normal PAP authentication as well as OTP\r\n# e.g. \"multiotp_prefix = 'otp:'\"\r\nmultiotp_prefix = ''\r\nmultiotp.authorize {\r\n   # This test force multiOTP for any MS-CHAP(v2),CHAP and PAP attempt\r\n    if (control:Auth-Type == mschap) {\r\n          update control {\r\n                  Auth-Type := multiotpmschap\r\n          }\r\n    }\r\n    elsif (control:Auth-Type == chap) {\r\n          update control {\r\n                  Auth-Type := multiotp\r\n          }\r\n    }\r\n    elsif (!control:Auth-Type) {\r\n        update control {\r\n            Auth-Type := multiotp\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n8) Enable files and add perl just after files, in the authorize section of /etc/freeradius/3.0/sites-available/default. Add the following lines:\r\n...\r\n    files\r\n```\r\n    perl #multiotp\r\n    if (ok || updated) { #multiotp\r\n        update control { #multiotp\r\n           Auth-Type := Perl #multiotp\r\n           Client-Shortname = \"%{Client-Shortname}\" #multiotp\r\n           Packet-Src-IP-Address = \"%{Packet-Src-IP-Address}\" #multiotp\r\n        } #multiotp\r\n    } #multiotp\r\n```\r\n\r\nAfter logintime add the following line :\r\n...\r\n\texpiration\r\n\tlogintime\r\n```\r\n    # Handle multiotp authentication\r\n    multiotp\r\n```\r\n\r\n9) Add a call to multiotp before the pap module in authenticate section of /etc/freeradius/3.0/sites-available/default. Add the following lines:\r\n...\r\nauthenticate {\r\n```\r\nAuth-Type multiotp {\r\n    multiotp\r\n} #multiotp\r\nAuth-Type multiotpmschap {\r\n    multiotpmschap\r\n} #multiotpmschap\r\nAuth-Type Perl { #multiotp\r\n    perl #multiotp\r\n} #multiotp\r\n```\r\n\r\n10) Add a call to perl in accounting section of /etc/freeradius/3.0/sites-available/default. Add the following lines:\r\n...\r\naccounting {\r\n```\r\n    perl #multiotp\r\n```\r\n\r\n11) Enable multiotp, in the authorize section of /etc/freeradius/3.0/sites-available/inner-tunnel. Add the following lines:\r\n\r\nAfter logintime add the following line :\r\n...\r\n\texpiration\r\n\tlogintime\r\n```\r\n    # Handle multiotp authentication\r\n    multiotp\r\n```\r\n\r\n...\r\nauthenticate {\r\n```\r\n    Auth-Type multiotp {\r\n        multiotp\r\n    } #multiotp\r\n    Auth-Type multiotpmschap {\r\n        multiotpmschap\r\n    } #multiotpmschap\r\n    Auth-Type Perl { #multiotp\r\n        perl #multiotp\r\n    } #multiotp\r\n\t\r\n```\r\n\r\n\r\n12) Start the server up in debug mode radiusd -X and test authentication\r\n\r\n\r\nHOW TO CONFIGURE MULTIOTP TO SYNCHRONIZED THE USERS FROM AN ACTIVE DIRECTORY ?\r\n==============================================================================\r\n1) Decide if you want that by default, created users need to type a prefix PIN (1|0):  \r\n   multiotp -config default-request-prefix-pin=1\r\n   \r\n2) Decide if you want that by default, created users need to type their\r\n   Active Directory password instead of PIN (1|0):  \r\n   multiotp -config default-request-ldap-pwd=1\r\n\r\n3) Set the AD/LDAP server type (1=Active Directory | 2=standard LDAP):  \r\n   multiotp -config ldap-server-type=1\r\n\r\n4) Set the user CN identifier (sAMAccountName, eventually userPrincipalName):  \r\n   multiotp -config ldap-cn-identifier=\"sAMAccountName\"\r\n\r\n5) Set the group CN identifier (sAMAccountName for Active Directory):  \r\n   multiotp -config ldap-group-cn-identifier=\"sAMAccountName\"\r\n\r\n6) Set the group attribute:  \r\n   multiotp -config ldap-group-attribute=\"memberOf\"\r\n\r\n7) Decide if you want to use by default an SSL connection or not (0|1):  \r\n   multiotp -config ldap-ssl=0\r\n   \r\n8) Set the default port (389=regular | 636=SSL connection):  \r\n   multiotp -config ldap-port=389\r\n   \r\n9) Set the Active Directory server(s), comma separated:  \r\n   multiotp -config ldap-domain-controllers=my.srv.com,ldaps://12.13.14.15:636  \r\n   (you can define more than one server, and you can also use a SSL connection\r\n    only for one server, on a specific port)\r\n   \r\n10) Set the Base DN:  \r\n    multiotp -config ldap-base-dn=\"DC=demo,DC=multiotp,DC=net\"  \r\n    (on a Microsoft Windows Server, the different values of the base DN of the\r\n     domain can be displayed using the command ECHO %USERDNSDOMAIN%, and the\r\n     result will be something like DEMO.MULTIOTP.NET)\r\n\r\n11) Set the Bind DN (which is the account used to connect to the AD/LDAP):  \r\n    multiotp -config ldap-bind-dn=\"CN=sync,CN=Users,DC=demo,DC=multiotp,DC=net\"  \r\n    (on a Microsoft Windows Server, the bind DN of the user can be displayed\r\n     using the command dsquery user -name sync, and the result will be\r\n     something like \"CN=sync,CN=Users,DC=demo,DC=multiotp,DC=net\")\r\n   \r\n12) Set the password of the user used to search in the Active Directory:  \r\n    multiotp -config ldap-server-password=\"password_of_my_ldap_user\"\r\n   \r\n13) Set in which groups users must be in the Active Directory in order to be added:  \r\n    multiotp -config ldap-in-group=\"VPNuser,dialin\"\r\n   \r\n14) If needed, set in which groups users must be in the Active Directory\r\n    in order to be whitelisted with a special without2fa token:\r\n    multiotp -config ldap-without2fa-in-group=\"Without2FA\"\r\n   \r\n15) If you prefer a 2FA opt-in approach (priority to 2FA membership)\r\n    instead of the standard 2FA opt-out approach (priority to Without2FA membership):\r\n    multiotp -config ldap-2fa-opt-in=1\r\n   \r\n16) Set the network timeout  \r\n    multiotp -config ldap-network-timeout=10\r\n   \r\n17) Set the transaction time limit  \r\n    multiotp -config ldap-time-limit=30\r\n   \r\n18) (EXPERT ONLY) If needed, you can change the LDAP filter.\r\n    By default, the LDAP filter for Active Directory is :\r\n      \"(\u0026(objectClass=user)(samaccounttype=805306368)(objectCategory=person)({cn_identifier}={username}))\r\n   \r\n19) Activate the AD/LDAP support (0|1):  \r\n    multiotp -config ldap-activated=1\r\n   \r\n20) Let's go for an AD/LDAP users synchronisation !\r\n    (users removed or deactivated in the AD/LDAP are deactivated in multiOTP)\r\n    multiotp -debug -display-log -ldap-users-sync\r\n    \r\nDON'T FORGET TO SCHEDULE A SCRIPT THAT WILL DO THE USERS SYNCHRONIZATION REGULARY!\r\n\r\n\r\nHOW TO CONFIGURE MULTIOTP TO SYNCHRONIZED THE USERS FROM A STANDARD LDAP ?\r\n==========================================================================\r\n1) Decide if you want that by default, created users need to type a prefix PIN (1|0):\r\n   multiotp -config default-request-prefix-pin=1\r\n   \r\n2) Decide if you want that by default, created users need to type their\r\n   LDAP password instead of PIN (1|0):\r\n   multiotp -config default-request-ldap-pwd=1\r\n\r\n3) Set the AD/LDAP server type (1=Active Directory | 2=standard LDAP):\r\n   multiotp -config ldap-server-type=2\r\n\r\n4) Set the user CN identifier (uid for standard LDAP):\r\n   multiotp -config ldap-cn-identifier=\"uid\"\r\n\r\n5) Set the group CN identifier (cn for standard LDAP):\r\n   multiotp -config ldap-group-cn-identifier=\"cn\"\r\n\r\n6) Set the group attribute:\r\n   multiotp -config ldap-group-attribute=\"memberOf\"\r\n\r\n7) Decide if you want to use by default an SSL connection or not (0|1):\r\n   multiotp -config ldap-ssl=0\r\n   \r\n8) Set the default port (389=regular | 636=SSL connection):\r\n   multiotp -config ldap-port=389\r\n   \r\n9) Set the LDAP server(s), comma separated:\r\n   multiotp -config ldap-domain-controllers=my.srv.com,ldaps://12.13.14.15:636\r\n   (you can define more than one server, and you can also use a SSL connection\r\n    only for one server, on a specific port)\r\n   \r\n10) Set the Base DN:\r\n    multiotp -config ldap-base-dn=\"dc=demo,dc=multiotp,dc=net\"\r\n\r\n11) Set the Bind DN (which is the account used to connect to the AD/LDAP):\r\n    multiotp -config ldap-bind-dn=\"uid=sync,cn=users,dc=demo,dc=multiotp,dc=net\"\r\n   \r\n12) Set the password of the user used to search in the LDAP directory:\r\n    multiotp -config ldap-server-password=\"password_of_my_ldap_user\"\r\n   \r\n13) Set in which groups users must be in the LDAP directory in order to be added:  \r\n    multiotp -config ldap-in-group=\"VPNuser,dialin\"\r\n   \r\n14) If needed, set in which groups users must be in the LDAP directory\r\n    in order to be whitelisted with a special without2fa token:\r\n    multiotp -config ldap-without2fa-in-group=\"Without2FA\"\r\n   \r\n15) If you prefer a 2FA opt-in approach (priority to 2FA membership)\r\n    instead of the standard 2FA opt-out approach (priority to Without2FA membership):\r\n    multiotp -config ldap-2fa-opt-in=1\r\n   \r\n16) Set the network timeout\r\n    multiotp -config ldap-network-timeout=10\r\n   \r\n17) Set the transaction time limit\r\n    multiotp -config ldap-time-limit=30\r\n\r\n18) (EXPERT ONLY) If needed, you can change the LDAP filter.\r\n    By default, the LDAP filter for standard LDAP is :\r\n      \"(\u0026(|(objectClass=posixAccount)(objectClass=user))({cn_identifier}={username}))\"\r\n    You can use the following placeholders: {cn_identifier}, {username}, and {groups_filtering}\r\n    multiotp -config ldap-filter=\"(\u0026(|(objectClass=posixAccount)(objectClass=user))({cn_identifier}={username}))\"\r\n\r\n19) Activate the AD/LDAP support (0|1):\r\n    multiotp -config ldap-activated=1\r\n   \r\n20) Let's go for an AD/LDAP users synchronisation !\r\n    (users removed or deactivated in the AD/LDAP are deactivated in multiOTP)\r\n    multiotp -debug -display-log -ldap-users-sync\r\n\r\nDON'T FORGET TO SCHEDULE A SCRIPT THAT WILL DO THE USERS SYNCHRONIZATION REGULARY!\r\n\r\n\r\nHOW TO CONFIGURE MULTIOTP TO USE THE CLIENT/SERVER FEATURE ?\r\n============================================================\r\nA) On the server\r\n1) Install the multiOTP web service on the authentication server side. If you\r\n   are using the unmodified included installer to install it under Windows,\r\n   the URL for the multiOTP web service is http://ip.address.of.server:8112\r\n   The web service script installer is called webservice_install.cmd.\r\n2) Set the shared secret key you will use to encode the data between the\r\n   server and the client: multiotp -config server-secret=MySharedSecret\r\n   (this command line will change the configuration file config/multiotp.ini)\r\n3) If you want to allow the client to cache the data on its side, set the\r\n   options accordingly (enable the cache and define the lifetime of the cache):\r\n   multiotp -config server-cache-level=1 server-cache-lifetime=15552000\r\n   (this command line will change the configuration file config/multiotp.ini)\r\n4) Create your users on the server using the CLI or the web GUI interface. If\r\n   you are using the unmodified included installer to install it under Windows,\r\n   the URL for the multiOTP web service is http://ip.address.of.server:8112\r\n\r\nB) On the client(s)\r\n1) Set the shared secret key you will use to encode the data between the\r\n   client and the server: multiotp -config server-secret=MySharedSecret\r\n   (this command line will change the configuration file config/multiotp.ini)\r\n2) If you want to have cache support (if allowed by the multiOTP web service),\r\n   set the option accordingly: multiotp -config server-cache-level=1\r\n   (this command line will change the configuration file config/multiotp.ini)\r\n3) Define the timeout after which you will switch to the next server(s), and\r\n   on the local cache if no server available: multiotp -config server-timeout=3\r\n   (this command line will change the configuration file config/multiotp.ini)\r\n4) Last but not least, define the server(s) you want to connect with:\r\n   multiotp -config server-url=http://ip.address.of.server:8112;http://url2\r\n   (this command line will change the configuration file config/multiotp.ini)\r\n   If you want to connect with a commercial multiOTP appliance, the URL is\r\n   https://ip.address.of.commercial.multiotp.server\r\n5) Check your installation on the client by typing\r\n   multiotp -display-log -log -debug \"user\" \"token\", where \"user\" is an\r\n   existing user and \"token\" is the generated token for this user.\r\n   If you have created a user with a prefix PIN, don't forget to type the prefix\r\n   PIN before the displayed token.\r\n   Example without a prefix PIN: multiotp test 457863\r\n   Example with the \"1234\" prefix PIN: multiotp test 1234457863\r\n\r\n   \r\nHOW TO INSTALL A LOCAL ONLY STRONG AUTHENTICATION ON A WINDOWS MACHINE ?\r\n========================================================================\r\n1) Install multiOTPCredentialProvider, which contains also multiOTP inside.\r\n   It works with Windows 7/8/8.1/10/11/2012(R2)/2016/2019/2022 in 64 bits.\r\n   (https://download.multiotp.net/credential-provider/)\r\n2) During the installation, specify the folder on the client where the\r\n   multiotp.exe file and folders must be installed and configured.\r\n3) In the wizard, leave the URL of the multiOTP server(s) empty.\r\n4) You can also choose to require a strong authentication only for RDP.\r\n5) When you are on the test page, open a command prompt in the folder where\r\n   multiOTP is now installed and create a new local user as explained above.\r\n6) If the test is successful, the Credential Provider is installed.\r\n7) To disable the Credential Provider, uninstall it from Windows,\r\n   or execute multiOTPCredentialProvider-unregister.reg\r\n\r\nHOW TO INSTALL A CENTRALIZED 2FA SERVER FOR WINDOWS DESKTOPS OR RDP LOGIN ?\r\n===========================================================================\r\n1) Install a client/server multiOTP environment like explained above.\r\n2) On each client, install multiOTPCredentialProvider .\r\n   It works with Windows 7/8/8.1/10/11/2012(R2)/2016/2019/2022 in 64 bits.\r\n   (https://download.multiotp.net/credential-provider/)\r\n3) During the installation, specify the folder on the client where the\r\n   multiotp.exe file and folders must be installed and configured.\r\n4) In the wizard, type the URL of the multiOTP server(s).\r\n5) You can also choose to require a strong authentication only for RDP.\r\n6) On the test page, test your account to be sure that everything works.\r\n7) If the test is successful, the Credential Provider is installed.\r\n8) To disable the Credential Provider, uninstall it from Windows,\r\n   or execute multiOTPCredentialProvider-unregister.reg\r\n\r\n\r\nADDING 2FA WITH MULTIOTP TO THE REMOTE DESKTOP WEB ACCESS (RDWEB) ON WINDOWS\r\n============================================================================\r\nFor these instructions, we assume that multiOTP is installed in the\r\nfolder C:\\multiOTP\r\nAfter Remote Desktop Web Access installation, RDWeb files are stored in the\r\nfolder C:\\Windows\\Web\\RDWeb\\\r\n\r\n1) Edit the file C:\\Windows\\Web\\RDWeb\\Web.config, and add three lines right after\r\n   the appSettings block like this:\r\n```\r\n   \u003c?xml version=\"1.0\"?\u003e\r\n   \u003cconfiguration\u003e\r\n       \u003cappSettings\u003e\r\n           \u003c!-- multiOTP addon begin --\u003e\r\n           \u003cadd key=\"MultiOTPPathAndName\" value=\"C:\\\\multiOTP\\\\multiotp.exe\" /\u003e\r\n           \u003cadd key=\"OTPUsernameRegex\" value=\"^[0-9a-zA-Z]*$\" /\u003e\r\n           \u003cadd key=\"OTPRegex\" value=\"^[0-9]{6}$\" /\u003e\r\n           \u003c!-- multiOTP addon end --\u003e\r\n           ...\r\n```\r\n\r\n2) Edit the file C:\\Windows\\Web\\RDWeb\\Pages\\en-US\\login.aspx (en-US is for the\r\n   american english version of the page), and add three lines here:\r\n```\r\n   ...\r\n   \u003c% @Import Namespace=\"System.Web.Security.AntiXss\" %\u003e\r\n   \u003c!-- multiOTP addon begin --\u003e\r\n   \u003c% @Import Namespace=\"System.Diagnostics\" %\u003e\r\n   \u003c% @Import Namespace=\"System.Text.RegularExpressions\" %\u003e\r\n   \u003c% @Import Namespace=\"System.Configuration\" %\u003e\r\n   \u003c!-- multiOTP addon end --\u003e\r\n   \u003cscript language=\"C#\" runat=server\u003e\r\n   ...\r\n```\r\n\r\n3) Always in the same file login.aspx, add this line after Localizable Text:\r\n```\r\n   ...\r\n   // Localizable Text\r\n   //\r\n   // multiOTP addon begin\r\n  const string L_OTPLabel_Text = \"OTP:\";\r\n   // multiOTP addon end\r\n   const string L_DomainUserNameLabel_Text = \"Domain\\\\user name:\";\r\n   ...\r\n```\r\n\r\n4) Always in the same file login.aspx, at the end of the LoginPageLoadAsync()\r\n   method, add this line:\r\n```\r\n   ...\r\n       // multiOTP addon begin\r\n       if ( Request.Form[\"UserOTP\"] != null ) Session[\"UserOTP\"] = (string)Request.Form[\"UserOTP\"];\t\r\n       // multiOTP addon end\r\n   }\r\n\r\n   //\r\n   // Special case to handle 'ServerConfigChanged' error from Response's Location header.\r\n   //\r\n   try\r\n   ...\r\n```\r\n\r\n5) Always in the same file login.aspx, replace the method\r\n   SafeRedirect(strReturnUrlPage); with the following lines:\r\n```\r\n   ...\r\n   if ( HttpContext.Current.User.Identity.IsAuthenticated == true )\r\n   {\r\n       // multiOTP addon begin\r\n       string strOTPUsername = HttpContext.Current.User.Identity.Name;\r\n       if (strOTPUsername.Split('\\\\').Length \u003e 1) strOTPUsername = strOTPUsername.Split('\\\\')[1];\r\n       if (strOTPUsername.Split('@').Length \u003e 0) strOTPUsername = strOTPUsername.Split('@')[0];\r\n\r\n       bool bOTPAuthenticated = false;\r\n\r\n       if (Session[\"UserOTP\"] != null)\r\n       {\r\n         string strOTP = (string)Session[\"UserOTP\"];\r\n         if (!string.IsNullOrEmpty(strOTP) \u0026\u0026 Regex.Match(strOTP,ConfigurationManager.AppSettings[\"OTPRegex\"]).Success \u0026\u0026 !string.IsNullOrEmpty(strOTPUsername) \u0026\u0026 Regex.Match(strOTPUsername,ConfigurationManager.AppSettings[\"OTPUsernameRegex\"]).Success)\r\n         {\r\n           ProcessStartInfo oOTPStartInfo = new ProcessStartInfo();\r\n           oOTPStartInfo.FileName = ConfigurationManager.AppSettings[\"MultiOTPPathAndName\"];\r\n           oOTPStartInfo.Arguments = strOTPUsername + \" \" + strOTP;\r\n           oOTPStartInfo.CreateNoWindow = true;\r\n           oOTPStartInfo.UseShellExecute = true;\r\n           Process oOTP = Process.Start(oOTPStartInfo);\r\n           oOTP.WaitForExit();\r\n           bOTPAuthenticated = (oOTP.ExitCode == 0);\r\n         }\r\n       }\r\n\r\n       if(bOTPAuthenticated)\r\n       {\r\n         if (String.IsNullOrEmpty(strReturnUrlPage))\r\n           Response.Redirect(\"default.aspx\");\r\n         else\r\n           SafeRedirect(strReturnUrlPage);\r\n       }\r\n       else\r\n       {\r\n         FormsAuthentication.SignOut(); \r\n         bFailedLogon = true;\r\n         if (bFailedAuthorization) bFailedAuthorization = false; \r\n       }\r\n       // multiOTP addon end\r\n       // multiOTP remove begin\r\n       // SafeRedirect(strReturnUrlPage);\r\n       // multiOTP remove end\r\n   }\r\n   ...\r\n```\r\n\r\n6) Always in the same file login.aspx, after the \"UserPass\" input, add the\r\n   following lines:\r\n```\r\n   ...\r\n           \u003clabel\u003e\u003cinput id=\"UserPass\" name=\"UserPass\" type=\"password\" class=\"textInputField\" runat=\"server\" size=\"25\" autocomplete=\"off\" /\u003e\u003c/label\u003e\r\n           \u003c/td\u003e\r\n       \u003c/tr\u003e\r\n       \u003c/table\u003e\r\n   \u003c/td\u003e\r\n   \u003c/tr\u003e\r\n\r\n   \u003c!-- multiOTP addon begin --\u003e\r\n   \u003ctr\u003e\r\n     \u003ctd\u003e\r\n       \u003ctable width=\"300\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"\u003e\r\n         \u003ctr\u003e\r\n           \u003ctd width=\"130\" align=\"right\"\u003e\u003c%=L_OTPLabel_Text%\u003e\u003c/td\u003e\r\n           \u003ctd width=\"7\"\u003e\u003c/td\u003e\r\n           \u003ctd align=\"right\"\u003e\r\n             \u003clabel\u003e\u003cinput id=\"UserOTP\" name=\"UserOTP\" type=\"password\" class=\"textInputField\" runat=\"server\" size=\"23\" autocomplete=\"off\" /\u003e\u003c/label\u003e\r\n           \u003c/td\u003e\r\n         \u003c/tr\u003e\r\n       \u003c/table\u003e\r\n     \u003c/td\u003e\r\n   \u003c/tr\u003e\r\n   \u003c!-- multiOTP addon end --\u003e\r\n   ...\r\n```\r\n\r\n7) Be sure that that the RDWeb Application Pool Account has read/write access\r\n   to the installed multiOTP folder and subfolder (C:\\multiOTP)\r\n\r\n8) In order to have some logs, you will have to enable the log option in the\r\n   multiotp.ini (C:\\multiOTP\\config\\multiotp.ini):\r\n```\r\n   ...\r\n   log=1\r\n   ...\r\n```\r\n\r\n9) Be sure to restart IIS on your Windows RDWeb server\r\n\r\n\r\nSAME WINDOWS GENERIC ACCOUNT WITH MULTIPLE TWO-FACTOR AUTHENTICATION ACCOUNTS \r\n=============================================================================\r\nIf you have to share the same generic Windows account, but you still need\r\n2FA authentication for each user (like for a specific industrial computer in a\r\n24/7/365 process), you can do the following configuration:\r\n1) Create (or sync with AD/LDAP) a multiOTP account for the generic account\r\n2) In multiOTP, set the description of the generic account to \"multi_account\"\r\n   (if the account is synced by AD/LDAP, put the description in the AD/LDAP)\r\n3) Create (or sync with AD/LDAP) the accounts of each users\r\n4) On the login screen of the computer, use the following credentials:\r\n   - Account : generic Windows account\r\n   - Password : password of the generic Windows account\r\n   - OTP : [username of the specific user][space][OTP code of the specific user]\r\n\r\n\r\nUSING MULTIOTP ON LINUX FOR SSH LOGIN\r\n=====================================\r\n0) Configure OpenSSH and PAM\r\n   Configure your OpenSSH server to request the PassCode (PinCode+OTP)\r\n   to the radius server. For this purpose we will use a radius PAM agent.\r\n\r\n1) PAM configuration for OpenSSH server:\r\n   Edit the file /etc/pam.d/sshd with this configuration.\r\n   Comment the username/password line and add the PAM library.\r\n   Be sure you have the PAM radius library.\r\n```\r\n   #auth required pam_stack.so service=system-auth\r\n   auth required /lib/security/pam_radius_auth.so\r\n```\r\n\r\n2) Specify the Radius Server.\r\n   Create and edit a file called server in /etc/raddb\r\n   with the Radius IP,port and the shared secret key.\r\n```\r\n   #Server[:port]  shared_secret      timeout (s)\r\n   127.0.0.1       secret             1\r\n   10.1.23.1:1812  myfirstpass        6\r\n```\r\n\r\n3) OpenSSH server (radiusd daemon) configuration:\r\n   Edit /etc/sshd/sshd_config and be sure PAM is\r\n   enabled and keyboard-interactive AuthN support.\r\n```\r\n   UsePAM yes\r\n   PasswordAuthentication no\r\n   ChallengeResponseAuthentication yes\r\n```\r\n\r\n4) Stop and start the OpenSSH server\r\n```\r\n   /etc/init.d/sshd stop\r\n   /etc/init.d/sshd start\r\n```\r\n\r\n5) You are now ready to test your login SSH with an software OTP :-)\r\n\r\n\r\nHOW TO BUILD A RASPBERRY PI STRONG AUTHENTICATION SERVER ?\r\n==========================================================\r\n0) If you want to download a multiOTP Raspberry Pi image ready to use, follow this URL:  \r\n   https://download.multiOTP.net/raspberry/\r\n   \r\n```\r\n   Nano-computer name: multiotp\r\n   IP address: 192.168.1.44 (netmask: 255.255.255.0, default gateway: 192.168.1.1)\r\n   Username: pi\r\n   Password: raspberry\r\n```\r\n   \r\n   You can now flash the SD (check point 3) and 4) if needed), put the SD Card\r\n   into the Raspberry Pi and boot it. You can go directly to point 15)\r\n   \r\n1) If you want to use a battery backed up Real Time Clock, install it now in your\r\n   Raspberry Pi, the drivers for these models are included in the package:\r\n   - https://afterthoughtsoftware.com/products/rasclock\r\n   - http://www.cjemicros.co.uk/micros/products/rpirtc.shtml\r\n   - https://www.robotshop.com/ca/en/elecrow-ds3231-high-precision-rtc-clock-module-raspberry-pi-b.html\r\n   - https://learningdevelopments.co.nz/products/rtc-clock-module-for-raspberry-pi\r\n   \r\n2) Download the last image of Raspbian to be flashed  \r\n   http://downloads.raspberrypi.org/raspbian_latest (currently 2017-09-07-raspbian-stretch.zip)\r\n\r\n3) Format your SD Card using the SD Card Association's formatting tool  \r\n   https://www.sdcard.org/downloads/formatter_4/\r\n\r\n4) Flash the raw image using UNIX tool dd or Win32DiskImager for Windows\r\n   (http://sourceforge.net/projects/win32diskimager/files/latest/download).  \r\n   This should take about 10 minutes.\r\n\r\n5) Copy all files from multiotp/raspberry/boot-part to the root of the SD Card  \r\n   (it could overwrite some files like config.txt)\r\n\r\n6) When copy is done, eject the SD Card\r\n\r\n7) Connect the Raspberry Pi to the local network\r\n\r\n8) Put the SD card into the Raspberry Pi and boot it\r\n\r\n9) Login directly on your Raspberry Pi, or using SSH, with the default username \"pi\" and the password \"raspberry\"\r\n\r\n10) Launch the initial configuration by typing sudo raspi-config\r\n\r\n11) Choose the following options\r\n    1) Expand Filesystem\r\n    2) Change User Password\r\n    4) Internationalisation Options (if needed)\r\n    8) Advanced Options  \r\n       A2 Hostname (change the hostname to your favorite name, for example \"multiotp\")\r\n\r\n12) Select Finish and answer \"\u003cYes\u003e\" to reboot, ore type \"sudo reboot\"\r\n\r\n13) Login again directly (after about 30 seconds) on your Raspberry Pi, or using SSH, with the default username \"pi\" and your new password\r\n\r\n14) Type \"sudo /boot/install.sh\"  \r\n    Everything is done automatically (it will take about 35 minutes) and the Raspberry Pi is rebooted automatically\r\n\r\n15) The fixed IP address is set to 192.168.1.44, with a default gateway at 192.168.1.1  \r\n    To adapt the network configuration, edit the file /etc/network/interfaces\r\n\r\n16) Congratulations! You have now an open source and fully OATH compliant\r\n    strong two factors authentication server!  \r\n    Surf on http(s)://192.168.1.44 to use the basic interface (admin / 1234)\r\n\r\n17) The default radius secret is set to myfirstpass for the subnet 0.0.0.0/0.\r\n    To adapt the freeradius configuration, edit the file /etc/freeradius/clients.conf.\r\n\r\n\r\nLDAP FILTER CUSTOMIZATION\r\n=========================\r\nYou can customize your own LDAP filter. By default, the LDAP filter is empty.\r\nIn the LDAP filter, you can use the following placeholders:\r\n  {cn_identifier}, {username}, {groups_filtering}\r\n\r\n\r\nOPENSSL OPTIONS FOR LDAPS\r\n=========================\r\nYou can define how the certificate bundle is handled with the ldaptls_reqcert option.\r\nYou can define a custom cipher suite with the ldaptls_cipher_suite option.\r\n\r\n\r\nCOMPATIBLE CLIENTS APPLICATIONS AND DEVICES\r\n===========================================\r\nOpen source project multiOTPCredentialProvider which is based on MultiotpCPV2RDP\r\nfrom arcadejust and MultiOneTimePassword Credential Provider from Last Squirrel IT.\r\nIt works with Windows 7/8/8.1/10/11/2012(R2)/2016/2019/2022 in 64 bits.  \r\nThe Credential Provider is using directly a local version of multiOTP which\r\ncan be configured as a client of a centralized multiOTP server (with caching support)\r\n(https://github.com/multiOTP/multiOTPCredentialProvider)\r\n\r\nAny firewall can connect with the Radius protocol to a multiOTP radius server.\r\nOn advanced firewalls like the ZyXEL ZyWALL USG series, you can do some advanced\r\nthings like:\r\n- receiving a specific group for each multiOTP user (using the Filter-Id\r\noption). This is very useful to allow specific rules for some groups.\r\n- VPN connections can be set-up to have a strong authentication (X-Auth).\r\n- Strong Web authentication can be combined with specific firewall rules.\r\n\r\n\r\nEXTERNAL PACKAGES AND SOFTWARE USED\r\n```\r\n    barcode (MIT License)\r\n    Kreative Software\r\n    https://github.com/kreativekorp/barcode\r\n\r\n    CryptoJS (BSD New)\r\n    This product contains software provided by Jeff Mott\r\n    https://code.google.com/p/crypto-js/\r\n\r\n    FreeRADIUS / WinRADIUS for Windows (GPLv2)\r\n    This product contains software provided by FreeRADIUS team and its contributors.\r\n    https://freeradius.org/ - http://www.winradius.eu/\r\n\r\n    md5 JavaScript 2010 algorithm (BSD)\r\n    Joseph Myers, Paul Johnston, Greg Holt, Will Bond\r\n    https://www.myersdaily.org/joseph/javascript/md5-text.html\r\n\r\n    multiOTP Credential Provider\r\n    Credential Provider (64 bits) supporting Windows 7/8/8.1/10/11/2012(R2)/2016/2019/2022\r\n    SysCo / ArcadeJust / LastSquirrelIT \r\n    https://github.com/multiOTP/multiOTPCredentialProvider\r\n\r\n    Nginx (BSD)\r\n    This product contains software provided by Nginx, Inc. and its contributors.\r\n    https://nginx.org/\r\n    \r\n    nssm service helper (public domain)\r\n    https://nssm.cc/\r\n\r\n    NuSOAP - PHP Web Services Toolkit (LGPLv2.1)\r\n    NuSphere Corporation\r\n    http://sourceforge.net/projects/nusoap/\r\n\r\n    PHP (PHP License)\r\n    Voluntary contributions made by many individuals on behalf of the PHP Group.    \r\n    https://www.php.net/\r\n    \r\n    phpseclib (MIT License)\r\n    MMVI Jim Wigginton\r\n    http://phpseclib.sourceforge.net/\r\n\r\n    PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY (LGPLv2.1)\r\n    Scott Barnett - enhanced by SysCo\r\n    http://adldap.sourceforge.net/\r\n\r\n    PHP radius class (LGPLv3)\r\n    Andre Liechti\r\n    https://developer.sysco.ch/php/\r\n\r\n    PHP Syslog class (FREE \"AS IS\")\r\n    Andre Liechti\r\n    https://developer.sysco.ch/php/\r\n\r\n    status_bar.php (2010) (FREE \"AS IS\")\r\n    dealnews.com, Inc.\r\n    https://snipplr.com/view/29548\r\n\r\n    TCPDF (LGPLv3)\r\n    Nicola Asuni\r\n    https://tcpdf.org/\r\n\r\n    XML Parser Class (LGPLv3)\r\n    Adam A. Flynn - enhanced by SysCo\r\n    http://www.criticaldevelopment.net/xml/\r\n\r\n    XPertMailer package (LGPLv2.1)\r\n    Tanase Laurentiu Iulian\r\n    http://xpertmailer.sourceforge.net/\r\n\r\n    The source files can be downloaded at https://download.multiOTP.net/multiotp.zip\r\n```\r\n\r\n \r\nMULTIOTP PHP CLASS DOCUMENTATION\r\n================================\r\nHave a look into the source code if you want to know how to use it,\r\nand you may also check multiotp.cli.header.php which implements the class.\r\n\r\n\r\nMULTIOTP COMMAND LINE TOOL\r\n==========================\r\n\n``` \r\nmultiOTP 5.10.2.2 (2026-04-03)\n(c) 2010-2026 SysCo systemes de communication sa\nhttp://www.multiOTP.net   (you can try the [Donate] button ;-)\n\nmultiotp will check if the token of a user is correct, based on a specified\nalgorithm (currently Mobile-OTP (http://motp.sf.net), OATH/HOTP (RFC 4226) \nand OATH/TOTP (RFC 6238) are implemented). PSKC format supported (RFC 6030).\nSupported encryption methods are PAP and CHAP.\nYubico OTP format supported (44 bytes long, with prefixed serial number).\nSMS-code are supported (current providers: afilnet,aspsms,clickatell,\n                        clickatell2,ecall,intellisms,nexmo,nowsms,smseagle,\n                        smsgateway,swisscom,telnyx,custom,exec).\nSpecific SMS sender program supported by specifying exec as SMS provider.\n\nGoogle Authenticator base32_seed tokens must be of n*8 characters.\nGoogle Authenticator TOTP tokens must have a 30 seconds interval.\nAvailable characters in base32 are only ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\n\nTo quickly create a user, use the -fastcreate option with the name of the user.\nA quickly created user is compatible with Google Auth (30 seconds, 6 digits).\nDepending on the prefix PIN option (WHICH IS ENABLED BY DEFAULT), a prefix PIN\nwill be requested or not before the displayed token.\nIf the PIN is not given, it is generated randomly.\n\nTo quickly create a user without a prefix PIN request, use -fastcreatenopin\n\nTo quickly create a user with a prefix PIN request, use -fastcreatewithpin\n\nIf a token is locked (return code 24), you have to resync the token to unlock.\nRequesting an SMS token (put sms as the password), and typing the received\n token correctly will also unlock the token.\n\nThe check will return 0 for a correct token, and the other return code means:\n\nReturn codes:\n\n 0 OK: Token accepted \n 7 INFO: User requires a token \n 8 INFO: User can be authenticated without a token (WITHOUT2FA) \n 9 INFO: Access Challenge returned back to the client \n10 INFO: Access Challenge returned back to the client \n11 INFO: User successfully created or updated \n12 INFO: User successfully deleted \n13 INFO: User PIN code successfully changed \n14 INFO: Token has been resynchronized successfully \n15 INFO: Tokens definition file successfully imported \n16 INFO: QRcode successfully created \n17 INFO: UrlLink successfully created \n18 INFO: Static code request received \n19 INFO: Requested operation successfully done \n20 ERROR: User blacklisted \n21 ERROR: User doesn't exist \n22 ERROR: User already exists \n23 ERROR: Invalid algorithm \n24 ERROR: User locked (too many tries) \n25 ERROR: User delayed (too many tries, but still a hope in a few minutes) \n26 ERROR: This token has already been used \n27 ERROR: Resynchronization of the token has failed \n28 ERROR: Unable to write the changes in the file \n29 ERROR: Token doesn't exist \n30 ERROR: At least one parameter is missing \n31 ERROR: Tokens definition file doesn't exist \n32 ERROR: Tokens definition file not successfully imported \n33 ERROR: Encryption hash error, encryption key is not matching \n34 ERROR: Linked user doesn't exist \n35 ERROR: User not created \n36 ERROR: Token doesn't exist \n37 ERROR: Token already attributed \n38 ERROR: User is desactivated \n39 ERROR: Requested operation aborted \n40 ERROR: SQL query error \n41 ERROR: SQL error \n42 ERROR: They key is not in the table schema \n43 ERROR: SQL entry cannot be updated \n50 ERROR: QRcode not created \n51 ERROR: UrlLink not created (no provisionable client for this protocol) \n52 ERROR: HTML info not created \n58 ERROR: File is missing \n59 ERROR: Bad restore configuration password \n60 ERROR: No information on where to send SMS code \n61 ERROR: SMS code request received, but an error occurred during transmission \n62 ERROR: SMS provider not supported \n63 ERROR: This SMS code has expired \n64 ERROR: Cannot resent an SMS code right now \n65 ERROR: SMS code request not allowed \n66 ERROR: Email code request not allowed \n67 ERROR: No information on where to send Email code \n68 ERROR: Email code request received, but an error occurred during transmission \n69 ERROR: Failed to send email \n70 ERROR: Server authentication error \n71 ERROR: Server request is not correctly formatted \n72 ERROR: Server answer is not correctly formatted \n73 ERROR: Email SMTP server not defined \n79 ERROR: AD/LDAP connection error \n80 ERROR: Server cache error \n81 ERROR: Cache too old for this user, account autolocked \n82 ERROR: User not allowed for this device \n88 ERROR: Device is not defined as a HA slave \n89 ERROR: Device is not defined as a HA master \n90 ERROR: AD/LDAP authentication failed \n91 ERROR: Authentication failed (without2fa token not authorized here) \n92 ERROR: Authentication failed (bad password) \n93 ERROR: Authentication failed (time based token probably out of sync) \n94 ERROR: API request error \n95 ERROR: API authentication failed \n96 ERROR: Push authentication timeout \n97 ERROR: Push authentication denied \n98 ERROR: Authentication failed (wrong token length) \n99 ERROR: Authentication failed (and other possible unknown errors) \n\n\nUsage:\n\n PLEASE NOTE THAT BY DEFAULT, A PREFIX PIN IS REQUIRED.\n\n multiotp user [prefix PIN]OTP (check the OTP (with prefix PIN) of the user)\n multiotp -checkpam (to check with pam-script, using PAM_USER and PAM_AUTHTOK)\n\n multiotp -requiresms user (generate and send an SMS token to the user)\n multiotp user sms (send an SMS token to the user)\n\n multiotp user [-chap-id=0x..] -chap-challenge=0x... -chap-password=0x...\n   (the first byte of the chap-password value can contain the chap-id value)\n\n multiotp -fastcreate user [pin] (create a TOTP compatible token)\n multiotp -fastcreatenopin user (create a user without a prefix PIN)\n multiotp -fastcreatewithpin user [pin] (create a user with a prefix PIN)\n multiotp -createga user base32_seed [pin] (create Google Auth user with TOTP)\n multiotp -create user algo seed pin digits [pos|interval]\n multiotp -create -token-id user token-id pin\n\n  token-id: id of the previously imported token to attribute to the user\n      user: name of the user (should be the account name)\n      algo: available algorithms are mOTP, HOTP, TOTP, YubicoOTP and without2FA\n      seed: hexadecimal or base32 seed of the token\n       pin: private pin code of the user\n    digits: number of digits given by the token\n       pos: for HOTP algorithm, position of the next awaited event\n  interval: for mOTP and TOTP algorithms, token interval time in seconds\n\n multiotp -import tokens_definition_file [key|pass|key_file]\n   (auto-detect format)\n multiotp -import-csv csv_tokens_file.csv (tokens definition in a file)\n   (serial_number;manufacturer;algorithm;seed;digits;interval_or_event)\n multiotp -import-pskc pskc_tokens_file.pskc [key|pass|key_file]\n   (PSKC format, RFC 6030)\n multiotp -import-yubikey yubikey_traditional_format_log.csv (YubiKey)\n multiotp -import-dat importAlpine.dat (SafeWord/Aladdin/SafeNet tokens)\n multiotp -import-alpine-xml alpineXml.xml (SafeWord/Aladdin/SafeNet)\n multiotp -import-xml xml_tokens_definition_file.xml (old Feitian)\n multiotp -import-sql tokens_definition_file.sql (ZyXEL/Authenex)\n\n multiotp -iswithout2fa user (return 8 for WITHOUT2FA token, otherwise 7)\n\n multiotp -delete-token token\n\n multiotp -qrcode user png_file_name.png (only for TOTP and HOTP)\n multiotp -urllink user (only for TOTP and HOTP, generate provisioning URL)\n multiotp -htmlinfo user htlm_file_name.html (create file for one user) or \n multiotp -htmlinfo htlm_file_folder (to create all files)\n\n multiotp -scratchlist user (generate \u0026 display scratch passwords for the user)\n\n multiotp -resync [-status] user token1 token2 (two consecutive tokens)\n multiotp -update-pin user pin\n\n multiotp -assign-token user token-id (assign the token to the user)\n multiotp -remove-token user (remove the token assigned to the user)\n\n multiotp -default-dialin-ip-mask (set the default dialin IP mask)\n multiotp -dialin-ip-address user ip-address (set the user dialin IP address)\n multiotp -dialin-ip-mask user ip-address (set the user dialin IP mask)\n\n multiotp -[des]activate user\n multiotp -[un]lock user\n\n multiotp -delete user\n\n multiotp -user-info user\n\n multiotp -config option1=value1 option2=value2 ... optionN=valueN\n  options are    autoresync: [0|1] enable/disable autoresync during login\n      attributes-to-encrypt: specific attributes list to encrypt, must be\n                             surrounded by *, like '*token_seed*user_pin*'\n               backend-type: backend storage type (files|mysql|pgsql)\n challenge-response-enabled: [0|1] enable/disable Challenge-Response\n        clear-otp-attribute: attribute to return for the clear OTP\n                             (for example 'ietf|2' for TekRADIUS)\n                      debug: [0|1] enable/disable enhanced log information\n                             (code result are also displayed on the console)\n               debug-prefix: add a prefix when using the debug mode\n                             (for example 'Reply-Message := ' for FreeRADIUS)\n         default-2fa-digits: [6-16] set the default amount of OTP digits\n         default-pin-digits: [4-32] set the default amount of PIN digits\n default-request-prefix-pin: [0|1] prefix PIN enabled/disabled by default\n   default-request-ldap-pwd: [0|1] LDAP/AD password enabled/disabled by default\n                display-log: [0|1] enable/disable log display on the console\n            group-attribute: attribute to return for the group membership\n                             (for example 'Filter-Id' for FreeRADIUS)\n        ignore-no-prefix-cp: [0|1] Disable 'no prefix' for Credential Provider\n                     issuer: default name of the issuer of the (soft) token\n            ldap-2fa-opt-in: [0|1] disable/enable LDAP/AD 2FA opt-in (default 0)\n        ldap-account-suffix: LDAP/AD account suffix\n             ldap-activated: [0|1] enable/disable LDAP/AD support\n               ldap-base-dn: LDAP/AD base\n               ldap-bind-dn: LDAP/AD bind \n         ldap-cn-identifier: LDAP/AD cn identifier (default is sAMAccountName)\n     ldap-default-algorithm: [totp|hotp|motp|without2fa] default algorithm\n                             for new LDAP/AD users\n    ldap-domain-controllers: LDAP/AD domain controller(s), comma separated\n                ldap-filter: LDAP/AD filter customization (check documentation)\n       ldap-group-attribute: LDAP/AD group attribute (default is memberOf)\n   ldap-group-cn-identifier: LDAP/AD group cn identifier\n                             (default is sAMAccountName for AD, cn for LDAP)\n              ldap-in-group: LDAP/AD group(s) in which users should be in\n       ldap-network-timeout: LDAP/AD network timeout (in seconds)\n                  ldap-port: LDAP/AD port (default is set to 389)\n       ldap-server-password: LDAP/AD server password\n           ldap-server-type: [1|2|4] LDAP/AD server type\n                             (1=AD, 2=standard LDAP, 4=eDirectory)\n                   ldap-ssl: [0|1] enable/disable LDAP/AD SSL connection\n ldap-synced-user-attribute: LDAP/AD attribute used as the account name\n            ldap-time-limit: LDAP/AD number of sec. to wait for search results\n              ldap-users-dn: LDAP/AD users DN (optional, use base-dn if empty)\n                             (you can put several DN separated by semicolons)\n   ldap-without2fa-in-group: Special LDAP/AD group(s) for without2fa users\n            ldaptls-reqcert: ['auto'|'never'|''|...] how to perform the LDAP TLS\n                             server certificate checks (LDAPTLS_REQCERT)\n                             'auto' means 'never' for Windows and '' for Linux\n       ldaptls-cipher-suite: ['auto'|''|...] which cipher suite is used for the\n                             LDAP TLS connection (LDAPTLS_CIPHER_SUITE)\n                             'auto' means '' for PHP higher than 5.x and\n                             'NORMAL:!VERS-TLS1.2' for PHP 5.x and before\n                        log: [0|1] enable/disable log permanently\n         log-forced-in-file: [0|1] enable/disable log always in file (no DB)\n            multiple-groups: [0|1] enable/disable multiple groups per user\n    radius-reply-attributor: [ += |=] how to attribute a value\n                             ('=' for TekRADIUS, ' += ' for FreeRADIUS)\n     radius-reply-separator: [,|:|;|cr|crlf] returned attributes separator\n                             ('crlf' for TekRADIUS, ',' for FreeRADIUS)\n          self-registration: [1|0] enable/disable self-registration of tokens\n         server-cache-level: [1|0] enable/disable cache from server to client\n      server-cache-lifetime: lifetime in seconds of the cached information\n              server-secret: shared secret used for client/server operation\n             server-timeout: timeout value for the connection to the server\n                server-type: [xml] type of the server\n                             (only xml server type is able to do caching)\n                 server-url: full url of the server(s) for client/server mode\n                             (server_url_1;server_url_2 is accepted)\n                 sms-api-id: SMS API id (if any, give your REST/XML API id)\n                             with exec as provider, define the script to call\n                               (available variables: %from, %to, %msg)\n                 sms-digits: [6-32] set the default amount of SMS digits\n                     sms-ip: IP address of the SMS server (for inhouse server)\n      sms-challenge-enabled: [0|1] enable/disable SMS challenge\n                sms-message: SMS message to display before the OTP\n             sms-originator: SMS sender (if authorized by provider)\n               sms-password: SMS account password\n                   sms-port: Port of the SMS server (for inhouse server)\n               sms-provider: SMS provider (aspsms,clickatell,clickatell2,\n                             intellisms,nexmo,nowsms,smseagle,swisscom,telnyx,\n                             custom,exec)\n                sms-userkey: SMS account username or userkey\n\nCustom SMS provider only\n                    sms-url: URL(s) of the custom SMS provider\n                               (multiple URLs can be separated by [space],\n                                supported variables : %api_id,%username,\n                                %password,%from,%to,%msg,%ip,%url)\n          sms-send-template: POST template content for custom SMS provider\n                               (supported variables : %api_id,%username,\n                                %password,%from,%to,%msg)\n                 sms-method: [GET|POST|POST-JSON|POST-XML] send method\n               sms-encoding: [ISO|UTF] characters encoding\n         sms-status-success: status result if successful (partial supported)\n                               (example: 20, for any 20x result)\n        sms-content-success: content result if successful (partial supported)\n                               (example: \"status\": \"0\")\n       sms-content-encoding: [''|'HTML'|'URL'|'QUOTES'] Special content encoding\n         sms-no-double-zero: [0|1] Remove double zero for international numbers\n             sms-basic-auth: [0|1] Enable basic HTTP authentication\n                               (sms-userkey:sms-password)\n\n                 sql-server: SQL server (FQDN or IP)\n               sql-username: SQL username\n               sql-password: SQL password\n               sql-database: SQL database\n           sql-config-table: SQL config table, default is multiotp_config\n          sql-devices-table: SQL devices table, default is multiotp_devices\n              sql-log-table: SQL log table, default is multiotp_log\n           sql-tokens-table: SQL tokens table, default is multiotp_tokens\n            sql-users-table: SQL users table, default is multiotp_users\n sync-delete-retention-days: days of retention before deleting a no more\n                             existing AD/LDAP user (0=disable only, no delete)\n   tel-default-country-code: Default country code for phone number\n         text-sms-challenge: Text displayed for the SMS challenge\n       text-token-challenge: Text displayed for the challenge\n token-serial-number-length: Length of the serial number of the tokens\n                             (used for self-registration)\n\n multiotp -initialize-backend (when all options are set, it will initialize\n                               the backend, including creating the tables)\n\n multiotp -set user option1=value1 option2=value2 ... optionN=valueN\n  options are  email: update the email of the user\n         cache-level: [1|0] enable/disable cache for this user on the client\n      cache-lifetime: set/update lifetime in seconds of cached information\n         description: set a description to the user, used for example during\n                      the QRcode generation as the description of the account\n               group: set/update the group of the user\n            ldap-pwd: [0|1] the LDAP/AD password is used instead of the pin\n                 pin: set/update the private pin code of the user\n          prefix-pin: [0|1] the pin and the token must by merged by the user\n                      (if your pin is 1234 and your token displays 5556677,\n                      you will have to type 1234556677)\n                 sms: set/update the sms phone number of the user\n\n\nAuthentication parameters:\n\n -calling-ip=Framed-IP-Address\n -calling-mac=Calling-Station-Id\n -chap-challenge=0x... CHAP-Challenge\n -chap-id=0x... Optional CHAP-Id\n          (the first byte of the chap-password value should contain this value)\n -chap-password=0x... CHAP-Password\n -mac=Called-Station-Id\n -ms-chap-challenge=0x... MS-CHAP-Challenge\n -ms-chap-response=0x... MS-CHAP-Response\n -ms-chap2-response=0x... MS-CHAP2-Response\n -src=Packet-Src-IP-Address\n -state=State\n -tag=Client-Shortname\n\n -usersid=Windows SID of the user (provided by multiOTP Credential Provider)\n\n\nClient/server inline parameters:\n\n -server-cache-level=[1|0] enable/disable cache from server to client\n -server-secret=shared secret used for client/server operation\n -server-timeout=timeout value for the connection to the server\n -server-url=full url of the server(s) for client/server mode\n             (-server-url=server_url_1;server_url_2 is accepted)\n\n\nAD/LDAP integration:\n\n multiotp -ldap-check          : check the AD/LDAP connection\n multiotp -ldap-user-info user : print the AD/LDAP information for this user\n multiotp -ldap-users-list     : print the list of selected the AD/LDAP users\n multiotp -ldap-users-sync     : launch the AD/LDAP synchronization\n                                 (will check first if a lock file is present)\n multiotp -sync-delete-retention-days=days of retention before deleting a no\n                                      more existing AD/LDAP user\n                                      (0=disable only the user, do not delete)\n\n\nBackup/restore commands:\n\n multiotp -backup-config  password [file-name]\n multiotp -restore-config password [file-name]\n   By default, the file name is multiotp.cfg in the current folder.\n\n\nOther information commands:\n\n multiotp -phpinfo         : print the current PHP version\n multiotp -showlog         : print the log entries\n multiotp -clearlog        : clear the log entries\n multiotp -tokenslist      : print the list of the tokens\n multiotp -userslist       : print the list of the users\n multiotp -lockeduserslist : print the list of the locked users\n\n\nSpecial commands: \n\n multiotp -purge-lock-folder\n   This will delete the .lock files in the lock folder.\n   .lock files are used to handle multiple instances.\n   They are valid by default for 5 minutes.\n\n multiotp -purge-ldap-cache-folder\n   This will delete the .cache files in the AD/LDAP cache folder.\n   .cache files are used to speed up the AD/LDAP synchronizsation process.\n   They are valid by default for 60 minutes.\n\n multiotp -log-error \"log information\"\n   This will write \"log information\" error in the default log storage.\n\n multiotp -log-info \"log information\"\n   This will write \"log information\" info in the default log storage.\n\n\nOther parameters:\n\n -base-dir=/full/path/to/the/main/folder/of/multiotp/\n           (if the script folder is wrongly detected, this will fix the issue)\n\n\nSwitches:\n\n -debug          Enhanced log information activated and code result on console\n                 (the permanent state of debug can be set with -config debug=1)\n -display-log    Log information will also be displayed on the console\n                 (the permanent state can be set with -config display-log=1)\n -help           Display this help page\n -keep-local     Keep local user even if the server doesn't have it\n                 (if the server doesn't have it, the local one will be checked)\n -log            Log operation in the log subdirectory or in the database\n                 (the permanent state of log can be set with -config log=1)\n -network-info   Display network info (mode, ip, mask, gateway, dns1, dns2)\n -nt-key-only    Return ONLY NT_KEY to the radius server\n -param          All parameters are logged for debugging purposes\n -php-version    Display the current version of the running PHP interpreter\n -request-nt-key Return NT_KEY with the other attributes to the radius server\n -error-codes    List all error codes\n -status         Display a status bar during resynchronization\n -version        Display the current version of the library\n\n\nExamples:\n\n multiotp -fastcreate gademo\n multiotp -debug -createga gauser 2233445566777733\n multiotp -debug -create alan TOTP 3683453456769abc3452 2233 6 60\n multiotp -debug -set alan prefix-pin=1\n multiotp -debug -create anna TOTP 56821bac24fbd2343393 4455 6 30\n multiotp -debug -set anna prefix-pin=0\n multiotp -debug -create john HOTP 31323334353637383930 5678 6 137\n multiotp -debug -create -token-id rick 2010090201901 2345\n multiotp -log -create jimmy mOTP 004f5a158bca13984d349a7f23 1234 6 10\n\n multiotp -set gademo description=\"VPN code for gademo\"\n multiotp -set jimmy sms=41791234567\n\n multiotp jimmy sms\n\n multiotp -scratchlist gademo\n\n multiotp -display-log -log -debug jimmy ea2315\n multiotp -display-log -log anna 546078\n multiotp -display-log -log -checkpam\n multiotp john 5678124578\n\n multiotp -debug -import tokens.pskc \"1234 5678 9012 3456 7890 1234 5678 9012\"\n multiotp -debug -import-pskc tokens.pskc \"qwerty\"\n multiotp -debug -import 10OTP_data01_upgrade.sql\n multiotp -debug -import-dat importAlpine.dat\n\n multiotp -debug -qrcode gademo gademo.png\n multiotp -debug -urllink john\n\n multiotp -resync john 5678456789 5678345231\n multiotp -resync -status anna 4455487352 4455983513\n multiotp -update-pin alan 4417\n\n multiotp -config debug-prefix=\"Reply-Message := \"\n\n multiotp -config server-cache-level=1 server-cache-lifetime=15552000\n multiotp -config server-secret=MySharedSecret server-type=xml\n multiotp -config server-timeout=3\n multiotp -config server-url=http://my.server/multiotp/;my.server2:8112/secure/\n\n multiotp -config sms-provider=clickatell sms-userkey=CL1 sms-password=PASS\n multiotp -config sms-api-id=1234567\n multiotp -config sms-message=\"Your SMS-code is:\" sms-originator=Company\n multiotp -config sms-message=\"Type %s as code\" sms-originator=0041797654321\n\n multiotp -config sms-provider=exec sms-api-id=\"/path/to/app %from %to \"%msg\"\"\n\n multiotp -config token-serial-number-length=10,12\n\n multiotp -config backend-type=mysql sql-server=fqdn.or.ip sql-database=dbname\n multiotp -config sql-username=user sql-password=pass\n multiotp -initialize-backend\n\n multiotp -config backend-type=pgsql sql-server=fqdn.or.ip sql-database=dbname\n multiotp -config sql-schema=schemaname sql-username=user sql-password=pass\n multiotp -initialize-backend\n\n\nmultiOTP can be combined with a Raspberry Pi (http://www.raspberrypi.org/) in\norder to have a very low budget strong authentication device. Please look at\nthe readme file in order to learn how to set it up in a few steps.\nThe distribution is already optimized with an HTTP proxy to speed up the CLI.\nA ready to use binary image can be downloaded at https://download.multiOTP.net/\n\nmultiOTP open source is also available as a ready to use virtual appliance in\nstandard OVA, VMware optimized or Hyper-V formats.\nVirtual appliance images can be downloaded at https://download.multiOTP.net/\n\nmultiOTP web service is working fine with any web server supporting PHP.\n - nginx is a light one under Linux and Windows (http://nginx.org/)\n - Mongoose is a light one under Windows (http://code.google.com/p/mongoose/)\n - and many others like Apache HTTP Server (http://httpd.apache.org/)\n\nmultiOTP is working fine with FreeRADIUS under Linux (http://freeradius.org/)\n\nmultiOTP is working fine under Windows with WinRADIUS, a port of FreeRADIUS\n(http://winradius.eu/)\n\nWhen used with TekRADIUS (http://www.tekradius.com) the External-Executable\nmust be called like this: C:\\multiotp\\multiotp.exe %ietf|1% %ietf|2%\nCheck the readme file for more information\n\n\nSome of other products and services based on multiOTP:\n multiOTP Credential Provider (https://download.multiotp.net/)\n  Open-source Credential Provider for Windows Logon, based on MultiotpCPV2RDP\n MultiotpCPV2RDP (https://github.com/arcadejust/MultiotpCPV2RDP)\n  Open-source Credential Provider for Windows Logon, by arcadejust\n mOTP-CP (https://goo.gl/Y8g4ON)\n  Open-source Credential Provider for Windows Logon, by Last Squirrel IT\n ownCloud OTP (https://goo.gl/mKjt43)\n  Open-source One Time Password app for ownCloud (http://owncloud.org)\n UserCredential (https://github.com/cymapgt/UserCredential)\n  Open-source authentication PHP library by Cyril Ogana\n multiOTP Pro 501V (https://www.multiotp.com)\n  Pro version virtual appliance, with full web GUI, 1 free user licence\n multiOTP Pro 420B (https://www.multiotp.com)\n  Pro version tiny hardware device (BeagleBone Black), with full web GUI\n multiOTP Enterprise (http:s//firmware.multiotp.com/enterprise/)\n  Enterprise version virtual appliance, with HA master-slave support,\n   also available as a Raspberry Pi image file\n secuPASS.net (https://www.secuPASS.net)\n  simple SMS trusting service for free WLAN Hotspot\n\nDon't hesitate to send us an email if your product uses our multiOTP library.\n\nVisit https://forum.multiotp.net/ for additional support\n\n\n``` \r\n \r\n``` \r\nHash verification for multiotp_5.10.2.2.zip \r\nSHA256:1d9af793d4264031fa7dfb4234d9bdd90ed2c5045b59c99920dc7c5c72858e2e \r\nSHA1:021c8403263143fc711067b436ee2cb0f801835b \r\nMD5:adb94d25815a59646569d8a40e3476cb \r\n``` \r\n","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026currency_code=USD\u0026business=paypal@sysco.ch\u0026item_name=Donation%20for%20multiOTP%20project"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultiotp%2Fmultiotp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmultiotp%2Fmultiotp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultiotp%2Fmultiotp/lists"}