From ee9631a82d3a39603ac6c07e19fff9dbc8b6ef62 Mon Sep 17 00:00:00 2001 From: Austin Date: Mon, 22 Nov 2021 06:18:05 -0500 Subject: [PATCH] cleanup twofactor --- globals/Dependencies/Users/TwoFactor.php | 159 +++++++++++++++++++++++ globals/config.php | 6 +- globals/functions.php | 151 --------------------- html/2fa.php | 6 +- html_api/settings/index.php | 5 +- html_api/settings/twofactor/activate.php | 3 +- html_api/settings/twofactor/disable.php | 3 +- html_api/settings/twofactor/settings.php | 3 +- 8 files changed, 177 insertions(+), 159 deletions(-) create mode 100644 globals/Dependencies/Users/TwoFactor.php diff --git a/globals/Dependencies/Users/TwoFactor.php b/globals/Dependencies/Users/TwoFactor.php new file mode 100644 index 0000000..408e11c --- /dev/null +++ b/globals/Dependencies/Users/TwoFactor.php @@ -0,0 +1,159 @@ +createSecret(); + $keycheck = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `secret` = :ac"); + $keycheck->bindParam(":ac", $secret, PDO::PARAM_STR); + $keycheck->execute(); + } while ($keycheck->rowCount() != 0); + return $secret; + } + + public static function deauth2FAUserSession() + { + $session = $GLOBALS['user']->sessionCookieID; + $check = $GLOBALS['pdo']->prepare("UPDATE `sessions` SET `twoFactorUnlocked` = 0 WHERE `id` = :session"); + $check->bindParam(":session", $session, PDO::PARAM_INT); + if ($check->execute()) { + return true; + } + return false; + } + + public static function deleteUser2FA($userid) + { + $del = $GLOBALS['pdo']->prepare("DELETE FROM `google_2fa` WHERE `userid` = :uid"); + $del->bindParam(":uid", $userid, PDO::PARAM_INT); + $del->execute(); + if ($del->rowCount() > 0) { + TwoFactor::deauth2FAUserSession(); + return true; + } + return false; + } + + public static function getUser2FASecret($userid) + { + $code = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `userid` = :uid"); + $code->bindParam(":uid", $userid, PDO::PARAM_INT); + $code->execute(); + if ($code->rowCount() > 0) { + return $code->fetch(PDO::FETCH_OBJ)->secret; + } + } + + public static function verify2FACode($userid, $code) + { + $secret = TwoFactor::getUser2FASecret($userid); + if ($secret) { + if ($GLOBALS['authenticator']->verifyCode($secret, $code, 0)) { + return true; + } + } + return false; + } + + public static function is2FAInitialized($userid) + { + $isinit = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `validated` = 1 AND `userid` = :uid"); + $isinit->bindParam(":uid", $userid, PDO::PARAM_INT); + $isinit->execute(); + if ($isinit->rowCount() > 0) { + return true; + } + return false; + } + + public static function auth2FAUserSession() + { + $session = $GLOBALS['user']->sessionCookieID; + $check = $GLOBALS['pdo']->prepare("UPDATE `sessions` SET `twoFactorUnlocked` = 1 WHERE `id` = :session"); + $check->bindParam(":session", $session, PDO::PARAM_INT); + if ($check->execute()) { + return true; + } + return false; + } + + public static function activateUser2FA($userid, $code) //after initializing we make sure it works with a first time activation code + { + if(!TwoFactor::is2FAInitialized($userid) && + TwoFactor::verify2FACode($userid, $code)) { + $check = $GLOBALS['pdo']->prepare("UPDATE `google_2fa` SET `validated` = 1 WHERE `userid` = :uid"); + $check->bindParam(":uid", $userid, PDO::PARAM_INT); + if ($check->execute()) { + TwoFactor::auth2FAUserSession(); + return true; + } + } + return false; + } + + public static function initialize2FA($userid) + { + $check = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `userid` = :uid"); + $check->bindParam(":uid", $userid, PDO::PARAM_INT); + $check->execute(); + if ($check->rowCount() == 0) { + $username = getUsername($userid); + if ($username) { + $secret = TwoFactor::safeGenerate2FASecret(); + $qrcode = $GLOBALS['authenticator']->getQRCodeGoogleUrl($username, $secret, "Alphaland"); + $new2fa = $GLOBALS['pdo']->prepare("INSERT INTO `google_2fa`(`userid`, `secret`, `qr`, `whenGenerated`) VALUES (:uid, :secret, :qr, UNIX_TIMESTAMP())"); + $new2fa->bindParam(":uid", $userid, PDO::PARAM_INT); + $new2fa->bindParam(":secret", $secret, PDO::PARAM_STR); + $new2fa->bindParam(":qr", $qrcode, PDO::PARAM_STR); + $new2fa->execute(); + } + } + } + + public static function getUser2FAQR($userid) + { + $qrcode = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `userid` = :uid"); + $qrcode->bindParam(":uid", $userid, PDO::PARAM_INT); + $qrcode->execute(); + if ($qrcode->rowCount() > 0) { + return $qrcode->fetch(PDO::FETCH_OBJ)->qr; + } + } + + public static function isSession2FAUnlocked() + { + $localuser = $GLOBALS['user']->id; + $session = $GLOBALS['user']->sessionCookieID; + $check = $GLOBALS['pdo']->prepare("SELECT * FROM `sessions` WHERE `twoFactorUnlocked` = 1 AND `id` = :session"); + $check->bindParam(":session", $session, PDO::PARAM_INT); + $check->execute(); + if ($check->rowCount() > 0 || !TwoFactor::is2FAInitialized($localuser)) { + return true; + } + return false; + } + + public static function attemptSession2FAUnlock($code) + { + $localuser = $GLOBALS['user']->id; + if (!TwoFactor::isSession2FAUnlocked()) { + if (TwoFactor::verify2FACode($localuser, $code)) { + TwoFactor::auth2FAUserSession(); + return true; + } + } + return false; + } + } +} \ No newline at end of file diff --git a/globals/config.php b/globals/config.php index b50fb24..246ae95 100644 --- a/globals/config.php +++ b/globals/config.php @@ -91,6 +91,7 @@ try //alphaland specfic dependencies include "C:/Webserver/nginx/Alphaland/globals/Dependencies/Users/Activation.php"; + include "C:/Webserver/nginx/Alphaland/globals/Dependencies/Users/TwoFactor.php"; //authenticator $authenticator = new PHPGangsta_GoogleAuthenticator(); @@ -130,9 +131,12 @@ try $activated = new Alphaland\Users\Activation(); $activated = $activated::isUserActivated($GLOBALS['user']->id); + + $twofactor = new Alphaland\Users\TwoFactor(); + $twofactor = $twofactor::isSession2FAUnlocked(); + $maintenance = checkIfUnderMaintenance(); $banned = checkIfBanned($GLOBALS['user']->id); - $twofactor = isSession2FAUnlocked(); //step 1, check if under maintenance if ($maintenance) { //maintenance redirect diff --git a/globals/functions.php b/globals/functions.php index 3f756e3..8b90b1c 100644 --- a/globals/functions.php +++ b/globals/functions.php @@ -5236,157 +5236,6 @@ function getBC($id) { //settings portion { -function safeGenerate2FASecret() -{ - $secret = ""; - while (true) { - $secret = $GLOBALS['authenticator']->createSecret(); - - $keycheck = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `secret` = :ac"); - $keycheck->bindParam(":ac", $secret, PDO::PARAM_STR); - $keycheck->execute(); - if ($keycheck->rowCount() == 0) { - break; - } - } - return $secret; -} - -function deleteUser2FA($userid) -{ - $del = $GLOBALS['pdo']->prepare("DELETE FROM `google_2fa` WHERE `userid` = :uid"); - $del->bindParam(":uid", $userid, PDO::PARAM_INT); - $del->execute(); - if ($del->rowCount() > 0) { - deauth2FAUserSession(); - return true; - } - return false; -} - -function getUser2FASecret($userid) -{ - $code = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `userid` = :uid"); - $code->bindParam(":uid", $userid, PDO::PARAM_INT); - $code->execute(); - if ($code->rowCount() > 0) { - return $code->fetch(PDO::FETCH_OBJ)->secret; - } -} - -function verify2FACode($userid, $code) -{ - $secret = getUser2FASecret($userid); - if ($secret) { - if ($GLOBALS['authenticator']->verifyCode($secret, $code, 0)) { - return true; - } - } - return false; -} - -function activateUser2FA($userid, $code) //after initializing we make sure it works with a first time activation code -{ - if(!is2FAInitialized($userid) && - verify2FACode($userid, $code)) { - $check = $GLOBALS['pdo']->prepare("UPDATE `google_2fa` SET `validated` = 1 WHERE `userid` = :uid"); - $check->bindParam(":uid", $userid, PDO::PARAM_INT); - if ($check->execute()) { - auth2FAUserSession(); - return true; - } - } - return false; -} - -function is2FAInitialized($userid) -{ - $isinit = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `validated` = 1 AND `userid` = :uid"); - $isinit->bindParam(":uid", $userid, PDO::PARAM_INT); - $isinit->execute(); - if ($isinit->rowCount() > 0) { - return true; - } - return false; -} - -function initialize2FA($userid) -{ - $check = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `userid` = :uid"); - $check->bindParam(":uid", $userid, PDO::PARAM_INT); - $check->execute(); - if ($check->rowCount() == 0) { - $username = getUsername($userid); - if ($username) { - $secret = safeGenerate2FASecret(); - $qrcode = $GLOBALS['authenticator']->getQRCodeGoogleUrl($username, $secret, "Alphaland"); - $new2fa = $GLOBALS['pdo']->prepare("INSERT INTO `google_2fa`(`userid`, `secret`, `qr`, `whenGenerated`) VALUES (:uid, :secret, :qr, UNIX_TIMESTAMP())"); - $new2fa->bindParam(":uid", $userid, PDO::PARAM_INT); - $new2fa->bindParam(":secret", $secret, PDO::PARAM_STR); - $new2fa->bindParam(":qr", $qrcode, PDO::PARAM_STR); - $new2fa->execute(); - } - } -} - -function getUser2FAQR($userid) -{ - $qrcode = $GLOBALS['pdo']->prepare("SELECT * FROM `google_2fa` WHERE `userid` = :uid"); - $qrcode->bindParam(":uid", $userid, PDO::PARAM_INT); - $qrcode->execute(); - if ($qrcode->rowCount() > 0) { - return $qrcode->fetch(PDO::FETCH_OBJ)->qr; - } -} - -function isSession2FAUnlocked() -{ - $localuser = $GLOBALS['user']->id; - $session = $GLOBALS['user']->sessionCookieID; - - $check = $GLOBALS['pdo']->prepare("SELECT * FROM `sessions` WHERE `twoFactorUnlocked` = 1 AND `id` = :session"); - $check->bindParam(":session", $session, PDO::PARAM_INT); - $check->execute(); - if ($check->rowCount() > 0 || !is2FAInitialized($localuser)) { - return true; - } - return false; -} - -function auth2FAUserSession() -{ - $session = $GLOBALS['user']->sessionCookieID; - - $check = $GLOBALS['pdo']->prepare("UPDATE `sessions` SET `twoFactorUnlocked` = 1 WHERE `id` = :session"); - $check->bindParam(":session", $session, PDO::PARAM_INT); - if ($check->execute()) { - return true; - } - return false; -} - -function deauth2FAUserSession() -{ - $session = $GLOBALS['user']->sessionCookieID; - - $check = $GLOBALS['pdo']->prepare("UPDATE `sessions` SET `twoFactorUnlocked` = 0 WHERE `id` = :session"); - $check->bindParam(":session", $session, PDO::PARAM_INT); - if ($check->execute()) { - return true; - } - return false; -} - -function attemptSession2FAUnlock($code) -{ - $localuser = $GLOBALS['user']->id; - if (!isSession2FAUnlocked()) { - if (verify2FACode($localuser, $code)) { - auth2FAUserSession(); - } - } -} - function setBlurb($newblurb) { $newblurb = cleanInput($newblurb); diff --git a/html/2fa.php b/html/2fa.php index 1333aad..cb73953 100644 --- a/html/2fa.php +++ b/html/2fa.php @@ -1,12 +1,14 @@ id; //user info @@ -27,7 +28,7 @@ $tradepref = null; $theme = $userquery->theme; //initialize 2FA in the database if it hasnt been already -initialize2FA($userid); +$twofactor::initialize2FA($userid); $userInfo = array ( "userid" => $userid, @@ -35,7 +36,7 @@ $userInfo = array ( "email" => $email, "verified" => $verified, "blurb" => $blurb, - "twofactorenabled" => is2FAInitialized($userid), + "twofactorenabled" => $twofactor::is2FAInitialized($userid), "referralprogram" => inReferralProgram($userid), "joinpref" => $joinpref, "tradepref" => $tradepref, diff --git a/html_api/settings/twofactor/activate.php b/html_api/settings/twofactor/activate.php index 1c671a1..c7de746 100644 --- a/html_api/settings/twofactor/activate.php +++ b/html_api/settings/twofactor/activate.php @@ -8,6 +8,7 @@ Alphaland 2021 header("Access-Control-Allow-Origin: https://www.alphaland.cc"); header("access-control-allow-credentials: true"); +$twofactor = new Alphaland\Users\TwoFactor(); $userid = $user->id; $data = json_decode(file_get_contents('php://input')); @@ -20,5 +21,5 @@ else { $code = $data->code; header('Content-Type: application/json'); - echo json_encode(array("success" => activateUser2FA($userid, $code))); + echo json_encode(array("success" => $twofactor::activateUser2FA($userid, $code))); } \ No newline at end of file diff --git a/html_api/settings/twofactor/disable.php b/html_api/settings/twofactor/disable.php index 3ac6e14..fe8387c 100644 --- a/html_api/settings/twofactor/disable.php +++ b/html_api/settings/twofactor/disable.php @@ -9,6 +9,7 @@ header("Access-Control-Allow-Origin: https://www.alphaland.cc"); header("access-control-allow-credentials: true"); header('Content-Type: application/json'); +$twofactor = new Alphaland\Users\TwoFactor(); $userid = $user->id; -echo json_encode(array("success" => deleteUser2FA($userid))); \ No newline at end of file +echo json_encode(array("success" => $twofactor::deleteUser2FA($userid))); \ No newline at end of file diff --git a/html_api/settings/twofactor/settings.php b/html_api/settings/twofactor/settings.php index 9b17dfd..efdd667 100644 --- a/html_api/settings/twofactor/settings.php +++ b/html_api/settings/twofactor/settings.php @@ -10,6 +10,7 @@ header("Access-Control-Allow-Origin: https://www.alphaland.cc"); header("access-control-allow-credentials: true"); header('Content-Type: application/json'); +$twofactor = new Alphaland\Users\TwoFactor(); $userid = $user->id; -die(json_encode(["qr"=>getUser2FAQR($userid),"secret"=>getUser2FASecret($userid)])); \ No newline at end of file +die(json_encode(["qr"=>$twofactor::getUser2FAQR($userid),"secret"=>$twofactor::getUser2FASecret($userid)])); \ No newline at end of file