diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..f3dbd81df688ba6f9caca5cd4af9386ea4a65b08 --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "spomky-labs/otphp": "^10.0" + } +} diff --git a/config/config-template.php b/config/config-template.php new file mode 100644 index 0000000000000000000000000000000000000000..5927622f63586cc83212cecf3f7f1b416a915095 --- /dev/null +++ b/config/config-template.php @@ -0,0 +1,4 @@ +<?php + +define('DB_CONFIG_LOCATION', 'location of otp_config.php'); + diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000000000000000000000000000000000000..5927622f63586cc83212cecf3f7f1b416a915095 --- /dev/null +++ b/config/config.php @@ -0,0 +1,4 @@ +<?php + +define('DB_CONFIG_LOCATION', 'location of otp_config.php'); + diff --git a/config/otp_config-template.php b/config/otp_config-template.php new file mode 100644 index 0000000000000000000000000000000000000000..685d80733fda9be864bd0463a9149b0143050354 --- /dev/null +++ b/config/otp_config-template.php @@ -0,0 +1,6 @@ +<?php +define('DB_HOST','edugain-db'); +define('DB_DATABASE','edugain'); +define('USER', 'otp'); +define('PASSWORD', 'xxxx'); + diff --git a/web/otp-server.php b/web/otp-server.php new file mode 100644 index 0000000000000000000000000000000000000000..be9b75e5de7ebfe2d67fbf8fc9b329054e4319a9 --- /dev/null +++ b/web/otp-server.php @@ -0,0 +1,83 @@ +<?php +/* + * The server can dwo two things - it can test if the user is defined or it can + * validate the otp_code against the secret in the database. + * + * Return values: + * -1 - user not found in the DB + * 0 - user exists but there was a missmatch in the code + * 1 - there was a success in verification of the code against the user secret + * 2 - the code has not been provided - the user has not been verified yet + * 3 - the code has not been provided - just confirming that the user is verified + * 4 - the code has been used for a second time + */ +session_start(); + +require_once('../vendor/autoload.php'); +require_once('../../config/config.php'); +require_once(DB_CONFIG_LOCATION); +use OTPHP\TOTP; + +$mysqli = new mysqli(DB_HOST, USER, PASSWORD, DB_DATABASE); +if ($mysqli->connect_error) { + die("Not connected"); +} +$mysqli->set_charset('utf8'); +$mysqli->query("SET time_zone='+00:00'"); + +if (empty($_GET['user'])) { + exit; +} + +$user = filter_var($_GET['user'], FILTER_SANITIZE_EMAIL); +$out = 0; + +$result = $mysqli->query("SELECT secret, last_code, verified from otp where user ='$user'"); + +if ($result) { + if ($result->num_rows == 0) { + $out = -1; // the user is not defined + } else { + $r = $result->fetch_row(); + $otpSecret = $r[0]; + $otpLastCode = $r[1]; + $verified = $r[2]; + $out = 0; // the user exists in the database - this is a temporary code value + } +} else { + exit; +} + +$otpCode = filter_var($_GET['otp'], FILTER_SANITIZE_NUMBER_INT); + +// check if any code has been passed and if so update the result code accordingle - again this value is temporary + +if ($otpCode == '' && $out == 0) { + if ($verified == 1) { + $out = 3; + } else { + $out = 2; + } +} + + +if ($out == 0) { // the otp code must have been provided and the user exists in the DB, the secret is taken form the DB + $otpObject = TOTP::create($otpSecret); + $otpTestCode = $otpObject->now(); + if ($otpCode === $otpTestCode) { + if($otpCode === $otpLastCode) { + $out = 4; + } else { + $mysqli->query("UPDATE otp SET verified = 1, last_code = $otpCode where user = '$user'"); + $out = 1; + } + } else { + // there was a missmatch in the codes + $out = 0; + } +} +header('Content-type: application/json; charset=utf-8'); +header('Access-Control-Allow-Origin: *'); +print json_encode($out, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + +