├── README ├── README.adoc ├── composer.json ├── readme.txt └── u2f.php /README: -------------------------------------------------------------------------------- 1 | == U2F for Wordpress 2 | 3 | NOTE: This project is deprecated and is no longer being maintained. 4 | 5 | This plugin adds support for the two factor authentication standard U2F. 6 | 7 | The functionality is similar to the U2F (Security Key) support available for Google accounts: 8 | 9 | * Users registers U2F devices themselves. 10 | * Users are not required to register devices. 11 | * A user can have multiple devices registered. 12 | * Currently, only Google Chrome is supported. 13 | 14 | 15 | === Installation 16 | 17 | . Install the dependencies using http://getcomposer.org[Composer]. 18 | . Move the wordpress-u2f directory into the `/wp-content/plugins/` directory. 19 | . Activate the plugin through the 'Plugins' menu in WordPress. 20 | . Go to _Settings_ -> _U2F_. 21 | . Set https://developers.yubico.com/U2F/App_ID.html[App ID] to the the base URL of your website, for example _https://mysite.wordpress.com_. 22 | 23 | === Managing devices 24 | U2F devices can be added and removed from the profile screen (accessible by clicking on your name at the top of the screen). 25 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | README -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "yubico/u2flib-server": "dev-master" 4 | } 5 | } -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === U2F for Wordpress === 2 | Contributors: yubico 3 | Tags: authentication, login 4 | Requires at least: 4.0 5 | Tested up to: 4.1 6 | Stable tag: trunk 7 | License: GPLv2 8 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 9 | 10 | Allows users to login using U2F devices. 11 | 12 | == Description == 13 | 14 | This plugin adds support for the two factor authentication standard U2F. 15 | 16 | The functionality is similar to the U2F (Security Key) support available for Google accounts: 17 | 18 | * Users registers U2F devices themselves. 19 | * Users are not required to register devices. 20 | * A user can have multiple devices registered. 21 | * Currently, only Google Chrome is supported. 22 | 23 | 24 | == Installation == 25 | 26 | 1. Move the wordpress-u2f directory into the `/wp-content/plugins/` directory 27 | 1. Activate the plugin through the 'Plugins' menu in WordPress 28 | 1. Go to _Settings_ -> _U2F_. 29 | 1. Set https://developers.yubico.com/U2F/App_ID.html[App ID] to the the base URL of your website, for example _https://mysite.wordpress.com_. 30 | 31 | == Changelog == 32 | 33 | = 0.2 = 34 | * Initial release. 35 | 36 | == Upgrade Notice == 37 | 38 | = 0.2 = 39 | None 40 | -------------------------------------------------------------------------------- /u2f.php: -------------------------------------------------------------------------------- 1 | 78 | ' class="regular-text code"> 79 | 86 | ' class="regular-text"> 87 | 98 |
99 |

U2F Settings

100 |
101 | 102 | 107 | 108 |
109 |
110 | ID); 131 | ?> 132 |

U2F Devices

133 | 134 | 135 | 136 | 163 | 164 |
Registered Devices 137 | 138 | 139 | 140 | 141 | 150 | 153 | 154 | 155 |
DeviceDelete
142 | 149 | 151 | 152 |
156 |
157 | 158 | Register a new U2F Device 159 | 162 |
165 | 166 | 187 | time < time() - 300) { 199 | return new WP_Error('u2f_registration_failed', "The u2f registration request for $user_id expired before reply"); 200 | } 201 | unset($req->time); 202 | $registerResponse = $_POST['u2f_register_response']; 203 | 204 | $registration = $u2f->doRegister($req, json_decode(stripslashes($registerResponse))); 205 | $now = new DateTime(); 206 | $registration->dateRegistered = $now->getTimeStamp(); 207 | 208 | $regs = u2f_get_registrations($user_id); 209 | array_push($regs, $registration); 210 | update_user_option($user_id, 'u2f_user_registrations', $regs); 211 | } else if(isset($_POST['u2f_unregister'])) { 212 | $handles = $_POST['u2f_unregister']; 213 | $regs = u2f_get_registrations($user_id); 214 | 215 | foreach($handles as $handle) { 216 | foreach($regs as $key => $reg) { 217 | if($reg->keyHandle == $handle) { 218 | unset($regs[$key]); 219 | } 220 | } 221 | } 222 | update_user_option($user_id, 'u2f_user_registrations', $regs); 223 | } 224 | } 225 | 226 | function u2f_store_regData($user, $regData) { 227 | $regData->time = time(); 228 | update_user_option($user->ID, 'u2f_user_regData', $regData); 229 | } 230 | 231 | function ajax_u2f_register_begin() { 232 | global $u2f; 233 | $user = wp_get_current_user(); 234 | if(is_user_logged_in()) { 235 | 236 | try { 237 | $regData = $u2f->getRegisterData(u2f_get_registrations($user->ID)); 238 | } catch( Exception $e ) { 239 | $errors->add('u2f_error', "ERROR: There was an error obtaining U2F registration data: " . $data->errorMessage); 240 | } 241 | 242 | u2f_store_regData($user, $regData[0]); 243 | echo json_encode($regData); 244 | } 245 | die(); 246 | } 247 | add_action('wp_ajax_u2f_register', 'ajax_u2f_register_begin'); 248 | 249 | function validate_u2f_register(&$errors, $update=null, &$user=null) { 250 | if(isset($_POST['u2f_register_response'])) { 251 | $data = json_decode(stripslashes($_POST['u2f_register_response']), true); 252 | if(isset($data['errorCode'])) { 253 | $errors->add('u2f_error', "ERROR: There was an error registering your U2F device (error code ".$data['errorCode'].")."); 254 | } 255 | } 256 | } 257 | add_action('user_profile_update_errors', 'validate_u2f_register'); 258 | 259 | add_action('profile_personal_options', 'u2f_profile_fields'); 260 | add_action('personal_options_update', 'u2f_profile_save'); 261 | 262 | /* 263 | * AUTHENTICATION 264 | */ 265 | 266 | $u2f_transient = null; 267 | 268 | function u2f_login($user) { 269 | global $u2f; 270 | $options = get_option('u2f_settings'); 271 | 272 | if(empty($options['appId'])) return $user; 273 | 274 | if(wp_check_password($_POST['pwd'], $user->data->user_pass, $user->ID) && !isset($_POST['u2f'])) { 275 | $registrations = u2f_get_registrations($user->ID); 276 | if(!$registrations) { 277 | return $user; 278 | } 279 | $authData = $u2f->getAuthenticateData($registrations); 280 | //if(false) { 281 | // return new WP_Error('u2f_error_'.$authData['errorCode'], 'The U2F validation server is unreachable.'); 282 | //} 283 | global $u2f_transient; 284 | $u2f_transient = $authData; 285 | 286 | update_user_option($user->ID, 'u2f_user_reqData', $authData); 287 | 288 | if(has_devices($authData)) { 289 | return new WP_Error('authentication_failed', 'Touch your U2F device now.'); 290 | } 291 | } else if(isset($_POST['u2f'])) { 292 | $authenticateResponse = json_decode(stripslashes($_POST['u2f'])); 293 | 294 | if(property_exists($authenticateResponse, 'errorCode')) { 295 | switch($authenticateResponse->errorCode) { 296 | case 4: 297 | return new WP_Error('u2f_error', 'Device ineligible. Try another device.'); 298 | case 5: 299 | return new WP_Error('u2f_error', 'Authentication timed out. Please try again.'); 300 | default: 301 | return new WP_Error('u2f_error', 'Client error.'); 302 | } 303 | } 304 | 305 | //$properties = array('last-ip' => $_SERVER['REMOTE_ADDR']); 306 | $authRequest = get_user_option('u2f_user_reqData', $user->ID); 307 | 308 | $u2f->doAuthenticate($authRequest, u2f_get_registrations($user->ID), $authenticateResponse); 309 | } 310 | 311 | return $user; 312 | } 313 | 314 | function has_devices($authData) { 315 | return sizeof($authData > 0); 316 | } 317 | 318 | function u2f_form() { 319 | global $u2f_transient; 320 | $options = get_option('u2f_settings'); 321 | 322 | if(empty($options['appId'])) { 323 | _log("No appId set!"); 324 | ?> 325 |

326 | WARNING: The U2F plugin has not been configured, and is therefore disabled. 327 |

328 | 332 | 333 | 366 | 374 | --------------------------------------------------------------------------------