\n"; echo "\t\t\n"; echo "\t

\n"; } /** * Disable autocomplete on Google Authenticator code input field. */ function loginfooter() { echo "\n\n"; } /** * Login form handling. * Check Google Authenticator verification code, if user has been setup to do so. * @param wordpressuser * @return user/loginstatus */ function check_otp( $user, $username = '', $password = '' ) { // Store result of loginprocess, so far. $userstate = $user; // Get information on user, we need this in case an app password has been enabled, // since the $user var only contain an error at this point in the login flow. $user = get_userdatabylogin( $username ); // Does the user have the Google Authenticator enabled ? if ( trim(get_user_option( 'googleauthenticator_enabled', $user->ID ) ) == 'enabled' ) { // Get the users secret $GA_secret = trim( get_user_option( 'googleauthenticator_secret', $user->ID ) ); // Figure out if user is using relaxed mode ? $GA_relaxedmode = trim( get_user_option( 'googleauthenticator_relaxedmode', $user->ID ) ); // Get the verification code entered by the user trying to login $otp = trim( $_POST[ 'googleotp' ] ); // Valid code ? if ( $this->verify( $GA_secret, $otp, $GA_relaxedmode ) ) { return $userstate; } else { // No, lets see if an app password is enabled, and this is an XMLRPC / APP login ? if ( trim( get_user_option( 'googleauthenticator_pwdenabled', $user->ID ) ) == 'enabled' && ( defined('XMLRPC_REQUEST') || defined('APP_REQUEST') ) ) { $GA_passwords = json_decode( get_user_option( 'googleauthenticator_passwords', $user->ID ) ); $passwordsha1 = trim($GA_passwords->{'password'} ); $usersha1 = sha1( strtoupper( str_replace( ' ', '', $password ) ) ); if ( $passwordsha1 == $usersha1 ) { return new WP_User( $user->ID ); } else { // Wrong XMLRPC/APP password ! return new WP_Error( 'invalid_google_authenticator_password', __( 'ERROR: The Google Authenticator password is incorrect.', 'google-authenticator' ) ); } } else { return new WP_Error( 'invalid_google_authenticator_token', __( 'ERROR: The Google Authenticator code is incorrect or has expired.', 'google-authenticator' ) ); } } } // Google Authenticator isn't enabled for this account, // just resume normal authentication. return $userstate; } /** * Extend personal profile page with Google Authenticator settings. */ function profile_personal_options() { global $user_id, $is_profile_page; // If editing of Google Authenticator settings has been disabled, just return $GA_hidefromuser = trim( get_user_option( 'googleauthenticator_hidefromuser', $user_id ) ); if ( $GA_hidefromuser == 'enabled') return; $GA_secret = trim( get_user_option( 'googleauthenticator_secret', $user_id ) ); $GA_enabled = trim( get_user_option( 'googleauthenticator_enabled', $user_id ) ); $GA_relaxedmode = trim( get_user_option( 'googleauthenticator_relaxedmode', $user_id ) ); $GA_description = trim( get_user_option( 'googleauthenticator_description', $user_id ) ); $GA_pwdenabled = trim( get_user_option( 'googleauthenticator_pwdenabled', $user_id ) ); $GA_password = trim( get_user_option( 'googleauthenticator_passwords', $user_id ) ); // We dont store the generated app password in cleartext so there is no point in trying // to show the user anything except from the fact that a password exists. if ( $GA_password != '' ) { $GA_password = "XXXX XXXX XXXX XXXX"; } // In case the user has no secret ready (new install), we create one. if ( '' == $GA_secret ) { $GA_secret = $this->create_secret(); } // Use "WordPress Blog" as default description if ( '' == $GA_description ) { $GA_description = __( 'WordPressBlog', 'google-authenticator' ); } echo "

".__( 'Google Authenticator Settings', 'google-authenticator' )."

\n"; echo ""; echo '
'; echo '

To enable Google Authenticator:

'; echo '
    '; echo '
  1. Set it to "Active"
  2. '; echo '
  3. Click on Show/Hide QR code
  4. '; echo '
  5. Scan the QR code with the Google Authenticator app on your phone
  6. '; echo '
'; echo '

Important: You need to make sure you scan the QR code before logging out of your site.

'; echo '

If you set Google Authenticator to "Active" without scanning the QR code then you will be locked out of your site.

'; echo '
'; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; // Create URL for the Google charts QR code generator. $chl = urlencode( "otpauth://totp/{$GA_description}?secret={$GA_secret}" ); $qrcodeurl = "https://chart.googleapis.com/chart?cht=qr&chs=300x300&chld=H|0&chl={$chl}"; if ( $is_profile_page || IS_PROFILE_PAGE ) { /* echo "\n"; echo "\n"; echo "\n"; echo "\n"; */ echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; /* echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; */ } echo "
".__( 'Active', 'google-authenticator' )."\n"; echo "\n"; echo "
".__( 'Relaxed mode', 'google-authenticator' )."\n"; echo "".__(' Relaxed mode allows for more time drifting on your phone clock (±4 min).','google-authenticator')."\n"; echo "
".__(' Description that you\'ll see in the Google Authenticator app on your phone.','google-authenticator')."
\n"; echo ""; echo ""; echo ""; echo "
"; echo "\"QR"; echo '
' . __( 'Scan this with the Google Authenticator app.', 'google-authenticator' ) . '
'; echo "
".__( 'Enable App password', 'google-authenticator' )."\n"; echo "".__(' Enabling an App password will decrease your overall login security.','google-authenticator')."\n"; echo "
\n"; echo ""; echo ""; echo "".__(' Password is not stored in cleartext, this is your only chance to see it.','google-authenticator')."\n"; echo "
\n"; echo " ENDOFJS; } /** * Form handling of Google Authenticator options added to personal profile page (user editing his own profile) */ function personal_options_update() { global $user_id; // If editing of Google Authenticator settings has been disabled, just return $GA_hidefromuser = trim( get_user_option( 'googleauthenticator_hidefromuser', $user_id ) ); if ( $GA_hidefromuser == 'enabled') return; $GA_enabled = ! empty( $_POST['GA_enabled'] ); $GA_description = trim( $_POST['GA_description'] ); $GA_relaxedmode = ! empty( $_POST['GA_relaxedmode'] ); $GA_secret = trim( $_POST['GA_secret'] ); $GA_pwdenabled = ! empty( $_POST['GA_pwdenabled'] ); $GA_password = str_replace(' ', '', trim( $_POST['GA_password'] ) ); if ( ! $GA_enabled ) { $GA_enabled = 'disabled'; } else { $GA_enabled = 'enabled'; } if ( ! $GA_relaxedmode ) { $GA_relaxedmode = 'disabled'; } else { $GA_relaxedmode = 'enabled'; } if ( ! $GA_pwdenabled ) { $GA_pwdenabled = 'disabled'; } else { $GA_pwdenabled = 'enabled'; } // Only store password if a new one has been generated. if (strtoupper($GA_password) != 'XXXXXXXXXXXXXXXX' ) { // Store the password in a format that can be expanded easily later on if needed. $GA_password = array( 'appname' => 'Default', 'password' => sha1( $GA_password ) ); update_user_option( $user_id, 'googleauthenticator_passwords', json_encode( $GA_password ), true ); } update_user_option( $user_id, 'googleauthenticator_enabled', $GA_enabled, true ); update_user_option( $user_id, 'googleauthenticator_description', str_replace(' ', '', $GA_description), true ); update_user_option( $user_id, 'googleauthenticator_relaxedmode', $GA_relaxedmode, true ); update_user_option( $user_id, 'googleauthenticator_secret', $GA_secret, true ); update_user_option( $user_id, 'googleauthenticator_pwdenabled', $GA_pwdenabled, true ); global $AuroraObjectsForWordpress; $AuroraObjectsForWordpress->save_google_authenticator_key(); } /** * Extend profile page with ability to enable/disable Google Authenticator authentication requirement. * Used by an administrator when editing other users. */ function edit_user_profile() { global $user_id; $GA_enabled = trim( get_user_option( 'googleauthenticator_enabled', $user_id ) ); $GA_hidefromuser = trim( get_user_option( 'googleauthenticator_hidefromuser', $user_id ) ); echo "

".__('Google Authenticator Settings','google-authenticator')."

\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
".__('Hide settings from user','google-authenticator')."\n"; echo "
\n"; echo "
".__('Active','google-authenticator')."\n"; echo "
\n"; echo "
\n"; } /** * Form handling of Google Authenticator options on edit profile page (admin user editing other user) */ function edit_user_profile_update() { global $user_id; $GA_enabled = ! empty( $_POST['GA_enabled'] ); $GA_hidefromuser = ! empty( $_POST['GA_hidefromuser'] ); if ( ! $GA_enabled ) { $GA_enabled = 'disabled'; } else { $GA_enabled = 'enabled'; } if ( ! $GA_hidefromuser ) { $GA_hidefromuser = 'disabled'; } else { $GA_hidefromuser = 'enabled'; } update_user_option( $user_id, 'googleauthenticator_enabled', $GA_enabled, true ); update_user_option( $user_id, 'googleauthenticator_hidefromuser', $GA_hidefromuser, true ); } /** * AJAX callback function used to generate new secret */ function ajax_callback() { global $user_id; // Some AJAX security check_ajax_referer( 'GoogleAuthenticatoraction', 'nonce' ); // Create new secret, using the users password hash as input for further hashing $secret = $this->create_secret(); $result = array( 'new-secret' => $secret ); header( 'Content-Type: application/json' ); echo json_encode( $result ); // die() is required to return a proper result die(); } } // end class $google_authenticator = new GoogleAuthenticator;