<?php
/**
* @file check.multiotp.class.php
* @brief Check the implementation of some multiOTP functionalities
*
* multiOTP - Strong two-factor authentication PHP class package
* https://www.multiotp.net
*
* Visit http://forum.multiotp.net/ for additional support.
*
* Donation are always welcome! Please check https://www.multiotp.net
* and you will find the magic button ;-)
*
*
* check.multiotp.class.php is a file implementing the Multiotp class
* in order to check the compliance with RFC4226. It must be
* placed in the same directory as the multiotp.class.php file.
*
* WARNING! DO NOT FORGET TO REMOVE this test file from your disk when you go in production !
*
*
* PHP 5.4.0 or higher is supported.
*
* @author Andre Liechti, SysCo systemes de communication sa, <info@multiotp.net>
* @version 5.9.7.1
* @date 2023-12-03
* @since 2013-07-10
* @copyright (c) 2013-2023 SysCo systemes de communication sa
* @copyright GNU Lesser General Public License
*
*//*
*
* LICENCE
*
* Copyright (c) 2013-2023 SysCo systemes de communication sa
* SysCo (tm) is a trademark of SysCo systemes de communication sa
* (http://www.sysco.ch/)
* All rights reserved.
*
* This file is part of the multiOTP project.
*
* This script is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with multiOTP PHP class.
* If not, see <http://www.gnu.org/licenses/>.
*
*
* Usage
*
* The file must be placed in the same directory as multiotp.class.php
*
*
* External file needed
*
* multiotp.class.php
*
*
* External file created
*
* Multiotp class will create some internals folders and files
*
*
* Change Log
*
* 2020-08-31 5.8.0.0 SysCo/al By default, clean log before test
* 2019-10-23 5.6.1.4 SysCo/al Additional tests included
* 2017-06-02 5.0.4.6 SysCo/al Enhanced tests display
* 2017-05-29 5.0.4.5 SysCo/al Additional PostgreSQL backend included
* Parameters adapted (set the $check_mysql_xxx and/or the $check_pgsql_xxx parameters below)
* 2016-11-04 5.0.2.6 SysCo/al GetNetworkInfo() test included
* 2015-07-17 4.3.2.6 SysCo/al Additional tests included
* 2015-06-09 4.3.2.2 SysCo/al Additional tests included
* 2014-11-04 4.3.0.0 SysCo/al Additional tests included
* 2014-03-30 4.2.4.2 SysCo/al Additional tokens tests included
* 2014-03-30 4.2.4 SysCo/al Additional tests included
* MySQL backend test added (set the $check_sql_xxx parameters below)
* List of attributes to encrypt in the backend is set to null during the tests
* 2013-08-25 4.0.7 SysCo/al Version synchronization
* 2013-08-25 4.0.6 SysCo/al File renamed to check.multiotp.class.php
* 2013-07-10 4.0.4 SysCo/al Initial release of check.multiotp.php
***************************************************************/
/*
// PostgreSQL
# CREATE DATABASE multiotptest;
# \connect multiotptest
# CREATE USER root PASSWORD 'pass';
# CREATE SCHEMA multiotptest;
# GRANT ALL ON SCHEMA multiotptest to root;
# \list
# SELECT table_name FROM information_schema.tables WHERE table_schema='multiotptest';
# SELECT * from multiotptest.multiotp_config;
$GLOBALS['check_pgsql_server'] = '127.0.0.1:5432';
$GLOBALS['check_pgsql_username'] = 'root';
$GLOBALS['check_pgsql_password'] = 'pass';
$GLOBALS['check_pgsql_database'] = 'multiotptest';
$GLOBALS['check_pgsql_schema'] = 'multiotptest';
// MySQL
$GLOBALS['check_mysql_server'] = '127.0.0.1:3306';
$GLOBALS['check_mysql_username'] = 'root';
$GLOBALS['check_mysql_password'] = 'pass';
$GLOBALS['check_mysql_database'] = 'multiotptest';
*/
set_time_limit(3600);
$first_time = time();
if (!isset($GLOBALS['minima'])) {
if (isset($_GET['minima'])) {
$GLOBALS['minima'] = isset($_GET['minima']);
} else {
$GLOBALS['minima'] = false;
}
}
if (!isset($GLOBALS['keeplog'])) {
if (isset($_GET['keeplog'])) {
$GLOBALS['keeplog'] = isset($_GET['keeplog']);
} else {
$GLOBALS['keeplog'] = false;
}
}
if (!isset($GLOBALS['noresume'])) {
if (isset($_GET['noresume'])) {
$GLOBALS['noresume'] = isset($_GET['noresume']);
} else {
$GLOBALS['noresume'] = false;
}
}
$test_mail = isset($GLOBALS['test_mail'])?$GLOBALS['test_mail']:'';
if (!function_exists('echo_full')) {
function echo_full($to_display) {
if (!$GLOBALS['minima']) {
@ob_end_flush();
echo $to_display;
}
}
}
require_once('multiotp.class.php');
// MySQL server test parameters
$check_mysql_server = isset($GLOBALS['check_mysql_server'])?$GLOBALS['check_mysql_server']:'';
$check_mysql_username = isset($GLOBALS['check_mysql_username'])?$GLOBALS['check_mysql_username']:'';
$check_mysql_password = isset($GLOBALS['check_mysql_password'])?$GLOBALS['check_mysql_password']:'';
$check_mysql_database = isset($GLOBALS['check_mysql_database'])?$GLOBALS['check_mysql_database']:'';
// PostgreSQL server test parameters
$check_pgsql_server = isset($GLOBALS['check_pgsql_server'])?$GLOBALS['check_pgsql_server']:'';
$check_pgsql_username = isset($GLOBALS['check_pgsql_username'])?$GLOBALS['check_pgsql_username']:'';
$check_pgsql_password = isset($GLOBALS['check_pgsql_password'])?$GLOBALS['check_pgsql_password']:'';
$check_pgsql_database = isset($GLOBALS['check_pgsql_database'])?$GLOBALS['check_pgsql_database']:'';
$check_pgsql_schema = isset($GLOBALS['check_pgsql_schema'])?$GLOBALS['check_pgsql_schema']:'';
$backend_array = array();
// Default backend is 'files'
$default_backend = 'files';
$backend_array[] = $default_backend;
// Tests counter
$tests = 0;
// Successes counter
$successes = 0;
$browser_mode = isset($_SERVER["HTTP_USER_AGENT"]);
$html_mode = (!$GLOBALS['minima']) && $browser_mode;
// $crlf will skip a line in command line mode and also in browser mode
$crlf = $html_mode?"<br />\n":"\r\n";
$b_on = $html_mode?'<b>':'';
$b_off = $html_mode?'</b>':'';
$h2_on = $html_mode?'<h2>':' *** ';
$h2_off = $html_mode?'</h2>':' *** ';
$hr = $html_mode?'<hr />':'----------'.$crlf;
$i_on = $html_mode?'<i>':'';
$i_off = $html_mode?'</i>':'';
$ok_on = $html_mode?'<span style="color: green;"><b>':'';
$ok_off = $html_mode?'</b></span>':'';
$ko_on = $html_mode?'<span style="color: red;"><b>':'';
$ko_off = $html_mode?'</b></span>':'';
// Declare and initialize the Multiotp class if not done by an other file including this one
if (!isset($multiotp))
{
$multiotp = new Multiotp('DefaultCliEncryptionKey');
}
$multiotp->SetMaxEventResyncWindow(500); // 500 is enough and quicker for the check
$multiotp->EnableVerboseLog(); // Could be helpful at the beginning
if ($html_mode) {
$multiotp->EnableDebugViaHtml();
}
// $multiotp->_config_data['attributes_to_encrypt'] = '**'; // For test purposes only
// Write the configuration information in the configuration file
$multiotp->WriteConfigData();
if (('' != $check_mysql_server) &&
('' != $check_mysql_username) &&
('' != $check_mysql_password) &&
('' != $check_mysql_database)
) {
$backend_array[] = 'mysql';
}
if (('' != $check_pgsql_server) &&
('' != $check_pgsql_username) &&
('' != $check_pgsql_password) &&
('' != $check_pgsql_database) &&
('' != $check_pgsql_schema)
) {
$backend_array[] = 'pgsql';
}
if ($html_mode && (!isset($GLOBALS['no_header']))) {
echo <<<EOWEBHEADER
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>
multiOTP class implementation check
</title>
<style>
body {
font-family: Verdana, Helvetica, Arial;
color: black;
font-size: 10pt;
font-weight: normal;
text-decoration: none;
}
</style>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<script>
// Finds y value of given object
function findPos(obj)
{
var curtop = 0;
if (obj.offsetParent)
{
do
{
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return [curtop];
}
}
// Scroll to an object
function scrollToObject(object_div)
{
//Get object
var ObjectDiv = document.getElementById(object_div);
//Scroll to location of ObjectDiv
window.scroll(0,findPos(ObjectDiv));
}
</script>
</head>
<body onload="scrollToObject('test_result');">
EOWEBHEADER;
}
//====================================================================
// Display header and version information
echo_full($crlf);
echo_full($b_on.$multiotp->GetClassName()." HOTP implementation check".$b_off.$crlf);
echo_full("(RFC 4226, http://www.ietf.org/rfc/rfc4226.txt)".$crlf);
echo_full("-----------------------------------------------".$crlf);
echo_full($crlf);
echo_full($multiotp->GetFullVersionInfo());
echo_full(", running with PHP version ".phpversion().$crlf);
echo_full($crlf);
if (!$GLOBALS['minima']) {
echo_full("Library hash: ".str_replace("\t",", ",$multiotp->GetLibraryHash()).$crlf);
echo_full($crlf);
}
echo_full("Valid algorithms: ".str_replace("\t",", ",$multiotp->GetAlgorithmsList()).$crlf);
echo_full($crlf);
echo_full($b_on."List of supported SMS providers".$b_off.$crlf);
echo_full(str_replace("\t",$crlf,$multiotp->GetSmsProvidersList()));
echo_full($crlf);
foreach ($backend_array as $backend) {
$multiotp->SetBackendType($backend);
if ('mysql' == $backend) {
$multiotp->SetSqlServer($check_mysql_server);
$multiotp->SetSqlUsername($check_mysql_username);
$multiotp->SetSqlPassword($check_mysql_password);
$multiotp->SetSqlDatabase($check_mysql_database);
$multiotp->InitializeBackend();
} elseif ('pgsql' == $backend) {
$multiotp->SetSqlServer($check_pgsql_server);
$multiotp->SetSqlUsername($check_pgsql_username);
$multiotp->SetSqlPassword($check_pgsql_password);
$multiotp->SetSqlDatabase($check_pgsql_database);
$multiotp->SetSqlSchema($check_pgsql_schema);
$multiotp->InitializeBackend();
}
$multiotp->WriteConfigData();
if (!$GLOBALS['minima']) {
echo $hr;
echo_full($crlf);
echo "Selected backend: ".$b_on.$backend.$b_off.$crlf;
echo_full($crlf);
}
//====================================================================
// TEST: Backup
$tests++;
echo_full($b_on."Configuration backup".$b_off.$crlf);
@set_time_limit(0); // No time limit fot the backup
$backup_start = time();
$backup_file = sys_get_temp_dir().DIRECTORY_SEPARATOR."multiotp-backup-".date("Ymd-His").".bin";
if (file_exists($backup_file)) {
unlink($backup_file);
}
$encryption_key = "-backup-";
$return_content = false;
// $backup_file = "@";
echo_full("Backup file: ".$backup_file.$crlf);
$backup_content = $multiotp->BackupConfiguration(array("backup_file" => $backup_file,
"encryption_key" => $encryption_key,
"encrypt_all" => false, // is set to true by default
"return_content" => $return_content,
"keep_file" => true,
"no_send" => true
));
if ($return_content) {
echo str_replace("\n", "<br />\n", $backup_content);
}
/*
$file_handler = fopen($backup_file,"rt");
while (!feof($file_handler)) {
echo_full(fgets($file_handler));
echo_full($crlf);
}
fclose($file_handler);
*/
$backup_time = time() - $backup_start;
if (0 >= $backup_time) {
$backup_time += 1;
}
if (false !== $backup_content) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Configuration successfully backed up with pass $encryption_key in $backup_time second".(($backup_time > 1)?"s":"").$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Unable to backup the configuration".$crlf);
}
echo_full($crlf);
if (!isset($GLOBALS['keeplog'])) {
if (isset($GLOBALS['eraselog'])) {
//====================================================================
// TEST: Clear completely the log
$tests++;
echo_full($b_on."Clear the log completely".$b_off.$crlf);
if ($multiotp->ClearLog()) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Log successfully cleared".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Unable to clear the log".$crlf);
}
echo_full($crlf);
} else {
//====================================================================
// TEST: Clear the log (keep last 2 days)
$tests++;
echo_full($b_on."Clear the log".$b_off.$crlf);
if ($multiotp->ClearLog(2)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Log successfully cleared (keep the last 2 days)".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Unable to clear the log".$crlf);
}
echo_full($crlf);
}
}
//====================================================================
// TEST: Write in the log
$tests++;
echo_full($b_on."Write in the log".$b_off.$crlf);
$test_tag = '['.date("YmdHis").']';
$multiotp->WriteLog("Test: test tag is $test_tag", FALSE, FALSE, 19, 'System', '');
$log_content = $multiotp->ShowLog(TRUE);
if (FALSE !== mb_strpos($log_content, $test_tag))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Log successfully updated".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Unable to write in the log".$crlf);
}
echo_full($crlf);
//============================================
// TEST: Write the configuration file/database
$tests++;
echo_full($b_on."Write the configuration file/database".$b_off.$crlf);
$backup_prefix = $multiotp->GetVerboseLogPrefix();
$multiotp->SetVerboseLogPrefix('tESt');
if ($multiotp->WriteConfigData())
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Configuration successfully written".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Failed while writing the configuration".$crlf);
}
echo_full($crlf);
//===========================================
// TEST: Read the configuration file/database
$tests++;
echo_full($b_on."Read the configuration file/database".$b_off.$crlf);
$multiotp->SetVerboseLogPrefix('EMPTY');
$multiotp->ReadConfigData();
$test_prefix = $multiotp->GetVerboseLogPrefix();
$multiotp->SetVerboseLogPrefix($backup_prefix);
$multiotp->WriteConfigData();
if ('tESt' == $test_prefix)
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Configuration successfully read".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Failed while reading the configuration ($test_prefix)".$crlf);
}
echo_full($crlf);
$yubikey_class = new MultiotpYubikey();
//====================================================================
// TEST: Hexa to ModHex
$tests++;
echo_full($b_on."Check Hexa to ModHex encoding".$b_off.$crlf);
$source = '0123456789abcdef';
$expected = 'cbdefghijklnrtuv';
if (FALSE === ($result = $yubikey_class->HexToModHex($source)))
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Hexa to ModHex encoding failed".$crlf);
}
elseif ($expected == $result)
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Hexa to ModHex encoding successful ($result)".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Hexa to ModHex encoding failed ($result instead of $expected)".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: ModHex to Hexa
$tests++;
echo_full($b_on."Check ModHex to Hexa decoding".$b_off.$crlf);
$source = 'cbdefghijklnrtuv';
$expected = '0123456789abcdef';
if (FALSE === ($result = $yubikey_class->ModHexToHex($source)))
{
echo_full("- ".$ko_on.'KO!'.$ko_off." ModHex to Hexa encoding failed".$crlf);
}
elseif ($expected == $result)
{
echo_full("- ".$ok_on.'OK!'.$ok_off." ModHex to Hexa encoding successful ($result)".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." ModHex to Hexa encoding failed ($result instead of $expected)".$crlf);
}
echo_full($crlf);
//====================================================================
// Delete the user test_user if it exists
echo_full($i_on);
echo_full("Deleting the test_user".$crlf);
if (!$multiotp->DeleteUser('test_user', TRUE))
{
echo_full("- INFO: User test_user doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: User test_user successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// Delete the user test_user twice if it exists
echo_full($i_on);
echo_full("Deleting the test_user (twice)".$crlf);
if (!$multiotp->DeleteUser('test_user', TRUE))
{
echo_full("- INFO: User test_user doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: User test_user successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// Delete the user test_totp if it exists
echo_full($i_on);
echo_full("Deleting the test_totp".$crlf);
if (!$multiotp->DeleteUser('test_totp', TRUE))
{
echo_full("- INFO: User test_totp doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: User test_totp successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
//====================================================================
// Delete the token test_token if it exists
echo_full($i_on);
echo_full("Deleting the test_token".$crlf);
if (!$multiotp->DeleteToken('test_token'))
{
echo_full("- INFO: Token test_token doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: Token test_token successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
//====================================================================
// Delete the token test_token_totp if it exists
echo_full($i_on);
echo_full("Deleting the test_token_totp".$crlf);
if (!$multiotp->DeleteToken('test_token_totp'))
{
echo_full("- INFO: Token test_token_totp doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: Token test_token_totp successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// TEST: Creating token test_token with the RFC test values HOTP token
$tests++;
echo_full($b_on."Creating token test_token with the RFC test values HOTP token".$b_off.$crlf);
if ($multiotp->CreateToken('test_token', 'HOTP', '3132333435363738393031323334353637383930', 6, -1))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token test_token successfully created".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of test_token token failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Creating token test_token_totp with the RFC test values HOTP token
$tests++;
echo_full($b_on."Creating token test_token_totp with the RFC test token".$b_off.$crlf);
if ($multiotp->CreateToken('test_token_totp', 'TOTP', '3132333435363738393031323334353637383930', 6, -1))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token test_token_totp successfully created".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of test_token_totp token failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Creating user test_user with the HOTP RFC test token test_token created before
$tests++;
echo_full($b_on."Creating user test_user with the HOTP RFC test token test_token created before".$b_off.$crlf);
if (!$multiotp->CreateUserFromToken('test_user', 'test_token'))
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Token test_token doesn't exist".$crlf);
}
else
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_user successfully created with token test_token".$crlf);
$successes++;
}
$multiotp->SetUser('test_user');
$multiotp->SetUserPrefixPin(0);
$multiotp->WriteUserData();
echo_full($crlf);
//====================================================================
// TEST: Creating user test_totp with the HOTP RFC test token test_token_totp created before
$tests++;
echo_full($b_on."Creating user test_totp with the HOTP RFC test token test_token_totp created before".$b_off.$crlf);
if (!$multiotp->CreateUserFromToken('test_totp', 'test_token_totp'))
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Token test_token_totp doesn't exist".$crlf);
}
else
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_totp successfully created with token test_token_totp".$crlf);
$successes++;
}
$multiotp->SetUser('test_totp');
$multiotp->SetUserPrefixPin(0);
$multiotp->WriteUserData();
echo_full($crlf);
//====================================================================
// TEST: Authenticating test_user with the first token of the RFC test values
$tests++;
echo_full($b_on."Authenticating test_user with the first token of the RFC test values".$b_off.$crlf);
$multiotp->SetUser('test_user');
if (0 == ($error = $multiotp->CheckToken('755224')))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token of the user test_user successfully accepted".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Error authenticating the user test_user with the first token".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Authenticating test_totp with too old TOTP token of the RFC test token
$tests++;
echo_full($b_on."Authenticating test_totp with too old TOTP token of the RFC test token".$b_off.$crlf);
$multiotp->SetUser('test_totp');
$otp_value = $multiotp->GenerateOathHotp(hex2bin('3132333435363738393031323334353637383930'),intval((time()-(2*$multiotp->GetMaxTimeWindow()))/30), 6,'TOTP');
if (93 == ($error = $multiotp->CheckToken($otp_value)))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Too old token of the user test_totp refused and detected out of sync ($error)".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Error authenticating the user test_totp with an out-of-sync token ($error)".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Authenticating test_totp with the actual TOTP token of the RFC test token
$tests++;
echo_full($b_on."Authenticating test_totp with the actual TOTP token of the RFC test token".$b_off.$crlf);
$multiotp->SetUser('test_totp');
$otp_value = $multiotp->GenerateOathHotp(hex2bin('3132333435363738393031323334353637383930'),intval(time()/30), 6,'TOTP');
if (0 == ($error = $multiotp->CheckToken($otp_value)))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token of the user test_totp successfully accepted".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Error authenticating the user test_totp with the RFC test token".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Testing the replay rejection
$tests++;
echo_full($b_on."Testing the replay rejection".$b_off.$crlf);
$multiotp->SetUser('test_user');
if (0 != ($error = $multiotp->CheckToken('755224')))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token of the user test_user successfully REJECTED (replay)".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Replayed token *WRONGLY* accepted".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Resynchronizing the key
$tests++;
echo_full($b_on."Resynchronizing the key".$b_off.$crlf);
if ($multiotp->ResyncUserToken('test_user', '338314', '254676', (!$browser_mode)))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token of the user test_user successfully resynchronized".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Token of the user test_user NOT resynchronized".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Testing a false resynchronisation (in the past, may take some time)
$tests++;
echo_full($b_on."Testing a false resynchronisation (in the past, may take some time)".$b_off.$crlf);
$multiotp->SetUser('test_user');
$start_time = time();
if (!$multiotp->ResyncToken('287082', '359152', (!$browser_mode)))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token of test_user successfully NOT resynchronized (in the past), in less than ".(1+time()-$start_time)." second(s) ".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Token of user test_user *WRONGLY* resynchronized".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Get user information
$tests++;
echo_full($b_on."Getting user information".$b_off.$crlf);
$test_user_info = $multiotp->GetUserInfo('test_user');
if ($test_user_info != "")
{
echo_full(nl2br($test_user_info));
echo_full("- ".$ok_on.'OK!'.$ok_off." User information returned".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." User information not returned".$crlf);
}
echo_full($crlf);
//================================================
// TEST: Generate Email token for the current user
if ('' != $test_mail) {
$tests++;
echo_full($b_on."Generate Email token for user test_user".$b_off.$crlf);
$multiotp->SetUser('test_user');
$multiotp->SetEmailCodeAllowed(1);
$multiotp->SetUserEmail($test_mail);
$multiotp->WriteUserData();
$token_result = $multiotp->GenerateEmailToken();
if (18 == $token_result) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Email token successfully generated".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Email token generation failed, error $token_result.".$crlf);
}
echo_full($crlf);
}
//====================================================================
// Delete the user test_user8 if it exists
echo_full($i_on);
echo_full("Deleting the test_user8".$crlf);
if (!$multiotp->DeleteUser('test_user8', TRUE))
{
echo_full("- INFO: User test_user8 doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: User test_user8 successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// Delete the token test_token8 if it exists
echo_full($i_on);
echo_full("Deleting the test_token8".$crlf);
if (!$multiotp->DeleteToken('test_token8'))
{
echo_full("- INFO: Token test_token8 doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: Token test_token8 successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// TEST: Creating token test_token8 with the RFC test values HOTP token
$tests++;
echo_full($b_on."Creating token test_token8 with the RFC test values HOTP token".$b_off.$crlf);
if ($multiotp->CreateToken('test_token8', 'HOTP', '3132333435363738393031323334353637383930', 8, -1))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token test_token8 successfully created".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of test_token8 token failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Creating user test_user8 with the HOTP RFC test token test_token8 created before
$tests++;
echo_full($b_on."Creating user test_user8 with the HOTP RFC test token test_token8 created before".$b_off.$crlf);
if (!$multiotp->CreateUserFromToken('test_user8', 'test_token8'))
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Token test_token8 doesn't exist".$crlf);
}
else
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_user8 successfully created with token test_token8".$crlf);
$successes++;
}
$multiotp->SetUser('test_user8');
$multiotp->SetUserPrefixPin(0);
$multiotp->WriteUserData();
echo_full($crlf);
//====================================================================
// TEST: Authenticating test_user8 with the first token of the RFC test values
$tests++;
echo_full($b_on."Authenticating test_user8 with the first 8 digits token of the RFC test values".$b_off.$crlf);
$multiotp->SetUser('test_user8');
if (0 == ($error = $multiotp->CheckToken('84755224')))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token of the user test_user8 successfully accepted".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Error authenticating the user test_user8 with the first token".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Deleting the Test_user2 if it exists
echo_full($i_on);
echo_full("Deleting the Test_user2".$crlf);
if (!$multiotp->DeleteUser('Test_user2', TRUE))
{
echo_full("- INFO: User Test_user2 doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: User Test_user2 successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// TEST: Creating user tEst_user2 with the RFC test values HOTP token and PIN prefix
$tests++;
echo_full($b_on."Creating user tEst_user2 with the RFC test values HOTP token and PIN prefix".$b_off.$crlf);
if ($multiotp->CreateUser('tEst_user2',1,'HOTP','3132333435363738393031323334353637383930','*!1-2-3-4?*',6,0))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User tEst_user2 successfully created".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of user tEst_user2 failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Authenticating teSt_user2 with the first token of the RFC test values with PIN
$tests++;
echo_full($b_on."Authenticating teSt_user2 with the first token of the RFC test values with PIN".$b_off.$crlf);
$multiotp->SetUser('teSt_user2');
if (0 == ($error = $multiotp->CheckToken('*!1-2-3-4?*755224')))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token of the user teSt_user2 (with prefix PIN) successfully accepted".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Error #".$error." authenticating user teSt_user2 with the first token and PIN prefix".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Deleting the testmail@mydomain.sub.net if it exists
echo_full($i_on);
echo_full("Deleting the testmail@mydomain".$crlf);
if (!$multiotp->DeleteUser('testmail@mydomain', TRUE))
{
echo_full("- INFO: User testmail@mydomain doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: User testmail@mydomain successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// TEST: Creating user testmail@mydomain with the RFC test values HOTP token and PIN prefix
$tests++;
echo_full($b_on."Creating user testmail@mydomain with the RFC test values HOTP token and PIN prefix".$b_off.$crlf);
if ($multiotp->CreateUser('testmail@mydomain',1,'HOTP','3132333435363738393031323334353637383930','*!1-2-3-4-5-6?*',6,0))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User testmail@mydomain successfully created".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of user testmail@mydomain failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Authenticating testmail@mydomain.sub.net with the first token of the RFC test values with PIN
$tests++;
$test_user = 'testmail@mydomain.sub.net';
$real_user = $multiotp->FindRealUserName($test_user);
echo_full($b_on."Authenticating testmail@mydomain.sub.net with the first token of the RFC test values with PIN".$b_off.$crlf);
$multiotp->SetUser($real_user);
if (0 == ($error = $multiotp->CheckToken('*!1-2-3-4-5-6?*755224')))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Token of the real user $real_user (user $test_user) (with prefix PIN) successfully accepted".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Error #".$error." authenticating real user $real_user (user $test_user) with the first token and PIN prefix".$crlf);
}
echo_full($crlf);
//====================================================================
// Delete the user fast_user if it exists
echo_full($i_on);
echo_full("Deleting the user fast_user".$crlf);
if (!$multiotp->DeleteUser('fast_user', TRUE))
{
echo_full("- INFO: User fast_user doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: User fast_user successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// Delete the user fast_user_renamed if it exists
echo_full($i_on);
echo_full("Deleting the user fast_user_renamed".$crlf);
if (!$multiotp->DeleteUser('fast_user_renamed', TRUE))
{
echo_full("- INFO: User fast_user_renamed doesn't exist yet".$crlf);
}
else
{
echo_full("- INFO: User fast_user_renamed successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// TEST: Creating user fast_user using the one parameter FastCreateUser() function
$tests++;
echo_full($b_on."Creating user fast_user using the one parameter FastCreateUser() function".$b_off.$crlf);
if ($multiotp->FastCreateUser('fast_user'))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User fast_user successfully created".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of user fast_user failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Check if user fast_user exists
$tests++;
echo_full($b_on."Check if the user fast_user exists".$b_off.$crlf);
if ($multiotp->CheckUserExists('fast_user'))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User fast_user exists".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." fast_user does not exist".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Rename user fast_user
$tests++;
echo_full($b_on."Renaming the user fast_user to fast_user_renamed".$b_off.$crlf);
$multiotp->SetUser('fast_user');
if ($multiotp->RenameCurrentUser('fast_user_renamed'))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User fast_user successfully renamed to fast_user_renamed".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." RenameCurrentUser function failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Creating user test_wo2fa without 2FA token, but with a prefix PIN
$tests++;
echo_full($b_on."Creating user test_wo2fa without 2FA token, but with a prefix PIN".$b_off.$crlf);
if ($multiotp->CreateUser('test_wo2fa',1,'without2FA','','!prefixpin!',0,0)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_wo2fa successfully created".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of user test_wo2fa failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Authenticating test_wo2fa without 2FA token and with correct PIN
$tests++;
echo_full($b_on."Authenticating test_wo2fa without 2FA token and with correct PIN".$b_off.$crlf);
$multiotp->SetUser('test_wo2fa');
if (0 == ($error = $multiotp->CheckToken('!prefixpin!'))) {
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_wo2fa (with prefix PIN) successfully accepted".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Error #".$error." authenticating user test_wo2fa with the prefix PIN".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Authenticating test_wo2fa without 2FA token and with incorrect PIN
$tests++;
echo_full($b_on."Authenticating test_wo2fa without 2FA token and with incorrect PIN".$b_off.$crlf);
$multiotp->SetUser('test_wo2fa');
if (0 != ($error = $multiotp->CheckToken('badprefixpin'))) {
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_wo2fa (with incorrect prefix PIN) successfully refused".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Authenticating user test_wo2fa with the incorrect prefix PIN accepted".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: GetActiveUsersCount with and without "without2FA" users
$tests++;
$multiotp->SetUser('test_wo2fa');
$multiotp->EnableUserRequestLdapPassword();
$multiotp->WriteUserData();
echo_full($b_on."GetActiveUsersCount with and without \"LDAP without 2FA\" users".$b_off.$crlf);
$with_2fa = $multiotp->GetActiveUsersCount(FALSE);
$without_2fa = $multiotp->GetActiveUsersCount(TRUE);
if ($with_2fa > $without_2fa) {
echo_full("- ".$ok_on.'OK!'.$ok_off." GetActiveUsersCount check successful ($with_2fa/$without_2fa)".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." GetActiveUsersCount check error ($with_2fa/$without_2fa)".$crlf);
}
echo_full($crlf);
//====================================================================
// Delete the user test_wo2fa if it exists
echo_full($i_on);
echo_full("Deleting the user test_wo2fa".$crlf);
if (!$multiotp->DeleteUser('test_wo2fa', TRUE)) {
echo_full("- INFO: User test_wo2fa doesn't exist yet".$crlf);
} else {
echo_full("- INFO: User test_wo2fa successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// TEST: Creating user test_wo2fa2 without 2FA token and without a prefix PIN
$tests++;
echo_full($b_on."Creating user test_wo2fa2 without 2FA token and without prefix PIN".$b_off.$crlf);
if ($multiotp->CreateUser('test_wo2fa2',0,'without2FA','','!noprefixpin!',0,0)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_wo2fa2 successfully created".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of user test_wo2fa2 failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Authenticating test_wo2fa2 without 2FA token and without a prefix PIN
$tests++;
echo_full($b_on."Authenticating test_wo2fa2 without 2FA token and without a prefix PIN".$b_off.$crlf);
$multiotp->SetUser('test_wo2fa2');
if (0 == ($error = $multiotp->CheckToken(''))) {
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_wo2fa2 (without prefix PIN) successfully accepted".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Error #".$error." authenticating user test_wo2fa2 without prefix PIN".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Authenticating test_wo2fa2 without 2FA token and with incorrect prefix PIN
$tests++;
echo_full($b_on."Authenticating test_wo2fa2 without 2FA token and with incorrect prefix PIN".$b_off.$crlf);
$multiotp->SetUser('test_wo2fa2');
if (0 != ($error = $multiotp->CheckToken('badprefixpin'))) {
echo_full("- ".$ok_on.'OK!'.$ok_off." User test_wo2fa2 (with incorrect prefix PIN) successfully refused".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Authenticating user test_wo2fa2 with the incorrect prefix PIN accepted".$crlf);
}
echo_full($crlf);
//====================================================================
// Delete the user test_wo2fa2 if it exists
echo_full($i_on);
echo_full("Deleting the user test_wo2fa2".$crlf);
if (!$multiotp->DeleteUser('test_wo2fa2', TRUE)) {
echo_full("- INFO: User test_wo2fa2 doesn't exist yet".$crlf);
} else {
echo_full("- INFO: User test_wo2fa2 successfully deleted".$crlf);
}
echo_full($i_off);
echo_full($crlf);
//====================================================================
// TEST: WriteUserData / ReadUserData with fast_user_renamed
$tests++;
echo_full($b_on."Write/Read information concerning user fast_user_renamed".$b_off.$crlf);
$test_value = 'tESt';
$multiotp->ReadUserData('fast_user_renamed');
$multiotp->SetUserDescription($test_value);
$multiotp->WriteUserData();
$multiotp->SetUserDescription('');
$multiotp->ReadUserData('fast_user_renamed');
if ($test_value == $multiotp->GetUserDescription())
{
echo_full("- ".$ok_on.'OK!'.$ok_off." Write/Read information for fast_user_renamed successfully done".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Write/Read information for fast_user_renamed failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Delete the user fast_user_renamed
$tests++;
echo_full($b_on."Deleting the user fast_user_renamed".$b_off.$crlf);
if ($multiotp->DeleteUser('fast_user_renamed'))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User fast_user fast_user_renamed successfully deleted".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." DeleteUser function failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Check if user fast_user exists
$tests++;
echo_full($b_on."Check if the user fast_user does not exist".$b_off.$crlf);
if (!$multiotp->CheckUserExists('fast_user'))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." User fast_user does not exist".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." fast_user exist".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Creating a QRcode provisioning file for the HOTP RFC test token
$tests++;
echo_full($b_on."Creating a QRcode provisioning file for the HOTP RFC test token".$b_off.$crlf);
$size_result = $multiotp->qrcode('otpauth://hotp/multiOTP%20test:multiOTP%20hotp%20test?counter=0&digits=6&secret='.base32_encode(hex2bin('3132333435363738393031323334353637383930')), $multiotp->GetLogFolder().'qrHOTP.png');
if (0 < $size_result)
{
echo_full("- ".$ok_on.'OK!'.$ok_off." HOTP QRcode successfully created".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." HOTP QRcode not created".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Creating a QRcode provisioning file for the TOTP RFC test token
$tests++;
echo_full($b_on."Creating a QRcode provisioning file for the TOTP RFC test token".$b_off.$crlf);
$size_result = $multiotp->qrcode('otpauth://totp/multiOTP%20test:multiOTP%20totp%20test?period=30&digits=6&secret='.base32_encode(hex2bin('3132333435363738393031323334353637383930')), $multiotp->GetLogFolder().'qrTOTP.png');
if (0 < $size_result)
{
echo_full("- ".$ok_on.'OK!'.$ok_off." TOTP QRcode successfully created".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." TOTP QRcode not created".$crlf);
}
echo_full($crlf);
//====================================================================
// Display the QRcode in the browser using inline images
if ($html_mode && ($size_result > 0))
{
echo_full("Displaying inline image for the test_user (HOTP QRCode Google Auhtenticator token)".$crlf);
echo_full("<img src=\"data:image/png;base64,".base64_encode($multiotp->GetUserTokenQrCode('test_user', 'multiOTP test_user token'))."\" alt=\"test_user test token\">".$crlf);
echo_full($crlf);
echo_full("Displaying inline image for TOTP QRCode Google Auhtenticator token".$crlf);
$binary_result = $multiotp->qrcode('otpauth://totp/multiOTP%20test:multiOTP%20totp%20test?secret='.base32_encode(hex2bin('3132333435363738393031323334353637383930')).'&digits=6&period=30', "binary");
echo_full("<img src=\"data:image/png;base64,".base64_encode($binary_result)."\" alt=\"multiOTP TOTP test token\">".$crlf);
echo_full($crlf);
}
//====================================================================
// Display the user token URL link
echo_full("User token URL link for test_user".$crlf);
echo_full($multiotp->GetUserTokenUrlLink('test_user', 'multiOTP test_user token').$crlf);
echo_full($crlf);
//====================================================================
// TEST: Check Base32 functions
$tests++;
$base32_vector = '3132333435363738393031323334353637383930';
$base32_encoded_vector = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ';
echo_full($b_on."Check Base32 encode/decode functions".$b_off." (should return $base32_vector)".$crlf);
$base32_encoded_result = base32_encode(hex2bin($base32_vector));
$base32_result = bin2hex(base32_decode($base32_encoded_result));
if ($base32_vector == $base32_result) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Base32 functions successfully checked".$crlf);
$successes++;
} else {
if ($base32_encoded_vector != $base32_encoded_result) {
echo_full("- ".$ko_on.'KO!'.$ko_off." Base32 encoding function failed ($base32_encoded_result)".$crlf);
}
if ($base32_vector != $base32_result) {
echo_full("- ".$ko_on.'KO!'.$ko_off." Base32 decoding function failed ($base32_result)".$crlf);
}
}
echo_full($crlf);
//====================================================================
// TEST: Check Base32 functions (random long string)
$tests++;
$length = 100001;
$base32_vector = '';
for ($i = 0; $i < $length; $i++) {
$base32_vector .= chr(rand(0,255));
}
echo_full($b_on."Check Base32 functions (random long string of ".strlen($base32_vector)." chars)".$b_off.$crlf);
$base32_encoded_result = base32_encode($base32_vector);
$base32_result = base32_decode($base32_encoded_result);
if ($base32_vector == $base32_result) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Base32 functions with long string successfully checked".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Base32 functions with long string failed".$crlf);
echo bin2hex($base32_vector).$crlf;
echo ($base32_vector).$crlf;
echo ($base32_encoded_result).$crlf;
echo bin2hex($base32_result).$crlf;
echo ($base32_result).$crlf;
}
echo_full($crlf);
//====================================================================
// Locking the test_user
echo_full($i_on);
echo_full("Locking the test_user".$crlf);
$multiotp->SetUser('test_user');
$multiotp->SetUserErrorCounter(1000);
$multiotp->WriteUserData();
$multiotp->CheckToken('LOCKME');
echo_full($crlf);
//====================================================================
// Delaying the test_user8
echo_full($i_on);
echo_full("Delaying the test_user8".$crlf);
$multiotp->SetUser('test_user8');
$multiotp->CheckToken('LOCKME1');
$multiotp->CheckToken('LOCKME2');
$multiotp->CheckToken('LOCKME3');
$multiotp->CheckToken('LOCKME4');
echo_full($crlf);
//====================================================================
// Delaying the tesT_user2
echo_full($i_on);
echo_full("Delaying the tesT_user2".$crlf);
$multiotp->SetUser('tesT_user2');
$multiotp->CheckToken('LOCKME1');
$multiotp->CheckToken('LOCKME2');
$multiotp->CheckToken('LOCKME3');
$multiotp->CheckToken('LOCKME4');
echo_full($crlf);
//====================================================================
// TEST: Number of existing users
$tests++;
echo_full($b_on."Number of existing users".$b_off.$crlf);
$count = $multiotp->GetUsersCount();
if (0 < $count)
{
echo_full("- ".$ok_on.'OK!'.$ok_off." $count existing users".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." Failed to count existing users".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: List of existing users (originally tab separated)
$tests++;
echo_full($b_on."List of existing users".$b_off.$crlf);
$list = $multiotp->GetUsersList();
echo_full(str_replace("\t",", ",$list).$crlf);
if ('' != trim($list))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." List is not empty".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." List is empty".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: List of active users (originally tab separated)
$tests++;
echo_full($b_on."List of active users".$b_off.$crlf);
$list = $multiotp->GetActiveUsersList();
echo_full(str_replace("\t",", ",$list).$crlf);
if ('' != trim($list))
{
echo_full("- ".$ok_on.'OK!'.$ok_off." List is not empty".$crlf);
$successes++;
}
else
{
echo_full("- ".$ko_on.'KO!'.$ko_off." List is empty".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: List of locked users (originally tab separated)
$tests++;
echo_full($b_on."List of locked users".$b_off.$crlf);
$list = $multiotp->GetLockedUsersList();
echo_full(str_replace("\t",", ",$list).$crlf);
if ('' != trim($list)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." List is not empty".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." List is empty".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: List of delayed users (originally tab separated)
$tests++;
echo_full($b_on."List of delayed users".$b_off.$crlf);
$list = $multiotp->GetDelayedUsersList();
echo_full(str_replace("\t",", ",$list).$crlf);
if ('' != trim($list)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." List is not empty".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." List is empty".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: List of existing users in an array
$tests++;
echo_full($b_on."List of existing users in an array".$b_off.$crlf);
$counter = 0;
foreach($multiotp->GetDetailedUsersArray() as $one_detail) {
echo_full($one_detail['user'].': '.encode_utf8_if_needed($one_detail['description']).$crlf);
$counter++;
}
if ($counter > 0) {
echo_full("- ".$ok_on.'OK!'.$ok_off." List is not empty".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." List is empty".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Check if user fast_user exists
$tests++;
echo_full($b_on."Check if the user fast_user does not exist".$b_off.$crlf);
if (!$multiotp->CheckUserExists('fast_user')) {
echo_full("- ".$ok_on.'OK!'.$ok_off." User fast_user does not exist".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." fast_user exist".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Import CSV test tokens definition file
$tests++;
echo_full($b_on."Import CSV test tokens definition file".$b_off.$crlf);
if ($multiotp->ImportTokensFile('test-tokens.csv', 'test-tokens.csv')) {
echo_full("- ".$ok_on.'OK!'.$ok_off." File test-tokens.csv successfully imported".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Unable to import test-tokens.csv file".$crlf);
}
echo_full($crlf);
//====================================================================
// List of existing tokens (originally tab separated)
$tests++;
echo_full($b_on."List of existing CSV tokens".$b_off.$crlf);
$list = $multiotp->GetTokensList();
echo_full(str_replace("\t",", ",$list).$crlf);
if (FALSE !== mb_strpos(mb_strtolower($list), mb_strtolower('ABCDEF012302'))) {
echo_full("- ".$ok_on.'OK!'.$ok_off." CSV Token ABCDEF012302 is present".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." CSV Token ABCDEF012302 is missing".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Import PSKC test tokens definition file
$tests++;
echo_full($b_on."Import PSKC test tokens definition file".$b_off.$crlf);
$token_import_error = FALSE;
if (!$multiotp->ImportTokensFile('oath/pskc-hotp-aes.txt', 'pskc-hotp-aes.txt', '12345678901234567890123456789012', '1122334455667788990011223344556677889900')) {
if (!file_exists('oath/pskc-hotp-aes.txt')) {
echo_full("- file oath/pskc-hotp-aes.txt doesn't exists".$crlf);
} else {
echo_full("- oath/pskc-hotp-aes.txt not imported correctly".$crlf);
}
$token_import_error = TRUE;
}
if (!$multiotp->ImportTokensFile('oath/pskc-hotp-pbe.txt', 'pskc-hotp-pbe.txt', 'qwerty', 'bdaab8d648e850d25a3289364f7d7eaaf53ce581')) {
echo_full("- oath/pskc-hotp-pbe.txt not imported correctly".$crlf);
$token_import_error = TRUE;
}
if (!$multiotp->ImportTokensFile('oath/pskc-totp-aes.txt', 'pskc-totp-aes.txt', '12345678901234567890123456789012', '1122334455667788990011223344556677889900')) {
echo_full("- oath/pskc-totp-aes.txt not imported correctly".$crlf);
$token_import_error = TRUE;
}
if (!$multiotp->ImportTokensFile('oath/pskc-totp-pbe.txt', 'pskc-totp-pbe.txt', 'qwerty', 'bdaab8d648e850d25a3289364f7d7eaaf53ce581')) {
echo_full("- oath/pskc-totp-pbe.txt not imported correctly".$crlf);
$token_import_error = TRUE;
}
if (!$multiotp->ImportTokensFile('oath/tokens_hotp_aes.pskc', 'tokens_hotp_aes.pskc', '12345678901234567890123456789012', '')) {
echo_full("- oath/tokens_hotp_aes.pskc not imported correctly".$crlf);
$token_import_error = TRUE;
}
if (!$multiotp->ImportTokensFile('oath/tokens_totp_aes.pskc', 'tokens_totp_aes.pskc', '12345678901234567890123456789012', '')) {
echo_full("- oath/tokens_totp_aes.pskc not imported correctly".$crlf);
$token_import_error = TRUE;
}
if (!$multiotp->ImportTokensFile('oath/tokens_hotp_pbe.pskc', 'tokens_hotp_pbe.pskc', 'qwerty', '')) {
echo_full("- oath/tokens_hotp_pbe.pskc not imported correctly".$crlf);
$token_import_error = TRUE;
}
if (!$multiotp->ImportTokensFile('oath/tokens_totp_pbe.pskc', 'tokens_totp_pbe.pskc', 'qwerty', '')) {
echo_full("- oath/tokens_totp_pbe.pskc not imported correctly".$crlf);
$token_import_error = TRUE;
}
// $multiotp->ImportTokensFile('oath/tokens_ocra_aes.pskc', 'tokens_ocra_aes.pskc', '12345678901234567890123456789012', '');
// $multiotp->ImportTokensFile('oath/tokens_ocra_pbe.pskc', 'tokens_ocra_pbe.pskc', 'qwerty', '');
if (!$token_import_error) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Test files from oath successfully imported".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Unable to import test files from ".getcwd()."/oath".$crlf);
}
echo_full($crlf);
//====================================================================
// List of existing tokens (originally tab separated)
$tests++;
echo_full($b_on."List of existing tokens".$b_off.$crlf);
$list = $multiotp->GetTokensList();
echo_full(str_replace("\t",", ",$list).$crlf);
if (FALSE !== mb_strpos(mb_strtolower($list), mb_strtolower('ZZ0100000000'))) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Token ZZ0100000000 is present".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Token ZZ0100000000 is missing".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Rename token ZZ0100000000 to ZZ0100000001
$tests++;
echo_full($b_on."Rename token ZZ0100000000 to ZZ0100000001".$b_off.$crlf);
$multiotp->SetToken('ZZ0100000000');
if ($multiotp->RenameCurrentToken('ZZ0100000001')) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Token ZZ0100000000 successfully renamed to ZZ0100000001".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Unable to rename the token ZZ0100000000".$crlf);
$multiotp->DeleteToken('ZZ0100000000');
}
echo_full($crlf);
//=======================================
// Check if the token ZZ0100000001 exists
$tests++;
echo_full($b_on."Check if the token ZZ0100000001 exists".$b_off.$crlf);
if ($multiotp->CheckTokenExists('ZZ0100000001')) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Token ZZ0100000001 exists".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Token ZZ0100000001 is missing".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: WriteTokenData / ReadTokenData with ZZ0100000001
$tests++;
echo_full($b_on."Write/Read information concerning token ZZ0100000001".$b_off.$crlf);
$test_value = 'tEStToKeN';
$multiotp->ReadTokenData('ZZ0100000001');
$multiotp->SetTokenDescription($test_value);
$multiotp->WriteTokenData();
$multiotp->SetTokenDescription('');
$multiotp->ReadTokenData('ZZ0100000001');
if ($test_value == $multiotp->GetTokenDescription()) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Write/Read information concerning token ZZ0100000001 successfully done".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Write/Read information concerning token ZZ0100000001 failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Delete tokens ZZ0000000000 and ZZ0100000001
$tests++;
echo_full($b_on."Delete tokens ZZ0000000000 and ZZ0100000001".$b_off.$crlf);
if (($multiotp->DeleteToken('ZZ0000000000')) && ($multiotp->DeleteToken('ZZ0100000001')) && (!$multiotp->CheckTokenExists('ZZ0100000001'))) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Tokens ZZ0000000000 and ZZ0100000001 successfully deleted".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Failed during tokens deletion".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Create the device 123456 test_device
$tests++;
$multiotp->DeleteDevice("123456", TRUE);
echo_full($b_on."Create the device test_device (123456)".$b_off.$crlf);
if ($multiotp->CreateDevice("123456", 'test_device', 'test_secret', '123.124.125.126', '255.255.255.255', 'test_device', FALSE)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Device test_device successfully created".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of device test_device failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Read the device 123456 test_device
$tests++;
echo_full($b_on."Read the device test_device (123456)".$b_off.$crlf);
$multiotp->SetDeviceDescription('');
$multiotp->ReadDeviceData("123456");
$description = $multiotp->GetDeviceDescription();
if ('test_device' == $description) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Device test_device successfully read".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Failed to read the device test_device".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: List of existing devices (originally tab separated)
$tests++;
echo_full($b_on."List of existing devices".$b_off.$crlf);
$list = $multiotp->GetDevicesList();
echo_full(str_replace("\t",", ",$list).$crlf);
if ('' != trim($list)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." List is not empty".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." List is empty".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Delete the device test_device
$tests++;
echo_full($b_on."Delete the device test_device".$b_off.$crlf);
if ($multiotp->DeleteDevice("123456")) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Device test_device successfully deleted".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." DeleteDevice function failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Create the group 123456 test_group
$tests++;
$multiotp->DeleteGroup("123456", TRUE);
echo_full($b_on."Create the group test_group (123456)".$b_off.$crlf);
if ($multiotp->CreateGroup("123456", 'test_group', 'test_description')) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Group test_group successfully created".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Creation of group test_group failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Read the group 123456 test_group
$tests++;
echo_full($b_on."Read the group test_group (123456)".$b_off.$crlf);
$multiotp->SetGroupDescription('');
$multiotp->ReadGroupData("123456");
$description = $multiotp->GetGroupDescription();
if ('test_description' == $description) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Group test_group successfully read".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Failed to read the group test_group".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Check if the group 123456 test_group exists
$tests++;
echo_full($b_on."Check if the group test_group (123456) exists".$b_off.$crlf);
if ($multiotp->CheckGroupExists("123456")) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Group test_group exists".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Group test_group doesn't exists".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Set an ldap_in_group with special chars
$tests++;
echo_full($b_on."Set an ldap_in_group with special chars".$b_off.$crlf);
$my_groups = "\"My-group\"";
$multiotp->SetLdapInGroup($my_groups);
$multiotp->WriteConfigData();
$multiotp->ReadConfigData();
$in_group = $multiotp->GetLdapInGroup();
if ($in_group == $my_groups) {
echo_full("- ".$ok_on.'OK!'.$ok_off." The ldap-in-group is set correctly (<b>".htmlentities($in_group)."</b>)".$crlf);
$successes++;
} else {
echo_full("- ".$ok_on.'OK!'.$ok_off." The ldap-in-group is not set correctly (<b>".htmlentities($in_group)."</b>)".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: List of existing groups (originally tab separated)
$tests++;
echo_full($b_on."List of existing groups".$b_off.$crlf);
$list = $multiotp->GetGroupsList();
echo_full(str_replace("\t",", ",$list).$crlf);
if ('' != trim($list)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." List is not empty".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." List is empty".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Delete the group test_group
$tests++;
echo_full($b_on."Delete the group test_group".$b_off.$crlf);
if ($multiotp->DeleteGroup(123456)) {
echo_full("- ".$ok_on.'OK!'.$ok_off." Group test_group successfully deleted".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." DeleteGroup function failed".$crlf);
}
echo_full($crlf);
//====================================================================
// TEST: Show the log
$tests++;
echo_full($b_on."Show the log".$b_off.$crlf);
if (FALSE !== ($log = $multiotp->ShowLog(TRUE))) {
echo_full(str_replace("\n",$crlf, htmlentities($log)));
echo_full("- ".$ok_on.'OK!'.$ok_off." Log successfuly displayed".$crlf);
$successes++;
} else {
echo_full("- ".$ko_on.'KO!'.$ko_off." Unable to show the log".$crlf);
}
echo_full($crlf);
}
//====================================================================
echo_full($b_on."Network information".$b_off.$crlf);
$network_info = $multiotp->GetNetworkInfo();
echo_full(implode($crlf, $network_info));
echo_full($crlf);
echo_full($crlf);
// TESTS result
if ($html_mode) {
echo_full('<div id="test_result">');
}
echo_full($b_on);
if (!$GLOBALS['noresume']) {
if ($successes == $tests) {
echo($ok_on."OK! ALL $tests TESTS HAVE PASSED SUCCESSFULLY !".$ok_off.$crlf);
} else {
echo($ko_on."KO! ONLY $successes/$tests TESTS HAVE PASSED SUCCESSFULLY !".$ko_off.$crlf);
}
}
echo_full($b_off);
if ($html_mode) {
echo_full('</div>');
}
echo_full($crlf);
echo_full($hr);
echo_full("Time spent for the whole check.multiotp.class.php: ".(1+time()-$first_time)." second(s)");
echo_full($crlf);
echo_full($crlf);
$multiotp->SetBackendType($default_backend);
$multiotp->_config_data['attributes_to_encrypt'] = '';
$multiotp->WriteConfigData();
if ($html_mode && (!isset($GLOBALS['no_header']))) {
echo <<<EOWEBFOOTER
</body>
</html>
EOWEBFOOTER;
}
?>
|