Example #1
0
 /**
  * Enable the Two-factor Authentication.
  *
  * @return \Cake\Network\Response|void
  */
 public function enable()
 {
     if (!$this->request->is('post')) {
         return $this->redirect(['action' => 'configure']);
     }
     $this->loadModel('UsersTwoFactorAuth');
     $userTfa = $this->UsersTwoFactorAuth->find()->where(['UsersTwoFactorAuth.user_id' => $this->Auth->user('id')])->first();
     if (is_null($userTfa) || empty($userTfa->secret) || !isset($this->request->data['code'])) {
         $this->Flash->error(__('Two-factor secret verification failed. Please verify your secret and try again.'));
         return $this->redirect(['action' => 'configure']);
     }
     $tfa = new TwoFactorAuth('Xeta');
     if ($tfa->verifyCode($userTfa->secret, $this->request->data['code']) === true && $this->request->data['code'] != $userTfa->current_code) {
         $this->loadModel('Users');
         $user = $this->Users->find()->where(['Users.id' => $this->Auth->user('id')])->select(['id', 'username', 'two_factor_auth_enabled'])->first();
         $user->two_factor_auth_enabled = true;
         $this->Users->save($user);
         $data = ['session' => $this->request->clientIp() . $this->request->header('User-Agent') . gethostbyaddr($this->request->clientIp()), 'current_code' => $this->request->data['code'], 'recovery_code' => $this->_generateNewRecoveryCode($userTfa->username)];
         $this->UsersTwoFactorAuth->patchEntity($userTfa, $data);
         $this->UsersTwoFactorAuth->save($userTfa);
         //Logs Event.
         $this->eventManager()->attach(new Logs());
         $event = new Event('Log.User', $this, ['user_id' => $user->id, 'username' => $user->username, 'user_ip' => $this->request->clientIp(), 'user_agent' => $this->request->header('User-Agent'), 'action' => '2FA.enabled']);
         $this->eventManager()->dispatch($event);
         $this->Flash->success(__('Two-factor authentication successfully enabled !'));
         $this->set(compact('user', 'userTfa'));
     } else {
         $this->Flash->error(__('Two-factor secret verification failed. Please verify your secret and try again.'));
         return $this->redirect(['action' => 'configure']);
     }
 }
 public function testKnownTestVectors_sha512()
 {
     //Known test vectors for SHA512: https://tools.ietf.org/html/rfc6238#page-15
     $secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNA';
     //== base32encode('1234567890123456789012345678901234567890123456789012345678901234')
     $tfa = new TwoFactorAuth('Test', 8, 30, 'sha512');
     $this->assertEquals('90693936', $tfa->getCode($secret, 59));
     $this->assertEquals('25091201', $tfa->getCode($secret, 1111111109));
     $this->assertEquals('99943326', $tfa->getCode($secret, 1111111111));
     $this->assertEquals('93441116', $tfa->getCode($secret, 1234567890));
     $this->assertEquals('38618901', $tfa->getCode($secret, 2000000000));
     $this->assertEquals('47863826', $tfa->getCode($secret, 20000000000));
 }
Example #3
0
<!doctype html>
<html>
<head>
    <title>Demo</title>
</head>
<body>
    <ol>
        <?php 
require_once 'loader.php';
Loader::register('../lib', 'RobThree\\Auth');
use RobThree\Auth\TwoFactorAuth;
$tfa = new TwoFactorAuth('MyApp');
echo '<li>First create a secret and associate it with a user';
$secret = $tfa->createSecret();
echo '<li>Next create a QR code and let the user scan it:<br><img src="' . $tfa->getQRCodeImageAsDataUri('My label', $secret) . '"><br>...or display the secret to the user for manual entry: ' . chunk_split($secret, 4, ' ');
$code = $tfa->getCode($secret);
echo '<li>Next, have the user verify the code; at this time the code displayed by a 2FA-app would be: <span style="color:#00c">' . $code . '</span> (but that changes periodically)';
echo '<li>When the code checks out, 2FA can be / is enabled; store (encrypted?) secret with user and have the user verify a code each time a new session is started.';
echo '<li>When aforementioned code (' . $code . ') was entered, the result would be: ' . ($tfa->verifyCode($secret, $code) === true ? '<span style="color:#0c0">OK</span>' : '<span style="color:#c00">FAIL</span>');
?>
    </ol>
    <p>Note: Make sure your server-time is <a href="http://en.wikipedia.org/wiki/Network_Time_Protocol">NTP-synced</a>! Depending on the $discrepancy allowed your time cannot drift too much from the users' time!</p>
</body>
</html>
Example #4
0
/* 
 *	Made by Samerton
 *  http://worldscapemc.co.uk
 *
 *  License: MIT
 */
$page = 'tfa';
// Two factor auth
// Ensure user is logged in
if (!$user->isLoggedIn()) {
    Redirect::to('/');
    die;
}
use RobThree\Auth\TwoFactorAuth;
$tfa = new TwoFactorAuth('NamelessMC');
if (!isset($_GET['s'])) {
    // Generate secret
    $secret = $tfa->createSecret();
    if ($user->data()->tfa_secret) {
        Redirect::to('/user/settings');
        die;
    }
    $queries->update('users', $user->data()->id, array('tfa_secret' => $secret));
    ?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
Example #5
0
             $siteemail = $siteemail[0]->value;
             $to = $user_query[0]->email;
             $subject = $sitename . ' - ' . $user_language['two_factor_authentication'];
             $message = $email_language['greeting'] . PHP_EOL . $user_language['tfa_email_contents'] . PHP_EOL . PHP_EOL . $code . PHP_EOL . PHP_EOL . $email_language['thanks'] . PHP_EOL . $sitename;
             $headers = 'From: ' . $siteemail . "\r\n" . 'Reply-To: ' . $siteemail . "\r\n" . 'X-Mailer: PHP/' . phpversion();
             mail($to, $subject, $message, $headers);
         }
     }
     // Ask user to input code now
     require 'core/includes/tfa_signin.php';
     die;
 } else {
     // Verify code
     if ($user_query[0]->tfa_type == 1) {
         // App
         $tfa = new TwoFactorAuth('NamelessMC');
         if ($tfa->verifyCode($user_query[0]->tfa_secret, $_POST['tfa_code']) !== true) {
             Session::flash('tfa_signin', '<div class="alert alert-danger">' . $user_language['invalid_tfa'] . '</div>');
             require 'core/includes/tfa_signin.php';
             die;
         }
     } else {
         // Email
         // Get the code
         $code = $user_query[0]->tfa_secret;
         $code = explode(':', $code);
         // Check it hasn't expired
         if ($code[1] < strtotime("-10 minutes")) {
             // Expired
             Session::flash('signin', '<div class="alert alert-danger">' . $user_language['invalid_tfa'] . '</div>');
             Redirect::to('/signin');
 /**
  * getQRCodeImageAsDataUri
  * @return string base64 string containing QR code for shared secret
  */
 public function getQRCodeImageAsDataUri($issuer, $secret)
 {
     return $this->tfa->getQRCodeImageAsDataUri($issuer, $secret);
 }
Example #7
0
 /**
  * Ask to the user the 2FA code and verify it.
  *
  * @return \Cake\Network\Response|void
  */
 public function tfa()
 {
     if ($this->Auth->user()) {
         return $this->redirect($this->Auth->redirectUrl());
     }
     if ($this->request->is('post')) {
         $this->loadModel('UsersTwoFactorAuth');
         $id = $this->Cookie->read('CookieTfa');
         if (empty($id) || $id == false) {
             $this->Cookie->delete('CookieTfa');
             return $this->redirect($this->Auth->config('loginAction'));
         }
         try {
             $id = Security::decrypt(base64_decode($id), Configure::read('Security.key'));
         } catch (\Exception $e) {
             $this->Flash->error(__('The link used for the Two-factor Authentication is incorrect.'));
             return $this->redirect($this->Auth->config('loginAction'));
         }
         $userTfa = $this->UsersTwoFactorAuth->find()->where(['user_id' => $id])->first();
         $tfa = new TwoFactorAuth('Xeta');
         $isAuthorized = false;
         $recoveryCodeUsed = false;
         if ($tfa->verifyCode($userTfa->secret, $this->request->data['code']) === true && $this->request->data['code'] !== $userTfa->current_code) {
             $isAuthorized = true;
             //Check recovery code and verify if the recovery code is not already used.
         } elseif ($userTfa->recovery_code === $this->request->data['code'] && $userTfa->recovery_code_used == false && $this->request->data['code'] !== $userTfa->current_code) {
             $isAuthorized = true;
             $recoveryCodeUsed = true;
         }
         if ($isAuthorized === true) {
             $data = ['session' => $this->request->clientIp() . $this->request->header('User-Agent') . gethostbyaddr($this->request->clientIp()), 'current_code' => $recoveryCodeUsed === true ? 'recovery' : $this->request->data['code'], 'recovery_code_used' => $recoveryCodeUsed === true ? 1 : $userTfa->recovery_code_used];
             $this->UsersTwoFactorAuth->patchEntity($userTfa, $data);
             $this->UsersTwoFactorAuth->save($userTfa);
             //Login the user.
             $userLogin = $this->Users->find()->where(['id' => $id])->hydrate(false)->first();
             unset($userLogin['password']);
             $this->_handleLogin($userLogin);
             $this->Cookie->delete('CookieTfa');
             //Logs Event.
             $this->eventManager()->attach(new Logs());
             $event = new Event('Log.User', $this, ['user_id' => $userLogin['id'], 'username' => $userLogin['username'], 'user_ip' => $this->request->clientIp(), 'user_agent' => $this->request->header('User-Agent'), 'action' => '2FA.recovery_code.used']);
             $this->eventManager()->dispatch($event);
             return $this->redirect(['controller' => 'pages', 'action' => 'home']);
         } else {
             $this->Flash->error(__('Two-factor secret verification failed. Please verify your code and try again.'));
         }
     }
     $id = $this->Cookie->read('CookieTfa');
     if (empty($id) || $id == false) {
         $this->Cookie->delete('CookieTfa');
         return $this->redirect($this->Auth->config('loginAction'));
     }
 }