RFC 2289 to protect your weblog in less trustworthy environments, like internet cafés.
Version: 1.2
Author: Marcel Bokhorst
Author URI: http://blog.bokhorst.biz/
*/
/*
Copyright 2009 Marcel Bokhorst
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
Acknowledgments
PHP One-Time Passwords class by Tomas Mrozek
See http://sourceforge.net/projects/php-otp/ for details
This class is publised under the GNU Lesser General Public License version 3 or later
jqPrint by tanathos
See http://plugins.jquery.com/project/jqPrint
This jQuery plugin is publised under the GNU General Public License and MIT License
*/
#error_reporting(E_ALL);
// Check PHP version
if (version_compare(PHP_VERSION, '5.0.0', '<')) {
die('One-Time Password requires at least PHP 5.0.0');
}
// Include OTP class
require_once('include/class.otp.php');
// Get challenge
if (isset($_GET['action']) && $_GET['action'] == 'challenge') {
@header('Content-Type: text/html; charset=' . get_option('blog_charset'));
try {
// Get data
global $wpdb;
$otp_user = $wpdb->escape(trim($_GET['otp_user']));
$otp_table = $wpdb->prefix . 'otp';
$otp_row = $wpdb->get_row("SELECT seed, algorithm, sequence FROM " . $otp_table . " WHERE user='" . $otp_user . "'");
// Create challenge
if ($otp_row != null && $otp_row->sequence >= 0) {
$otp_class = new otp();
echo $otp_class->createChallenge($otp_row->seed, $otp_row->sequence, $otp_row->algorithm);
}
}
catch (Exception $e) {
echo $e->getMessage();
}
exit;
}
// Get seed
if (isset($_GET['action']) && $_GET['action'] == 'seed') {
@header('Content-Type: text/html; charset=' . get_option('blog_charset'));
$otp_class = new otp();
echo $otp_class->generateSeed();
exit;
}
// Handle plugin activation
if (!function_exists('otp_activate')) {
function otp_activate() {
global $wpdb;
// Check if table exists
$otp_table = $wpdb->prefix . 'otp';
if ($wpdb->get_var("SHOW TABLES LIKE '" . $otp_table . "'") != $otp_table) {
// Create table
$sql = "CREATE TABLE " . $otp_table . " (
user VARCHAR(60) NOT NULL,
seed VARCHAR(60) NOT NULL,
algorithm VARCHAR(60) NOT NULL,
sequence INT(11) NOT NULL,
hash VARCHAR(60) NOT NULL,
generated DATETIME NOT NULL,
last_login DATETIME NULL,
UNIQUE KEY user (user)
);";
if ($wpdb->query($sql) === false)
$wpdb->print_error();
// Store database version
update_option('otp_dbver', 1);
}
// Update table definition
else if (get_option('otp_dbver') < 1) {
$sql = "ALTER TABLE " . $otp_table . " CHANGE COLUMN time generated DATETIME NOT NULL;";
if ($wpdb->query($sql) === false)
$wpdb->print_error();
$sql = "ALTER TABLE " . $otp_table . " ADD COLUMN last_login DATETIME NULL;";
if ($wpdb->query($sql) === false)
$wpdb->print_error();
}
}
}
// Handle plugin deactivation
function otp_deactivate() {
// Cleanup if requested
if (get_option('otp_cleanup')) {
global $wpdb;
// Check if table exists
$otp_table = $wpdb->prefix . 'otp';
if ($wpdb->get_var("SHOW TABLES LIKE '" . $otp_table . "'") == $otp_table) {
// Delete table
$sql = "DROP TABLE " . $otp_table . ";";
if ($wpdb->query($sql) === false)
$wpdb->print_error();
}
// Delete options
delete_option('otp_dbver');
delete_option('otp_cleanup');
}
}
// Handle initialize
function otp_init() {
// Only load styles and scripts when necessary
if (is_admin() || strpos($_SERVER['REQUEST_URI'], 'wp-login')) {
// I18n
$plugin_dir = basename(dirname(__FILE__));
load_plugin_textdomain('one-time-password', 'wp-content/plugins/' . $plugin_dir, $plugin_dir );
// Enqueue style sheet
if (function_exists('wp_register_style')) {
$plugin_url = WP_PLUGIN_URL . '/' . plugin_basename(dirname(__FILE__));
wp_register_style('otp_style', $plugin_url . '/otp.css');
if (function_exists('wp_enqueue_style'))
wp_enqueue_style('otp_style');
}
// Enqueue scripts
if (function_exists('wp_enqueue_script')) {
wp_enqueue_script('jquery');
if (is_admin())
wp_enqueue_script('printElement', '/' . PLUGINDIR . '/one-time-password/js/jquery.jqprint.js');
}
}
}
// Modify login head
function otp_login_head() {
// Print styles and scripts not called on login page
if (function_exists('wp_print_styles'))
wp_print_styles();
if (function_exists('wp_print_scripts'))
wp_print_scripts();
}
// Modify login form
function otp_login_form() {
?>
escape(trim($_POST['log']));
$otp_table = $wpdb->prefix . 'otp';
$otp_row = $wpdb->get_row('SELECT seed, algorithm, sequence, hash FROM ' . $otp_table . " WHERE user='" . $otp_user . "'");
// Check data
if ($otp_row != null && $otp_row->sequence >= 0) {
// Check password
$otp_class = new otp();
$otp_data = $otp_class->initializeOtp($otp_row->hash, $otp_row->seed, $otp_row->sequence, $otp_row->algorithm);
$otp_auth = $otp_class->authAgainstHexOtp($_POST['pwd'], $otp_data['previous_hex_otp'], 'previous', $otp_row->sequence, $otp_row->algorithm);
if ($otp_auth['result']) {
// Update data
$next_seq = $otp_row->sequence - 1;
$query = "UPDATE " . $otp_table . " SET sequence=" . $next_seq . ", hash='" . $otp_auth['otp']['previous_hex_otp'] . "', last_login=now();";
if ($wpdb->query($query) === false)
$wpdb->print_error();
// Athenticate user
return new WP_User($otp_user);
}
}
// Fallback to other handlers
return null;
}
// Fail-safe
catch (Exception $e) {
return null;
}
}
// Register options page
function otp_admin_menu() {
if (function_exists('add_options_page'))
add_options_page(__('One-Time Password Administration', 'one-time-password'), __('One-Time Password', 'one-time-password'), 0, __FILE__, 'otp_administration');
}
// Handle option page
function otp_administration() {
// Check minimal wordpress version
global $wp_version;
if (version_compare($wp_version, '2.8') < 0) {
echo '
';
return;
}
// Reference database
global $wpdb;
$otp_table = $wpdb->prefix . 'otp';
// Instantiate OTP
$otp_class = new otp();
// Get current user
global $current_user;
get_currentuserinfo();
$otp_user = $wpdb->escape($current_user->user_login);
// Output header
echo '
' . __('One-Time Password list', 'one-time-password'); echo ' ' . __('should be generated', 'one-time-password') . '