Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions application/config/bitauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@
* Add as many roles here as you like.
* Follow the format:
* 'role_slug' => 'Role Description',
*/

);
*/
);

/**
* GAuth window of opportunity when entering code
*/
$config['gauth_range'] = 20;
76 changes: 71 additions & 5 deletions application/controllers/example.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ public function login()
{
$data = array();

if($this->bitauth->login_from_token())
{
// Check if it passed two factor auth
if($this->bitauth->logged_in())
{
// Not require two factor auth
if($redir = $this->session->userdata('redir'))
{
$this->session->unset_userdata('redir');
}

redirect($redir ? $redir : 'example');
} else {
// Redirect to enter challange code
redirect('example/twofactorauth');
}
}

if($this->input->post())
{
$this->form_validation->set_rules('username', 'Username', 'trim|required');
Expand All @@ -65,13 +83,21 @@ public function login()
// Login
if($this->bitauth->login($this->input->post('username'), $this->input->post('password'), $this->input->post('remember_me')))
{
// Redirect
if($redir = $this->session->userdata('redir'))
// Check if it passed two factor auth
if($this->bitauth->logged_in())
{
$this->session->unset_userdata('redir');
// Not require two factor auth
if($redir = $this->session->userdata('redir'))
{
$this->session->unset_userdata('redir');
}

redirect($redir ? $redir : 'example');
} else {
// Redirect to enter challange code
redirect('example/twofactorauth');
}

redirect($redir ? $redir : 'example');

}
else
{
Expand Down Expand Up @@ -192,6 +218,7 @@ public function edit_user($user_id)
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('active', 'Active', '');
$this->form_validation->set_rules('enabled', 'Enabled', '');
$this->form_validation->set_rules('google_auth', 'Two Factor Auth', '');
$this->form_validation->set_rules('password_never_expires', 'Password Never Expires', '');
$this->form_validation->set_rules('groups[]', 'Groups', '');

Expand Down Expand Up @@ -358,4 +385,43 @@ public function logout()
redirect('example');
}

/**
* Example::twofactorauth()
*
*/
public function twofactorauth()
{
$data = array();

if($this->bitauth->logged_in())
{
redirect('example');
}

if($this->input->post())
{
$this->form_validation->set_rules('token', 'Token', 'required');

if($this->form_validation->run() === TRUE)
{
if($this->bitauth->validate_gauth_code($this->input->post('token'),$this->session->userdata($this->bitauth->_cookie_elem_prefix.'user_id')))
{
if($redir = $this->session->userdata('redir'))
{
$this->session->unset_userdata('redir');
}

redirect($redir ? $redir : 'example');
} else
{
$data['error'] = $this->bitauth->get_error();
}
} else {
$data['error'] = validation_errors();
}
}

$this->load->view('example/two_factor_auth', $data);
}

}
1 change: 1 addition & 0 deletions application/language/english/bitauth_lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@
$lang['bitauth_edit_group_failed'] = 'Updating group failed, please notify an administrator.';
$lang['bitauth_del_group_failed'] = 'Deleting group failed, please notify an administrator.';
$lang['bitauth_lang_not_found'] = '(No language entry for "%s" found!)';
$lang['bitauth_invalid_token'] = 'Invalid token!';
14 changes: 14 additions & 0 deletions application/language/english/gauth_lang.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* Input Validation Error Messages
*
*/
$lang['gauth_invalid_range'] = "Invalid window range";
$lang['gauth_invalid_base32'] = "Invalid base32 hash!";
$lang['gauth_invalid_refresh'] = "Invalid refresh window";
$lang['gauth_invalid_code_lenght'] = "Incorrect code length";
/**
* General Error
*/
$lang['gauth_instance_na'] = "GAuth was unable to get the CodeIgniter instance.";
145 changes: 131 additions & 14 deletions application/libraries/Bitauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class Bitauth
private $_all_roles;
private $_error;

// GAuth Config
private $_time_range;

// IF YOU CHANGE THE STRUCTURE OF THE `users` TABLE, THAT CHANGE MUST BE REFLECTED HERE
private $_data_fields = array(
'username','password','password_last_set','password_never_expires','remember_me', 'activation_code',
Expand Down Expand Up @@ -69,14 +72,16 @@ public function __construct()
$this->_date_format = $this->config->item('date_format', 'bitauth');

$this->_all_roles = $this->config->item('roles', 'bitauth');

// Grab the first role on the list as the administrator role
$slugs = array_keys($this->_all_roles);
$this->_admin_role = $slugs[0];

// Specify any extra login fields
$this->_login_fields = array();

// Set GAuth time range on allowed codes
$this->_time_range = $this->config->item('gauth_range', 'bitauth');

// If we're logged in, grab session values. If not, check for a "remember me" cookie
if($this->logged_in())
{
Expand Down Expand Up @@ -140,27 +145,33 @@ public function login($username, $password, $remember = FALSE, $extra = array(),

$this->set_session_values($user);

if($remember != FALSE)
if($remember !== FALSE)
{
$this->update_remember_token($user->username, $user->user_id);
}

$data = array(
'last_login' => $this->timestamp(),
'last_login_ip' => ip2long($_SERVER['REMOTE_ADDR'])
);

// If user logged in, they must have remembered their password.
if( ! empty($user->forgot_code))
{
$data['forgot_code'] = '';
}

// Update last login timestamp and IP
$this->update_user($user->user_id, $data);
if($user->google_auth)
{
return TRUE;
} else {

$this->log_attempt($user->user_id, TRUE);
return TRUE;
$data = array(
'last_login' => $this->timestamp(),
'last_login_ip' => ip2long($_SERVER['REMOTE_ADDR'])
);

// Update last login timestamp and IP
$this->update_user($user->user_id, $data);

$this->log_attempt($user->user_id, TRUE);
return TRUE;
}
}

$this->log_attempt($user->user_id, FALSE);
Expand Down Expand Up @@ -403,11 +414,15 @@ public function get_session_values()
*/
public function update_remember_token($username = NULL, $user_id = NULL)
{
if( ! $this->logged_in())
if( ! $this->session->userdata($this->_cookie_elem_prefix.'google_auth'))
{
return;
if( ! $this->logged_in())
{
return;
}
}


if($username === NULL)
{
$username = $this->username;
Expand Down Expand Up @@ -524,6 +539,12 @@ public function add_user($data, $require_activation = NULL)

$data['password'] = $this->hash_password($data['password']);
$data['password_last_set'] = $this->timestamp();
if(isset($userdata['google_auth']))
{
$data['google_auth'] = 1;
unset($userdata['google_auth']);
$data['google_key'] = $this->generate_gauth_key();
}

$this->db->trans_begin();

Expand Down Expand Up @@ -700,6 +721,22 @@ public function update_user($id, $data)
}
}

if(isset($userdata['google_auth']))
{
if($userdata['google_auth'] == 1)
{
$data['google_auth'] = TRUE;
$data['google_key'] = $this->generate_gauth_key();
unset($userdata['google_auth']);
} else if ($userdata['google_auth'] == 0)
{
$data['google_auth'] = FALSE;
$data['google_key'] = '';
unset($userdata['google_auth']);
}
}


if( ! empty($data['password']))
{
$new_password = $this->hash_password($data['password']);
Expand Down Expand Up @@ -1348,6 +1385,77 @@ public function get_group_by_id($id)
return FALSE;
}

/**
* Bitauth::set_gauth_key()
*
* Set Google Authenticator secret key for user
*
*/
public function set_gauth_key($user_id)
{

}

/**
* Bitauth::set_gauth_key()
*
* Get Google Authenticator secret key by user id
*
*/
public function get_gauth_key($user_id)
{
$query = $this->db->select('google_key')
->from('bitauth_users')
->where('user_id',$user_id)
->get();

$result = $query->row_array();
return $result['google_key'];
}

/**
* Bitauth::generate_gauth_key()
*
* Generate Google Authenticator secret key
*
*/
public function generate_gauth_key()
{
return $this->gauth->generateCode();
}

/**
* Bitauth::generate_gauth_key()
*
* Validate Google Authenticator code
*
*/
public function validate_gauth_code($code = '', $user_id = '')
{
$this->gauth->setRange($this->_time_range);
$this->gauth->setInitKey($this->get_gauth_key($user_id));
if ($this->gauth->validateCode($code))
{
$data = array(
'last_login' => $this->timestamp(),
'last_login_ip' => ip2long($_SERVER['REMOTE_ADDR'])
);

// Update last login timestamp and IP
$this->update_user($this->session->userdata($this->_cookie_elem_prefix.'user_id'),$data);

$this->log_attempt($this->session->userdata($this->_cookie_elem_prefix.'user_id'), TRUE);

$this->session->set_userdata($this->_cookie_elem_prefix.'google_code',$code);
return TRUE;
} else
{
$this->set_error($this->lang->line('bitauth_invalid_token'));
$this->log_attempt($this->session->userdata($this->_cookie_elem_prefix.'user_id'), FALSE);
return FALSE;
}
}

/**
* Bitauth::set_error()
*
Expand Down Expand Up @@ -1416,7 +1524,12 @@ public function generate_code()
*/
public function logged_in()
{
return (bool)$this->session->userdata($this->_cookie_elem_prefix.'username');
if($this->session->userdata($this->_cookie_elem_prefix.'google_auth'))
{
return (bool)$this->session->userdata($this->_cookie_elem_prefix.'username') && (bool)$this->session->userdata($this->_cookie_elem_prefix.'google_code');
} else {
return (bool)$this->session->userdata($this->_cookie_elem_prefix.'username');
}
}

/**
Expand Down Expand Up @@ -1585,6 +1698,10 @@ public function _assign_libraries()
));
$this->phpass = $CI->phpass;

// Load GAuth library
$CI->load->library('GAuth');
$this->gauth = $CI->gauth;

return;
}

Expand Down
Loading