View source
<?php
function ga_login_menu() {
$items = array();
$items['ga_login/create'] = array(
'type' => MENU_NORMAL_ITEM,
'title' => 'Create GA login',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'ga_login_create_form',
),
'access arguments' => array(
'administer users',
),
);
$items['ga_login/test'] = array(
'type' => MENU_NORMAL_ITEM,
'title' => 'Test GA login',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'ga_login_test_form',
),
'access arguments' => array(
'administer users',
),
);
$items['admin/user/ga_login'] = array(
'type' => MENU_NORMAL_ITEM,
'title' => 'GA login',
'description' => 'Administer Google Authenticator login settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'ga_login_admin_settings_form',
),
'access arguments' => array(
'administer ga_login settings',
),
'file' => 'ga_login.admin.inc',
);
return $items;
}
function ga_login_perm() {
return array(
'login without code',
'administer ga_login settings',
);
}
function ga_login_create_form() {
$result = db_query("SELECT uid, name FROM {users}");
while ($account = db_fetch_object($result)) {
$options[$account->uid] = check_plain($account->name);
}
$form['info'] = array(
'#type' => 'markup',
'#value' => '<p>' . t('Everytime you use this form a new key will be generated!') . '</p>',
);
$form['uid'] = array(
'#title' => t('User'),
'#type' => 'select',
'#options' => $options,
'#required' => TRUE,
);
$form['tokentype'] = array(
'#title' => t('Code type'),
'#type' => 'select',
'#options' => array(
'TOTP' => t('Time-based code'),
'HOTP' => t('Counter-based code'),
),
'#default_value' => 'TOTP',
'#required' => TRUE,
'#description' => t('Select the type of code you want to create.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Create code'),
);
return $form;
}
function ga_login_test_form() {
$result = db_query("SELECT uid, name FROM {users}");
while ($account = db_fetch_object($result)) {
$options[$account->uid] = check_plain($account->name);
}
$form['uid'] = array(
'#title' => t('User'),
'#type' => 'select',
'#options' => $options,
'#required' => TRUE,
);
$form['code'] = array(
'#title' => t('Code'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Check code'),
);
return $form;
}
function ga_login_create_form_submit($form, $form_state) {
$uid = $form_state['values']['uid'];
$account = user_load($uid);
module_load_include('php', 'ga_login', 'ga_login.class');
$ga = new ga_loginGA(variable_get('ga_login_totp_skew', 10), variable_get('ga_login_hotp_skew', 10));
$username = _ga_login_username($account);
if (!$ga
->hasToken($username)) {
$key = $ga
->setUser($username, $form_state['values']['tokentype']);
}
$url = $ga
->createUrl($username);
drupal_set_message($url);
drupal_set_message(theme_qr_codes($url));
}
function ga_login_test_form_submit($form, $form_state) {
$uid = $form_state['values']['uid'];
$code = $form_state['values']['code'];
$account = user_load($uid);
module_load_include('php', 'ga_login', 'ga_login.class');
$ga = new ga_loginGA(variable_get('ga_login_totp_skew', 10), variable_get('ga_login_hotp_skew', 10));
$username = _ga_login_username($account);
$keyok = $ga
->authenticateUser($username, $code);
if ($keyok) {
drupal_set_message('Authentication OK');
}
else {
drupal_set_message('Authentication failed');
drupal_set_message($ga
->getErrorText());
}
}
function ga_login_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'user_login_block' || $form_id == 'user_login') {
array_unshift($form['#validate'], $form['#validate'][0]);
$form['#validate'][1] = 'ga_login_user_login_validate';
$form['#validate'][] = 'ga_login_user_login_validate_code_needed';
$form['gacode'] = array(
'#type' => 'textfield',
'#title' => 'Code',
'#maxlength' => 6,
'#size' => 6,
'#required' => FALSE,
);
$form['name']['#weight'] = 1;
$form['pass']['#weight'] = 2;
$form['gacode']['#weight'] = 3;
$form['submit']['#weight'] = 4;
if (isset($form['links'])) {
$form['links']['#weight'] = 5;
}
}
elseif ($form_id == 'user_profile_form') {
$account = user_load($form['#uid']);
$register = $account->uid > 0 ? FALSE : TRUE;
$form['ga_login'] = array(
'#type' => 'fieldset',
'#title' => t('Two factor authentication'),
'#weight' => 1,
'#access' => !$register && user_access('login without code', $account),
);
$data = unserialize($account->data);
$form['ga_login']['ga_login_force_tfa'] = array(
'#type' => 'checkbox',
'#title' => t('Protect my account with two-factor-authentication'),
'#default_value' => isset($data['ga_login_force_tfa']) ? $data['ga_login_force_tfa'] : FALSE,
'#description' => t('Check this box to force two-factor-authentication during login. If you decide to do so and haven\'t yet created your key, then please also refer to <a href="@url">GA Login</a>.', array(
'@url' => url('ga_login/create'),
)),
);
}
}
function ga_login_user_login_validate($form, &$form_state) {
$name = $form_state['values']['name'];
$code = $form_state['values']['gacode'];
$account = user_load(array(
'name' => $name,
));
$form_state['uid'] = $account->uid;
if (_ga_login_force_tfa($account) || !empty($code) || $account->uid == 1 && variable_get('ga_login_always_for_uid1', 0)) {
module_load_include('php', 'ga_login', 'ga_login.class');
$ga = new ga_loginGA(variable_get('ga_login_totp_skew', 10), variable_get('ga_login_hotp_skew', 10));
$username = _ga_login_username($account);
if ($ga
->hasToken($username)) {
$keyok = $ga
->authenticateUser($username, $code);
if (!$keyok) {
form_set_error('gacode', t("Your code isn't valid."));
$form_state['ga_code'] = 'invalid';
}
else {
$form_state['ga_code'] = 'valid';
}
}
}
}
function ga_login_user_login_validate_code_needed($form, &$form_state) {
$name = $form_state['values']['name'];
$code = $form_state['values']['gacode'];
$account = user_load(array(
'name' => $name,
));
if (_ga_login_force_tfa($account) || !empty($code) || $account->uid == 1 && variable_get('ga_login_always_for_uid1', 0)) {
if ($form_state['uid'] && !isset($form_state['ga_code'])) {
form_set_error('gacode');
unset($_GET['destination']);
drupal_set_message(t('You don\'t have a login code yet. This login will only work once. After you log in, you can go to your profile page to generate the GA login code.'), 'warning');
drupal_goto(user_pass_reset_url($account));
}
}
}
function _ga_login_force_tfa($account) {
if (user_access('login without code', $account)) {
$data = unserialize($account->data);
return isset($data['ga_login_force_tfa']) ? $data['ga_login_force_tfa'] : FALSE;
}
return TRUE;
}
function _ga_login_username($account, $encode = TRUE) {
$realm = variable_get('ga_login_textname', variable_get('site_name', 'Drupal'));
$suffix = variable_get('ga_login_textid', '');
$username = $account->name . '@' . $realm . $suffix;
return $encode ? rawurlencode($username) : $username;
}