예제 #1
0
 /**
  * Displays the page used to set up login verification using one-time
  * passwords.
  */
 public function setup()
 {
     $auth = AuthManager::instance();
     $store = StoreManager::instance();
     $user = $auth->getUser();
     $tpl = new \Template();
     $token = new SecurityToken();
     // Require HTTPS, redirect if necessary
     $this->checkHttps('redirect', true);
     if (!$auth->isLoggedIn()) {
         $this->f3->reroute('/my/dashboard');
         return;
     }
     if ($this->f3->get('POST.op') == $this->t('Disable')) {
         if ($this->f3->exists('POST.tk') === false || !$token->verify($this->f3->get('POST.tk'), 'otp')) {
             $this->f3->set('message', $this->t('SimpleID detected a potential security attack.  Please try again.'));
             $this->f3->mock('GET /my/dashboard');
             return;
         }
         if (isset($user['otp'])) {
             unset($user['otp']);
             $store->saveUser($user);
         }
         $this->f3->set('message', $this->t('Login verification has been disabled.'));
         $this->f3->mock('GET /my/dashboard');
         return;
     } elseif ($this->f3->get('POST.op') == $this->t('Verify')) {
         $params = $token->getPayload($this->f3->get('POST.otp_params'));
         $this->f3->set('otp_params', $this->f3->get('POST.otp_params'));
         if ($this->f3->exists('POST.tk') === false || !$token->verify($this->f3->get('POST.tk'), 'otp')) {
             $this->f3->set('message', $this->t('SimpleID detected a potential security attack.  Please try again.'));
             page_dashboard();
             return;
         } elseif ($this->f3->exists('POST.otp') === false || $this->f3->get('POST.otp') == '') {
             $this->f3->set('message', $this->t('You need to enter the verification code to complete enabling login verification.'));
         } elseif ($this->verifyOTP($params, $this->f3->get('POST.otp'), 10) === false) {
             $this->f3->set('message', $this->t('The verification code is not correct.'));
         } else {
             $user['otp'] = $params;
             $store->saveUser($user);
             $this->f3->set('message', $this->t('Login verification has been enabled.'));
             $this->f3->mock('GET /my/dashboard');
             return;
         }
     } else {
         $rand = new Random();
         $params = array('type' => 'totp', 'secret' => $rand->bytes(10), 'algorithm' => 'sha1', 'digits' => 6, 'period' => 30, 'drift' => 0, 'remember' => array());
         $this->f3->set('otp_params', $token->generate($params, SecurityToken::OPTION_BIND_SESSION));
     }
     $secret = new BigNum($params['secret'], 256);
     $code = strtr($secret->val(32), '0123456789abcdefghijklmnopqrstuv', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567');
     $code = str_repeat('A', 16 - strlen($code)) . $code;
     for ($i = 0; $i < strlen($code); $i += 4) {
         $this->f3->set('secret' . ($i + 1), substr($code, $i, 4));
     }
     $url = 'otpauth://totp/SimpleID?secret=' . $code . '&digits=' . $params['digits'] . '&period=' . $params['period'];
     $this->f3->set('qr', addslashes($url));
     $this->f3->set('about_otp', $this->t('Login verification adds an extra layer of protection to your account. When enabled, you will need to enter an additional security code whenever you log into SimpleID.'));
     $this->f3->set('otp_warning', $this->t('<strong>WARNING:</strong> If you enable login verification and lose your authenticator app, you will need to <a href="!url">edit your identity file manually</a> before you can log in again.', array('!url' => 'http://simpleid.koinic.net/docs/2/common_problems/#otp')));
     $this->f3->set('setup_otp', $this->t('To set up login verification, following these steps.'));
     $this->f3->set('download_app', $this->t('Download an authenticator app that supports TOTP for your smartphone, such as Google Authenticator.'));
     $this->f3->set('add_account', $this->t('Add your SimpleID account to authenticator app using this key.  If you are viewing this page on your smartphone you can use <a href="!url">this link</a> or scan the QR code to add your account.', array('!url' => $url)));
     $this->f3->set('verify_code', $this->t('To check that your account has been added properly, enter the verification code from your phone into the box below, and click Verify.'));
     $this->f3->set('tk', $token->generate('otp', SecurityToken::OPTION_BIND_SESSION));
     $this->f3->set('otp_label', $this->t('Verification code:'));
     $this->f3->set('submit_button', $this->t('Verify'));
     $this->f3->set('page_class', 'dialog-page');
     $this->f3->set('title', $this->t('Login Verification'));
     $this->f3->set('framekiller', true);
     $this->f3->set('layout', 'auth_otp_setup.html');
     print $tpl->render('page.html');
 }
예제 #2
0
    $f3->set('DEBUG', $config['f3_DEBUG']);
}
// 6. Fix up HTTP request
fix_http_request($f3);
// For SimpleID 1.x compatibility
if (isset($_GET['q'])) {
    $f3->set('PATH', $_GET['q']);
    unset($_GET['q']);
}
// 7. Check for other configuration errors
$i18n = \SimpleID\Util\LocaleManager::instance();
if (@ini_get('register_globals') === 1 || @ini_get('register_globals') === '1' || strtolower(@ini_get('register_globals')) == 'on') {
    $f3->get('logger')->log(\Psr\Log\LogLevel::CRITICAL, 'register_globals is enabled in PHP configuration.');
    $f3->error(500, $i18n->t('register_globals is enabled in PHP configuration, which is not supported by SimpleID.  See the <a href="!url">manual</a> for further information.', array('!url' => 'http://simpleid.koinic.net/docs/2/system-requirements/')));
}
if (!\SimpleID\Crypt\BigNum::loaded()) {
    $f3->get('logger')->log(\Psr\Log\LogLevel::CRITICAL, 'gmp/bcmath PHP extension not loaded.');
    $f3->error(500, $i18n->t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'gmp/bcmath', '!url' => 'http://simpleid.koinic.net/docs/2/system-requirements/')));
}
if (!function_exists('preg_match')) {
    $f3->get('logger')->log(\Psr\Log\LogLevel::CRITICAL, 'pcre PHP extension not loaded.');
    $f3->error(500, $i18n->t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'pcre', '!url' => 'http://simpleid.koinic.net/docs/2/system-requirements/')));
}
if (!function_exists('session_start')) {
    $f3->get('logger')->log(\Psr\Log\LogLevel::CRITICAL, 'session PHP extension not loaded.');
    $f3->error(500, $i18n->t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'session', '!url' => 'http://simpleid.koinic.net/docs/2/system-requirements/')));
}
if (!function_exists('xml_parser_create_ns')) {
    $f3->get('logger')->log(\Psr\Log\LogLevel::CRITICAL, 'xml PHP extension not loaded.');
    $f3->error(500, $i18n->t('One or more required PHP extensions (%extension) is not loaded.  See the <a href="!url">manual</a> for further information on system requirements.', array('%extension' => 'xml', '!url' => 'http://simpleid.koinic.net/docs/2/system-requirements/')));
}
예제 #3
0
 /**
  * Generates a random integer, which will be used to derive a private key
  * for Diffie-Hellman key exchange.  The integer must be less than $stop
  *
  * @param BigNum $stop a prime number as a bignum
  * @return BigNum the random integer as a bignum
  */
 private function generateRandom($stop)
 {
     $duplicate_cache = array();
     $rand = new Random();
     // Used as the key for the duplicate cache
     $rbytes = $stop->val(256);
     if (array_key_exists($rbytes, $duplicate_cache)) {
         list($duplicate, $nbytes) = $duplicate_cache[$rbytes];
     } else {
         if ($rbytes[0] == "") {
             $nbytes = strlen($rbytes) - 1;
         } else {
             $nbytes = strlen($rbytes);
         }
         $mxrand = new BigNum(256);
         $mxrand = $mxrand->pow(new BigNum($nbytes));
         // If we get a number less than this, then it is in the
         // duplicated range.
         $duplicate = $mxrand->mod($stop);
         if (count($duplicate_cache) > 10) {
             $duplicate_cache = array();
         }
         $duplicate_cache[$rbytes] = array($duplicate, $nbytes);
     }
     do {
         $bytes = "" . $rand->bytes($nbytes);
         $n = new BigNum($bytes, 256);
         // Keep looping if this value is in the low duplicated range
     } while ($n->cmp($duplicate) < 0);
     return $n->mod($stop);
 }