/** * Applies the upgrade. */ function apply() { $token = new SecurityToken(); if ($this->f3->exists('POST.tk') === false || !$token->verify($this->f3->get('POST.tk'), 'upgrade_selection')) { $this->f3->set('message', $this->t('SimpleID detected a potential security attack. Please try again.')); $this->info(); return; } $step = $token->generate(array('upgid' => $this->f3->get('POST.upgid'), 'step' => 0), SecurityToken::OPTION_BIND_SESSION); $this->f3->set('step', $step); $this->f3->set('applying_upgrade', $this->t('Applying upgrade...')); $this->f3->set('title', $this->t('Upgrade')); $this->f3->set('page_class', 'dialog-page'); $this->f3->set('layout', 'upgrade_apply.html'); print $tpl->render('page.html'); }
public function delete($f3, $params) { $this->checkHttps('error', true); parse_str($this->f3->get('BODY'), $delete); header('Content-Type: application/json'); $token = new SecurityToken(); if (!isset($delete['tk']) || !$token->verify($delete['tk'], 'apps')) { $this->f3->status(401); print json_encode(array('error' => 'unauthorized', 'error_description' => $this->t('Unauthorized'))); return; } $auth = AuthManager::instance(); $user = $auth->getUser(); $prefs =& $user->clients; if (!isset($prefs[$params['cid']])) { $this->f3->status(404); print json_encode(array('error' => 'not_found', 'error_description' => $this->t('Not found'))); return; } $mgr = ModuleManager::instance(); $mgr->invokeAll('revokeApp', $params['cid']); unset($prefs[$params['cid']]); $store = StoreManager::instance(); $store->saveUser($user); print json_encode(array('result' => 'success', 'result_description' => $this->t('App has been deleted.'))); }
/** * Processes a user response from the {@link consentForm()} function. * * @since 2.0 */ function consent() { $auth = AuthManager::instance(); $token = new SecurityToken(); $store = StoreManager::instance(); if (!$auth->isLoggedIn()) { $auth_module = $this->mgr->getModule('SimpleID\\Auth\\AuthModule'); $auth_module->loginForm(); return; } $user = $auth->getUser(); $form_state = $token->getPayload($this->f3->get('POST.fs')); $request = $form_state['rq']; $response = $form_state['rs']; if (!$token->verify($this->f3->get('POST.tk'), 'oauth_consent')) { $this->logger->log(LogLevel::WARNING, 'Security token ' . $this->f3->get('POST.tk') . ' invalid.'); $this->f3->set('message', $this->t('SimpleID detected a potential security attack. Please try again.')); $this->consentForm($request, $response); return; } if ($this->f3->get('POST.op') == $this->t('Deny')) { $response->setError('access_denied')->renderRedirect(); return; } else { $this->mgr->invokeRefAll('oAuthConsentFormSubmit', $form_state); $client = $store->loadClient($request['client_id'], 'SimpleID\\Protocols\\OAuth\\OAuthClient'); $cid = $client->getStoreID(); $now = time(); $consents = array('oauth' => $this->f3->get('POST.prefs.consents.oauth')); if (isset($user->clients[$cid])) { $prefs = $user->clients[$cid]; } else { $prefs = array('oauth' => array(), 'store_id' => $client->getStoreID(), 'display_name' => $client->getDisplayName(), 'display_html' => $client->getDisplayHTML(), 'first_time' => $now, 'consents' => array()); } $prefs['last_time'] = $now; $prefs['consents'] = array_merge($prefs['consents'], $consents); if ($this->f3->exists('POST.prefs.oauth.prompt_none') && $this->f3->exists('POST.prefs.oauth.prompt_none') == 'true') { $prefs['oauth']['prompt_none'] = true; } $user->clients[$cid] = $prefs; $store->saveUser($user); } $this->processAuthRequest($request, $response); }
/** * 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'); }
/** * Processes a user response from the {@link simpleid_openid_consent_form()} function. * * If the user verifies the relying party, an OpenID response will be sent to * the relying party. Otherwise, the dashboard will be displayed to the user. */ public function consent() { $auth = AuthManager::instance(); $token = new SecurityToken(); $store = StoreManager::instance(); if (!$auth->isLoggedIn()) { $auth_module = $this->mgr->getModule('SimpleID\\Auth\\AuthModule'); $auth_module->loginForm(); return; } $user = $auth->getUser(); $form_state = $token->getPayload($this->f3->get('POST.fs')); $request = $form_state['rq']; $response = $form_state['rs']; $reason = $form_state['code']; if (!$token->verify($this->f3->get('POST.tk'), 'openid_consent')) { $this->logger->log(LogLevel::WARNING, 'Security token ' . $this->f3->get('POST.tk') . ' invalid.'); $this->f3->set('message', $this->t('SimpleID detected a potential security attack. Please try again.')); $this->consentForm($request, $response, $reason); return; } $return_to = $response['return_to']; if ($return_to == null) { $return_to = $request['openid.return_to']; } if ($this->f3->get('POST.op') == $this->t('Cancel')) { $response = $this->createErrorResponse($request, false); if (!$return_to) { $this->f3->set('message', $this->t('Log in cancelled.')); } } else { $this->mgr->invokeRefAll('openIDConsentFormSubmit', $form_state); $consents = array('openid' => $this->f3->exists('POST.prefs.consents.openid') && $this->f3->exists('POST.prefs.consents.openid') == 'true'); $this->logActivity($request, $consents); $this->signResponse($response, isset($response['assoc_handle']) ? $response['assoc_handle'] : NULL); if (!$return_to) { $this->f3->set('message', $this->t('You were logged in successfully.')); } } if ($return_to) { $response->render($return_to); } else { $this->f3->reroute('/'); } }
/** * Attempts to log in a user, using the credentials specified in the * HTTP request. * * @param \Base $f3 * @param array $params */ public function login($f3, $params) { $params['destination'] = isset($params[1]) ? $params[1] : ''; $this->f3->set('PARAMS.destination', $params['destination']); $token = new SecurityToken(); $token->gc(); // Require HTTPS or return an error $this->checkHttps('error', true); if ($this->f3->exists('POST.fs') === false) { $form_state = array('mode' => AuthManager::MODE_CREDENTIALS); if (in_array($this->f3->get('GET.mode'), array(AuthManager::MODE_VERIFY, AuthManager::MODE_REENTER_CREDENTIALS))) { $form_state['mode'] = $this->f3->get('GET.mode'); } $this->loginForm($params, $form_state); return; } $form_state = $token->getPayload($this->f3->get('POST.fs')); if ($form_state === false) { $form_state = array('mode' => AuthManager::MODE_CREDENTIALS); } $mode = $form_state['mode']; if (!in_array($mode, array(AuthManager::MODE_CREDENTIALS, AuthManager::MODE_REENTER_CREDENTIALS, AuthManager::MODE_VERIFY))) { $this->f3->set('message', $this->t('SimpleID detected a potential security attack on your log in. Please log in again.')); $this->loginForm($params, $form_state); return; } if ($this->f3->exists('POST.tk') === false) { if (isset($params['destination'])) { // User came from a log in form. $this->f3->set('message', $this->t('You seem to be attempting to log in from another web page. You must use this page to log in.')); } $this->loginForm($params, $form_state); return; } if (!$token->verify($this->f3->get('POST.tk'), 'login')) { $this->logger->log(LogLevel::WARNING, 'Login attempt: Security token ' . $this->f3->get('POST.tk') . ' invalid.'); $this->f3->set('message', $this->t('SimpleID detected a potential security attack on your log in. Please log in again.')); $this->loginForm($params, $form_state); return; } if ($this->f3->exists('POST.op') && $this->f3->get('POST.op') == $this->t('Cancel')) { $results = $this->mgr->invokeAll('loginFormCancelled', $form_state); if (!array_reduce($results, function ($overall, $result) { return $result ? true : $overall; }, false)) { $this->fatalError($this->t('Login cancelled without a proper request.')); } return; } // If the user is already logged in, return if ($mode == AuthManager::MODE_CREDENTIALS && $this->auth->isLoggedIn()) { $this->f3->reroute('/'); } $results = $this->mgr->invokeRefAll('loginFormValidate', $form_state); if (!array_reduce($results, function ($overall, $result) { return $result !== null && $result === false ? false : $overall; }, true)) { $this->loginForm($params, $form_state); return; } $modules = $this->mgr->getModules(); foreach ($modules as $module) { $results = $this->mgr->invokeRef($module, 'loginFormSubmit', $form_state); if ($results === false) { $this->loginForm($params, $form_state); return; } if (is_array($results)) { if (isset($results['uid'])) { $form_state['uid'] = $results['uid']; } if (isset($results['auth_level'])) { $form_state['auth_level'] = isset($form_state['auth_level']) ? max($form_state['auth_level'], $results['auth_level']) : $results['auth_level']; } if (!isset($form_state['modules'])) { $form_state['modules'] = array(); } $form_state['modules'][] = $module; } } if (!isset($form_state['uid'])) { // No user $this->loginForm($params, $form_state); return; } if ($mode == AuthManager::MODE_CREDENTIALS) { $form_state['mode'] = AuthManager::MODE_VERIFY; $forms = $this->mgr->invokeRefAll('loginForm', $form_state); if (count($forms) > 0) { $this->loginForm($params, $form_state); return; } } $this->auth->login($form_state['uid'], $form_state['auth_level'], $form_state['modules'], $form_state); $this->f3->reroute('/' . $params['destination']); }